• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/scsi/bfa/
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 *  n2n.c n2n implementation.
20 */
21#include <bfa.h>
22#include <bfa_svc.h>
23#include "fcs_lport.h"
24#include "fcs_rport.h"
25#include "fcs_trcmod.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, N2N);
29
30/**
31 *   Called by fcs/port to initialize N2N topology.
32 */
33void
34bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port)
35{
36}
37
38/**
39 *   Called by fcs/port to notify transition to online state.
40 */
41void
42bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port)
43{
44	struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
45	struct bfa_port_cfg_s *pcfg = &port->port_cfg;
46	struct bfa_fcs_rport_s *rport;
47
48	bfa_trc(port->fcs, pcfg->pwwn);
49
50	/*
51	 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
52	 * and assign an Address. if not, we need to wait for its PLOGI.
53	 *
54	 * If our PWWN is < than that of the remote port, it will send a PLOGI
55	 * with the PIDs assigned. The rport state machine take care of this
56	 * incoming PLOGI.
57	 */
58	if (memcmp
59	    ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
60	     sizeof(wwn_t)) > 0) {
61		port->pid = N2N_LOCAL_PID;
62		/**
63		 * First, check if we know the device by pwwn.
64		 */
65		rport = bfa_fcs_port_get_rport_by_pwwn(port,
66						       n2n_port->rem_port_wwn);
67		if (rport) {
68			bfa_trc(port->fcs, rport->pid);
69			bfa_trc(port->fcs, rport->pwwn);
70			rport->pid = N2N_REMOTE_PID;
71			bfa_fcs_rport_online(rport);
72			return;
73		}
74
75		/*
76		 * In n2n there can be only one rport. Delete the old one whose
77		 * pid should be zero, because it is offline.
78		 */
79		if (port->num_rports > 0) {
80			rport = bfa_fcs_port_get_rport_by_pid(port, 0);
81			bfa_assert(rport != NULL);
82			if (rport) {
83				bfa_trc(port->fcs, rport->pwwn);
84				bfa_fcs_rport_delete(rport);
85			}
86		}
87		bfa_fcs_rport_create(port, N2N_REMOTE_PID);
88	}
89}
90
91/**
92 *   Called by fcs/port to notify transition to offline state.
93 */
94void
95bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port)
96{
97	struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
98
99	bfa_trc(port->fcs, port->pid);
100	port->pid = 0;
101	n2n_port->rem_port_wwn = 0;
102	n2n_port->reply_oxid = 0;
103}
104