upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / scsi / bfa / n2n.c
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
28 BFA_TRC_FILE(FCS, N2N);
29
30 /**
31  *   Called by fcs/port to initialize N2N topology.
32  */
33 void
34 bfa_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  */
41 void
42 bfa_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  */
94 void
95 bfa_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
105