blob: 25fc96c9081f4d930603e7cc5f25164c82834d97 [file] [log] [blame]
dea31012005-04-17 16:05:31 -05001/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04003 * Fibre Channel Host Bus Adapters. *
James Smarte47c9092008-02-08 18:49:26 -05004 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04005 * EMULEX and SLI are trademarks of Emulex. *
dea31012005-04-17 16:05:31 -05006 * www.emulex.com *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -04007 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
dea31012005-04-17 16:05:31 -05008 * *
9 * This program is free software; you can redistribute it and/or *
James.Smart@Emulex.Comc44ce172005-06-25 10:34:39 -040010 * modify it under the terms of version 2 of the GNU General *
11 * Public License as published by the Free Software Foundation. *
12 * This program is distributed in the hope that it will be useful. *
13 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
14 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
15 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
16 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17 * TO BE LEGALLY INVALID. See the GNU General Public License for *
18 * more details, a copy of which can be found in the file COPYING *
19 * included with this package. *
dea31012005-04-17 16:05:31 -050020 *******************************************************************/
21
dea31012005-04-17 16:05:31 -050022#include <linux/blkdev.h>
23#include <linux/pci.h>
24#include <linux/kthread.h>
25#include <linux/interrupt.h>
26
James.Smart@Emulex.Com91886522005-08-10 15:03:09 -040027#include <scsi/scsi.h>
dea31012005-04-17 16:05:31 -050028#include <scsi/scsi_device.h>
29#include <scsi/scsi_host.h>
30#include <scsi/scsi_transport_fc.h>
31
32#include "lpfc_hw.h"
James Smartea2151b2008-09-07 11:52:10 -040033#include "lpfc_nl.h"
dea31012005-04-17 16:05:31 -050034#include "lpfc_disc.h"
35#include "lpfc_sli.h"
36#include "lpfc_scsi.h"
37#include "lpfc.h"
38#include "lpfc_logmsg.h"
39#include "lpfc_crtn.h"
James Smart92d7f7b2007-06-17 19:56:38 -050040#include "lpfc_vport.h"
James Smart858c9f62007-06-17 19:56:39 -050041#include "lpfc_debugfs.h"
dea31012005-04-17 16:05:31 -050042
43/* AlpaArray for assignment of scsid for scan-down and bind_method */
44static uint8_t lpfcAlpaArray[] = {
45 0xEF, 0xE8, 0xE4, 0xE2, 0xE1, 0xE0, 0xDC, 0xDA, 0xD9, 0xD6,
46 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA,
47 0xC9, 0xC7, 0xC6, 0xC5, 0xC3, 0xBC, 0xBA, 0xB9, 0xB6, 0xB5,
48 0xB4, 0xB3, 0xB2, 0xB1, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9,
49 0xA7, 0xA6, 0xA5, 0xA3, 0x9F, 0x9E, 0x9D, 0x9B, 0x98, 0x97,
50 0x90, 0x8F, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7C, 0x7A, 0x79,
51 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6E, 0x6D, 0x6C, 0x6B,
52 0x6A, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5C, 0x5A, 0x59, 0x56,
53 0x55, 0x54, 0x53, 0x52, 0x51, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A,
54 0x49, 0x47, 0x46, 0x45, 0x43, 0x3C, 0x3A, 0x39, 0x36, 0x35,
55 0x34, 0x33, 0x32, 0x31, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29,
56 0x27, 0x26, 0x25, 0x23, 0x1F, 0x1E, 0x1D, 0x1B, 0x18, 0x17,
57 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01
58};
59
James Smart2e0fef82007-06-17 19:56:36 -050060static void lpfc_disc_timeout_handler(struct lpfc_vport *);
Adrian Bunka6ababd2007-11-05 18:07:33 +010061static void lpfc_disc_flush_list(struct lpfc_vport *vport);
dea31012005-04-17 16:05:31 -050062
James Smartc01f3202006-08-18 17:47:08 -040063void
64lpfc_terminate_rport_io(struct fc_rport *rport)
dea31012005-04-17 16:05:31 -050065{
James Smartc01f3202006-08-18 17:47:08 -040066 struct lpfc_rport_data *rdata;
67 struct lpfc_nodelist * ndlp;
68 struct lpfc_hba *phba;
dea31012005-04-17 16:05:31 -050069
James Smartc01f3202006-08-18 17:47:08 -040070 rdata = rport->dd_data;
71 ndlp = rdata->pnode;
72
James Smart58da1ff2008-04-07 10:15:56 -040073 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
James Smartc01f3202006-08-18 17:47:08 -040074 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
75 printk(KERN_ERR "Cannot find remote node"
76 " to terminate I/O Data x%x\n",
77 rport->port_id);
dea31012005-04-17 16:05:31 -050078 return;
79 }
80
James Smarta257bf92009-04-06 18:48:10 -040081 phba = ndlp->phba;
James Smart1a169682006-03-07 15:04:06 -050082
James Smart858c9f62007-06-17 19:56:39 -050083 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_RPORT,
84 "rport terminate: sid:x%x did:x%x flg:x%x",
85 ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
86
James Smartc01f3202006-08-18 17:47:08 -040087 if (ndlp->nlp_sid != NLP_NO_SID) {
James Smart51ef4c22007-08-02 11:10:31 -040088 lpfc_sli_abort_iocb(ndlp->vport,
89 &phba->sli.ring[phba->sli.fcp_ring],
90 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
James Smartc01f3202006-08-18 17:47:08 -040091 }
James Smartc01f3202006-08-18 17:47:08 -040092}
93
94/*
95 * This function will be called when dev_loss_tmo fire.
96 */
97void
98lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
99{
100 struct lpfc_rport_data *rdata;
101 struct lpfc_nodelist * ndlp;
James Smart2e0fef82007-06-17 19:56:36 -0500102 struct lpfc_vport *vport;
James Smart858c9f62007-06-17 19:56:39 -0500103 struct lpfc_hba *phba;
James Smart858c9f62007-06-17 19:56:39 -0500104 struct lpfc_work_evt *evtp;
James Smarta8adb832007-10-27 13:37:53 -0400105 int put_node;
106 int put_rport;
James Smartc01f3202006-08-18 17:47:08 -0400107
108 rdata = rport->dd_data;
109 ndlp = rdata->pnode;
James Smart58da1ff2008-04-07 10:15:56 -0400110 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
James Smartc01f3202006-08-18 17:47:08 -0400111 return;
James Smartc01f3202006-08-18 17:47:08 -0400112
James Smart858c9f62007-06-17 19:56:39 -0500113 vport = ndlp->vport;
114 phba = vport->phba;
115
116 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
117 "rport devlosscb: sid:x%x did:x%x flg:x%x",
118 ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
119
James Smarta8adb832007-10-27 13:37:53 -0400120 /* Don't defer this if we are in the process of deleting the vport
121 * or unloading the driver. The unload will cleanup the node
122 * appropriately we just need to cleanup the ndlp rport info here.
123 */
124 if (vport->load_flag & FC_UNLOADING) {
125 put_node = rdata->pnode != NULL;
126 put_rport = ndlp->rport != NULL;
127 rdata->pnode = NULL;
128 ndlp->rport = NULL;
129 if (put_node)
130 lpfc_nlp_put(ndlp);
131 if (put_rport)
132 put_device(&rport->dev);
133 return;
134 }
135
136 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
137 return;
138
James Smart858c9f62007-06-17 19:56:39 -0500139 evtp = &ndlp->dev_loss_evt;
140
141 if (!list_empty(&evtp->evt_listp))
142 return;
143
144 spin_lock_irq(&phba->hbalock);
James Smartfa4066b2008-01-11 01:53:27 -0500145 /* We need to hold the node by incrementing the reference
146 * count until this queued work is done
147 */
148 evtp->evt_arg1 = lpfc_nlp_get(ndlp);
James Smart5e9d9b82008-06-14 22:52:53 -0400149 if (evtp->evt_arg1) {
150 evtp->evt = LPFC_EVT_DEV_LOSS;
151 list_add_tail(&evtp->evt_listp, &phba->work_list);
152 lpfc_worker_wake_up(phba);
153 }
James Smart858c9f62007-06-17 19:56:39 -0500154 spin_unlock_irq(&phba->hbalock);
155
James Smart858c9f62007-06-17 19:56:39 -0500156 return;
157}
158
159/*
160 * This function is called from the worker thread when dev_loss_tmo
161 * expire.
162 */
Adrian Bunka6ababd2007-11-05 18:07:33 +0100163static void
James Smart858c9f62007-06-17 19:56:39 -0500164lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
165{
166 struct lpfc_rport_data *rdata;
167 struct fc_rport *rport;
168 struct lpfc_vport *vport;
169 struct lpfc_hba *phba;
170 uint8_t *name;
James Smart87af33f2007-10-27 13:37:43 -0400171 int put_node;
172 int put_rport;
James Smart858c9f62007-06-17 19:56:39 -0500173 int warn_on = 0;
174
175 rport = ndlp->rport;
176
177 if (!rport)
178 return;
179
180 rdata = rport->dd_data;
181 name = (uint8_t *) &ndlp->nlp_portname;
182 vport = ndlp->vport;
183 phba = vport->phba;
184
185 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
186 "rport devlosstmo:did:x%x type:x%x id:x%x",
187 ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);
188
James Smarta8adb832007-10-27 13:37:53 -0400189 /* Don't defer this if we are in the process of deleting the vport
190 * or unloading the driver. The unload will cleanup the node
191 * appropriately we just need to cleanup the ndlp rport info here.
192 */
193 if (vport->load_flag & FC_UNLOADING) {
James Smart09372822008-01-11 01:52:54 -0500194 if (ndlp->nlp_sid != NLP_NO_SID) {
195 /* flush the target */
196 lpfc_sli_abort_iocb(vport,
197 &phba->sli.ring[phba->sli.fcp_ring],
198 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
199 }
James Smarta8adb832007-10-27 13:37:53 -0400200 put_node = rdata->pnode != NULL;
201 put_rport = ndlp->rport != NULL;
202 rdata->pnode = NULL;
203 ndlp->rport = NULL;
204 if (put_node)
205 lpfc_nlp_put(ndlp);
206 if (put_rport)
207 put_device(&rport->dev);
208 return;
209 }
210
James Smartd7c255b2008-08-24 21:50:00 -0400211 if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
212 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
213 "0284 Devloss timeout Ignored on "
214 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
215 "NPort x%x\n",
216 *name, *(name+1), *(name+2), *(name+3),
217 *(name+4), *(name+5), *(name+6), *(name+7),
218 ndlp->nlp_DID);
James Smart858c9f62007-06-17 19:56:39 -0500219 return;
James Smartd7c255b2008-08-24 21:50:00 -0400220 }
James Smart858c9f62007-06-17 19:56:39 -0500221
James Smart92d7f7b2007-06-17 19:56:38 -0500222 if (ndlp->nlp_type & NLP_FABRIC) {
223 /* We will clean up these Nodes in linkup */
224 put_node = rdata->pnode != NULL;
225 put_rport = ndlp->rport != NULL;
226 rdata->pnode = NULL;
227 ndlp->rport = NULL;
228 if (put_node)
229 lpfc_nlp_put(ndlp);
230 if (put_rport)
231 put_device(&rport->dev);
James Smart82085712007-04-25 09:52:41 -0400232 return;
James Smart92d7f7b2007-06-17 19:56:38 -0500233 }
James Smart82085712007-04-25 09:52:41 -0400234
dea31012005-04-17 16:05:31 -0500235 if (ndlp->nlp_sid != NLP_NO_SID) {
James.Smart@Emulex.Com6e8215e2005-06-25 10:34:04 -0400236 warn_on = 1;
dea31012005-04-17 16:05:31 -0500237 /* flush the target */
James Smart51ef4c22007-08-02 11:10:31 -0400238 lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
239 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
dea31012005-04-17 16:05:31 -0500240 }
James Smartc01f3202006-08-18 17:47:08 -0400241
James.Smart@Emulex.Com6e8215e2005-06-25 10:34:04 -0400242 if (warn_on) {
James Smarte8b62012007-08-02 11:10:09 -0400243 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
244 "0203 Devloss timeout on "
James Smart58da1ff2008-04-07 10:15:56 -0400245 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
246 "NPort x%06x Data: x%x x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -0400247 *name, *(name+1), *(name+2), *(name+3),
248 *(name+4), *(name+5), *(name+6), *(name+7),
249 ndlp->nlp_DID, ndlp->nlp_flag,
250 ndlp->nlp_state, ndlp->nlp_rpi);
James.Smart@Emulex.Com6e8215e2005-06-25 10:34:04 -0400251 } else {
James Smarte8b62012007-08-02 11:10:09 -0400252 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
253 "0204 Devloss timeout on "
James Smart58da1ff2008-04-07 10:15:56 -0400254 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
255 "NPort x%06x Data: x%x x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -0400256 *name, *(name+1), *(name+2), *(name+3),
257 *(name+4), *(name+5), *(name+6), *(name+7),
258 ndlp->nlp_DID, ndlp->nlp_flag,
259 ndlp->nlp_state, ndlp->nlp_rpi);
James.Smart@Emulex.Com6e8215e2005-06-25 10:34:04 -0400260 }
261
James Smart87af33f2007-10-27 13:37:43 -0400262 put_node = rdata->pnode != NULL;
263 put_rport = ndlp->rport != NULL;
264 rdata->pnode = NULL;
265 ndlp->rport = NULL;
266 if (put_node)
267 lpfc_nlp_put(ndlp);
268 if (put_rport)
269 put_device(&rport->dev);
270
James Smart2e0fef82007-06-17 19:56:36 -0500271 if (!(vport->load_flag & FC_UNLOADING) &&
James Smart1dcb58e2007-04-25 09:51:30 -0400272 !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
James Smart82085712007-04-25 09:52:41 -0400273 !(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
James Smarte47c9092008-02-08 18:49:26 -0500274 (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE))
James Smart2e0fef82007-06-17 19:56:36 -0500275 lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
James Smart92d7f7b2007-06-17 19:56:38 -0500276}
James Smartc01f3202006-08-18 17:47:08 -0400277
James Smartea2151b2008-09-07 11:52:10 -0400278/**
James Smart3621a712009-04-06 18:47:14 -0400279 * lpfc_alloc_fast_evt - Allocates data structure for posting event
James Smartea2151b2008-09-07 11:52:10 -0400280 * @phba: Pointer to hba context object.
281 *
282 * This function is called from the functions which need to post
283 * events from interrupt context. This function allocates data
284 * structure required for posting event. It also keeps track of
285 * number of events pending and prevent event storm when there are
286 * too many events.
287 **/
288struct lpfc_fast_path_event *
289lpfc_alloc_fast_evt(struct lpfc_hba *phba) {
290 struct lpfc_fast_path_event *ret;
291
292 /* If there are lot of fast event do not exhaust memory due to this */
293 if (atomic_read(&phba->fast_event_count) > LPFC_MAX_EVT_COUNT)
294 return NULL;
295
296 ret = kzalloc(sizeof(struct lpfc_fast_path_event),
297 GFP_ATOMIC);
298 if (ret)
299 atomic_inc(&phba->fast_event_count);
300 INIT_LIST_HEAD(&ret->work_evt.evt_listp);
301 ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT;
302 return ret;
303}
304
305/**
James Smart3621a712009-04-06 18:47:14 -0400306 * lpfc_free_fast_evt - Frees event data structure
James Smartea2151b2008-09-07 11:52:10 -0400307 * @phba: Pointer to hba context object.
308 * @evt: Event object which need to be freed.
309 *
310 * This function frees the data structure required for posting
311 * events.
312 **/
313void
314lpfc_free_fast_evt(struct lpfc_hba *phba,
315 struct lpfc_fast_path_event *evt) {
316
317 atomic_dec(&phba->fast_event_count);
318 kfree(evt);
319}
320
321/**
James Smart3621a712009-04-06 18:47:14 -0400322 * lpfc_send_fastpath_evt - Posts events generated from fast path
James Smartea2151b2008-09-07 11:52:10 -0400323 * @phba: Pointer to hba context object.
324 * @evtp: Event data structure.
325 *
326 * This function is called from worker thread, when the interrupt
327 * context need to post an event. This function posts the event
328 * to fc transport netlink interface.
329 **/
330static void
331lpfc_send_fastpath_evt(struct lpfc_hba *phba,
332 struct lpfc_work_evt *evtp)
333{
334 unsigned long evt_category, evt_sub_category;
335 struct lpfc_fast_path_event *fast_evt_data;
336 char *evt_data;
337 uint32_t evt_data_size;
338 struct Scsi_Host *shost;
339
340 fast_evt_data = container_of(evtp, struct lpfc_fast_path_event,
341 work_evt);
342
343 evt_category = (unsigned long) fast_evt_data->un.fabric_evt.event_type;
344 evt_sub_category = (unsigned long) fast_evt_data->un.
345 fabric_evt.subcategory;
346 shost = lpfc_shost_from_vport(fast_evt_data->vport);
347 if (evt_category == FC_REG_FABRIC_EVENT) {
348 if (evt_sub_category == LPFC_EVENT_FCPRDCHKERR) {
349 evt_data = (char *) &fast_evt_data->un.read_check_error;
350 evt_data_size = sizeof(fast_evt_data->un.
351 read_check_error);
352 } else if ((evt_sub_category == LPFC_EVENT_FABRIC_BUSY) ||
James Smarteaf15d52008-12-04 22:39:29 -0500353 (evt_sub_category == LPFC_EVENT_PORT_BUSY)) {
James Smartea2151b2008-09-07 11:52:10 -0400354 evt_data = (char *) &fast_evt_data->un.fabric_evt;
355 evt_data_size = sizeof(fast_evt_data->un.fabric_evt);
356 } else {
357 lpfc_free_fast_evt(phba, fast_evt_data);
358 return;
359 }
360 } else if (evt_category == FC_REG_SCSI_EVENT) {
361 switch (evt_sub_category) {
362 case LPFC_EVENT_QFULL:
363 case LPFC_EVENT_DEVBSY:
364 evt_data = (char *) &fast_evt_data->un.scsi_evt;
365 evt_data_size = sizeof(fast_evt_data->un.scsi_evt);
366 break;
367 case LPFC_EVENT_CHECK_COND:
368 evt_data = (char *) &fast_evt_data->un.check_cond_evt;
369 evt_data_size = sizeof(fast_evt_data->un.
370 check_cond_evt);
371 break;
372 case LPFC_EVENT_VARQUEDEPTH:
373 evt_data = (char *) &fast_evt_data->un.queue_depth_evt;
374 evt_data_size = sizeof(fast_evt_data->un.
375 queue_depth_evt);
376 break;
377 default:
378 lpfc_free_fast_evt(phba, fast_evt_data);
379 return;
380 }
381 } else {
382 lpfc_free_fast_evt(phba, fast_evt_data);
383 return;
384 }
385
386 fc_host_post_vendor_event(shost,
387 fc_get_event_number(),
388 evt_data_size,
389 evt_data,
James Smartddcc50f2008-12-04 22:38:46 -0500390 LPFC_NL_VENDOR_ID);
James Smartea2151b2008-09-07 11:52:10 -0400391
392 lpfc_free_fast_evt(phba, fast_evt_data);
393 return;
394}
395
dea31012005-04-17 16:05:31 -0500396static void
James Smart2e0fef82007-06-17 19:56:36 -0500397lpfc_work_list_done(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500398{
399 struct lpfc_work_evt *evtp = NULL;
400 struct lpfc_nodelist *ndlp;
401 int free_evt;
402
James Smart2e0fef82007-06-17 19:56:36 -0500403 spin_lock_irq(&phba->hbalock);
404 while (!list_empty(&phba->work_list)) {
dea31012005-04-17 16:05:31 -0500405 list_remove_head((&phba->work_list), evtp, typeof(*evtp),
406 evt_listp);
James Smart2e0fef82007-06-17 19:56:36 -0500407 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500408 free_evt = 1;
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500409 switch (evtp->evt) {
dea31012005-04-17 16:05:31 -0500410 case LPFC_EVT_ELS_RETRY:
James Smart2e0fef82007-06-17 19:56:36 -0500411 ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
dea31012005-04-17 16:05:31 -0500412 lpfc_els_retry_delay_handler(ndlp);
James Smart92d7f7b2007-06-17 19:56:38 -0500413 free_evt = 0; /* evt is part of ndlp */
James Smartfa4066b2008-01-11 01:53:27 -0500414 /* decrement the node reference count held
415 * for this queued work
416 */
417 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -0500418 break;
James Smart858c9f62007-06-17 19:56:39 -0500419 case LPFC_EVT_DEV_LOSS:
420 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
James Smart858c9f62007-06-17 19:56:39 -0500421 lpfc_dev_loss_tmo_handler(ndlp);
422 free_evt = 0;
James Smartfa4066b2008-01-11 01:53:27 -0500423 /* decrement the node reference count held for
424 * this queued work
425 */
James Smart858c9f62007-06-17 19:56:39 -0500426 lpfc_nlp_put(ndlp);
427 break;
dea31012005-04-17 16:05:31 -0500428 case LPFC_EVT_ONLINE:
James Smart2e0fef82007-06-17 19:56:36 -0500429 if (phba->link_state < LPFC_LINK_DOWN)
430 *(int *) (evtp->evt_arg1) = lpfc_online(phba);
Jamie Wellnitz41415862006-02-28 19:25:27 -0500431 else
James Smart2e0fef82007-06-17 19:56:36 -0500432 *(int *) (evtp->evt_arg1) = 0;
dea31012005-04-17 16:05:31 -0500433 complete((struct completion *)(evtp->evt_arg2));
434 break;
James Smart46fa3112007-04-25 09:51:45 -0400435 case LPFC_EVT_OFFLINE_PREP:
James Smart2e0fef82007-06-17 19:56:36 -0500436 if (phba->link_state >= LPFC_LINK_DOWN)
James Smart46fa3112007-04-25 09:51:45 -0400437 lpfc_offline_prep(phba);
438 *(int *)(evtp->evt_arg1) = 0;
439 complete((struct completion *)(evtp->evt_arg2));
440 break;
441 case LPFC_EVT_OFFLINE:
442 lpfc_offline(phba);
Jamie Wellnitz41415862006-02-28 19:25:27 -0500443 lpfc_sli_brdrestart(phba);
444 *(int *)(evtp->evt_arg1) =
James Smart46fa3112007-04-25 09:51:45 -0400445 lpfc_sli_brdready(phba, HS_FFRDY | HS_MBRDY);
446 lpfc_unblock_mgmt_io(phba);
Jamie Wellnitz41415862006-02-28 19:25:27 -0500447 complete((struct completion *)(evtp->evt_arg2));
448 break;
449 case LPFC_EVT_WARM_START:
James Smart46fa3112007-04-25 09:51:45 -0400450 lpfc_offline(phba);
James Smart92908312006-03-07 15:04:13 -0500451 lpfc_reset_barrier(phba);
Jamie Wellnitz41415862006-02-28 19:25:27 -0500452 lpfc_sli_brdreset(phba);
453 lpfc_hba_down_post(phba);
454 *(int *)(evtp->evt_arg1) =
455 lpfc_sli_brdready(phba, HS_MBRDY);
James Smart46fa3112007-04-25 09:51:45 -0400456 lpfc_unblock_mgmt_io(phba);
Jamie Wellnitz41415862006-02-28 19:25:27 -0500457 complete((struct completion *)(evtp->evt_arg2));
458 break;
459 case LPFC_EVT_KILL:
James Smart46fa3112007-04-25 09:51:45 -0400460 lpfc_offline(phba);
James Smart92908312006-03-07 15:04:13 -0500461 *(int *)(evtp->evt_arg1)
James Smart2e0fef82007-06-17 19:56:36 -0500462 = (phba->pport->stopped)
463 ? 0 : lpfc_sli_brdkill(phba);
James Smart46fa3112007-04-25 09:51:45 -0400464 lpfc_unblock_mgmt_io(phba);
dea31012005-04-17 16:05:31 -0500465 complete((struct completion *)(evtp->evt_arg2));
466 break;
James Smartea2151b2008-09-07 11:52:10 -0400467 case LPFC_EVT_FASTPATH_MGMT_EVT:
468 lpfc_send_fastpath_evt(phba, evtp);
469 free_evt = 0;
470 break;
dea31012005-04-17 16:05:31 -0500471 }
472 if (free_evt)
473 kfree(evtp);
James Smart2e0fef82007-06-17 19:56:36 -0500474 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500475 }
James Smart2e0fef82007-06-17 19:56:36 -0500476 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500477
478}
479
James Smart311464e2007-08-02 11:10:37 -0400480static void
James Smart2e0fef82007-06-17 19:56:36 -0500481lpfc_work_done(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500482{
483 struct lpfc_sli_ring *pring;
James Smart858c9f62007-06-17 19:56:39 -0500484 uint32_t ha_copy, status, control, work_port_events;
James Smart549e55c2007-08-02 11:09:51 -0400485 struct lpfc_vport **vports;
James Smart51ef4c22007-08-02 11:10:31 -0400486 struct lpfc_vport *vport;
James Smart549e55c2007-08-02 11:09:51 -0400487 int i;
dea31012005-04-17 16:05:31 -0500488
James Smart2e0fef82007-06-17 19:56:36 -0500489 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500490 ha_copy = phba->work_ha;
491 phba->work_ha = 0;
James Smart2e0fef82007-06-17 19:56:36 -0500492 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500493
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500494 if (ha_copy & HA_ERATT)
James Smart93996272008-08-24 21:50:30 -0400495 /* Handle the error attention event */
dea31012005-04-17 16:05:31 -0500496 lpfc_handle_eratt(phba);
497
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500498 if (ha_copy & HA_MBATT)
dea31012005-04-17 16:05:31 -0500499 lpfc_sli_handle_mb_event(phba);
500
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500501 if (ha_copy & HA_LATT)
dea31012005-04-17 16:05:31 -0500502 lpfc_handle_latt(phba);
James Smart93996272008-08-24 21:50:30 -0400503
James Smart549e55c2007-08-02 11:09:51 -0400504 vports = lpfc_create_vport_work_array(phba);
505 if (vports != NULL)
James Smart09372822008-01-11 01:52:54 -0500506 for(i = 0; i <= phba->max_vpi; i++) {
James Smart51ef4c22007-08-02 11:10:31 -0400507 /*
508 * We could have no vports in array if unloading, so if
509 * this happens then just use the pport
510 */
511 if (vports[i] == NULL && i == 0)
512 vport = phba->pport;
513 else
514 vport = vports[i];
515 if (vport == NULL)
516 break;
James Smart58da1ff2008-04-07 10:15:56 -0400517 spin_lock_irq(&vport->work_port_lock);
James Smart51ef4c22007-08-02 11:10:31 -0400518 work_port_events = vport->work_port_events;
James Smart58da1ff2008-04-07 10:15:56 -0400519 vport->work_port_events &= ~work_port_events;
520 spin_unlock_irq(&vport->work_port_lock);
James Smart549e55c2007-08-02 11:09:51 -0400521 if (work_port_events & WORKER_DISC_TMO)
James Smart51ef4c22007-08-02 11:10:31 -0400522 lpfc_disc_timeout_handler(vport);
James Smart549e55c2007-08-02 11:09:51 -0400523 if (work_port_events & WORKER_ELS_TMO)
James Smart51ef4c22007-08-02 11:10:31 -0400524 lpfc_els_timeout_handler(vport);
James Smart549e55c2007-08-02 11:09:51 -0400525 if (work_port_events & WORKER_HB_TMO)
526 lpfc_hb_timeout_handler(phba);
527 if (work_port_events & WORKER_MBOX_TMO)
528 lpfc_mbox_timeout_handler(phba);
529 if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
530 lpfc_unblock_fabric_iocbs(phba);
531 if (work_port_events & WORKER_FDMI_TMO)
James Smart51ef4c22007-08-02 11:10:31 -0400532 lpfc_fdmi_timeout_handler(vport);
James Smart549e55c2007-08-02 11:09:51 -0400533 if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
534 lpfc_ramp_down_queue_handler(phba);
535 if (work_port_events & WORKER_RAMP_UP_QUEUE)
536 lpfc_ramp_up_queue_handler(phba);
James Smart92d7f7b2007-06-17 19:56:38 -0500537 }
James Smart09372822008-01-11 01:52:54 -0500538 lpfc_destroy_vport_work_array(phba, vports);
dea31012005-04-17 16:05:31 -0500539
James Smart858c9f62007-06-17 19:56:39 -0500540 pring = &phba->sli.ring[LPFC_ELS_RING];
541 status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING)));
542 status >>= (4*LPFC_ELS_RING);
543 if ((status & HA_RXMASK)
544 || (pring->flag & LPFC_DEFERRED_RING_EVENT)) {
James Smart0b727fe2007-10-27 13:37:25 -0400545 if (pring->flag & LPFC_STOP_IOCB_EVENT) {
James Smart858c9f62007-06-17 19:56:39 -0500546 pring->flag |= LPFC_DEFERRED_RING_EVENT;
James Smart5e9d9b82008-06-14 22:52:53 -0400547 /* Set the lpfc data pending flag */
548 set_bit(LPFC_DATA_READY, &phba->data_flags);
James Smart858c9f62007-06-17 19:56:39 -0500549 } else {
James Smart58da1ff2008-04-07 10:15:56 -0400550 pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
James Smart858c9f62007-06-17 19:56:39 -0500551 lpfc_sli_handle_slow_ring_event(phba, pring,
552 (status &
553 HA_RXMASK));
James Smart858c9f62007-06-17 19:56:39 -0500554 }
555 /*
556 * Turn on Ring interrupts
557 */
James Smart3772a992009-05-22 14:50:54 -0400558 if (phba->sli_rev <= LPFC_SLI_REV3) {
559 spin_lock_irq(&phba->hbalock);
560 control = readl(phba->HCregaddr);
561 if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) {
562 lpfc_debugfs_slow_ring_trc(phba,
563 "WRK Enable ring: cntl:x%x hacopy:x%x",
564 control, ha_copy, 0);
James Smarta58cbd52007-08-02 11:09:43 -0400565
James Smart3772a992009-05-22 14:50:54 -0400566 control |= (HC_R0INT_ENA << LPFC_ELS_RING);
567 writel(control, phba->HCregaddr);
568 readl(phba->HCregaddr); /* flush */
569 } else {
570 lpfc_debugfs_slow_ring_trc(phba,
571 "WRK Ring ok: cntl:x%x hacopy:x%x",
572 control, ha_copy, 0);
573 }
574 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500575 }
576 }
James Smart2e0fef82007-06-17 19:56:36 -0500577 lpfc_work_list_done(phba);
dea31012005-04-17 16:05:31 -0500578}
579
dea31012005-04-17 16:05:31 -0500580int
581lpfc_do_work(void *p)
582{
583 struct lpfc_hba *phba = p;
584 int rc;
dea31012005-04-17 16:05:31 -0500585
586 set_user_nice(current, -20);
James Smart5e9d9b82008-06-14 22:52:53 -0400587 phba->data_flags = 0;
dea31012005-04-17 16:05:31 -0500588
James Smart3a55b532008-12-04 22:38:54 -0500589 while (!kthread_should_stop()) {
James Smart5e9d9b82008-06-14 22:52:53 -0400590 /* wait and check worker queue activities */
591 rc = wait_event_interruptible(phba->work_waitq,
592 (test_and_clear_bit(LPFC_DATA_READY,
593 &phba->data_flags)
594 || kthread_should_stop()));
James Smart3a55b532008-12-04 22:38:54 -0500595 /* Signal wakeup shall terminate the worker thread */
596 if (rc) {
597 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
598 "0433 Wakeup on signal: rc=x%x\n", rc);
dea31012005-04-17 16:05:31 -0500599 break;
James Smart3a55b532008-12-04 22:38:54 -0500600 }
dea31012005-04-17 16:05:31 -0500601
James Smart5e9d9b82008-06-14 22:52:53 -0400602 /* Attend pending lpfc data processing */
dea31012005-04-17 16:05:31 -0500603 lpfc_work_done(phba);
dea31012005-04-17 16:05:31 -0500604 }
James Smart3a55b532008-12-04 22:38:54 -0500605 phba->worker_thread = NULL;
606 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
607 "0432 Worker thread stopped.\n");
dea31012005-04-17 16:05:31 -0500608 return 0;
609}
610
611/*
612 * This is only called to handle FC worker events. Since this a rare
613 * occurance, we allocate a struct lpfc_work_evt structure here instead of
614 * embedding it in the IOCB.
615 */
616int
James Smart2e0fef82007-06-17 19:56:36 -0500617lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2,
dea31012005-04-17 16:05:31 -0500618 uint32_t evt)
619{
620 struct lpfc_work_evt *evtp;
James Smarted957682007-06-17 19:56:37 -0500621 unsigned long flags;
dea31012005-04-17 16:05:31 -0500622
623 /*
624 * All Mailbox completions and LPFC_ELS_RING rcv ring IOCB events will
625 * be queued to worker thread for processing
626 */
James Smart92d7f7b2007-06-17 19:56:38 -0500627 evtp = kmalloc(sizeof(struct lpfc_work_evt), GFP_ATOMIC);
dea31012005-04-17 16:05:31 -0500628 if (!evtp)
629 return 0;
630
631 evtp->evt_arg1 = arg1;
632 evtp->evt_arg2 = arg2;
633 evtp->evt = evt;
634
James Smarted957682007-06-17 19:56:37 -0500635 spin_lock_irqsave(&phba->hbalock, flags);
James Smart071fbd3d2006-04-15 11:53:20 -0400636 list_add_tail(&evtp->evt_listp, &phba->work_list);
James Smarted957682007-06-17 19:56:37 -0500637 spin_unlock_irqrestore(&phba->hbalock, flags);
dea31012005-04-17 16:05:31 -0500638
James Smart5e9d9b82008-06-14 22:52:53 -0400639 lpfc_worker_wake_up(phba);
640
dea31012005-04-17 16:05:31 -0500641 return 1;
642}
643
James Smart92d7f7b2007-06-17 19:56:38 -0500644void
645lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
646{
James Smart09372822008-01-11 01:52:54 -0500647 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart92d7f7b2007-06-17 19:56:38 -0500648 struct lpfc_hba *phba = vport->phba;
649 struct lpfc_nodelist *ndlp, *next_ndlp;
650 int rc;
651
652 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
James Smarte47c9092008-02-08 18:49:26 -0500653 if (!NLP_CHK_NODE_ACT(ndlp))
654 continue;
James Smart92d7f7b2007-06-17 19:56:38 -0500655 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
656 continue;
James Smart98c9ea52007-10-27 13:37:33 -0400657 if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) ||
658 ((vport->port_type == LPFC_NPIV_PORT) &&
659 (ndlp->nlp_DID == NameServer_DID)))
James Smart92d7f7b2007-06-17 19:56:38 -0500660 lpfc_unreg_rpi(vport, ndlp);
661
662 /* Leave Fabric nodes alone on link down */
663 if (!remove && ndlp->nlp_type & NLP_FABRIC)
664 continue;
665 rc = lpfc_disc_state_machine(vport, ndlp, NULL,
666 remove
667 ? NLP_EVT_DEVICE_RM
668 : NLP_EVT_DEVICE_RECOVERY);
669 }
670 if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) {
671 lpfc_mbx_unreg_vpi(vport);
James Smart09372822008-01-11 01:52:54 -0500672 spin_lock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -0500673 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
James Smart09372822008-01-11 01:52:54 -0500674 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -0500675 }
676}
677
James Smart87af33f2007-10-27 13:37:43 -0400678void
James Smart98c9ea52007-10-27 13:37:33 -0400679lpfc_port_link_failure(struct lpfc_vport *vport)
James Smart92d7f7b2007-06-17 19:56:38 -0500680{
James Smart92d7f7b2007-06-17 19:56:38 -0500681 /* Cleanup any outstanding RSCN activity */
682 lpfc_els_flush_rscn(vport);
683
684 /* Cleanup any outstanding ELS commands */
685 lpfc_els_flush_cmd(vport);
686
687 lpfc_cleanup_rpis(vport, 0);
688
James Smart92d7f7b2007-06-17 19:56:38 -0500689 /* Turn off discovery timer if its running */
690 lpfc_can_disctmo(vport);
691}
692
James Smart3772a992009-05-22 14:50:54 -0400693void
James Smart98c9ea52007-10-27 13:37:33 -0400694lpfc_linkdown_port(struct lpfc_vport *vport)
695{
696 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
697
698 fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
699
700 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
701 "Link Down: state:x%x rtry:x%x flg:x%x",
702 vport->port_state, vport->fc_ns_retry, vport->fc_flag);
703
704 lpfc_port_link_failure(vport);
705
706}
707
dea31012005-04-17 16:05:31 -0500708int
James Smart685f0bf2007-04-25 09:53:08 -0400709lpfc_linkdown(struct lpfc_hba *phba)
dea31012005-04-17 16:05:31 -0500710{
James Smart2e0fef82007-06-17 19:56:36 -0500711 struct lpfc_vport *vport = phba->pport;
712 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart549e55c2007-08-02 11:09:51 -0400713 struct lpfc_vport **vports;
James Smart685f0bf2007-04-25 09:53:08 -0400714 LPFC_MBOXQ_t *mb;
James Smart549e55c2007-08-02 11:09:51 -0400715 int i;
dea31012005-04-17 16:05:31 -0500716
James Smart3163f722008-02-08 18:50:25 -0500717 if (phba->link_state == LPFC_LINK_DOWN)
James Smart2e0fef82007-06-17 19:56:36 -0500718 return 0;
James Smart2e0fef82007-06-17 19:56:36 -0500719 spin_lock_irq(&phba->hbalock);
James Smart92d7f7b2007-06-17 19:56:38 -0500720 if (phba->link_state > LPFC_LINK_DOWN) {
James Smart2e0fef82007-06-17 19:56:36 -0500721 phba->link_state = LPFC_LINK_DOWN;
James Smart92d7f7b2007-06-17 19:56:38 -0500722 phba->pport->fc_flag &= ~FC_LBIT;
723 }
James Smart2e0fef82007-06-17 19:56:36 -0500724 spin_unlock_irq(&phba->hbalock);
James Smart549e55c2007-08-02 11:09:51 -0400725 vports = lpfc_create_vport_work_array(phba);
726 if (vports != NULL)
James Smart09372822008-01-11 01:52:54 -0500727 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
James Smart549e55c2007-08-02 11:09:51 -0400728 /* Issue a LINK DOWN event to all nodes */
729 lpfc_linkdown_port(vports[i]);
730 }
James Smart09372822008-01-11 01:52:54 -0500731 lpfc_destroy_vport_work_array(phba, vports);
dea31012005-04-17 16:05:31 -0500732 /* Clean up any firmware default rpi's */
James Smart2e0fef82007-06-17 19:56:36 -0500733 mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
734 if (mb) {
James Smart92d7f7b2007-06-17 19:56:38 -0500735 lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb);
James Smarted957682007-06-17 19:56:37 -0500736 mb->vport = vport;
James Smart2e0fef82007-06-17 19:56:36 -0500737 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smart0b727fe2007-10-27 13:37:25 -0400738 if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT)
dea31012005-04-17 16:05:31 -0500739 == MBX_NOT_FINISHED) {
James Smart2e0fef82007-06-17 19:56:36 -0500740 mempool_free(mb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -0500741 }
742 }
743
dea31012005-04-17 16:05:31 -0500744 /* Setup myDID for link up if we are in pt2pt mode */
James Smart92d7f7b2007-06-17 19:56:38 -0500745 if (phba->pport->fc_flag & FC_PT2PT) {
746 phba->pport->fc_myDID = 0;
James Smart2e0fef82007-06-17 19:56:36 -0500747 mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
748 if (mb) {
dea31012005-04-17 16:05:31 -0500749 lpfc_config_link(phba, mb);
James Smart92d7f7b2007-06-17 19:56:38 -0500750 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smarted957682007-06-17 19:56:37 -0500751 mb->vport = vport;
James Smart0b727fe2007-10-27 13:37:25 -0400752 if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT)
dea31012005-04-17 16:05:31 -0500753 == MBX_NOT_FINISHED) {
James Smart2e0fef82007-06-17 19:56:36 -0500754 mempool_free(mb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -0500755 }
756 }
James Smart2e0fef82007-06-17 19:56:36 -0500757 spin_lock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -0500758 phba->pport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI);
James Smart2e0fef82007-06-17 19:56:36 -0500759 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500760 }
James Smart2e0fef82007-06-17 19:56:36 -0500761
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -0500762 return 0;
dea31012005-04-17 16:05:31 -0500763}
764
James Smart92d7f7b2007-06-17 19:56:38 -0500765static void
766lpfc_linkup_cleanup_nodes(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -0500767{
James Smart92d7f7b2007-06-17 19:56:38 -0500768 struct lpfc_nodelist *ndlp;
769
770 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smarte47c9092008-02-08 18:49:26 -0500771 if (!NLP_CHK_NODE_ACT(ndlp))
772 continue;
James Smart92d7f7b2007-06-17 19:56:38 -0500773 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
774 continue;
James Smart92d7f7b2007-06-17 19:56:38 -0500775 if (ndlp->nlp_type & NLP_FABRIC) {
James Smarte47c9092008-02-08 18:49:26 -0500776 /* On Linkup its safe to clean up the ndlp
777 * from Fabric connections.
778 */
James Smart92d7f7b2007-06-17 19:56:38 -0500779 if (ndlp->nlp_DID != Fabric_DID)
780 lpfc_unreg_rpi(vport, ndlp);
781 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
782 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
James Smarte47c9092008-02-08 18:49:26 -0500783 /* Fail outstanding IO now since device is
784 * marked for PLOGI.
785 */
James Smart92d7f7b2007-06-17 19:56:38 -0500786 lpfc_unreg_rpi(vport, ndlp);
787 }
788 }
789}
790
791static void
792lpfc_linkup_port(struct lpfc_vport *vport)
793{
794 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart92d7f7b2007-06-17 19:56:38 -0500795 struct lpfc_hba *phba = vport->phba;
796
797 if ((vport->load_flag & FC_UNLOADING) != 0)
798 return;
799
James Smart858c9f62007-06-17 19:56:39 -0500800 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
801 "Link Up: top:x%x speed:x%x flg:x%x",
802 phba->fc_topology, phba->fc_linkspeed, phba->link_flag);
803
James Smart92d7f7b2007-06-17 19:56:38 -0500804 /* If NPIV is not enabled, only bring the physical port up */
805 if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
806 (vport != phba->pport))
807 return;
dea31012005-04-17 16:05:31 -0500808
James Smart2e0fef82007-06-17 19:56:36 -0500809 fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0);
James Smartd2873e42006-08-18 17:46:43 -0400810
James Smart2e0fef82007-06-17 19:56:36 -0500811 spin_lock_irq(shost->host_lock);
James Smart2e0fef82007-06-17 19:56:36 -0500812 vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
813 FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY);
814 vport->fc_flag |= FC_NDISC_ACTIVE;
815 vport->fc_ns_retry = 0;
816 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500817
James Smart92d7f7b2007-06-17 19:56:38 -0500818 if (vport->fc_flag & FC_LBIT)
819 lpfc_linkup_cleanup_nodes(vport);
dea31012005-04-17 16:05:31 -0500820
James Smart92d7f7b2007-06-17 19:56:38 -0500821}
822
823static int
824lpfc_linkup(struct lpfc_hba *phba)
825{
James Smart549e55c2007-08-02 11:09:51 -0400826 struct lpfc_vport **vports;
827 int i;
James Smart92d7f7b2007-06-17 19:56:38 -0500828
829 phba->link_state = LPFC_LINK_UP;
830
831 /* Unblock fabric iocbs if they are blocked */
832 clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
833 del_timer_sync(&phba->fabric_block_timer);
834
James Smart549e55c2007-08-02 11:09:51 -0400835 vports = lpfc_create_vport_work_array(phba);
836 if (vports != NULL)
James Smart09372822008-01-11 01:52:54 -0500837 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++)
James Smart549e55c2007-08-02 11:09:51 -0400838 lpfc_linkup_port(vports[i]);
James Smart09372822008-01-11 01:52:54 -0500839 lpfc_destroy_vport_work_array(phba, vports);
James Smart92d7f7b2007-06-17 19:56:38 -0500840 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
841 lpfc_issue_clear_la(phba, phba->pport);
dea31012005-04-17 16:05:31 -0500842
843 return 0;
844}
845
846/*
847 * This routine handles processing a CLEAR_LA mailbox
848 * command upon completion. It is setup in the LPFC_MBOXQ
849 * as the completion routine when the command is
850 * handed off to the SLI layer.
851 */
Adrian Bunka6ababd2007-11-05 18:07:33 +0100852static void
James Smart2e0fef82007-06-17 19:56:36 -0500853lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -0500854{
James Smart2e0fef82007-06-17 19:56:36 -0500855 struct lpfc_vport *vport = pmb->vport;
856 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
857 struct lpfc_sli *psli = &phba->sli;
858 MAILBOX_t *mb = &pmb->mb;
dea31012005-04-17 16:05:31 -0500859 uint32_t control;
860
dea31012005-04-17 16:05:31 -0500861 /* Since we don't do discovery right now, turn these off here */
James Smarta4bc3372006-12-02 13:34:16 -0500862 psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
dea31012005-04-17 16:05:31 -0500863 psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
864 psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
865
866 /* Check for error */
867 if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) {
James Smart92d7f7b2007-06-17 19:56:38 -0500868 /* CLEAR_LA mbox error <mbxStatus> state <hba_state> */
James Smarte8b62012007-08-02 11:10:09 -0400869 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
870 "0320 CLEAR_LA mbxStatus error x%x hba "
871 "state x%x\n",
872 mb->mbxStatus, vport->port_state);
James Smart2e0fef82007-06-17 19:56:36 -0500873 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -0500874 goto out;
875 }
876
James Smart92d7f7b2007-06-17 19:56:38 -0500877 if (vport->port_type == LPFC_PHYSICAL_PORT)
878 phba->link_state = LPFC_HBA_READY;
879
880 spin_lock_irq(&phba->hbalock);
881 psli->sli_flag |= LPFC_PROCESS_LA;
882 control = readl(phba->HCregaddr);
883 control |= HC_LAINT_ENA;
884 writel(control, phba->HCregaddr);
885 readl(phba->HCregaddr); /* flush */
886 spin_unlock_irq(&phba->hbalock);
James Smart1b32f6a2008-02-08 18:49:39 -0500887 mempool_free(pmb, phba->mbox_mem_pool);
James Smart92d7f7b2007-06-17 19:56:38 -0500888 return;
dea31012005-04-17 16:05:31 -0500889
dea31012005-04-17 16:05:31 -0500890out:
891 /* Device Discovery completes */
James Smarte8b62012007-08-02 11:10:09 -0400892 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
893 "0225 Device Discovery completes\n");
James Smart2e0fef82007-06-17 19:56:36 -0500894 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -0500895
James Smart2e0fef82007-06-17 19:56:36 -0500896 spin_lock_irq(shost->host_lock);
James Smart58da1ff2008-04-07 10:15:56 -0400897 vport->fc_flag &= ~FC_ABORT_DISCOVERY;
James Smart2e0fef82007-06-17 19:56:36 -0500898 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -0500899
James Smart2e0fef82007-06-17 19:56:36 -0500900 lpfc_can_disctmo(vport);
dea31012005-04-17 16:05:31 -0500901
902 /* turn on Link Attention interrupts */
James Smart2e0fef82007-06-17 19:56:36 -0500903
904 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500905 psli->sli_flag |= LPFC_PROCESS_LA;
906 control = readl(phba->HCregaddr);
907 control |= HC_LAINT_ENA;
908 writel(control, phba->HCregaddr);
909 readl(phba->HCregaddr); /* flush */
James Smart2e0fef82007-06-17 19:56:36 -0500910 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -0500911
912 return;
913}
914
James Smart2e0fef82007-06-17 19:56:36 -0500915
dea31012005-04-17 16:05:31 -0500916static void
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500917lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -0500918{
James Smart2e0fef82007-06-17 19:56:36 -0500919 struct lpfc_vport *vport = pmb->vport;
dea31012005-04-17 16:05:31 -0500920
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500921 if (pmb->mb.mbxStatus)
dea31012005-04-17 16:05:31 -0500922 goto out;
dea31012005-04-17 16:05:31 -0500923
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500924 mempool_free(pmb, phba->mbox_mem_pool);
925
926 if (phba->fc_topology == TOPOLOGY_LOOP &&
James Smart2e0fef82007-06-17 19:56:36 -0500927 vport->fc_flag & FC_PUBLIC_LOOP &&
928 !(vport->fc_flag & FC_LBIT)) {
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500929 /* Need to wait for FAN - use discovery timer
James Smart2e0fef82007-06-17 19:56:36 -0500930 * for timeout. port_state is identically
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500931 * LPFC_LOCAL_CFG_LINK while waiting for FAN
932 */
James Smart2e0fef82007-06-17 19:56:36 -0500933 lpfc_set_disctmo(vport);
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500934 return;
James Smart92d7f7b2007-06-17 19:56:38 -0500935 }
dea31012005-04-17 16:05:31 -0500936
James Smart2e0fef82007-06-17 19:56:36 -0500937 /* Start discovery by sending a FLOGI. port_state is identically
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500938 * LPFC_FLOGI while waiting for FLOGI cmpl
939 */
James Smart92d7f7b2007-06-17 19:56:38 -0500940 if (vport->port_state != LPFC_FLOGI) {
James Smart92d7f7b2007-06-17 19:56:38 -0500941 lpfc_initial_flogi(vport);
942 }
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500943 return;
dea31012005-04-17 16:05:31 -0500944
945out:
James Smarte8b62012007-08-02 11:10:09 -0400946 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
947 "0306 CONFIG_LINK mbxStatus error x%x "
948 "HBA state x%x\n",
949 pmb->mb.mbxStatus, vport->port_state);
James Smart92d7f7b2007-06-17 19:56:38 -0500950 mempool_free(pmb, phba->mbox_mem_pool);
Jamie Wellnitz25594c62006-02-28 19:25:34 -0500951
952 lpfc_linkdown(phba);
953
James Smarte8b62012007-08-02 11:10:09 -0400954 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
955 "0200 CONFIG_LINK bad hba state x%x\n",
956 vport->port_state);
dea31012005-04-17 16:05:31 -0500957
James Smart92d7f7b2007-06-17 19:56:38 -0500958 lpfc_issue_clear_la(phba, vport);
dea31012005-04-17 16:05:31 -0500959 return;
960}
961
962static void
James Smart2e0fef82007-06-17 19:56:36 -0500963lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -0500964{
dea31012005-04-17 16:05:31 -0500965 MAILBOX_t *mb = &pmb->mb;
966 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
James Smart2e0fef82007-06-17 19:56:36 -0500967 struct lpfc_vport *vport = pmb->vport;
dea31012005-04-17 16:05:31 -0500968
969
970 /* Check for error */
971 if (mb->mbxStatus) {
972 /* READ_SPARAM mbox error <mbxStatus> state <hba_state> */
James Smarte8b62012007-08-02 11:10:09 -0400973 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
974 "0319 READ_SPARAM mbxStatus error x%x "
975 "hba state x%x>\n",
976 mb->mbxStatus, vport->port_state);
dea31012005-04-17 16:05:31 -0500977 lpfc_linkdown(phba);
dea31012005-04-17 16:05:31 -0500978 goto out;
979 }
980
James Smart2e0fef82007-06-17 19:56:36 -0500981 memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt,
dea31012005-04-17 16:05:31 -0500982 sizeof (struct serv_parm));
James Smarta12e07b2006-12-02 13:35:30 -0500983 if (phba->cfg_soft_wwnn)
James Smart2e0fef82007-06-17 19:56:36 -0500984 u64_to_wwn(phba->cfg_soft_wwnn,
985 vport->fc_sparam.nodeName.u.wwn);
James Smartc3f28af2006-08-18 17:47:18 -0400986 if (phba->cfg_soft_wwpn)
James Smart2e0fef82007-06-17 19:56:36 -0500987 u64_to_wwn(phba->cfg_soft_wwpn,
988 vport->fc_sparam.portName.u.wwn);
James Smart92d7f7b2007-06-17 19:56:38 -0500989 memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
990 sizeof(vport->fc_nodename));
991 memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
992 sizeof(vport->fc_portname));
993 if (vport->port_type == LPFC_PHYSICAL_PORT) {
994 memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn));
995 memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn));
996 }
997
dea31012005-04-17 16:05:31 -0500998 lpfc_mbuf_free(phba, mp->virt, mp->phys);
999 kfree(mp);
James Smart2e0fef82007-06-17 19:56:36 -05001000 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001001 return;
1002
1003out:
1004 pmb->context1 = NULL;
1005 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1006 kfree(mp);
James Smart92d7f7b2007-06-17 19:56:38 -05001007 lpfc_issue_clear_la(phba, vport);
1008 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001009 return;
1010}
1011
1012static void
James Smart92d7f7b2007-06-17 19:56:38 -05001013lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
dea31012005-04-17 16:05:31 -05001014{
James Smart92d7f7b2007-06-17 19:56:38 -05001015 struct lpfc_vport *vport = phba->pport;
dea31012005-04-17 16:05:31 -05001016 LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox;
James Smart2e0fef82007-06-17 19:56:36 -05001017 int i;
James Smart14691152006-12-02 13:34:28 -05001018 struct lpfc_dmabuf *mp;
1019 int rc;
1020
dea31012005-04-17 16:05:31 -05001021 sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1022 cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1023
James Smart92d7f7b2007-06-17 19:56:38 -05001024 spin_lock_irq(&phba->hbalock);
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05001025 switch (la->UlnkSpeed) {
James Smart92d7f7b2007-06-17 19:56:38 -05001026 case LA_1GHZ_LINK:
1027 phba->fc_linkspeed = LA_1GHZ_LINK;
1028 break;
1029 case LA_2GHZ_LINK:
1030 phba->fc_linkspeed = LA_2GHZ_LINK;
1031 break;
1032 case LA_4GHZ_LINK:
1033 phba->fc_linkspeed = LA_4GHZ_LINK;
1034 break;
1035 case LA_8GHZ_LINK:
1036 phba->fc_linkspeed = LA_8GHZ_LINK;
1037 break;
1038 default:
1039 phba->fc_linkspeed = LA_UNKNW_LINK;
1040 break;
dea31012005-04-17 16:05:31 -05001041 }
1042
1043 phba->fc_topology = la->topology;
James Smart92d7f7b2007-06-17 19:56:38 -05001044 phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
dea31012005-04-17 16:05:31 -05001045
1046 if (phba->fc_topology == TOPOLOGY_LOOP) {
James Smart92d7f7b2007-06-17 19:56:38 -05001047 phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
dea31012005-04-17 16:05:31 -05001048
James Smart495a7142008-06-14 22:52:59 -04001049 if (phba->cfg_enable_npiv)
1050 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1051 "1309 Link Up Event npiv not supported in loop "
1052 "topology\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001053 /* Get Loop Map information */
dea31012005-04-17 16:05:31 -05001054 if (la->il)
James Smart2e0fef82007-06-17 19:56:36 -05001055 vport->fc_flag |= FC_LBIT;
dea31012005-04-17 16:05:31 -05001056
James Smart2e0fef82007-06-17 19:56:36 -05001057 vport->fc_myDID = la->granted_AL_PA;
dea31012005-04-17 16:05:31 -05001058 i = la->un.lilpBde64.tus.f.bdeSize;
1059
1060 if (i == 0) {
1061 phba->alpa_map[0] = 0;
1062 } else {
James Smarte8b62012007-08-02 11:10:09 -04001063 if (vport->cfg_log_verbose & LOG_LINK_EVENT) {
dea31012005-04-17 16:05:31 -05001064 int numalpa, j, k;
1065 union {
1066 uint8_t pamap[16];
1067 struct {
1068 uint32_t wd1;
1069 uint32_t wd2;
1070 uint32_t wd3;
1071 uint32_t wd4;
1072 } pa;
1073 } un;
1074 numalpa = phba->alpa_map[0];
1075 j = 0;
1076 while (j < numalpa) {
1077 memset(un.pamap, 0, 16);
1078 for (k = 1; j < numalpa; k++) {
1079 un.pamap[k - 1] =
1080 phba->alpa_map[j + 1];
1081 j++;
1082 if (k == 16)
1083 break;
1084 }
1085 /* Link Up Event ALPA map */
1086 lpfc_printf_log(phba,
James Smart92d7f7b2007-06-17 19:56:38 -05001087 KERN_WARNING,
1088 LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -04001089 "1304 Link Up Event "
James Smart92d7f7b2007-06-17 19:56:38 -05001090 "ALPA map Data: x%x "
1091 "x%x x%x x%x\n",
James Smart92d7f7b2007-06-17 19:56:38 -05001092 un.pa.wd1, un.pa.wd2,
1093 un.pa.wd3, un.pa.wd4);
dea31012005-04-17 16:05:31 -05001094 }
1095 }
1096 }
1097 } else {
James Smart92d7f7b2007-06-17 19:56:38 -05001098 if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
James Smart78b2d852007-08-02 11:10:21 -04001099 if (phba->max_vpi && phba->cfg_enable_npiv &&
James Smart92d7f7b2007-06-17 19:56:38 -05001100 (phba->sli_rev == 3))
1101 phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
1102 }
James Smart2e0fef82007-06-17 19:56:36 -05001103 vport->fc_myDID = phba->fc_pref_DID;
1104 vport->fc_flag |= FC_LBIT;
dea31012005-04-17 16:05:31 -05001105 }
James Smart92d7f7b2007-06-17 19:56:38 -05001106 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001107
1108 lpfc_linkup(phba);
1109 if (sparam_mbox) {
James Smart92d7f7b2007-06-17 19:56:38 -05001110 lpfc_read_sparam(phba, sparam_mbox, 0);
James Smart2e0fef82007-06-17 19:56:36 -05001111 sparam_mbox->vport = vport;
dea31012005-04-17 16:05:31 -05001112 sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
James Smart0b727fe2007-10-27 13:37:25 -04001113 rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
James Smart14691152006-12-02 13:34:28 -05001114 if (rc == MBX_NOT_FINISHED) {
1115 mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
1116 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1117 kfree(mp);
1118 mempool_free(sparam_mbox, phba->mbox_mem_pool);
1119 if (cfglink_mbox)
1120 mempool_free(cfglink_mbox, phba->mbox_mem_pool);
James Smart92d7f7b2007-06-17 19:56:38 -05001121 goto out;
James Smart14691152006-12-02 13:34:28 -05001122 }
dea31012005-04-17 16:05:31 -05001123 }
1124
1125 if (cfglink_mbox) {
James Smart2e0fef82007-06-17 19:56:36 -05001126 vport->port_state = LPFC_LOCAL_CFG_LINK;
dea31012005-04-17 16:05:31 -05001127 lpfc_config_link(phba, cfglink_mbox);
James Smart2e0fef82007-06-17 19:56:36 -05001128 cfglink_mbox->vport = vport;
Jamie Wellnitz25594c62006-02-28 19:25:34 -05001129 cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
James Smart0b727fe2007-10-27 13:37:25 -04001130 rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT);
James Smart92d7f7b2007-06-17 19:56:38 -05001131 if (rc != MBX_NOT_FINISHED)
1132 return;
1133 mempool_free(cfglink_mbox, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001134 }
James Smart92d7f7b2007-06-17 19:56:38 -05001135out:
1136 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
James Smarte8b62012007-08-02 11:10:09 -04001137 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
1138 "0263 Discovery Mailbox error: state: 0x%x : %p %p\n",
1139 vport->port_state, sparam_mbox, cfglink_mbox);
James Smart92d7f7b2007-06-17 19:56:38 -05001140 lpfc_issue_clear_la(phba, vport);
1141 return;
dea31012005-04-17 16:05:31 -05001142}
1143
1144static void
James Smart84774a42008-08-24 21:50:06 -04001145lpfc_enable_la(struct lpfc_hba *phba)
James Smart2e0fef82007-06-17 19:56:36 -05001146{
dea31012005-04-17 16:05:31 -05001147 uint32_t control;
1148 struct lpfc_sli *psli = &phba->sli;
James Smart2e0fef82007-06-17 19:56:36 -05001149 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001150 psli->sli_flag |= LPFC_PROCESS_LA;
James Smart3772a992009-05-22 14:50:54 -04001151 if (phba->sli_rev <= LPFC_SLI_REV3) {
1152 control = readl(phba->HCregaddr);
1153 control |= HC_LAINT_ENA;
1154 writel(control, phba->HCregaddr);
1155 readl(phba->HCregaddr); /* flush */
1156 }
James Smart2e0fef82007-06-17 19:56:36 -05001157 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05001158}
1159
James Smart84774a42008-08-24 21:50:06 -04001160static void
1161lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
1162{
1163 lpfc_linkdown(phba);
1164 lpfc_enable_la(phba);
1165 /* turn on Link Attention interrupts - no CLEAR_LA needed */
1166}
1167
1168
dea31012005-04-17 16:05:31 -05001169/*
1170 * This routine handles processing a READ_LA mailbox
1171 * command upon completion. It is setup in the LPFC_MBOXQ
1172 * as the completion routine when the command is
1173 * handed off to the SLI layer.
1174 */
1175void
James Smart2e0fef82007-06-17 19:56:36 -05001176lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -05001177{
James Smart2e0fef82007-06-17 19:56:36 -05001178 struct lpfc_vport *vport = pmb->vport;
1179 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05001180 READ_LA_VAR *la;
1181 MAILBOX_t *mb = &pmb->mb;
1182 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
1183
James Smart0d2b6b82008-06-14 22:52:47 -04001184 /* Unblock ELS traffic */
1185 phba->sli.ring[LPFC_ELS_RING].flag &= ~LPFC_STOP_IOCB_EVENT;
dea31012005-04-17 16:05:31 -05001186 /* Check for error */
1187 if (mb->mbxStatus) {
James Smarted957682007-06-17 19:56:37 -05001188 lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -04001189 "1307 READ_LA mbox error x%x state x%x\n",
1190 mb->mbxStatus, vport->port_state);
dea31012005-04-17 16:05:31 -05001191 lpfc_mbx_issue_link_down(phba);
James Smart2e0fef82007-06-17 19:56:36 -05001192 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -05001193 goto lpfc_mbx_cmpl_read_la_free_mbuf;
1194 }
1195
1196 la = (READ_LA_VAR *) & pmb->mb.un.varReadLA;
1197
1198 memcpy(&phba->alpa_map[0], mp->virt, 128);
1199
James Smart2e0fef82007-06-17 19:56:36 -05001200 spin_lock_irq(shost->host_lock);
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05001201 if (la->pb)
James Smart2e0fef82007-06-17 19:56:36 -05001202 vport->fc_flag |= FC_BYPASSED_MODE;
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05001203 else
James Smart2e0fef82007-06-17 19:56:36 -05001204 vport->fc_flag &= ~FC_BYPASSED_MODE;
1205 spin_unlock_irq(shost->host_lock);
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05001206
dea31012005-04-17 16:05:31 -05001207 if (((phba->fc_eventTag + 1) < la->eventTag) ||
James Smart92d7f7b2007-06-17 19:56:38 -05001208 (phba->fc_eventTag == la->eventTag)) {
dea31012005-04-17 16:05:31 -05001209 phba->fc_stat.LinkMultiEvent++;
James Smart2e0fef82007-06-17 19:56:36 -05001210 if (la->attType == AT_LINK_UP)
dea31012005-04-17 16:05:31 -05001211 if (phba->fc_eventTag != 0)
1212 lpfc_linkdown(phba);
James Smart92d7f7b2007-06-17 19:56:38 -05001213 }
dea31012005-04-17 16:05:31 -05001214
1215 phba->fc_eventTag = la->eventTag;
James Smart84774a42008-08-24 21:50:06 -04001216 if (la->mm)
1217 phba->sli.sli_flag |= LPFC_MENLO_MAINT;
1218 else
1219 phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
dea31012005-04-17 16:05:31 -05001220
James Smart84774a42008-08-24 21:50:06 -04001221 if (la->attType == AT_LINK_UP && (!la->mm)) {
dea31012005-04-17 16:05:31 -05001222 phba->fc_stat.LinkUp++;
James Smart2e0fef82007-06-17 19:56:36 -05001223 if (phba->link_flag & LS_LOOPBACK_MODE) {
James Smart3163f722008-02-08 18:50:25 -05001224 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -04001225 "1306 Link Up Event in loop back mode "
1226 "x%x received Data: x%x x%x x%x x%x\n",
1227 la->eventTag, phba->fc_eventTag,
1228 la->granted_AL_PA, la->UlnkSpeed,
1229 phba->alpa_map[0]);
James Smart5b8bd0c2007-04-25 09:52:49 -04001230 } else {
1231 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -04001232 "1303 Link Up Event x%x received "
James Smart84774a42008-08-24 21:50:06 -04001233 "Data: x%x x%x x%x x%x x%x x%x %d\n",
James Smarte8b62012007-08-02 11:10:09 -04001234 la->eventTag, phba->fc_eventTag,
1235 la->granted_AL_PA, la->UlnkSpeed,
James Smart84774a42008-08-24 21:50:06 -04001236 phba->alpa_map[0],
1237 la->mm, la->fa,
1238 phba->wait_4_mlo_maint_flg);
James Smart5b8bd0c2007-04-25 09:52:49 -04001239 }
James Smart92d7f7b2007-06-17 19:56:38 -05001240 lpfc_mbx_process_link_up(phba, la);
James Smart84774a42008-08-24 21:50:06 -04001241 } else if (la->attType == AT_LINK_DOWN) {
dea31012005-04-17 16:05:31 -05001242 phba->fc_stat.LinkDown++;
James Smart3163f722008-02-08 18:50:25 -05001243 if (phba->link_flag & LS_LOOPBACK_MODE) {
1244 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1245 "1308 Link Down Event in loop back mode "
1246 "x%x received "
1247 "Data: x%x x%x x%x\n",
1248 la->eventTag, phba->fc_eventTag,
1249 phba->pport->port_state, vport->fc_flag);
1250 }
1251 else {
1252 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
James Smarte8b62012007-08-02 11:10:09 -04001253 "1305 Link Down Event x%x received "
James Smart84774a42008-08-24 21:50:06 -04001254 "Data: x%x x%x x%x x%x x%x\n",
1255 la->eventTag, phba->fc_eventTag,
1256 phba->pport->port_state, vport->fc_flag,
1257 la->mm, la->fa);
1258 }
1259 lpfc_mbx_issue_link_down(phba);
1260 }
1261 if (la->mm && la->attType == AT_LINK_UP) {
1262 if (phba->link_state != LPFC_LINK_DOWN) {
1263 phba->fc_stat.LinkDown++;
1264 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1265 "1312 Link Down Event x%x received "
dea31012005-04-17 16:05:31 -05001266 "Data: x%x x%x x%x\n",
James Smarte8b62012007-08-02 11:10:09 -04001267 la->eventTag, phba->fc_eventTag,
James Smart2e0fef82007-06-17 19:56:36 -05001268 phba->pport->port_state, vport->fc_flag);
James Smart84774a42008-08-24 21:50:06 -04001269 lpfc_mbx_issue_link_down(phba);
1270 } else
1271 lpfc_enable_la(phba);
1272
1273 lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1274 "1310 Menlo Maint Mode Link up Event x%x rcvd "
1275 "Data: x%x x%x x%x\n",
1276 la->eventTag, phba->fc_eventTag,
1277 phba->pport->port_state, vport->fc_flag);
1278 /*
1279 * The cmnd that triggered this will be waiting for this
1280 * signal.
1281 */
1282 /* WAKEUP for MENLO_SET_MODE or MENLO_RESET command. */
1283 if (phba->wait_4_mlo_maint_flg) {
1284 phba->wait_4_mlo_maint_flg = 0;
1285 wake_up_interruptible(&phba->wait_4_mlo_m_q);
James Smart3163f722008-02-08 18:50:25 -05001286 }
James Smart84774a42008-08-24 21:50:06 -04001287 }
1288
1289 if (la->fa) {
1290 if (la->mm)
1291 lpfc_issue_clear_la(phba, vport);
1292 lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
1293 "1311 fa %d\n", la->fa);
dea31012005-04-17 16:05:31 -05001294 }
1295
1296lpfc_mbx_cmpl_read_la_free_mbuf:
1297 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1298 kfree(mp);
1299 mempool_free(pmb, phba->mbox_mem_pool);
1300 return;
1301}
1302
1303/*
1304 * This routine handles processing a REG_LOGIN mailbox
1305 * command upon completion. It is setup in the LPFC_MBOXQ
1306 * as the completion routine when the command is
1307 * handed off to the SLI layer.
1308 */
1309void
James Smart2e0fef82007-06-17 19:56:36 -05001310lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -05001311{
James Smart2e0fef82007-06-17 19:56:36 -05001312 struct lpfc_vport *vport = pmb->vport;
James Smart92d7f7b2007-06-17 19:56:38 -05001313 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
James Smart2e0fef82007-06-17 19:56:36 -05001314 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
dea31012005-04-17 16:05:31 -05001315
dea31012005-04-17 16:05:31 -05001316 pmb->context1 = NULL;
1317
1318 /* Good status, call state machine */
James Smart2e0fef82007-06-17 19:56:36 -05001319 lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
dea31012005-04-17 16:05:31 -05001320 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1321 kfree(mp);
James Smart2e0fef82007-06-17 19:56:36 -05001322 mempool_free(pmb, phba->mbox_mem_pool);
James Smartfa4066b2008-01-11 01:53:27 -05001323 /* decrement the node reference count held for this callback
1324 * function.
1325 */
James Smart329f9bc2007-04-25 09:53:01 -04001326 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05001327
1328 return;
1329}
1330
James Smart92d7f7b2007-06-17 19:56:38 -05001331static void
1332lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1333{
1334 MAILBOX_t *mb = &pmb->mb;
1335 struct lpfc_vport *vport = pmb->vport;
1336 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1337
1338 switch (mb->mbxStatus) {
1339 case 0x0011:
1340 case 0x0020:
1341 case 0x9700:
James Smarte8b62012007-08-02 11:10:09 -04001342 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
1343 "0911 cmpl_unreg_vpi, mb status = 0x%x\n",
1344 mb->mbxStatus);
James Smart92d7f7b2007-06-17 19:56:38 -05001345 break;
James Smart92d7f7b2007-06-17 19:56:38 -05001346 }
1347 vport->unreg_vpi_cmpl = VPORT_OK;
1348 mempool_free(pmb, phba->mbox_mem_pool);
1349 /*
1350 * This shost reference might have been taken at the beginning of
1351 * lpfc_vport_delete()
1352 */
1353 if (vport->load_flag & FC_UNLOADING)
1354 scsi_host_put(shost);
1355}
1356
James Smartd7c255b2008-08-24 21:50:00 -04001357int
James Smart92d7f7b2007-06-17 19:56:38 -05001358lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
1359{
1360 struct lpfc_hba *phba = vport->phba;
1361 LPFC_MBOXQ_t *mbox;
1362 int rc;
1363
1364 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1365 if (!mbox)
James Smartd7c255b2008-08-24 21:50:00 -04001366 return 1;
James Smart92d7f7b2007-06-17 19:56:38 -05001367
1368 lpfc_unreg_vpi(phba, vport->vpi, mbox);
1369 mbox->vport = vport;
1370 mbox->mbox_cmpl = lpfc_mbx_cmpl_unreg_vpi;
James Smart0b727fe2007-10-27 13:37:25 -04001371 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
James Smart92d7f7b2007-06-17 19:56:38 -05001372 if (rc == MBX_NOT_FINISHED) {
James Smarte8b62012007-08-02 11:10:09 -04001373 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
1374 "1800 Could not issue unreg_vpi\n");
James Smart92d7f7b2007-06-17 19:56:38 -05001375 mempool_free(mbox, phba->mbox_mem_pool);
1376 vport->unreg_vpi_cmpl = VPORT_ERROR;
James Smartd7c255b2008-08-24 21:50:00 -04001377 return rc;
James Smart92d7f7b2007-06-17 19:56:38 -05001378 }
James Smartd7c255b2008-08-24 21:50:00 -04001379 return 0;
James Smart92d7f7b2007-06-17 19:56:38 -05001380}
1381
1382static void
1383lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1384{
1385 struct lpfc_vport *vport = pmb->vport;
1386 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1387 MAILBOX_t *mb = &pmb->mb;
1388
1389 switch (mb->mbxStatus) {
1390 case 0x0011:
1391 case 0x9601:
1392 case 0x9602:
James Smarte8b62012007-08-02 11:10:09 -04001393 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
1394 "0912 cmpl_reg_vpi, mb status = 0x%x\n",
1395 mb->mbxStatus);
James Smart92d7f7b2007-06-17 19:56:38 -05001396 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
1397 spin_lock_irq(shost->host_lock);
1398 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
1399 spin_unlock_irq(shost->host_lock);
1400 vport->fc_myDID = 0;
1401 goto out;
1402 }
James Smart92d7f7b2007-06-17 19:56:38 -05001403
1404 vport->num_disc_nodes = 0;
1405 /* go thru NPR list and issue ELS PLOGIs */
1406 if (vport->fc_npr_cnt)
1407 lpfc_els_disc_plogi(vport);
1408
1409 if (!vport->num_disc_nodes) {
1410 spin_lock_irq(shost->host_lock);
1411 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1412 spin_unlock_irq(shost->host_lock);
1413 lpfc_can_disctmo(vport);
1414 }
1415 vport->port_state = LPFC_VPORT_READY;
1416
1417out:
1418 mempool_free(pmb, phba->mbox_mem_pool);
1419 return;
1420}
1421
dea31012005-04-17 16:05:31 -05001422/*
1423 * This routine handles processing a Fabric REG_LOGIN mailbox
1424 * command upon completion. It is setup in the LPFC_MBOXQ
1425 * as the completion routine when the command is
1426 * handed off to the SLI layer.
1427 */
1428void
James Smart2e0fef82007-06-17 19:56:36 -05001429lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -05001430{
James Smart92d7f7b2007-06-17 19:56:38 -05001431 struct lpfc_vport *vport = pmb->vport;
James Smart2e0fef82007-06-17 19:56:36 -05001432 MAILBOX_t *mb = &pmb->mb;
1433 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
James Smart92d7f7b2007-06-17 19:56:38 -05001434 struct lpfc_nodelist *ndlp;
James Smart549e55c2007-08-02 11:09:51 -04001435 struct lpfc_vport **vports;
1436 int i;
dea31012005-04-17 16:05:31 -05001437
James Smart549e55c2007-08-02 11:09:51 -04001438 ndlp = (struct lpfc_nodelist *) pmb->context2;
James Smart329f9bc2007-04-25 09:53:01 -04001439 pmb->context1 = NULL;
1440 pmb->context2 = NULL;
dea31012005-04-17 16:05:31 -05001441 if (mb->mbxStatus) {
1442 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1443 kfree(mp);
James Smart329f9bc2007-04-25 09:53:01 -04001444 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001445
James Smart92d7f7b2007-06-17 19:56:38 -05001446 if (phba->fc_topology == TOPOLOGY_LOOP) {
1447 /* FLOGI failed, use loop map to make discovery list */
1448 lpfc_disc_list_loopmap(vport);
dea31012005-04-17 16:05:31 -05001449
James Smart92d7f7b2007-06-17 19:56:38 -05001450 /* Start discovery */
1451 lpfc_disc_start(vport);
James Smarte47c9092008-02-08 18:49:26 -05001452 /* Decrement the reference count to ndlp after the
1453 * reference to the ndlp are done.
1454 */
1455 lpfc_nlp_put(ndlp);
James Smart92d7f7b2007-06-17 19:56:38 -05001456 return;
1457 }
1458
1459 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
James Smarte8b62012007-08-02 11:10:09 -04001460 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
1461 "0258 Register Fabric login error: 0x%x\n",
1462 mb->mbxStatus);
James Smarte47c9092008-02-08 18:49:26 -05001463 /* Decrement the reference count to ndlp after the reference
1464 * to the ndlp are done.
1465 */
1466 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05001467 return;
1468 }
1469
dea31012005-04-17 16:05:31 -05001470 ndlp->nlp_rpi = mb->un.varWords[0];
dea31012005-04-17 16:05:31 -05001471 ndlp->nlp_type |= NLP_FABRIC;
James Smart2e0fef82007-06-17 19:56:36 -05001472 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
dea31012005-04-17 16:05:31 -05001473
James Smart2e0fef82007-06-17 19:56:36 -05001474 if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
James Smart549e55c2007-08-02 11:09:51 -04001475 vports = lpfc_create_vport_work_array(phba);
1476 if (vports != NULL)
1477 for(i = 0;
James Smart09372822008-01-11 01:52:54 -05001478 i <= phba->max_vpi && vports[i] != NULL;
James Smart549e55c2007-08-02 11:09:51 -04001479 i++) {
1480 if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
1481 continue;
James Smart58da1ff2008-04-07 10:15:56 -04001482 if (phba->fc_topology == TOPOLOGY_LOOP) {
1483 lpfc_vport_set_state(vports[i],
1484 FC_VPORT_LINKDOWN);
1485 continue;
1486 }
James Smart549e55c2007-08-02 11:09:51 -04001487 if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
1488 lpfc_initial_fdisc(vports[i]);
James Smart58da1ff2008-04-07 10:15:56 -04001489 else {
James Smart549e55c2007-08-02 11:09:51 -04001490 lpfc_vport_set_state(vports[i],
1491 FC_VPORT_NO_FABRIC_SUPP);
James Smarte8b62012007-08-02 11:10:09 -04001492 lpfc_printf_vlog(vport, KERN_ERR,
1493 LOG_ELS,
1494 "0259 No NPIV "
1495 "Fabric support\n");
James Smart549e55c2007-08-02 11:09:51 -04001496 }
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05001497 }
James Smart09372822008-01-11 01:52:54 -05001498 lpfc_destroy_vport_work_array(phba, vports);
James Smart92d7f7b2007-06-17 19:56:38 -05001499 lpfc_do_scr_ns_plogi(phba, vport);
dea31012005-04-17 16:05:31 -05001500 }
1501
1502 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1503 kfree(mp);
James Smart329f9bc2007-04-25 09:53:01 -04001504 mempool_free(pmb, phba->mbox_mem_pool);
James Smarte47c9092008-02-08 18:49:26 -05001505
1506 /* Drop the reference count from the mbox at the end after
1507 * all the current reference to the ndlp have been done.
1508 */
1509 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05001510 return;
1511}
1512
1513/*
1514 * This routine handles processing a NameServer REG_LOGIN mailbox
1515 * command upon completion. It is setup in the LPFC_MBOXQ
1516 * as the completion routine when the command is
1517 * handed off to the SLI layer.
1518 */
1519void
James Smart2e0fef82007-06-17 19:56:36 -05001520lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -05001521{
James Smart2e0fef82007-06-17 19:56:36 -05001522 MAILBOX_t *mb = &pmb->mb;
1523 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
1524 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
1525 struct lpfc_vport *vport = pmb->vport;
dea31012005-04-17 16:05:31 -05001526
1527 if (mb->mbxStatus) {
James Smart92d7f7b2007-06-17 19:56:38 -05001528out:
James Smartfa4066b2008-01-11 01:53:27 -05001529 /* decrement the node reference count held for this
1530 * callback function.
1531 */
James Smart329f9bc2007-04-25 09:53:01 -04001532 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05001533 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1534 kfree(mp);
James Smartde0c5b32007-04-25 09:52:27 -04001535 mempool_free(pmb, phba->mbox_mem_pool);
James Smart87af33f2007-10-27 13:37:43 -04001536
1537 /* If no other thread is using the ndlp, free it */
1538 lpfc_nlp_not_used(ndlp);
dea31012005-04-17 16:05:31 -05001539
James Smart92d7f7b2007-06-17 19:56:38 -05001540 if (phba->fc_topology == TOPOLOGY_LOOP) {
1541 /*
1542 * RegLogin failed, use loop map to make discovery
1543 * list
1544 */
1545 lpfc_disc_list_loopmap(vport);
dea31012005-04-17 16:05:31 -05001546
James Smart92d7f7b2007-06-17 19:56:38 -05001547 /* Start discovery */
1548 lpfc_disc_start(vport);
1549 return;
1550 }
1551 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
James Smarte8b62012007-08-02 11:10:09 -04001552 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1553 "0260 Register NameServer error: 0x%x\n",
1554 mb->mbxStatus);
dea31012005-04-17 16:05:31 -05001555 return;
1556 }
1557
1558 pmb->context1 = NULL;
1559
dea31012005-04-17 16:05:31 -05001560 ndlp->nlp_rpi = mb->un.varWords[0];
dea31012005-04-17 16:05:31 -05001561 ndlp->nlp_type |= NLP_FABRIC;
James Smart2e0fef82007-06-17 19:56:36 -05001562 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
dea31012005-04-17 16:05:31 -05001563
James Smart2e0fef82007-06-17 19:56:36 -05001564 if (vport->port_state < LPFC_VPORT_READY) {
1565 /* Link up discovery requires Fabric registration. */
James Smart92d7f7b2007-06-17 19:56:38 -05001566 lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, 0); /* Do this first! */
1567 lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
1568 lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
1569 lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
1570 lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);
1571
1572 /* Issue SCR just before NameServer GID_FT Query */
1573 lpfc_issue_els_scr(vport, SCR_DID, 0);
dea31012005-04-17 16:05:31 -05001574 }
1575
James Smart2e0fef82007-06-17 19:56:36 -05001576 vport->fc_ns_retry = 0;
dea31012005-04-17 16:05:31 -05001577 /* Good status, issue CT Request to NameServer */
James Smart92d7f7b2007-06-17 19:56:38 -05001578 if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0)) {
dea31012005-04-17 16:05:31 -05001579 /* Cannot issue NameServer Query, so finish up discovery */
James Smart92d7f7b2007-06-17 19:56:38 -05001580 goto out;
dea31012005-04-17 16:05:31 -05001581 }
1582
James Smartfa4066b2008-01-11 01:53:27 -05001583 /* decrement the node reference count held for this
1584 * callback function.
1585 */
James Smart329f9bc2007-04-25 09:53:01 -04001586 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05001587 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1588 kfree(mp);
James Smart2e0fef82007-06-17 19:56:36 -05001589 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05001590
1591 return;
1592}
1593
1594static void
James Smart2e0fef82007-06-17 19:56:36 -05001595lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05001596{
James Smart2e0fef82007-06-17 19:56:36 -05001597 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1598 struct fc_rport *rport;
dea31012005-04-17 16:05:31 -05001599 struct lpfc_rport_data *rdata;
1600 struct fc_rport_identifiers rport_ids;
James Smart2e0fef82007-06-17 19:56:36 -05001601 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001602
1603 /* Remote port has reappeared. Re-register w/ FC transport */
Andrew Morton68ce1eb2005-09-21 09:46:54 -07001604 rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
1605 rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
dea31012005-04-17 16:05:31 -05001606 rport_ids.port_id = ndlp->nlp_DID;
1607 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
dea31012005-04-17 16:05:31 -05001608
James Smart329f9bc2007-04-25 09:53:01 -04001609 /*
1610 * We leave our node pointer in rport->dd_data when we unregister a
1611 * FCP target port. But fc_remote_port_add zeros the space to which
1612 * rport->dd_data points. So, if we're reusing a previously
1613 * registered port, drop the reference that we took the last time we
1614 * registered the port.
1615 */
1616 if (ndlp->rport && ndlp->rport->dd_data &&
James Smarte47c9092008-02-08 18:49:26 -05001617 ((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp)
James Smart329f9bc2007-04-25 09:53:01 -04001618 lpfc_nlp_put(ndlp);
James Smart858c9f62007-06-17 19:56:39 -05001619
1620 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
1621 "rport add: did:x%x flg:x%x type x%x",
1622 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
1623
James Smart2e0fef82007-06-17 19:56:36 -05001624 ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids);
James Smart329f9bc2007-04-25 09:53:01 -04001625 if (!rport || !get_device(&rport->dev)) {
dea31012005-04-17 16:05:31 -05001626 dev_printk(KERN_WARNING, &phba->pcidev->dev,
1627 "Warning: fc_remote_port_add failed\n");
1628 return;
1629 }
1630
1631 /* initialize static port data */
1632 rport->maxframe_size = ndlp->nlp_maxframe;
1633 rport->supported_classes = ndlp->nlp_class_sup;
dea31012005-04-17 16:05:31 -05001634 rdata = rport->dd_data;
James Smart329f9bc2007-04-25 09:53:01 -04001635 rdata->pnode = lpfc_nlp_get(ndlp);
James.Smart@Emulex.Com23dc04f2005-11-28 11:41:44 -05001636
1637 if (ndlp->nlp_type & NLP_FCP_TARGET)
1638 rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
1639 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
1640 rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1641
1642
1643 if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN)
1644 fc_remote_port_rolechg(rport, rport_ids.roles);
1645
James Smart071fbd3d2006-04-15 11:53:20 -04001646 if ((rport->scsi_target_id != -1) &&
James Smart92d7f7b2007-06-17 19:56:38 -05001647 (rport->scsi_target_id < LPFC_MAX_TARGET)) {
James Smart071fbd3d2006-04-15 11:53:20 -04001648 ndlp->nlp_sid = rport->scsi_target_id;
1649 }
James.Smart@Emulex.Com19a7b4a2005-10-18 12:03:35 -04001650 return;
1651}
1652
1653static void
James Smart2e0fef82007-06-17 19:56:36 -05001654lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
James.Smart@Emulex.Com19a7b4a2005-10-18 12:03:35 -04001655{
1656 struct fc_rport *rport = ndlp->rport;
James Smartc01f3202006-08-18 17:47:08 -04001657
James Smart858c9f62007-06-17 19:56:39 -05001658 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_RPORT,
1659 "rport delete: did:x%x flg:x%x type x%x",
1660 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
1661
James.Smart@Emulex.Com19a7b4a2005-10-18 12:03:35 -04001662 fc_remote_port_delete(rport);
dea31012005-04-17 16:05:31 -05001663
1664 return;
1665}
1666
James Smartde0c5b32007-04-25 09:52:27 -04001667static void
James Smart2e0fef82007-06-17 19:56:36 -05001668lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count)
James Smartde0c5b32007-04-25 09:52:27 -04001669{
James Smart2e0fef82007-06-17 19:56:36 -05001670 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1671
1672 spin_lock_irq(shost->host_lock);
James Smartde0c5b32007-04-25 09:52:27 -04001673 switch (state) {
1674 case NLP_STE_UNUSED_NODE:
James Smart2e0fef82007-06-17 19:56:36 -05001675 vport->fc_unused_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001676 break;
1677 case NLP_STE_PLOGI_ISSUE:
James Smart2e0fef82007-06-17 19:56:36 -05001678 vport->fc_plogi_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001679 break;
1680 case NLP_STE_ADISC_ISSUE:
James Smart2e0fef82007-06-17 19:56:36 -05001681 vport->fc_adisc_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001682 break;
1683 case NLP_STE_REG_LOGIN_ISSUE:
James Smart2e0fef82007-06-17 19:56:36 -05001684 vport->fc_reglogin_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001685 break;
1686 case NLP_STE_PRLI_ISSUE:
James Smart2e0fef82007-06-17 19:56:36 -05001687 vport->fc_prli_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001688 break;
1689 case NLP_STE_UNMAPPED_NODE:
James Smart2e0fef82007-06-17 19:56:36 -05001690 vport->fc_unmap_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001691 break;
1692 case NLP_STE_MAPPED_NODE:
James Smart2e0fef82007-06-17 19:56:36 -05001693 vport->fc_map_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001694 break;
1695 case NLP_STE_NPR_NODE:
James Smart2e0fef82007-06-17 19:56:36 -05001696 vport->fc_npr_cnt += count;
James Smartde0c5b32007-04-25 09:52:27 -04001697 break;
1698 }
James Smart2e0fef82007-06-17 19:56:36 -05001699 spin_unlock_irq(shost->host_lock);
James Smartde0c5b32007-04-25 09:52:27 -04001700}
Jamie Wellnitz66a9ed62006-02-28 22:33:10 -05001701
James Smartde0c5b32007-04-25 09:52:27 -04001702static void
James Smart2e0fef82007-06-17 19:56:36 -05001703lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
James Smartde0c5b32007-04-25 09:52:27 -04001704 int old_state, int new_state)
1705{
James Smart2e0fef82007-06-17 19:56:36 -05001706 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1707
James Smartde0c5b32007-04-25 09:52:27 -04001708 if (new_state == NLP_STE_UNMAPPED_NODE) {
1709 ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
1710 ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1711 ndlp->nlp_type |= NLP_FC_NODE;
1712 }
1713 if (new_state == NLP_STE_MAPPED_NODE)
1714 ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
1715 if (new_state == NLP_STE_NPR_NODE)
1716 ndlp->nlp_flag &= ~NLP_RCV_PLOGI;
dea31012005-04-17 16:05:31 -05001717
James Smartde0c5b32007-04-25 09:52:27 -04001718 /* Transport interface */
1719 if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE ||
1720 old_state == NLP_STE_UNMAPPED_NODE)) {
James Smart2e0fef82007-06-17 19:56:36 -05001721 vport->phba->nport_event_cnt++;
1722 lpfc_unregister_remote_port(ndlp);
James Smartde0c5b32007-04-25 09:52:27 -04001723 }
dea31012005-04-17 16:05:31 -05001724
James Smartde0c5b32007-04-25 09:52:27 -04001725 if (new_state == NLP_STE_MAPPED_NODE ||
1726 new_state == NLP_STE_UNMAPPED_NODE) {
James Smart2e0fef82007-06-17 19:56:36 -05001727 vport->phba->nport_event_cnt++;
James Smart858c9f62007-06-17 19:56:39 -05001728 /*
1729 * Tell the fc transport about the port, if we haven't
1730 * already. If we have, and it's a scsi entity, be
1731 * sure to unblock any attached scsi devices
1732 */
1733 lpfc_register_remote_port(vport, ndlp);
James Smartde0c5b32007-04-25 09:52:27 -04001734 }
James Smartea2151b2008-09-07 11:52:10 -04001735 if ((new_state == NLP_STE_MAPPED_NODE) &&
1736 (vport->stat_data_enabled)) {
1737 /*
1738 * A new target is discovered, if there is no buffer for
1739 * statistical data collection allocate buffer.
1740 */
1741 ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT,
1742 sizeof(struct lpfc_scsicmd_bkt),
1743 GFP_KERNEL);
1744
1745 if (!ndlp->lat_data)
1746 lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
1747 "0286 lpfc_nlp_state_cleanup failed to "
1748 "allocate statistical data buffer DID "
1749 "0x%x\n", ndlp->nlp_DID);
1750 }
James Smart858c9f62007-06-17 19:56:39 -05001751 /*
1752 * if we added to Mapped list, but the remote port
1753 * registration failed or assigned a target id outside
1754 * our presentable range - move the node to the
1755 * Unmapped List
1756 */
James Smartde0c5b32007-04-25 09:52:27 -04001757 if (new_state == NLP_STE_MAPPED_NODE &&
1758 (!ndlp->rport ||
1759 ndlp->rport->scsi_target_id == -1 ||
1760 ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) {
James Smart2e0fef82007-06-17 19:56:36 -05001761 spin_lock_irq(shost->host_lock);
James Smartde0c5b32007-04-25 09:52:27 -04001762 ndlp->nlp_flag |= NLP_TGT_NO_SCSIID;
James Smart2e0fef82007-06-17 19:56:36 -05001763 spin_unlock_irq(shost->host_lock);
1764 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
dea31012005-04-17 16:05:31 -05001765 }
James Smartde0c5b32007-04-25 09:52:27 -04001766}
1767
James Smart685f0bf2007-04-25 09:53:08 -04001768static char *
1769lpfc_nlp_state_name(char *buffer, size_t size, int state)
1770{
1771 static char *states[] = {
1772 [NLP_STE_UNUSED_NODE] = "UNUSED",
1773 [NLP_STE_PLOGI_ISSUE] = "PLOGI",
1774 [NLP_STE_ADISC_ISSUE] = "ADISC",
1775 [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
1776 [NLP_STE_PRLI_ISSUE] = "PRLI",
1777 [NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
1778 [NLP_STE_MAPPED_NODE] = "MAPPED",
1779 [NLP_STE_NPR_NODE] = "NPR",
1780 };
1781
James Smart311464e2007-08-02 11:10:37 -04001782 if (state < NLP_STE_MAX_STATE && states[state])
James Smart685f0bf2007-04-25 09:53:08 -04001783 strlcpy(buffer, states[state], size);
1784 else
1785 snprintf(buffer, size, "unknown (%d)", state);
1786 return buffer;
1787}
1788
James Smartde0c5b32007-04-25 09:52:27 -04001789void
James Smart2e0fef82007-06-17 19:56:36 -05001790lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1791 int state)
James Smartde0c5b32007-04-25 09:52:27 -04001792{
James Smart2e0fef82007-06-17 19:56:36 -05001793 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smartde0c5b32007-04-25 09:52:27 -04001794 int old_state = ndlp->nlp_state;
James Smart685f0bf2007-04-25 09:53:08 -04001795 char name1[16], name2[16];
James Smartde0c5b32007-04-25 09:52:27 -04001796
James Smarte8b62012007-08-02 11:10:09 -04001797 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
1798 "0904 NPort state transition x%06x, %s -> %s\n",
1799 ndlp->nlp_DID,
1800 lpfc_nlp_state_name(name1, sizeof(name1), old_state),
1801 lpfc_nlp_state_name(name2, sizeof(name2), state));
James Smart858c9f62007-06-17 19:56:39 -05001802
1803 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
1804 "node statechg did:x%x old:%d ste:%d",
1805 ndlp->nlp_DID, old_state, state);
1806
James Smartde0c5b32007-04-25 09:52:27 -04001807 if (old_state == NLP_STE_NPR_NODE &&
James Smartde0c5b32007-04-25 09:52:27 -04001808 state != NLP_STE_NPR_NODE)
James Smart2e0fef82007-06-17 19:56:36 -05001809 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smartde0c5b32007-04-25 09:52:27 -04001810 if (old_state == NLP_STE_UNMAPPED_NODE) {
1811 ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID;
1812 ndlp->nlp_type &= ~NLP_FC_NODE;
1813 }
1814
James Smart685f0bf2007-04-25 09:53:08 -04001815 if (list_empty(&ndlp->nlp_listp)) {
James Smart2e0fef82007-06-17 19:56:36 -05001816 spin_lock_irq(shost->host_lock);
1817 list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
1818 spin_unlock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04001819 } else if (old_state)
James Smart2e0fef82007-06-17 19:56:36 -05001820 lpfc_nlp_counters(vport, old_state, -1);
James Smartde0c5b32007-04-25 09:52:27 -04001821
1822 ndlp->nlp_state = state;
James Smart2e0fef82007-06-17 19:56:36 -05001823 lpfc_nlp_counters(vport, state, 1);
1824 lpfc_nlp_state_cleanup(vport, ndlp, old_state, state);
James Smartde0c5b32007-04-25 09:52:27 -04001825}
1826
1827void
James Smarte47c9092008-02-08 18:49:26 -05001828lpfc_enqueue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1829{
1830 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1831
1832 if (list_empty(&ndlp->nlp_listp)) {
1833 spin_lock_irq(shost->host_lock);
1834 list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
1835 spin_unlock_irq(shost->host_lock);
1836 }
1837}
1838
1839void
James Smart2e0fef82007-06-17 19:56:36 -05001840lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
James Smartde0c5b32007-04-25 09:52:27 -04001841{
James Smart2e0fef82007-06-17 19:56:36 -05001842 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1843
James Smart0d2b6b82008-06-14 22:52:47 -04001844 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smartde0c5b32007-04-25 09:52:27 -04001845 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
James Smart2e0fef82007-06-17 19:56:36 -05001846 lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
1847 spin_lock_irq(shost->host_lock);
James Smart685f0bf2007-04-25 09:53:08 -04001848 list_del_init(&ndlp->nlp_listp);
James Smart2e0fef82007-06-17 19:56:36 -05001849 spin_unlock_irq(shost->host_lock);
James Smart858c9f62007-06-17 19:56:39 -05001850 lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state,
James Smarte47c9092008-02-08 18:49:26 -05001851 NLP_STE_UNUSED_NODE);
1852}
1853
Adrian Bunk4d9db012008-02-14 23:24:02 +02001854static void
James Smarte47c9092008-02-08 18:49:26 -05001855lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1856{
James Smart0d2b6b82008-06-14 22:52:47 -04001857 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smarte47c9092008-02-08 18:49:26 -05001858 if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
1859 lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
1860 lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state,
1861 NLP_STE_UNUSED_NODE);
1862}
James Smart109f6ed2008-12-04 22:39:08 -05001863/**
James Smart3621a712009-04-06 18:47:14 -04001864 * lpfc_initialize_node - Initialize all fields of node object
James Smart109f6ed2008-12-04 22:39:08 -05001865 * @vport: Pointer to Virtual Port object.
1866 * @ndlp: Pointer to FC node object.
1867 * @did: FC_ID of the node.
James Smarta257bf92009-04-06 18:48:10 -04001868 *
1869 * This function is always called when node object need to be initialized.
1870 * It initializes all the fields of the node object. Although the reference
1871 * to phba from @ndlp can be obtained indirectly through it's reference to
1872 * @vport, a direct reference to phba is taken here by @ndlp. This is due
1873 * to the life-span of the @ndlp might go beyond the existence of @vport as
1874 * the final release of ndlp is determined by its reference count. And, the
1875 * operation on @ndlp needs the reference to phba.
James Smart109f6ed2008-12-04 22:39:08 -05001876 **/
1877static inline void
1878lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1879 uint32_t did)
1880{
1881 INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
1882 INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
1883 init_timer(&ndlp->nlp_delayfunc);
1884 ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
1885 ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
1886 ndlp->nlp_DID = did;
1887 ndlp->vport = vport;
James Smarta257bf92009-04-06 18:48:10 -04001888 ndlp->phba = vport->phba;
James Smart109f6ed2008-12-04 22:39:08 -05001889 ndlp->nlp_sid = NLP_NO_SID;
1890 kref_init(&ndlp->kref);
1891 NLP_INT_NODE_ACT(ndlp);
1892 atomic_set(&ndlp->cmd_pending, 0);
1893 ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
1894}
James Smarte47c9092008-02-08 18:49:26 -05001895
1896struct lpfc_nodelist *
1897lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1898 int state)
1899{
1900 struct lpfc_hba *phba = vport->phba;
1901 uint32_t did;
1902 unsigned long flags;
1903
1904 if (!ndlp)
1905 return NULL;
1906
1907 spin_lock_irqsave(&phba->ndlp_lock, flags);
1908 /* The ndlp should not be in memory free mode */
1909 if (NLP_CHK_FREE_REQ(ndlp)) {
1910 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
1911 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
1912 "0277 lpfc_enable_node: ndlp:x%p "
1913 "usgmap:x%x refcnt:%d\n",
1914 (void *)ndlp, ndlp->nlp_usg_map,
1915 atomic_read(&ndlp->kref.refcount));
1916 return NULL;
1917 }
1918 /* The ndlp should not already be in active mode */
1919 if (NLP_CHK_NODE_ACT(ndlp)) {
1920 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
1921 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
1922 "0278 lpfc_enable_node: ndlp:x%p "
1923 "usgmap:x%x refcnt:%d\n",
1924 (void *)ndlp, ndlp->nlp_usg_map,
1925 atomic_read(&ndlp->kref.refcount));
1926 return NULL;
1927 }
1928
1929 /* Keep the original DID */
1930 did = ndlp->nlp_DID;
1931
1932 /* re-initialize ndlp except of ndlp linked list pointer */
1933 memset((((char *)ndlp) + sizeof (struct list_head)), 0,
1934 sizeof (struct lpfc_nodelist) - sizeof (struct list_head));
James Smart109f6ed2008-12-04 22:39:08 -05001935 lpfc_initialize_node(vport, ndlp, did);
James Smarte47c9092008-02-08 18:49:26 -05001936
1937 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
1938
1939 if (state != NLP_STE_UNUSED_NODE)
1940 lpfc_nlp_set_state(vport, ndlp, state);
1941
1942 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
1943 "node enable: did:x%x",
1944 ndlp->nlp_DID, 0, 0);
1945 return ndlp;
James Smartde0c5b32007-04-25 09:52:27 -04001946}
1947
1948void
James Smart2e0fef82007-06-17 19:56:36 -05001949lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
James Smartde0c5b32007-04-25 09:52:27 -04001950{
James Smart87af33f2007-10-27 13:37:43 -04001951 /*
James Smartfa4066b2008-01-11 01:53:27 -05001952 * Use of lpfc_drop_node and UNUSED list: lpfc_drop_node should
James Smart87af33f2007-10-27 13:37:43 -04001953 * be used if we wish to issue the "last" lpfc_nlp_put() to remove
James Smartfa4066b2008-01-11 01:53:27 -05001954 * the ndlp from the vport. The ndlp marked as UNUSED on the list
1955 * until ALL other outstanding threads have completed. We check
1956 * that the ndlp not already in the UNUSED state before we proceed.
James Smart87af33f2007-10-27 13:37:43 -04001957 */
James Smartfa4066b2008-01-11 01:53:27 -05001958 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
1959 return;
James Smart51ef4c22007-08-02 11:10:31 -04001960 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
James Smart87af33f2007-10-27 13:37:43 -04001961 lpfc_nlp_put(ndlp);
James Smart98c9ea52007-10-27 13:37:33 -04001962 return;
dea31012005-04-17 16:05:31 -05001963}
1964
1965/*
1966 * Start / ReStart rescue timer for Discovery / RSCN handling
1967 */
1968void
James Smart2e0fef82007-06-17 19:56:36 -05001969lpfc_set_disctmo(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05001970{
James Smart2e0fef82007-06-17 19:56:36 -05001971 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1972 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05001973 uint32_t tmo;
1974
James Smart2e0fef82007-06-17 19:56:36 -05001975 if (vport->port_state == LPFC_LOCAL_CFG_LINK) {
Frederik Schwarzer025dfda2008-10-16 19:02:37 +02001976 /* For FAN, timeout should be greater than edtov */
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05001977 tmo = (((phba->fc_edtov + 999) / 1000) + 1);
1978 } else {
Frederik Schwarzer025dfda2008-10-16 19:02:37 +02001979 /* Normal discovery timeout should be > than ELS/CT timeout
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05001980 * FC spec states we need 3 * ratov for CT requests
1981 */
1982 tmo = ((phba->fc_ratov * 3) + 3);
1983 }
dea31012005-04-17 16:05:31 -05001984
James Smart858c9f62007-06-17 19:56:39 -05001985
1986 if (!timer_pending(&vport->fc_disctmo)) {
1987 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1988 "set disc timer: tmo:x%x state:x%x flg:x%x",
1989 tmo, vport->port_state, vport->fc_flag);
1990 }
1991
James Smart2e0fef82007-06-17 19:56:36 -05001992 mod_timer(&vport->fc_disctmo, jiffies + HZ * tmo);
1993 spin_lock_irq(shost->host_lock);
1994 vport->fc_flag |= FC_DISC_TMO;
1995 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05001996
1997 /* Start Discovery Timer state <hba_state> */
James Smarte8b62012007-08-02 11:10:09 -04001998 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1999 "0247 Start Discovery Timer state x%x "
2000 "Data: x%x x%lx x%x x%x\n",
2001 vport->port_state, tmo,
2002 (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt,
2003 vport->fc_adisc_cnt);
dea31012005-04-17 16:05:31 -05002004
2005 return;
2006}
2007
2008/*
2009 * Cancel rescue timer for Discovery / RSCN handling
2010 */
2011int
James Smart2e0fef82007-06-17 19:56:36 -05002012lpfc_can_disctmo(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05002013{
James Smart2e0fef82007-06-17 19:56:36 -05002014 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart2e0fef82007-06-17 19:56:36 -05002015 unsigned long iflags;
2016
James Smart858c9f62007-06-17 19:56:39 -05002017 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2018 "can disc timer: state:x%x rtry:x%x flg:x%x",
2019 vport->port_state, vport->fc_ns_retry, vport->fc_flag);
2020
dea31012005-04-17 16:05:31 -05002021 /* Turn off discovery timer if its running */
James Smart2e0fef82007-06-17 19:56:36 -05002022 if (vport->fc_flag & FC_DISC_TMO) {
2023 spin_lock_irqsave(shost->host_lock, iflags);
2024 vport->fc_flag &= ~FC_DISC_TMO;
2025 spin_unlock_irqrestore(shost->host_lock, iflags);
2026 del_timer_sync(&vport->fc_disctmo);
2027 spin_lock_irqsave(&vport->work_port_lock, iflags);
2028 vport->work_port_events &= ~WORKER_DISC_TMO;
2029 spin_unlock_irqrestore(&vport->work_port_lock, iflags);
dea31012005-04-17 16:05:31 -05002030 }
2031
2032 /* Cancel Discovery Timer state <hba_state> */
James Smarte8b62012007-08-02 11:10:09 -04002033 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2034 "0248 Cancel Discovery Timer state x%x "
2035 "Data: x%x x%x x%x\n",
2036 vport->port_state, vport->fc_flag,
2037 vport->fc_plogi_cnt, vport->fc_adisc_cnt);
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002038 return 0;
dea31012005-04-17 16:05:31 -05002039}
2040
2041/*
2042 * Check specified ring for outstanding IOCB on the SLI queue
2043 * Return true if iocb matches the specified nport
2044 */
2045int
James Smart2e0fef82007-06-17 19:56:36 -05002046lpfc_check_sli_ndlp(struct lpfc_hba *phba,
2047 struct lpfc_sli_ring *pring,
2048 struct lpfc_iocbq *iocb,
2049 struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05002050{
James Smart2e0fef82007-06-17 19:56:36 -05002051 struct lpfc_sli *psli = &phba->sli;
2052 IOCB_t *icmd = &iocb->iocb;
James Smart92d7f7b2007-06-17 19:56:38 -05002053 struct lpfc_vport *vport = ndlp->vport;
2054
2055 if (iocb->vport != vport)
2056 return 0;
2057
dea31012005-04-17 16:05:31 -05002058 if (pring->ringno == LPFC_ELS_RING) {
2059 switch (icmd->ulpCommand) {
2060 case CMD_GEN_REQUEST64_CR:
2061 if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi)
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002062 return 1;
dea31012005-04-17 16:05:31 -05002063 case CMD_ELS_REQUEST64_CR:
James Smart10d4e952006-04-15 11:53:15 -04002064 if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID)
2065 return 1;
dea31012005-04-17 16:05:31 -05002066 case CMD_XMIT_ELS_RSP64_CX:
2067 if (iocb->context1 == (uint8_t *) ndlp)
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002068 return 1;
dea31012005-04-17 16:05:31 -05002069 }
James Smarta4bc3372006-12-02 13:34:16 -05002070 } else if (pring->ringno == psli->extra_ring) {
dea31012005-04-17 16:05:31 -05002071
2072 } else if (pring->ringno == psli->fcp_ring) {
2073 /* Skip match check if waiting to relogin to FCP target */
2074 if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
James Smart92d7f7b2007-06-17 19:56:38 -05002075 (ndlp->nlp_flag & NLP_DELAY_TMO)) {
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002076 return 0;
dea31012005-04-17 16:05:31 -05002077 }
2078 if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) {
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002079 return 1;
dea31012005-04-17 16:05:31 -05002080 }
2081 } else if (pring->ringno == psli->next_ring) {
2082
2083 }
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002084 return 0;
dea31012005-04-17 16:05:31 -05002085}
2086
2087/*
2088 * Free resources / clean up outstanding I/Os
2089 * associated with nlp_rpi in the LPFC_NODELIST entry.
2090 */
2091static int
James Smart2e0fef82007-06-17 19:56:36 -05002092lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05002093{
James Smart2534ba72007-04-25 09:52:20 -04002094 LIST_HEAD(completions);
dea31012005-04-17 16:05:31 -05002095 struct lpfc_sli *psli;
2096 struct lpfc_sli_ring *pring;
2097 struct lpfc_iocbq *iocb, *next_iocb;
dea31012005-04-17 16:05:31 -05002098 uint32_t rpi, i;
2099
James Smart92d7f7b2007-06-17 19:56:38 -05002100 lpfc_fabric_abort_nport(ndlp);
2101
dea31012005-04-17 16:05:31 -05002102 /*
2103 * Everything that matches on txcmplq will be returned
2104 * by firmware with a no rpi error.
2105 */
2106 psli = &phba->sli;
2107 rpi = ndlp->nlp_rpi;
2108 if (rpi) {
2109 /* Now process each ring */
2110 for (i = 0; i < psli->num_rings; i++) {
2111 pring = &psli->ring[i];
2112
James Smart2e0fef82007-06-17 19:56:36 -05002113 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05002114 list_for_each_entry_safe(iocb, next_iocb, &pring->txq,
James Smart2e0fef82007-06-17 19:56:36 -05002115 list) {
dea31012005-04-17 16:05:31 -05002116 /*
2117 * Check to see if iocb matches the nport we are
2118 * looking for
2119 */
James Smart92d7f7b2007-06-17 19:56:38 -05002120 if ((lpfc_check_sli_ndlp(phba, pring, iocb,
2121 ndlp))) {
dea31012005-04-17 16:05:31 -05002122 /* It matches, so deque and call compl
2123 with an error */
James Smart2534ba72007-04-25 09:52:20 -04002124 list_move_tail(&iocb->list,
2125 &completions);
dea31012005-04-17 16:05:31 -05002126 pring->txq_cnt--;
dea31012005-04-17 16:05:31 -05002127 }
2128 }
James Smart2e0fef82007-06-17 19:56:36 -05002129 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05002130 }
2131 }
James Smart2534ba72007-04-25 09:52:20 -04002132
James Smarta257bf92009-04-06 18:48:10 -04002133 /* Cancel all the IOCBs from the completions list */
2134 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
2135 IOERR_SLI_ABORTED);
James Smart2534ba72007-04-25 09:52:20 -04002136
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002137 return 0;
dea31012005-04-17 16:05:31 -05002138}
2139
2140/*
2141 * Free rpi associated with LPFC_NODELIST entry.
2142 * This routine is called from lpfc_freenode(), when we are removing
2143 * a LPFC_NODELIST entry. It is also called if the driver initiates a
2144 * LOGO that completes successfully, and we are waiting to PLOGI back
2145 * to the remote NPort. In addition, it is called after we receive
2146 * and unsolicated ELS cmd, send back a rsp, the rsp completes and
2147 * we are waiting to PLOGI back to the remote NPort.
2148 */
2149int
James Smart2e0fef82007-06-17 19:56:36 -05002150lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05002151{
James Smart2e0fef82007-06-17 19:56:36 -05002152 struct lpfc_hba *phba = vport->phba;
2153 LPFC_MBOXQ_t *mbox;
dea31012005-04-17 16:05:31 -05002154 int rc;
2155
2156 if (ndlp->nlp_rpi) {
James Smart2e0fef82007-06-17 19:56:36 -05002157 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2158 if (mbox) {
James Smart92d7f7b2007-06-17 19:56:38 -05002159 lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
James Smarted957682007-06-17 19:56:37 -05002160 mbox->vport = vport;
James Smart92d7f7b2007-06-17 19:56:38 -05002161 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smart0b727fe2007-10-27 13:37:25 -04002162 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
dea31012005-04-17 16:05:31 -05002163 if (rc == MBX_NOT_FINISHED)
James Smart2e0fef82007-06-17 19:56:36 -05002164 mempool_free(mbox, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05002165 }
dea31012005-04-17 16:05:31 -05002166 lpfc_no_rpi(phba, ndlp);
2167 ndlp->nlp_rpi = 0;
2168 return 1;
2169 }
2170 return 0;
2171}
2172
James Smart92d7f7b2007-06-17 19:56:38 -05002173void
2174lpfc_unreg_all_rpis(struct lpfc_vport *vport)
2175{
2176 struct lpfc_hba *phba = vport->phba;
2177 LPFC_MBOXQ_t *mbox;
2178 int rc;
2179
2180 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2181 if (mbox) {
2182 lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox);
2183 mbox->vport = vport;
2184 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smart09372822008-01-11 01:52:54 -05002185 mbox->context1 = NULL;
2186 rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
James Smarta257bf92009-04-06 18:48:10 -04002187 if (rc != MBX_TIMEOUT)
James Smart92d7f7b2007-06-17 19:56:38 -05002188 mempool_free(mbox, phba->mbox_mem_pool);
James Smarta257bf92009-04-06 18:48:10 -04002189
2190 if ((rc == MBX_TIMEOUT) || (rc == MBX_NOT_FINISHED))
2191 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
2192 "1836 Could not issue "
2193 "unreg_login(all_rpis) status %d\n", rc);
James Smart92d7f7b2007-06-17 19:56:38 -05002194 }
2195}
2196
2197void
2198lpfc_unreg_default_rpis(struct lpfc_vport *vport)
2199{
2200 struct lpfc_hba *phba = vport->phba;
2201 LPFC_MBOXQ_t *mbox;
2202 int rc;
2203
2204 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2205 if (mbox) {
2206 lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox);
2207 mbox->vport = vport;
2208 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smart09372822008-01-11 01:52:54 -05002209 mbox->context1 = NULL;
2210 rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
James Smarta257bf92009-04-06 18:48:10 -04002211 if (rc != MBX_TIMEOUT)
2212 mempool_free(mbox, phba->mbox_mem_pool);
2213
2214 if ((rc == MBX_TIMEOUT) || (rc == MBX_NOT_FINISHED))
James Smarte8b62012007-08-02 11:10:09 -04002215 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
2216 "1815 Could not issue "
James Smarta257bf92009-04-06 18:48:10 -04002217 "unreg_did (default rpis) status %d\n",
2218 rc);
James Smart92d7f7b2007-06-17 19:56:38 -05002219 }
2220}
2221
dea31012005-04-17 16:05:31 -05002222/*
2223 * Free resources associated with LPFC_NODELIST entry
2224 * so it can be freed.
2225 */
2226static int
James Smart2e0fef82007-06-17 19:56:36 -05002227lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05002228{
James Smart2e0fef82007-06-17 19:56:36 -05002229 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2230 struct lpfc_hba *phba = vport->phba;
2231 LPFC_MBOXQ_t *mb, *nextmb;
dea31012005-04-17 16:05:31 -05002232 struct lpfc_dmabuf *mp;
dea31012005-04-17 16:05:31 -05002233
2234 /* Cleanup node for NPort <nlp_DID> */
James Smarte8b62012007-08-02 11:10:09 -04002235 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
2236 "0900 Cleanup node for NPort x%x "
2237 "Data: x%x x%x x%x\n",
2238 ndlp->nlp_DID, ndlp->nlp_flag,
2239 ndlp->nlp_state, ndlp->nlp_rpi);
James Smarte47c9092008-02-08 18:49:26 -05002240 if (NLP_CHK_FREE_REQ(ndlp)) {
2241 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
2242 "0280 lpfc_cleanup_node: ndlp:x%p "
2243 "usgmap:x%x refcnt:%d\n",
2244 (void *)ndlp, ndlp->nlp_usg_map,
2245 atomic_read(&ndlp->kref.refcount));
2246 lpfc_dequeue_node(vport, ndlp);
2247 } else {
2248 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
2249 "0281 lpfc_cleanup_node: ndlp:x%p "
2250 "usgmap:x%x refcnt:%d\n",
2251 (void *)ndlp, ndlp->nlp_usg_map,
2252 atomic_read(&ndlp->kref.refcount));
2253 lpfc_disable_node(vport, ndlp);
2254 }
dea31012005-04-17 16:05:31 -05002255
dea31012005-04-17 16:05:31 -05002256 /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
2257 if ((mb = phba->sli.mbox_active)) {
2258 if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
2259 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
2260 mb->context2 = NULL;
2261 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
2262 }
2263 }
James Smart33ccf8d2006-08-17 11:57:58 -04002264
James Smart2e0fef82007-06-17 19:56:36 -05002265 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05002266 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
2267 if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
James Smart92d7f7b2007-06-17 19:56:38 -05002268 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
dea31012005-04-17 16:05:31 -05002269 mp = (struct lpfc_dmabuf *) (mb->context1);
2270 if (mp) {
James Smart2e0fef82007-06-17 19:56:36 -05002271 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
dea31012005-04-17 16:05:31 -05002272 kfree(mp);
2273 }
2274 list_del(&mb->list);
2275 mempool_free(mb, phba->mbox_mem_pool);
James Smarte47c9092008-02-08 18:49:26 -05002276 /* We shall not invoke the lpfc_nlp_put to decrement
2277 * the ndlp reference count as we are in the process
2278 * of lpfc_nlp_release.
2279 */
dea31012005-04-17 16:05:31 -05002280 }
2281 }
James Smart2e0fef82007-06-17 19:56:36 -05002282 spin_unlock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05002283
James Smarte47c9092008-02-08 18:49:26 -05002284 lpfc_els_abort(phba, ndlp);
2285
James Smart2e0fef82007-06-17 19:56:36 -05002286 spin_lock_irq(shost->host_lock);
James Smartc01f3202006-08-18 17:47:08 -04002287 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
James Smart2e0fef82007-06-17 19:56:36 -05002288 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002289
Jamie Wellnitz5024ab12006-02-28 19:25:28 -05002290 ndlp->nlp_last_elscmd = 0;
dea31012005-04-17 16:05:31 -05002291 del_timer_sync(&ndlp->nlp_delayfunc);
2292
James Smart0d2b6b82008-06-14 22:52:47 -04002293 list_del_init(&ndlp->els_retry_evt.evt_listp);
2294 list_del_init(&ndlp->dev_loss_evt.evt_listp);
dea31012005-04-17 16:05:31 -05002295
James Smart2e0fef82007-06-17 19:56:36 -05002296 lpfc_unreg_rpi(vport, ndlp);
dea31012005-04-17 16:05:31 -05002297
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002298 return 0;
dea31012005-04-17 16:05:31 -05002299}
2300
2301/*
2302 * Check to see if we can free the nlp back to the freelist.
2303 * If we are in the middle of using the nlp in the discovery state
2304 * machine, defer the free till we reach the end of the state machine.
2305 */
James Smart329f9bc2007-04-25 09:53:01 -04002306static void
James Smart2e0fef82007-06-17 19:56:36 -05002307lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05002308{
James Smarta8adb832007-10-27 13:37:53 -04002309 struct lpfc_hba *phba = vport->phba;
James Smart1dcb58e2007-04-25 09:51:30 -04002310 struct lpfc_rport_data *rdata;
James Smarta8adb832007-10-27 13:37:53 -04002311 LPFC_MBOXQ_t *mbox;
2312 int rc;
dea31012005-04-17 16:05:31 -05002313
James Smart0d2b6b82008-06-14 22:52:47 -04002314 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smarta8adb832007-10-27 13:37:53 -04002315 if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) {
2316 /* For this case we need to cleanup the default rpi
2317 * allocated by the firmware.
2318 */
2319 if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
2320 != NULL) {
2321 rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID,
2322 (uint8_t *) &vport->fc_sparam, mbox, 0);
2323 if (rc) {
2324 mempool_free(mbox, phba->mbox_mem_pool);
2325 }
2326 else {
2327 mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
2328 mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
2329 mbox->vport = vport;
James Smart09372822008-01-11 01:52:54 -05002330 mbox->context2 = NULL;
James Smarta8adb832007-10-27 13:37:53 -04002331 rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
2332 if (rc == MBX_NOT_FINISHED) {
2333 mempool_free(mbox, phba->mbox_mem_pool);
2334 }
2335 }
2336 }
2337 }
James Smart2e0fef82007-06-17 19:56:36 -05002338 lpfc_cleanup_node(vport, ndlp);
James Smart1dcb58e2007-04-25 09:51:30 -04002339
James Smart2e0fef82007-06-17 19:56:36 -05002340 /*
James Smart92d7f7b2007-06-17 19:56:38 -05002341 * We can get here with a non-NULL ndlp->rport because when we
2342 * unregister a rport we don't break the rport/node linkage. So if we
2343 * do, make sure we don't leaving any dangling pointers behind.
James Smart2e0fef82007-06-17 19:56:36 -05002344 */
James Smart92d7f7b2007-06-17 19:56:38 -05002345 if (ndlp->rport) {
James Smart329f9bc2007-04-25 09:53:01 -04002346 rdata = ndlp->rport->dd_data;
2347 rdata->pnode = NULL;
2348 ndlp->rport = NULL;
dea31012005-04-17 16:05:31 -05002349 }
dea31012005-04-17 16:05:31 -05002350}
2351
2352static int
James Smart2e0fef82007-06-17 19:56:36 -05002353lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2354 uint32_t did)
dea31012005-04-17 16:05:31 -05002355{
James Smart2e0fef82007-06-17 19:56:36 -05002356 D_ID mydid, ndlpdid, matchdid;
dea31012005-04-17 16:05:31 -05002357
2358 if (did == Bcast_DID)
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002359 return 0;
dea31012005-04-17 16:05:31 -05002360
dea31012005-04-17 16:05:31 -05002361 /* First check for Direct match */
2362 if (ndlp->nlp_DID == did)
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002363 return 1;
dea31012005-04-17 16:05:31 -05002364
2365 /* Next check for area/domain identically equals 0 match */
James Smart2e0fef82007-06-17 19:56:36 -05002366 mydid.un.word = vport->fc_myDID;
dea31012005-04-17 16:05:31 -05002367 if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) {
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002368 return 0;
dea31012005-04-17 16:05:31 -05002369 }
2370
2371 matchdid.un.word = did;
2372 ndlpdid.un.word = ndlp->nlp_DID;
2373 if (matchdid.un.b.id == ndlpdid.un.b.id) {
2374 if ((mydid.un.b.domain == matchdid.un.b.domain) &&
2375 (mydid.un.b.area == matchdid.un.b.area)) {
2376 if ((ndlpdid.un.b.domain == 0) &&
2377 (ndlpdid.un.b.area == 0)) {
2378 if (ndlpdid.un.b.id)
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002379 return 1;
dea31012005-04-17 16:05:31 -05002380 }
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002381 return 0;
dea31012005-04-17 16:05:31 -05002382 }
2383
2384 matchdid.un.word = ndlp->nlp_DID;
2385 if ((mydid.un.b.domain == ndlpdid.un.b.domain) &&
2386 (mydid.un.b.area == ndlpdid.un.b.area)) {
2387 if ((matchdid.un.b.domain == 0) &&
2388 (matchdid.un.b.area == 0)) {
2389 if (matchdid.un.b.id)
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002390 return 1;
dea31012005-04-17 16:05:31 -05002391 }
2392 }
2393 }
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002394 return 0;
dea31012005-04-17 16:05:31 -05002395}
2396
James Smart685f0bf2007-04-25 09:53:08 -04002397/* Search for a nodelist entry */
James Smart2e0fef82007-06-17 19:56:36 -05002398static struct lpfc_nodelist *
2399__lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
dea31012005-04-17 16:05:31 -05002400{
James Smart2fb9bd82006-12-02 13:33:57 -05002401 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05002402 uint32_t data1;
2403
James Smart2e0fef82007-06-17 19:56:36 -05002404 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
2405 if (lpfc_matchdid(vport, ndlp, did)) {
James Smart685f0bf2007-04-25 09:53:08 -04002406 data1 = (((uint32_t) ndlp->nlp_state << 24) |
2407 ((uint32_t) ndlp->nlp_xri << 16) |
2408 ((uint32_t) ndlp->nlp_type << 8) |
2409 ((uint32_t) ndlp->nlp_rpi & 0xff));
James Smarte8b62012007-08-02 11:10:09 -04002410 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
2411 "0929 FIND node DID "
2412 "Data: x%p x%x x%x x%x\n",
2413 ndlp, ndlp->nlp_DID,
2414 ndlp->nlp_flag, data1);
James Smart685f0bf2007-04-25 09:53:08 -04002415 return ndlp;
dea31012005-04-17 16:05:31 -05002416 }
2417 }
Jamie Wellnitz66a9ed62006-02-28 22:33:10 -05002418
dea31012005-04-17 16:05:31 -05002419 /* FIND node did <did> NOT FOUND */
James Smarte8b62012007-08-02 11:10:09 -04002420 lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
2421 "0932 FIND node did x%x NOT FOUND.\n", did);
dea31012005-04-17 16:05:31 -05002422 return NULL;
2423}
2424
2425struct lpfc_nodelist *
James Smart2e0fef82007-06-17 19:56:36 -05002426lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
dea31012005-04-17 16:05:31 -05002427{
James Smart2e0fef82007-06-17 19:56:36 -05002428 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
dea31012005-04-17 16:05:31 -05002429 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05002430
James Smart2e0fef82007-06-17 19:56:36 -05002431 spin_lock_irq(shost->host_lock);
2432 ndlp = __lpfc_findnode_did(vport, did);
2433 spin_unlock_irq(shost->host_lock);
2434 return ndlp;
2435}
2436
2437struct lpfc_nodelist *
2438lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
2439{
2440 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2441 struct lpfc_nodelist *ndlp;
2442
2443 ndlp = lpfc_findnode_did(vport, did);
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002444 if (!ndlp) {
James Smart2e0fef82007-06-17 19:56:36 -05002445 if ((vport->fc_flag & FC_RSCN_MODE) != 0 &&
2446 lpfc_rscn_payload_check(vport, did) == 0)
dea31012005-04-17 16:05:31 -05002447 return NULL;
2448 ndlp = (struct lpfc_nodelist *)
James Smart2e0fef82007-06-17 19:56:36 -05002449 mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL);
dea31012005-04-17 16:05:31 -05002450 if (!ndlp)
2451 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05002452 lpfc_nlp_init(vport, ndlp, did);
2453 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2454 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002455 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
James Smart2e0fef82007-06-17 19:56:36 -05002456 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002457 return ndlp;
James Smarte47c9092008-02-08 18:49:26 -05002458 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
2459 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE);
2460 if (!ndlp)
2461 return NULL;
2462 spin_lock_irq(shost->host_lock);
2463 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2464 spin_unlock_irq(shost->host_lock);
2465 return ndlp;
dea31012005-04-17 16:05:31 -05002466 }
James Smarte47c9092008-02-08 18:49:26 -05002467
James Smart58da1ff2008-04-07 10:15:56 -04002468 if ((vport->fc_flag & FC_RSCN_MODE) &&
2469 !(vport->fc_flag & FC_NDISC_ACTIVE)) {
James Smart2e0fef82007-06-17 19:56:36 -05002470 if (lpfc_rscn_payload_check(vport, did)) {
James Smart87af33f2007-10-27 13:37:43 -04002471 /* If we've already recieved a PLOGI from this NPort
2472 * we don't need to try to discover it again.
2473 */
2474 if (ndlp->nlp_flag & NLP_RCV_PLOGI)
2475 return NULL;
2476
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002477 /* Since this node is marked for discovery,
2478 * delay timeout is not needed.
2479 */
James Smart0d2b6b82008-06-14 22:52:47 -04002480 lpfc_cancel_retry_delay_tmo(vport, ndlp);
James Smarta257bf92009-04-06 18:48:10 -04002481 spin_lock_irq(shost->host_lock);
2482 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2483 spin_unlock_irq(shost->host_lock);
James Smart071fbd3d2006-04-15 11:53:20 -04002484 } else
dea31012005-04-17 16:05:31 -05002485 ndlp = NULL;
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002486 } else {
James Smart87af33f2007-10-27 13:37:43 -04002487 /* If we've already recieved a PLOGI from this NPort,
2488 * or we are already in the process of discovery on it,
2489 * we don't need to try to discover it again.
2490 */
James Smart685f0bf2007-04-25 09:53:08 -04002491 if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE ||
James Smart87af33f2007-10-27 13:37:43 -04002492 ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
2493 ndlp->nlp_flag & NLP_RCV_PLOGI)
dea31012005-04-17 16:05:31 -05002494 return NULL;
James Smart2e0fef82007-06-17 19:56:36 -05002495 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2496 spin_lock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002497 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
James Smart2e0fef82007-06-17 19:56:36 -05002498 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002499 }
2500 return ndlp;
2501}
2502
2503/* Build a list of nodes to discover based on the loopmap */
2504void
James Smart2e0fef82007-06-17 19:56:36 -05002505lpfc_disc_list_loopmap(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05002506{
James Smart2e0fef82007-06-17 19:56:36 -05002507 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05002508 int j;
2509 uint32_t alpa, index;
2510
James Smart2e0fef82007-06-17 19:56:36 -05002511 if (!lpfc_is_link_up(phba))
dea31012005-04-17 16:05:31 -05002512 return;
James Smart2e0fef82007-06-17 19:56:36 -05002513
2514 if (phba->fc_topology != TOPOLOGY_LOOP)
dea31012005-04-17 16:05:31 -05002515 return;
dea31012005-04-17 16:05:31 -05002516
2517 /* Check for loop map present or not */
2518 if (phba->alpa_map[0]) {
2519 for (j = 1; j <= phba->alpa_map[0]; j++) {
2520 alpa = phba->alpa_map[j];
James Smart2e0fef82007-06-17 19:56:36 -05002521 if (((vport->fc_myDID & 0xff) == alpa) || (alpa == 0))
dea31012005-04-17 16:05:31 -05002522 continue;
James Smart2e0fef82007-06-17 19:56:36 -05002523 lpfc_setup_disc_node(vport, alpa);
dea31012005-04-17 16:05:31 -05002524 }
2525 } else {
2526 /* No alpamap, so try all alpa's */
2527 for (j = 0; j < FC_MAXLOOP; j++) {
2528 /* If cfg_scan_down is set, start from highest
2529 * ALPA (0xef) to lowest (0x1).
2530 */
James Smart3de2a652007-08-02 11:09:59 -04002531 if (vport->cfg_scan_down)
dea31012005-04-17 16:05:31 -05002532 index = j;
2533 else
2534 index = FC_MAXLOOP - j - 1;
2535 alpa = lpfcAlpaArray[index];
James Smart2e0fef82007-06-17 19:56:36 -05002536 if ((vport->fc_myDID & 0xff) == alpa)
dea31012005-04-17 16:05:31 -05002537 continue;
James Smart2e0fef82007-06-17 19:56:36 -05002538 lpfc_setup_disc_node(vport, alpa);
dea31012005-04-17 16:05:31 -05002539 }
2540 }
2541 return;
2542}
2543
dea31012005-04-17 16:05:31 -05002544void
James Smart2e0fef82007-06-17 19:56:36 -05002545lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05002546{
dea31012005-04-17 16:05:31 -05002547 LPFC_MBOXQ_t *mbox;
James Smart2e0fef82007-06-17 19:56:36 -05002548 struct lpfc_sli *psli = &phba->sli;
2549 struct lpfc_sli_ring *extra_ring = &psli->ring[psli->extra_ring];
2550 struct lpfc_sli_ring *fcp_ring = &psli->ring[psli->fcp_ring];
2551 struct lpfc_sli_ring *next_ring = &psli->ring[psli->next_ring];
2552 int rc;
2553
James Smart92d7f7b2007-06-17 19:56:38 -05002554 /*
2555 * if it's not a physical port or if we already send
2556 * clear_la then don't send it.
2557 */
2558 if ((phba->link_state >= LPFC_CLEAR_LA) ||
2559 (vport->port_type != LPFC_PHYSICAL_PORT))
2560 return;
2561
James Smart2e0fef82007-06-17 19:56:36 -05002562 /* Link up discovery */
2563 if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) != NULL) {
2564 phba->link_state = LPFC_CLEAR_LA;
2565 lpfc_clear_la(phba, mbox);
2566 mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
2567 mbox->vport = vport;
James Smart0b727fe2007-10-27 13:37:25 -04002568 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
James Smart2e0fef82007-06-17 19:56:36 -05002569 if (rc == MBX_NOT_FINISHED) {
2570 mempool_free(mbox, phba->mbox_mem_pool);
2571 lpfc_disc_flush_list(vport);
2572 extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
2573 fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
2574 next_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
James Smart92d7f7b2007-06-17 19:56:38 -05002575 phba->link_state = LPFC_HBA_ERROR;
2576 }
2577 }
2578}
2579
2580/* Reg_vpi to tell firmware to resume normal operations */
2581void
2582lpfc_issue_reg_vpi(struct lpfc_hba *phba, struct lpfc_vport *vport)
2583{
2584 LPFC_MBOXQ_t *regvpimbox;
2585
2586 regvpimbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2587 if (regvpimbox) {
2588 lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, regvpimbox);
2589 regvpimbox->mbox_cmpl = lpfc_mbx_cmpl_reg_vpi;
2590 regvpimbox->vport = vport;
James Smart0b727fe2007-10-27 13:37:25 -04002591 if (lpfc_sli_issue_mbox(phba, regvpimbox, MBX_NOWAIT)
James Smart92d7f7b2007-06-17 19:56:38 -05002592 == MBX_NOT_FINISHED) {
2593 mempool_free(regvpimbox, phba->mbox_mem_pool);
James Smart2e0fef82007-06-17 19:56:36 -05002594 }
2595 }
2596}
2597
2598/* Start Link up / RSCN discovery on NPR nodes */
2599void
2600lpfc_disc_start(struct lpfc_vport *vport)
2601{
2602 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2603 struct lpfc_hba *phba = vport->phba;
James Smart685f0bf2007-04-25 09:53:08 -04002604 uint32_t num_sent;
dea31012005-04-17 16:05:31 -05002605 uint32_t clear_la_pending;
James Smart685f0bf2007-04-25 09:53:08 -04002606 int did_changed;
dea31012005-04-17 16:05:31 -05002607
James Smart2e0fef82007-06-17 19:56:36 -05002608 if (!lpfc_is_link_up(phba))
dea31012005-04-17 16:05:31 -05002609 return;
James Smart2e0fef82007-06-17 19:56:36 -05002610
2611 if (phba->link_state == LPFC_CLEAR_LA)
dea31012005-04-17 16:05:31 -05002612 clear_la_pending = 1;
2613 else
2614 clear_la_pending = 0;
2615
James Smart2e0fef82007-06-17 19:56:36 -05002616 if (vport->port_state < LPFC_VPORT_READY)
2617 vport->port_state = LPFC_DISC_AUTH;
dea31012005-04-17 16:05:31 -05002618
James Smart2e0fef82007-06-17 19:56:36 -05002619 lpfc_set_disctmo(vport);
2620
2621 if (vport->fc_prevDID == vport->fc_myDID)
dea31012005-04-17 16:05:31 -05002622 did_changed = 0;
James Smart2e0fef82007-06-17 19:56:36 -05002623 else
dea31012005-04-17 16:05:31 -05002624 did_changed = 1;
James Smart2e0fef82007-06-17 19:56:36 -05002625
2626 vport->fc_prevDID = vport->fc_myDID;
2627 vport->num_disc_nodes = 0;
dea31012005-04-17 16:05:31 -05002628
2629 /* Start Discovery state <hba_state> */
James Smarte8b62012007-08-02 11:10:09 -04002630 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2631 "0202 Start Discovery hba state x%x "
2632 "Data: x%x x%x x%x\n",
2633 vport->port_state, vport->fc_flag, vport->fc_plogi_cnt,
2634 vport->fc_adisc_cnt);
dea31012005-04-17 16:05:31 -05002635
2636 /* First do ADISCs - if any */
James Smart2e0fef82007-06-17 19:56:36 -05002637 num_sent = lpfc_els_disc_adisc(vport);
dea31012005-04-17 16:05:31 -05002638
2639 if (num_sent)
2640 return;
2641
James Smart92d7f7b2007-06-17 19:56:38 -05002642 /*
2643 * For SLI3, cmpl_reg_vpi will set port_state to READY, and
2644 * continue discovery.
2645 */
2646 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
James Smart1b32f6a2008-02-08 18:49:39 -05002647 !(vport->fc_flag & FC_PT2PT) &&
James Smart92d7f7b2007-06-17 19:56:38 -05002648 !(vport->fc_flag & FC_RSCN_MODE)) {
2649 lpfc_issue_reg_vpi(phba, vport);
2650 return;
2651 }
James Smart2e0fef82007-06-17 19:56:36 -05002652
James Smart92d7f7b2007-06-17 19:56:38 -05002653 /*
2654 * For SLI2, we need to set port_state to READY and continue
2655 * discovery.
2656 */
2657 if (vport->port_state < LPFC_VPORT_READY && !clear_la_pending) {
2658 /* If we get here, there is nothing to ADISC */
2659 if (vport->port_type == LPFC_PHYSICAL_PORT)
2660 lpfc_issue_clear_la(phba, vport);
2661
2662 if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
James Smart2e0fef82007-06-17 19:56:36 -05002663 vport->num_disc_nodes = 0;
2664 /* go thru NPR nodes and issue ELS PLOGIs */
2665 if (vport->fc_npr_cnt)
2666 lpfc_els_disc_plogi(vport);
2667
2668 if (!vport->num_disc_nodes) {
2669 spin_lock_irq(shost->host_lock);
2670 vport->fc_flag &= ~FC_NDISC_ACTIVE;
2671 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05002672 lpfc_can_disctmo(vport);
dea31012005-04-17 16:05:31 -05002673 }
2674 }
James Smart92d7f7b2007-06-17 19:56:38 -05002675 vport->port_state = LPFC_VPORT_READY;
dea31012005-04-17 16:05:31 -05002676 } else {
2677 /* Next do PLOGIs - if any */
James Smart2e0fef82007-06-17 19:56:36 -05002678 num_sent = lpfc_els_disc_plogi(vport);
dea31012005-04-17 16:05:31 -05002679
2680 if (num_sent)
2681 return;
2682
James Smart2e0fef82007-06-17 19:56:36 -05002683 if (vport->fc_flag & FC_RSCN_MODE) {
dea31012005-04-17 16:05:31 -05002684 /* Check to see if more RSCNs came in while we
2685 * were processing this one.
2686 */
James Smart2e0fef82007-06-17 19:56:36 -05002687 if ((vport->fc_rscn_id_cnt == 0) &&
2688 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
2689 spin_lock_irq(shost->host_lock);
2690 vport->fc_flag &= ~FC_RSCN_MODE;
2691 spin_unlock_irq(shost->host_lock);
James Smart92d7f7b2007-06-17 19:56:38 -05002692 lpfc_can_disctmo(vport);
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002693 } else
James Smart2e0fef82007-06-17 19:56:36 -05002694 lpfc_els_handle_rscn(vport);
dea31012005-04-17 16:05:31 -05002695 }
2696 }
2697 return;
2698}
2699
2700/*
2701 * Ignore completion for all IOCBs on tx and txcmpl queue for ELS
2702 * ring the match the sppecified nodelist.
2703 */
2704static void
James Smart2e0fef82007-06-17 19:56:36 -05002705lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
dea31012005-04-17 16:05:31 -05002706{
James Smart2534ba72007-04-25 09:52:20 -04002707 LIST_HEAD(completions);
dea31012005-04-17 16:05:31 -05002708 struct lpfc_sli *psli;
2709 IOCB_t *icmd;
2710 struct lpfc_iocbq *iocb, *next_iocb;
2711 struct lpfc_sli_ring *pring;
dea31012005-04-17 16:05:31 -05002712
2713 psli = &phba->sli;
2714 pring = &psli->ring[LPFC_ELS_RING];
2715
2716 /* Error matching iocb on txq or txcmplq
2717 * First check the txq.
2718 */
James Smart2e0fef82007-06-17 19:56:36 -05002719 spin_lock_irq(&phba->hbalock);
dea31012005-04-17 16:05:31 -05002720 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
2721 if (iocb->context1 != ndlp) {
2722 continue;
2723 }
2724 icmd = &iocb->iocb;
2725 if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
2726 (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {
2727
James Smart2534ba72007-04-25 09:52:20 -04002728 list_move_tail(&iocb->list, &completions);
dea31012005-04-17 16:05:31 -05002729 pring->txq_cnt--;
dea31012005-04-17 16:05:31 -05002730 }
2731 }
2732
2733 /* Next check the txcmplq */
2734 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
2735 if (iocb->context1 != ndlp) {
2736 continue;
2737 }
2738 icmd = &iocb->iocb;
James Smart2e0fef82007-06-17 19:56:36 -05002739 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR ||
2740 icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX) {
James Smart2534ba72007-04-25 09:52:20 -04002741 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
dea31012005-04-17 16:05:31 -05002742 }
2743 }
James Smart2e0fef82007-06-17 19:56:36 -05002744 spin_unlock_irq(&phba->hbalock);
James Smart2534ba72007-04-25 09:52:20 -04002745
James Smarta257bf92009-04-06 18:48:10 -04002746 /* Cancel all the IOCBs from the completions list */
2747 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
2748 IOERR_SLI_ABORTED);
dea31012005-04-17 16:05:31 -05002749}
2750
Adrian Bunka6ababd2007-11-05 18:07:33 +01002751static void
James Smart2e0fef82007-06-17 19:56:36 -05002752lpfc_disc_flush_list(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05002753{
2754 struct lpfc_nodelist *ndlp, *next_ndlp;
James Smart2e0fef82007-06-17 19:56:36 -05002755 struct lpfc_hba *phba = vport->phba;
dea31012005-04-17 16:05:31 -05002756
James Smart2e0fef82007-06-17 19:56:36 -05002757 if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) {
2758 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
James Smart685f0bf2007-04-25 09:53:08 -04002759 nlp_listp) {
James Smarte47c9092008-02-08 18:49:26 -05002760 if (!NLP_CHK_NODE_ACT(ndlp))
2761 continue;
James Smart685f0bf2007-04-25 09:53:08 -04002762 if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
2763 ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
2764 lpfc_free_tx(phba, ndlp);
James Smart685f0bf2007-04-25 09:53:08 -04002765 }
dea31012005-04-17 16:05:31 -05002766 }
2767 }
dea31012005-04-17 16:05:31 -05002768}
2769
James Smart92d7f7b2007-06-17 19:56:38 -05002770void
2771lpfc_cleanup_discovery_resources(struct lpfc_vport *vport)
2772{
2773 lpfc_els_flush_rscn(vport);
2774 lpfc_els_flush_cmd(vport);
2775 lpfc_disc_flush_list(vport);
2776}
2777
dea31012005-04-17 16:05:31 -05002778/*****************************************************************************/
2779/*
2780 * NAME: lpfc_disc_timeout
2781 *
2782 * FUNCTION: Fibre Channel driver discovery timeout routine.
2783 *
2784 * EXECUTION ENVIRONMENT: interrupt only
2785 *
2786 * CALLED FROM:
2787 * Timer function
2788 *
2789 * RETURNS:
2790 * none
2791 */
2792/*****************************************************************************/
2793void
2794lpfc_disc_timeout(unsigned long ptr)
2795{
James Smart2e0fef82007-06-17 19:56:36 -05002796 struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
2797 struct lpfc_hba *phba = vport->phba;
James Smart5e9d9b82008-06-14 22:52:53 -04002798 uint32_t tmo_posted;
dea31012005-04-17 16:05:31 -05002799 unsigned long flags = 0;
2800
2801 if (unlikely(!phba))
2802 return;
2803
James Smart5e9d9b82008-06-14 22:52:53 -04002804 spin_lock_irqsave(&vport->work_port_lock, flags);
2805 tmo_posted = vport->work_port_events & WORKER_DISC_TMO;
2806 if (!tmo_posted)
James Smart2e0fef82007-06-17 19:56:36 -05002807 vport->work_port_events |= WORKER_DISC_TMO;
James Smart5e9d9b82008-06-14 22:52:53 -04002808 spin_unlock_irqrestore(&vport->work_port_lock, flags);
James Smart2e0fef82007-06-17 19:56:36 -05002809
James Smart5e9d9b82008-06-14 22:52:53 -04002810 if (!tmo_posted)
2811 lpfc_worker_wake_up(phba);
dea31012005-04-17 16:05:31 -05002812 return;
2813}
2814
2815static void
James Smart2e0fef82007-06-17 19:56:36 -05002816lpfc_disc_timeout_handler(struct lpfc_vport *vport)
dea31012005-04-17 16:05:31 -05002817{
James Smart2e0fef82007-06-17 19:56:36 -05002818 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2819 struct lpfc_hba *phba = vport->phba;
2820 struct lpfc_sli *psli = &phba->sli;
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002821 struct lpfc_nodelist *ndlp, *next_ndlp;
James Smart92d7f7b2007-06-17 19:56:38 -05002822 LPFC_MBOXQ_t *initlinkmbox;
dea31012005-04-17 16:05:31 -05002823 int rc, clrlaerr = 0;
2824
James Smart2e0fef82007-06-17 19:56:36 -05002825 if (!(vport->fc_flag & FC_DISC_TMO))
dea31012005-04-17 16:05:31 -05002826 return;
2827
James Smart2e0fef82007-06-17 19:56:36 -05002828 spin_lock_irq(shost->host_lock);
2829 vport->fc_flag &= ~FC_DISC_TMO;
2830 spin_unlock_irq(shost->host_lock);
dea31012005-04-17 16:05:31 -05002831
James Smart858c9f62007-06-17 19:56:39 -05002832 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2833 "disc timeout: state:x%x rtry:x%x flg:x%x",
2834 vport->port_state, vport->fc_ns_retry, vport->fc_flag);
2835
James Smart2e0fef82007-06-17 19:56:36 -05002836 switch (vport->port_state) {
dea31012005-04-17 16:05:31 -05002837
2838 case LPFC_LOCAL_CFG_LINK:
James Smart2e0fef82007-06-17 19:56:36 -05002839 /* port_state is identically LPFC_LOCAL_CFG_LINK while waiting for
2840 * FAN
2841 */
2842 /* FAN timeout */
James Smarte8b62012007-08-02 11:10:09 -04002843 lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
2844 "0221 FAN timeout\n");
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002845 /* Start discovery by sending FLOGI, clean up old rpis */
James Smart2e0fef82007-06-17 19:56:36 -05002846 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
James Smart685f0bf2007-04-25 09:53:08 -04002847 nlp_listp) {
James Smarte47c9092008-02-08 18:49:26 -05002848 if (!NLP_CHK_NODE_ACT(ndlp))
2849 continue;
James Smart685f0bf2007-04-25 09:53:08 -04002850 if (ndlp->nlp_state != NLP_STE_NPR_NODE)
2851 continue;
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002852 if (ndlp->nlp_type & NLP_FABRIC) {
2853 /* Clean up the ndlp on Fabric connections */
James Smart2e0fef82007-06-17 19:56:36 -05002854 lpfc_drop_node(vport, ndlp);
James Smart87af33f2007-10-27 13:37:43 -04002855
Jamie Wellnitz2fe165b2006-02-28 19:25:31 -05002856 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002857 /* Fail outstanding IO now since device
2858 * is marked for PLOGI.
2859 */
James Smart2e0fef82007-06-17 19:56:36 -05002860 lpfc_unreg_rpi(vport, ndlp);
Jamie Wellnitzc9f87352006-02-28 19:25:23 -05002861 }
2862 }
James Smart92d7f7b2007-06-17 19:56:38 -05002863 if (vport->port_state != LPFC_FLOGI) {
James Smart92d7f7b2007-06-17 19:56:38 -05002864 lpfc_initial_flogi(vport);
James Smart0ff10d42008-01-11 01:52:36 -05002865 return;
James Smart92d7f7b2007-06-17 19:56:38 -05002866 }
dea31012005-04-17 16:05:31 -05002867 break;
2868
James Smart92d7f7b2007-06-17 19:56:38 -05002869 case LPFC_FDISC:
dea31012005-04-17 16:05:31 -05002870 case LPFC_FLOGI:
James Smart2e0fef82007-06-17 19:56:36 -05002871 /* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */
dea31012005-04-17 16:05:31 -05002872 /* Initial FLOGI timeout */
James Smarte8b62012007-08-02 11:10:09 -04002873 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2874 "0222 Initial %s timeout\n",
James Smart87af33f2007-10-27 13:37:43 -04002875 vport->vpi ? "FDISC" : "FLOGI");
dea31012005-04-17 16:05:31 -05002876
2877 /* Assume no Fabric and go on with discovery.
2878 * Check for outstanding ELS FLOGI to abort.
2879 */
2880
2881 /* FLOGI failed, so just use loop map to make discovery list */
James Smart2e0fef82007-06-17 19:56:36 -05002882 lpfc_disc_list_loopmap(vport);
dea31012005-04-17 16:05:31 -05002883
2884 /* Start discovery */
James Smart2e0fef82007-06-17 19:56:36 -05002885 lpfc_disc_start(vport);
dea31012005-04-17 16:05:31 -05002886 break;
2887
2888 case LPFC_FABRIC_CFG_LINK:
2889 /* hba_state is identically LPFC_FABRIC_CFG_LINK while waiting for
2890 NameServer login */
James Smarte8b62012007-08-02 11:10:09 -04002891 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2892 "0223 Timeout while waiting for "
2893 "NameServer login\n");
dea31012005-04-17 16:05:31 -05002894 /* Next look for NameServer ndlp */
James Smart2e0fef82007-06-17 19:56:36 -05002895 ndlp = lpfc_findnode_did(vport, NameServer_DID);
James Smarte47c9092008-02-08 18:49:26 -05002896 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
James Smart87af33f2007-10-27 13:37:43 -04002897 lpfc_els_abort(phba, ndlp);
2898
2899 /* ReStart discovery */
2900 goto restart_disc;
dea31012005-04-17 16:05:31 -05002901
2902 case LPFC_NS_QRY:
2903 /* Check for wait for NameServer Rsp timeout */
James Smarte8b62012007-08-02 11:10:09 -04002904 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2905 "0224 NameServer Query timeout "
2906 "Data: x%x x%x\n",
2907 vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
dea31012005-04-17 16:05:31 -05002908
James Smart92d7f7b2007-06-17 19:56:38 -05002909 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
2910 /* Try it one more time */
2911 vport->fc_ns_retry++;
2912 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
2913 vport->fc_ns_retry, 0);
2914 if (rc == 0)
2915 break;
dea31012005-04-17 16:05:31 -05002916 }
James Smart92d7f7b2007-06-17 19:56:38 -05002917 vport->fc_ns_retry = 0;
dea31012005-04-17 16:05:31 -05002918
James Smart87af33f2007-10-27 13:37:43 -04002919restart_disc:
James Smart92d7f7b2007-06-17 19:56:38 -05002920 /*
2921 * Discovery is over.
2922 * set port_state to PORT_READY if SLI2.
2923 * cmpl_reg_vpi will set port_state to READY for SLI3.
2924 */
James Smart3772a992009-05-22 14:50:54 -04002925 if (phba->sli_rev < LPFC_SLI_REV4) {
2926 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
2927 lpfc_issue_reg_vpi(phba, vport);
2928 else { /* NPIV Not enabled */
2929 lpfc_issue_clear_la(phba, vport);
2930 vport->port_state = LPFC_VPORT_READY;
2931 }
dea31012005-04-17 16:05:31 -05002932 }
2933
2934 /* Setup and issue mailbox INITIALIZE LINK command */
2935 initlinkmbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2936 if (!initlinkmbox) {
James Smarte8b62012007-08-02 11:10:09 -04002937 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2938 "0206 Device Discovery "
2939 "completion error\n");
James Smart2e0fef82007-06-17 19:56:36 -05002940 phba->link_state = LPFC_HBA_ERROR;
dea31012005-04-17 16:05:31 -05002941 break;
2942 }
2943
2944 lpfc_linkdown(phba);
2945 lpfc_init_link(phba, initlinkmbox, phba->cfg_topology,
2946 phba->cfg_link_speed);
2947 initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
James Smarted957682007-06-17 19:56:37 -05002948 initlinkmbox->vport = vport;
James Smart92d7f7b2007-06-17 19:56:38 -05002949 initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
James Smart0b727fe2007-10-27 13:37:25 -04002950 rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT);
James Smart5b8bd0c2007-04-25 09:52:49 -04002951 lpfc_set_loopback_flag(phba);
dea31012005-04-17 16:05:31 -05002952 if (rc == MBX_NOT_FINISHED)
2953 mempool_free(initlinkmbox, phba->mbox_mem_pool);
2954
2955 break;
2956
2957 case LPFC_DISC_AUTH:
2958 /* Node Authentication timeout */
James Smarte8b62012007-08-02 11:10:09 -04002959 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2960 "0227 Node Authentication timeout\n");
James Smart2e0fef82007-06-17 19:56:36 -05002961 lpfc_disc_flush_list(vport);
2962
James Smart92d7f7b2007-06-17 19:56:38 -05002963 /*
2964 * set port_state to PORT_READY if SLI2.
2965 * cmpl_reg_vpi will set port_state to READY for SLI3.
2966 */
James Smart3772a992009-05-22 14:50:54 -04002967 if (phba->sli_rev < LPFC_SLI_REV4) {
2968 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
2969 lpfc_issue_reg_vpi(phba, vport);
2970 else { /* NPIV Not enabled */
2971 lpfc_issue_clear_la(phba, vport);
2972 vport->port_state = LPFC_VPORT_READY;
2973 }
dea31012005-04-17 16:05:31 -05002974 }
2975 break;
2976
James Smart2e0fef82007-06-17 19:56:36 -05002977 case LPFC_VPORT_READY:
2978 if (vport->fc_flag & FC_RSCN_MODE) {
James Smarte8b62012007-08-02 11:10:09 -04002979 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2980 "0231 RSCN timeout Data: x%x "
2981 "x%x\n",
2982 vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
dea31012005-04-17 16:05:31 -05002983
2984 /* Cleanup any outstanding ELS commands */
James Smart2e0fef82007-06-17 19:56:36 -05002985 lpfc_els_flush_cmd(vport);
dea31012005-04-17 16:05:31 -05002986
James Smart2e0fef82007-06-17 19:56:36 -05002987 lpfc_els_flush_rscn(vport);
2988 lpfc_disc_flush_list(vport);
dea31012005-04-17 16:05:31 -05002989 }
2990 break;
James Smart2e0fef82007-06-17 19:56:36 -05002991
James Smart92d7f7b2007-06-17 19:56:38 -05002992 default:
James Smarte8b62012007-08-02 11:10:09 -04002993 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
James Smartd7c255b2008-08-24 21:50:00 -04002994 "0273 Unexpected discovery timeout, "
James Smarte8b62012007-08-02 11:10:09 -04002995 "vport State x%x\n", vport->port_state);
James Smart2e0fef82007-06-17 19:56:36 -05002996 break;
2997 }
2998
2999 switch (phba->link_state) {
3000 case LPFC_CLEAR_LA:
James Smart92d7f7b2007-06-17 19:56:38 -05003001 /* CLEAR LA timeout */
James Smarte8b62012007-08-02 11:10:09 -04003002 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
3003 "0228 CLEAR LA timeout\n");
James Smart2e0fef82007-06-17 19:56:36 -05003004 clrlaerr = 1;
3005 break;
3006
James Smart09372822008-01-11 01:52:54 -05003007 case LPFC_LINK_UP:
3008 lpfc_issue_clear_la(phba, vport);
3009 /* Drop thru */
James Smart2e0fef82007-06-17 19:56:36 -05003010 case LPFC_LINK_UNKNOWN:
3011 case LPFC_WARM_START:
3012 case LPFC_INIT_START:
3013 case LPFC_INIT_MBX_CMDS:
3014 case LPFC_LINK_DOWN:
James Smart2e0fef82007-06-17 19:56:36 -05003015 case LPFC_HBA_ERROR:
James Smarte8b62012007-08-02 11:10:09 -04003016 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
3017 "0230 Unexpected timeout, hba link "
3018 "state x%x\n", phba->link_state);
James Smart2e0fef82007-06-17 19:56:36 -05003019 clrlaerr = 1;
3020 break;
James Smart92d7f7b2007-06-17 19:56:38 -05003021
3022 case LPFC_HBA_READY:
3023 break;
dea31012005-04-17 16:05:31 -05003024 }
3025
3026 if (clrlaerr) {
James Smart2e0fef82007-06-17 19:56:36 -05003027 lpfc_disc_flush_list(vport);
James Smarta4bc3372006-12-02 13:34:16 -05003028 psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
dea31012005-04-17 16:05:31 -05003029 psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
3030 psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
James Smart2e0fef82007-06-17 19:56:36 -05003031 vport->port_state = LPFC_VPORT_READY;
dea31012005-04-17 16:05:31 -05003032 }
3033
3034 return;
3035}
3036
dea31012005-04-17 16:05:31 -05003037/*
3038 * This routine handles processing a NameServer REG_LOGIN mailbox
3039 * command upon completion. It is setup in the LPFC_MBOXQ
3040 * as the completion routine when the command is
3041 * handed off to the SLI layer.
3042 */
3043void
James Smart2e0fef82007-06-17 19:56:36 -05003044lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
dea31012005-04-17 16:05:31 -05003045{
James Smart2e0fef82007-06-17 19:56:36 -05003046 MAILBOX_t *mb = &pmb->mb;
3047 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
3048 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
3049 struct lpfc_vport *vport = pmb->vport;
dea31012005-04-17 16:05:31 -05003050
3051 pmb->context1 = NULL;
3052
dea31012005-04-17 16:05:31 -05003053 ndlp->nlp_rpi = mb->un.varWords[0];
dea31012005-04-17 16:05:31 -05003054 ndlp->nlp_type |= NLP_FABRIC;
James Smart2e0fef82007-06-17 19:56:36 -05003055 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
dea31012005-04-17 16:05:31 -05003056
James Smart2e0fef82007-06-17 19:56:36 -05003057 /*
3058 * Start issuing Fabric-Device Management Interface (FDMI) command to
3059 * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if
3060 * fdmi-on=2 (supporting RPA/hostnmae)
dea31012005-04-17 16:05:31 -05003061 */
James Smart2e0fef82007-06-17 19:56:36 -05003062
James Smart3de2a652007-08-02 11:09:59 -04003063 if (vport->cfg_fdmi_on == 1)
James Smart2e0fef82007-06-17 19:56:36 -05003064 lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
3065 else
3066 mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
dea31012005-04-17 16:05:31 -05003067
James Smartfa4066b2008-01-11 01:53:27 -05003068 /* decrement the node reference count held for this callback
3069 * function.
3070 */
James Smart329f9bc2007-04-25 09:53:01 -04003071 lpfc_nlp_put(ndlp);
dea31012005-04-17 16:05:31 -05003072 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3073 kfree(mp);
James Smart329f9bc2007-04-25 09:53:01 -04003074 mempool_free(pmb, phba->mbox_mem_pool);
dea31012005-04-17 16:05:31 -05003075
3076 return;
3077}
3078
James Smart685f0bf2007-04-25 09:53:08 -04003079static int
3080lpfc_filter_by_rpi(struct lpfc_nodelist *ndlp, void *param)
3081{
3082 uint16_t *rpi = param;
3083
3084 return ndlp->nlp_rpi == *rpi;
3085}
3086
3087static int
3088lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param)
3089{
3090 return memcmp(&ndlp->nlp_portname, param,
3091 sizeof(ndlp->nlp_portname)) == 0;
3092}
3093
Adrian Bunka6ababd2007-11-05 18:07:33 +01003094static struct lpfc_nodelist *
James Smart2e0fef82007-06-17 19:56:36 -05003095__lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
dea31012005-04-17 16:05:31 -05003096{
James.Smart@Emulex.Com21568f52005-10-28 20:29:36 -04003097 struct lpfc_nodelist *ndlp;
dea31012005-04-17 16:05:31 -05003098
James Smart2e0fef82007-06-17 19:56:36 -05003099 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
James Smart87af33f2007-10-27 13:37:43 -04003100 if (filter(ndlp, param))
James Smart685f0bf2007-04-25 09:53:08 -04003101 return ndlp;
3102 }
James.Smart@Emulex.Com21568f52005-10-28 20:29:36 -04003103 return NULL;
dea31012005-04-17 16:05:31 -05003104}
3105
James Smart685f0bf2007-04-25 09:53:08 -04003106/*
3107 * This routine looks up the ndlp lists for the given RPI. If rpi found it
James Smart2e0fef82007-06-17 19:56:36 -05003108 * returns the node list element pointer else return NULL.
James Smart685f0bf2007-04-25 09:53:08 -04003109 */
3110struct lpfc_nodelist *
James Smart2e0fef82007-06-17 19:56:36 -05003111__lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
James Smart685f0bf2007-04-25 09:53:08 -04003112{
James Smart2e0fef82007-06-17 19:56:36 -05003113 return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
James Smart685f0bf2007-04-25 09:53:08 -04003114}
3115
James Smart488d1462006-03-07 15:02:37 -05003116/*
James Smart685f0bf2007-04-25 09:53:08 -04003117 * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
James Smart2e0fef82007-06-17 19:56:36 -05003118 * returns the node element list pointer else return NULL.
James Smart488d1462006-03-07 15:02:37 -05003119 */
3120struct lpfc_nodelist *
James Smart2e0fef82007-06-17 19:56:36 -05003121lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn)
James Smart488d1462006-03-07 15:02:37 -05003122{
James Smart2e0fef82007-06-17 19:56:36 -05003123 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
James Smart488d1462006-03-07 15:02:37 -05003124 struct lpfc_nodelist *ndlp;
James Smart488d1462006-03-07 15:02:37 -05003125
James Smart2e0fef82007-06-17 19:56:36 -05003126 spin_lock_irq(shost->host_lock);
3127 ndlp = __lpfc_find_node(vport, lpfc_filter_by_wwpn, wwpn);
3128 spin_unlock_irq(shost->host_lock);
James Smart858c9f62007-06-17 19:56:39 -05003129 return ndlp;
James Smart488d1462006-03-07 15:02:37 -05003130}
3131
dea31012005-04-17 16:05:31 -05003132void
James Smart2e0fef82007-06-17 19:56:36 -05003133lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
3134 uint32_t did)
dea31012005-04-17 16:05:31 -05003135{
3136 memset(ndlp, 0, sizeof (struct lpfc_nodelist));
James Smart109f6ed2008-12-04 22:39:08 -05003137
3138 lpfc_initialize_node(vport, ndlp, did);
James Smart685f0bf2007-04-25 09:53:08 -04003139 INIT_LIST_HEAD(&ndlp->nlp_listp);
James Smart858c9f62007-06-17 19:56:39 -05003140
3141 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
3142 "node init: did:x%x",
3143 ndlp->nlp_DID, 0, 0);
3144
dea31012005-04-17 16:05:31 -05003145 return;
3146}
James Smart329f9bc2007-04-25 09:53:01 -04003147
James Smart98c9ea52007-10-27 13:37:33 -04003148/* This routine releases all resources associated with a specifc NPort's ndlp
3149 * and mempool_free's the nodelist.
3150 */
James Smart311464e2007-08-02 11:10:37 -04003151static void
James Smart329f9bc2007-04-25 09:53:01 -04003152lpfc_nlp_release(struct kref *kref)
3153{
James Smarte47c9092008-02-08 18:49:26 -05003154 struct lpfc_hba *phba;
3155 unsigned long flags;
James Smart329f9bc2007-04-25 09:53:01 -04003156 struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
3157 kref);
James Smart858c9f62007-06-17 19:56:39 -05003158
3159 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
3160 "node release: did:x%x flg:x%x type:x%x",
3161 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
3162
James Smarte47c9092008-02-08 18:49:26 -05003163 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
3164 "0279 lpfc_nlp_release: ndlp:x%p "
3165 "usgmap:x%x refcnt:%d\n",
3166 (void *)ndlp, ndlp->nlp_usg_map,
3167 atomic_read(&ndlp->kref.refcount));
3168
3169 /* remove ndlp from action. */
James Smart2e0fef82007-06-17 19:56:36 -05003170 lpfc_nlp_remove(ndlp->vport, ndlp);
James Smarte47c9092008-02-08 18:49:26 -05003171
3172 /* clear the ndlp active flag for all release cases */
James Smarta257bf92009-04-06 18:48:10 -04003173 phba = ndlp->phba;
James Smarte47c9092008-02-08 18:49:26 -05003174 spin_lock_irqsave(&phba->ndlp_lock, flags);
3175 NLP_CLR_NODE_ACT(ndlp);
3176 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3177
3178 /* free ndlp memory for final ndlp release */
James Smartea2151b2008-09-07 11:52:10 -04003179 if (NLP_CHK_FREE_REQ(ndlp)) {
3180 kfree(ndlp->lat_data);
James Smarta257bf92009-04-06 18:48:10 -04003181 mempool_free(ndlp, ndlp->phba->nlp_mem_pool);
James Smartea2151b2008-09-07 11:52:10 -04003182 }
James Smart329f9bc2007-04-25 09:53:01 -04003183}
3184
James Smart98c9ea52007-10-27 13:37:33 -04003185/* This routine bumps the reference count for a ndlp structure to ensure
3186 * that one discovery thread won't free a ndlp while another discovery thread
3187 * is using it.
3188 */
James Smart329f9bc2007-04-25 09:53:01 -04003189struct lpfc_nodelist *
3190lpfc_nlp_get(struct lpfc_nodelist *ndlp)
3191{
James Smarte47c9092008-02-08 18:49:26 -05003192 struct lpfc_hba *phba;
3193 unsigned long flags;
3194
James Smart98c9ea52007-10-27 13:37:33 -04003195 if (ndlp) {
3196 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
3197 "node get: did:x%x flg:x%x refcnt:x%x",
3198 ndlp->nlp_DID, ndlp->nlp_flag,
3199 atomic_read(&ndlp->kref.refcount));
James Smarte47c9092008-02-08 18:49:26 -05003200 /* The check of ndlp usage to prevent incrementing the
3201 * ndlp reference count that is in the process of being
3202 * released.
3203 */
James Smarta257bf92009-04-06 18:48:10 -04003204 phba = ndlp->phba;
James Smarte47c9092008-02-08 18:49:26 -05003205 spin_lock_irqsave(&phba->ndlp_lock, flags);
3206 if (!NLP_CHK_NODE_ACT(ndlp) || NLP_CHK_FREE_ACK(ndlp)) {
3207 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3208 lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
3209 "0276 lpfc_nlp_get: ndlp:x%p "
3210 "usgmap:x%x refcnt:%d\n",
3211 (void *)ndlp, ndlp->nlp_usg_map,
3212 atomic_read(&ndlp->kref.refcount));
3213 return NULL;
3214 } else
3215 kref_get(&ndlp->kref);
3216 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
James Smart98c9ea52007-10-27 13:37:33 -04003217 }
James Smart329f9bc2007-04-25 09:53:01 -04003218 return ndlp;
3219}
3220
James Smart98c9ea52007-10-27 13:37:33 -04003221/* This routine decrements the reference count for a ndlp structure. If the
James Smarte47c9092008-02-08 18:49:26 -05003222 * count goes to 0, this indicates the the associated nodelist should be
3223 * freed. Returning 1 indicates the ndlp resource has been released; on the
3224 * other hand, returning 0 indicates the ndlp resource has not been released
3225 * yet.
James Smart98c9ea52007-10-27 13:37:33 -04003226 */
James Smart329f9bc2007-04-25 09:53:01 -04003227int
3228lpfc_nlp_put(struct lpfc_nodelist *ndlp)
3229{
James Smarte47c9092008-02-08 18:49:26 -05003230 struct lpfc_hba *phba;
3231 unsigned long flags;
3232
3233 if (!ndlp)
3234 return 1;
3235
3236 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
3237 "node put: did:x%x flg:x%x refcnt:x%x",
3238 ndlp->nlp_DID, ndlp->nlp_flag,
3239 atomic_read(&ndlp->kref.refcount));
James Smarta257bf92009-04-06 18:48:10 -04003240 phba = ndlp->phba;
James Smarte47c9092008-02-08 18:49:26 -05003241 spin_lock_irqsave(&phba->ndlp_lock, flags);
3242 /* Check the ndlp memory free acknowledge flag to avoid the
3243 * possible race condition that kref_put got invoked again
3244 * after previous one has done ndlp memory free.
3245 */
3246 if (NLP_CHK_FREE_ACK(ndlp)) {
3247 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3248 lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
3249 "0274 lpfc_nlp_put: ndlp:x%p "
3250 "usgmap:x%x refcnt:%d\n",
3251 (void *)ndlp, ndlp->nlp_usg_map,
3252 atomic_read(&ndlp->kref.refcount));
3253 return 1;
James Smart98c9ea52007-10-27 13:37:33 -04003254 }
James Smarte47c9092008-02-08 18:49:26 -05003255 /* Check the ndlp inactivate log flag to avoid the possible
3256 * race condition that kref_put got invoked again after ndlp
3257 * is already in inactivating state.
3258 */
3259 if (NLP_CHK_IACT_REQ(ndlp)) {
3260 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3261 lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE,
3262 "0275 lpfc_nlp_put: ndlp:x%p "
3263 "usgmap:x%x refcnt:%d\n",
3264 (void *)ndlp, ndlp->nlp_usg_map,
3265 atomic_read(&ndlp->kref.refcount));
3266 return 1;
3267 }
3268 /* For last put, mark the ndlp usage flags to make sure no
3269 * other kref_get and kref_put on the same ndlp shall get
3270 * in between the process when the final kref_put has been
3271 * invoked on this ndlp.
3272 */
3273 if (atomic_read(&ndlp->kref.refcount) == 1) {
3274 /* Indicate ndlp is put to inactive state. */
3275 NLP_SET_IACT_REQ(ndlp);
3276 /* Acknowledge ndlp memory free has been seen. */
3277 if (NLP_CHK_FREE_REQ(ndlp))
3278 NLP_SET_FREE_ACK(ndlp);
3279 }
3280 spin_unlock_irqrestore(&phba->ndlp_lock, flags);
3281 /* Note, the kref_put returns 1 when decrementing a reference
3282 * count that was 1, it invokes the release callback function,
3283 * but it still left the reference count as 1 (not actually
3284 * performs the last decrementation). Otherwise, it actually
3285 * decrements the reference count and returns 0.
3286 */
3287 return kref_put(&ndlp->kref, lpfc_nlp_release);
James Smart329f9bc2007-04-25 09:53:01 -04003288}
James Smart98c9ea52007-10-27 13:37:33 -04003289
3290/* This routine free's the specified nodelist if it is not in use
James Smarte47c9092008-02-08 18:49:26 -05003291 * by any other discovery thread. This routine returns 1 if the
3292 * ndlp has been freed. A return value of 0 indicates the ndlp is
3293 * not yet been released.
James Smart98c9ea52007-10-27 13:37:33 -04003294 */
3295int
3296lpfc_nlp_not_used(struct lpfc_nodelist *ndlp)
3297{
3298 lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
3299 "node not used: did:x%x flg:x%x refcnt:x%x",
3300 ndlp->nlp_DID, ndlp->nlp_flag,
3301 atomic_read(&ndlp->kref.refcount));
James Smarte47c9092008-02-08 18:49:26 -05003302 if (atomic_read(&ndlp->kref.refcount) == 1)
3303 if (lpfc_nlp_put(ndlp))
3304 return 1;
James Smart98c9ea52007-10-27 13:37:33 -04003305 return 0;
3306}