diff options
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 4 | ||||
-rw-r--r-- | drivers/scsi/fcoe/libfcoe.c | 300 |
2 files changed, 244 insertions, 60 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index d23a538a9dfc..9f9600b67001 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -854,7 +854,6 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
854 | 854 | ||
855 | /* Cleanup the fc_lport */ | 855 | /* Cleanup the fc_lport */ |
856 | fc_lport_destroy(lport); | 856 | fc_lport_destroy(lport); |
857 | fc_fcp_destroy(lport); | ||
858 | 857 | ||
859 | /* Stop the transmit retry timer */ | 858 | /* Stop the transmit retry timer */ |
860 | del_timer_sync(&port->timer); | 859 | del_timer_sync(&port->timer); |
@@ -876,6 +875,9 @@ static void fcoe_if_destroy(struct fc_lport *lport) | |||
876 | fc_remove_host(lport->host); | 875 | fc_remove_host(lport->host); |
877 | scsi_remove_host(lport->host); | 876 | scsi_remove_host(lport->host); |
878 | 877 | ||
878 | /* Destroy lport scsi_priv */ | ||
879 | fc_fcp_destroy(lport); | ||
880 | |||
879 | /* There are no more rports or I/O, free the EM */ | 881 | /* There are no more rports or I/O, free the EM */ |
880 | fc_exch_mgr_free(lport); | 882 | fc_exch_mgr_free(lport); |
881 | 883 | ||
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index bc17c7123202..625c6be25396 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -54,6 +54,7 @@ MODULE_LICENSE("GPL v2"); | |||
54 | static void fcoe_ctlr_timeout(unsigned long); | 54 | static void fcoe_ctlr_timeout(unsigned long); |
55 | static void fcoe_ctlr_timer_work(struct work_struct *); | 55 | static void fcoe_ctlr_timer_work(struct work_struct *); |
56 | static void fcoe_ctlr_recv_work(struct work_struct *); | 56 | static void fcoe_ctlr_recv_work(struct work_struct *); |
57 | static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *); | ||
57 | 58 | ||
58 | static void fcoe_ctlr_vn_start(struct fcoe_ctlr *); | 59 | static void fcoe_ctlr_vn_start(struct fcoe_ctlr *); |
59 | static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *); | 60 | static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *); |
@@ -176,6 +177,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode) | |||
176 | fip->mode = mode; | 177 | fip->mode = mode; |
177 | INIT_LIST_HEAD(&fip->fcfs); | 178 | INIT_LIST_HEAD(&fip->fcfs); |
178 | mutex_init(&fip->ctlr_mutex); | 179 | mutex_init(&fip->ctlr_mutex); |
180 | spin_lock_init(&fip->ctlr_lock); | ||
179 | fip->flogi_oxid = FC_XID_UNKNOWN; | 181 | fip->flogi_oxid = FC_XID_UNKNOWN; |
180 | setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); | 182 | setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); |
181 | INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work); | 183 | INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work); |
@@ -231,6 +233,49 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) | |||
231 | EXPORT_SYMBOL(fcoe_ctlr_destroy); | 233 | EXPORT_SYMBOL(fcoe_ctlr_destroy); |
232 | 234 | ||
233 | /** | 235 | /** |
236 | * fcoe_ctlr_announce() - announce new FCF selection | ||
237 | * @fip: The FCoE controller | ||
238 | * | ||
239 | * Also sets the destination MAC for FCoE and control packets | ||
240 | * | ||
241 | * Called with neither ctlr_mutex nor ctlr_lock held. | ||
242 | */ | ||
243 | static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) | ||
244 | { | ||
245 | struct fcoe_fcf *sel; | ||
246 | struct fcoe_fcf *fcf; | ||
247 | |||
248 | mutex_lock(&fip->ctlr_mutex); | ||
249 | spin_lock_bh(&fip->ctlr_lock); | ||
250 | |||
251 | kfree_skb(fip->flogi_req); | ||
252 | fip->flogi_req = NULL; | ||
253 | list_for_each_entry(fcf, &fip->fcfs, list) | ||
254 | fcf->flogi_sent = 0; | ||
255 | |||
256 | spin_unlock_bh(&fip->ctlr_lock); | ||
257 | sel = fip->sel_fcf; | ||
258 | |||
259 | if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr)) | ||
260 | goto unlock; | ||
261 | if (!is_zero_ether_addr(fip->dest_addr)) { | ||
262 | printk(KERN_NOTICE "libfcoe: host%d: " | ||
263 | "FIP Fibre-Channel Forwarder MAC %pM deselected\n", | ||
264 | fip->lp->host->host_no, fip->dest_addr); | ||
265 | memset(fip->dest_addr, 0, ETH_ALEN); | ||
266 | } | ||
267 | if (sel) { | ||
268 | printk(KERN_INFO "libfcoe: host%d: FIP selected " | ||
269 | "Fibre-Channel Forwarder MAC %pM\n", | ||
270 | fip->lp->host->host_no, sel->fcf_mac); | ||
271 | memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); | ||
272 | fip->map_dest = 0; | ||
273 | } | ||
274 | unlock: | ||
275 | mutex_unlock(&fip->ctlr_mutex); | ||
276 | } | ||
277 | |||
278 | /** | ||
234 | * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port | 279 | * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port |
235 | * @fip: The FCoE controller to get the maximum FCoE size from | 280 | * @fip: The FCoE controller to get the maximum FCoE size from |
236 | * | 281 | * |
@@ -564,6 +609,9 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport, | |||
564 | * The caller must check that the length is a multiple of 4. | 609 | * The caller must check that the length is a multiple of 4. |
565 | * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). | 610 | * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). |
566 | * The the skb must also be an fc_frame. | 611 | * The the skb must also be an fc_frame. |
612 | * | ||
613 | * This is called from the lower-level driver with spinlocks held, | ||
614 | * so we must not take a mutex here. | ||
567 | */ | 615 | */ |
568 | int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, | 616 | int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, |
569 | struct sk_buff *skb) | 617 | struct sk_buff *skb) |
@@ -601,7 +649,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, | |||
601 | switch (op) { | 649 | switch (op) { |
602 | case ELS_FLOGI: | 650 | case ELS_FLOGI: |
603 | op = FIP_DT_FLOGI; | 651 | op = FIP_DT_FLOGI; |
604 | break; | 652 | if (fip->mode == FIP_MODE_VN2VN) |
653 | break; | ||
654 | spin_lock_bh(&fip->ctlr_lock); | ||
655 | kfree_skb(fip->flogi_req); | ||
656 | fip->flogi_req = skb; | ||
657 | fip->flogi_req_send = 1; | ||
658 | spin_unlock_bh(&fip->ctlr_lock); | ||
659 | schedule_work(&fip->timer_work); | ||
660 | return -EINPROGRESS; | ||
605 | case ELS_FDISC: | 661 | case ELS_FDISC: |
606 | if (ntoh24(fh->fh_s_id)) | 662 | if (ntoh24(fh->fh_s_id)) |
607 | return 0; | 663 | return 0; |
@@ -922,11 +978,9 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
922 | } | 978 | } |
923 | mtu_valid = fcoe_ctlr_mtu_valid(fcf); | 979 | mtu_valid = fcoe_ctlr_mtu_valid(fcf); |
924 | fcf->time = jiffies; | 980 | fcf->time = jiffies; |
925 | if (!found) { | 981 | if (!found) |
926 | LIBFCOE_FIP_DBG(fip, "New FCF for fab %16.16llx " | 982 | LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n", |
927 | "map %x val %d\n", | 983 | fcf->fabric_name, fcf->fcf_mac); |
928 | fcf->fabric_name, fcf->fc_map, mtu_valid); | ||
929 | } | ||
930 | 984 | ||
931 | /* | 985 | /* |
932 | * If this advertisement is not solicited and our max receive size | 986 | * If this advertisement is not solicited and our max receive size |
@@ -945,6 +999,17 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
945 | fcoe_ctlr_solicit(fip, NULL); | 999 | fcoe_ctlr_solicit(fip, NULL); |
946 | 1000 | ||
947 | /* | 1001 | /* |
1002 | * Put this FCF at the head of the list for priority among equals. | ||
1003 | * This helps in the case of an NPV switch which insists we use | ||
1004 | * the FCF that answers multicast solicitations, not the others that | ||
1005 | * are sending periodic multicast advertisements. | ||
1006 | */ | ||
1007 | if (mtu_valid) { | ||
1008 | list_del(&fcf->list); | ||
1009 | list_add(&fcf->list, &fip->fcfs); | ||
1010 | } | ||
1011 | |||
1012 | /* | ||
948 | * If this is the first validated FCF, note the time and | 1013 | * If this is the first validated FCF, note the time and |
949 | * set a timer to trigger selection. | 1014 | * set a timer to trigger selection. |
950 | */ | 1015 | */ |
@@ -1061,18 +1126,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
1061 | els_op = *(u8 *)(fh + 1); | 1126 | els_op = *(u8 *)(fh + 1); |
1062 | 1127 | ||
1063 | if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) && | 1128 | if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) && |
1064 | sub == FIP_SC_REP && els_op == ELS_LS_ACC && | 1129 | sub == FIP_SC_REP && fip->mode != FIP_MODE_VN2VN) { |
1065 | fip->mode != FIP_MODE_VN2VN) { | 1130 | if (els_op == ELS_LS_ACC) { |
1066 | if (!is_valid_ether_addr(granted_mac)) { | 1131 | if (!is_valid_ether_addr(granted_mac)) { |
1067 | LIBFCOE_FIP_DBG(fip, | 1132 | LIBFCOE_FIP_DBG(fip, |
1068 | "Invalid MAC address %pM in FIP ELS\n", | 1133 | "Invalid MAC address %pM in FIP ELS\n", |
1069 | granted_mac); | 1134 | granted_mac); |
1070 | goto drop; | 1135 | goto drop; |
1071 | } | 1136 | } |
1072 | memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN); | 1137 | memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN); |
1073 | 1138 | ||
1074 | if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) | 1139 | if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) { |
1075 | fip->flogi_oxid = FC_XID_UNKNOWN; | 1140 | fip->flogi_oxid = FC_XID_UNKNOWN; |
1141 | if (els_dtype == FIP_DT_FLOGI) | ||
1142 | fcoe_ctlr_announce(fip); | ||
1143 | } | ||
1144 | } else if (els_dtype == FIP_DT_FLOGI && | ||
1145 | !fcoe_ctlr_flogi_retry(fip)) | ||
1146 | goto drop; /* retrying FLOGI so drop reject */ | ||
1076 | } | 1147 | } |
1077 | 1148 | ||
1078 | if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) && | 1149 | if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) && |
@@ -1326,20 +1397,39 @@ drop: | |||
1326 | * fcoe_ctlr_select() - Select the best FCF (if possible) | 1397 | * fcoe_ctlr_select() - Select the best FCF (if possible) |
1327 | * @fip: The FCoE controller | 1398 | * @fip: The FCoE controller |
1328 | * | 1399 | * |
1400 | * Returns the selected FCF, or NULL if none are usable. | ||
1401 | * | ||
1329 | * If there are conflicting advertisements, no FCF can be chosen. | 1402 | * If there are conflicting advertisements, no FCF can be chosen. |
1330 | * | 1403 | * |
1404 | * If there is already a selected FCF, this will choose a better one or | ||
1405 | * an equivalent one that hasn't already been sent a FLOGI. | ||
1406 | * | ||
1331 | * Called with lock held. | 1407 | * Called with lock held. |
1332 | */ | 1408 | */ |
1333 | static void fcoe_ctlr_select(struct fcoe_ctlr *fip) | 1409 | static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip) |
1334 | { | 1410 | { |
1335 | struct fcoe_fcf *fcf; | 1411 | struct fcoe_fcf *fcf; |
1336 | struct fcoe_fcf *best = NULL; | 1412 | struct fcoe_fcf *best = fip->sel_fcf; |
1413 | struct fcoe_fcf *first; | ||
1414 | |||
1415 | first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list); | ||
1337 | 1416 | ||
1338 | list_for_each_entry(fcf, &fip->fcfs, list) { | 1417 | list_for_each_entry(fcf, &fip->fcfs, list) { |
1339 | LIBFCOE_FIP_DBG(fip, "consider FCF for fab %16.16llx " | 1418 | LIBFCOE_FIP_DBG(fip, "consider FCF fab %16.16llx " |
1340 | "VFID %d map %x val %d\n", | 1419 | "VFID %d mac %pM map %x val %d " |
1341 | fcf->fabric_name, fcf->vfid, | 1420 | "sent %u pri %u\n", |
1342 | fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); | 1421 | fcf->fabric_name, fcf->vfid, fcf->fcf_mac, |
1422 | fcf->fc_map, fcoe_ctlr_mtu_valid(fcf), | ||
1423 | fcf->flogi_sent, fcf->pri); | ||
1424 | if (fcf->fabric_name != first->fabric_name || | ||
1425 | fcf->vfid != first->vfid || | ||
1426 | fcf->fc_map != first->fc_map) { | ||
1427 | LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, " | ||
1428 | "or FC-MAP\n"); | ||
1429 | return NULL; | ||
1430 | } | ||
1431 | if (fcf->flogi_sent) | ||
1432 | continue; | ||
1343 | if (!fcoe_ctlr_fcf_usable(fcf)) { | 1433 | if (!fcoe_ctlr_fcf_usable(fcf)) { |
1344 | LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx " | 1434 | LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx " |
1345 | "map %x %svalid %savailable\n", | 1435 | "map %x %svalid %savailable\n", |
@@ -1349,21 +1439,131 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) | |||
1349 | "" : "un"); | 1439 | "" : "un"); |
1350 | continue; | 1440 | continue; |
1351 | } | 1441 | } |
1352 | if (!best) { | 1442 | if (!best || fcf->pri < best->pri || best->flogi_sent) |
1353 | best = fcf; | ||
1354 | continue; | ||
1355 | } | ||
1356 | if (fcf->fabric_name != best->fabric_name || | ||
1357 | fcf->vfid != best->vfid || | ||
1358 | fcf->fc_map != best->fc_map) { | ||
1359 | LIBFCOE_FIP_DBG(fip, "Conflicting fabric, VFID, " | ||
1360 | "or FC-MAP\n"); | ||
1361 | return; | ||
1362 | } | ||
1363 | if (fcf->pri < best->pri) | ||
1364 | best = fcf; | 1443 | best = fcf; |
1365 | } | 1444 | } |
1366 | fip->sel_fcf = best; | 1445 | fip->sel_fcf = best; |
1446 | if (best) { | ||
1447 | LIBFCOE_FIP_DBG(fip, "using FCF mac %pM\n", best->fcf_mac); | ||
1448 | fip->port_ka_time = jiffies + | ||
1449 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | ||
1450 | fip->ctlr_ka_time = jiffies + best->fka_period; | ||
1451 | if (time_before(fip->ctlr_ka_time, fip->timer.expires)) | ||
1452 | mod_timer(&fip->timer, fip->ctlr_ka_time); | ||
1453 | } | ||
1454 | return best; | ||
1455 | } | ||
1456 | |||
1457 | /** | ||
1458 | * fcoe_ctlr_flogi_send_locked() - send FIP-encapsulated FLOGI to current FCF | ||
1459 | * @fip: The FCoE controller | ||
1460 | * | ||
1461 | * Returns non-zero error if it could not be sent. | ||
1462 | * | ||
1463 | * Called with ctlr_mutex and ctlr_lock held. | ||
1464 | * Caller must verify that fip->sel_fcf is not NULL. | ||
1465 | */ | ||
1466 | static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip) | ||
1467 | { | ||
1468 | struct sk_buff *skb; | ||
1469 | struct sk_buff *skb_orig; | ||
1470 | struct fc_frame_header *fh; | ||
1471 | int error; | ||
1472 | |||
1473 | skb_orig = fip->flogi_req; | ||
1474 | if (!skb_orig) | ||
1475 | return -EINVAL; | ||
1476 | |||
1477 | /* | ||
1478 | * Clone and send the FLOGI request. If clone fails, use original. | ||
1479 | */ | ||
1480 | skb = skb_clone(skb_orig, GFP_ATOMIC); | ||
1481 | if (!skb) { | ||
1482 | skb = skb_orig; | ||
1483 | fip->flogi_req = NULL; | ||
1484 | } | ||
1485 | fh = (struct fc_frame_header *)skb->data; | ||
1486 | error = fcoe_ctlr_encaps(fip, fip->lp, FIP_DT_FLOGI, skb, | ||
1487 | ntoh24(fh->fh_d_id)); | ||
1488 | if (error) { | ||
1489 | kfree_skb(skb); | ||
1490 | return error; | ||
1491 | } | ||
1492 | fip->send(fip, skb); | ||
1493 | fip->sel_fcf->flogi_sent = 1; | ||
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | /** | ||
1498 | * fcoe_ctlr_flogi_retry() - resend FLOGI request to a new FCF if possible | ||
1499 | * @fip: The FCoE controller | ||
1500 | * | ||
1501 | * Returns non-zero error code if there's no FLOGI request to retry or | ||
1502 | * no alternate FCF available. | ||
1503 | */ | ||
1504 | static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) | ||
1505 | { | ||
1506 | struct fcoe_fcf *fcf; | ||
1507 | int error; | ||
1508 | |||
1509 | mutex_lock(&fip->ctlr_mutex); | ||
1510 | spin_lock_bh(&fip->ctlr_lock); | ||
1511 | LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n"); | ||
1512 | fcf = fcoe_ctlr_select(fip); | ||
1513 | if (!fcf || fcf->flogi_sent) { | ||
1514 | kfree_skb(fip->flogi_req); | ||
1515 | fip->flogi_req = NULL; | ||
1516 | error = -ENOENT; | ||
1517 | } else { | ||
1518 | fcoe_ctlr_solicit(fip, NULL); | ||
1519 | error = fcoe_ctlr_flogi_send_locked(fip); | ||
1520 | } | ||
1521 | spin_unlock_bh(&fip->ctlr_lock); | ||
1522 | mutex_unlock(&fip->ctlr_mutex); | ||
1523 | return error; | ||
1524 | } | ||
1525 | |||
1526 | |||
1527 | /** | ||
1528 | * fcoe_ctlr_flogi_send() - Handle sending of FIP FLOGI. | ||
1529 | * @fip: The FCoE controller that timed out | ||
1530 | * | ||
1531 | * Done here because fcoe_ctlr_els_send() can't get mutex. | ||
1532 | * | ||
1533 | * Called with ctlr_mutex held. The caller must not hold ctlr_lock. | ||
1534 | */ | ||
1535 | static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) | ||
1536 | { | ||
1537 | struct fcoe_fcf *fcf; | ||
1538 | |||
1539 | spin_lock_bh(&fip->ctlr_lock); | ||
1540 | fcf = fip->sel_fcf; | ||
1541 | if (!fcf || !fip->flogi_req_send) | ||
1542 | goto unlock; | ||
1543 | |||
1544 | LIBFCOE_FIP_DBG(fip, "sending FLOGI\n"); | ||
1545 | |||
1546 | /* | ||
1547 | * If this FLOGI is being sent due to a timeout retry | ||
1548 | * to the same FCF as before, select a different FCF if possible. | ||
1549 | */ | ||
1550 | if (fcf->flogi_sent) { | ||
1551 | LIBFCOE_FIP_DBG(fip, "sending FLOGI - reselect\n"); | ||
1552 | fcf = fcoe_ctlr_select(fip); | ||
1553 | if (!fcf || fcf->flogi_sent) { | ||
1554 | LIBFCOE_FIP_DBG(fip, "sending FLOGI - clearing\n"); | ||
1555 | list_for_each_entry(fcf, &fip->fcfs, list) | ||
1556 | fcf->flogi_sent = 0; | ||
1557 | fcf = fcoe_ctlr_select(fip); | ||
1558 | } | ||
1559 | } | ||
1560 | if (fcf) { | ||
1561 | fcoe_ctlr_flogi_send_locked(fip); | ||
1562 | fip->flogi_req_send = 0; | ||
1563 | } else /* XXX */ | ||
1564 | LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n"); | ||
1565 | unlock: | ||
1566 | spin_unlock_bh(&fip->ctlr_lock); | ||
1367 | } | 1567 | } |
1368 | 1568 | ||
1369 | /** | 1569 | /** |
@@ -1411,34 +1611,16 @@ static void fcoe_ctlr_timer_work(struct work_struct *work) | |||
1411 | sel = fip->sel_fcf; | 1611 | sel = fip->sel_fcf; |
1412 | if (!sel && fip->sel_time) { | 1612 | if (!sel && fip->sel_time) { |
1413 | if (time_after_eq(jiffies, fip->sel_time)) { | 1613 | if (time_after_eq(jiffies, fip->sel_time)) { |
1414 | fcoe_ctlr_select(fip); | 1614 | sel = fcoe_ctlr_select(fip); |
1415 | sel = fip->sel_fcf; | ||
1416 | fip->sel_time = 0; | 1615 | fip->sel_time = 0; |
1417 | } else if (time_after(next_timer, fip->sel_time)) | 1616 | } else if (time_after(next_timer, fip->sel_time)) |
1418 | next_timer = fip->sel_time; | 1617 | next_timer = fip->sel_time; |
1419 | } | 1618 | } |
1420 | 1619 | ||
1421 | if (sel != fcf) { | 1620 | if (sel && fip->flogi_req_send) |
1422 | fcf = sel; /* the old FCF may have been freed */ | 1621 | fcoe_ctlr_flogi_send(fip); |
1423 | if (sel) { | 1622 | else if (!sel && fcf) |
1424 | printk(KERN_INFO "libfcoe: host%d: FIP selected " | 1623 | reset = 1; |
1425 | "Fibre-Channel Forwarder MAC %pM\n", | ||
1426 | fip->lp->host->host_no, sel->fcf_mac); | ||
1427 | memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); | ||
1428 | fip->map_dest = 0; | ||
1429 | fip->port_ka_time = jiffies + | ||
1430 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | ||
1431 | fip->ctlr_ka_time = jiffies + sel->fka_period; | ||
1432 | if (time_after(next_timer, fip->ctlr_ka_time)) | ||
1433 | next_timer = fip->ctlr_ka_time; | ||
1434 | } else { | ||
1435 | printk(KERN_NOTICE "libfcoe: host%d: " | ||
1436 | "FIP Fibre-Channel Forwarder timed out. " | ||
1437 | "Starting FCF discovery.\n", | ||
1438 | fip->lp->host->host_no); | ||
1439 | reset = 1; | ||
1440 | } | ||
1441 | } | ||
1442 | 1624 | ||
1443 | if (sel && !sel->fd_flags) { | 1625 | if (sel && !sel->fd_flags) { |
1444 | if (time_after_eq(jiffies, fip->ctlr_ka_time)) { | 1626 | if (time_after_eq(jiffies, fip->ctlr_ka_time)) { |
@@ -2475,7 +2657,7 @@ static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *fip) | |||
2475 | case FIP_ST_LINK_WAIT: | 2657 | case FIP_ST_LINK_WAIT: |
2476 | goto unlock; | 2658 | goto unlock; |
2477 | default: | 2659 | default: |
2478 | WARN(1, "unexpected state %d", fip->state); | 2660 | WARN(1, "unexpected state %d\n", fip->state); |
2479 | goto unlock; | 2661 | goto unlock; |
2480 | } | 2662 | } |
2481 | mod_timer(&fip->timer, next_time); | 2663 | mod_timer(&fip->timer, next_time); |