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