aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/libfcoe.c207
-rw-r--r--include/scsi/libfcoe.h8
2 files changed, 185 insertions, 30 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 826c260f7951..c90622c28b6c 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -54,6 +54,8 @@ MODULE_LICENSE("GPL v2");
54static void fcoe_ctlr_timeout(unsigned long); 54static void fcoe_ctlr_timeout(unsigned long);
55static void fcoe_ctlr_timer_work(struct work_struct *); 55static void fcoe_ctlr_timer_work(struct work_struct *);
56static void fcoe_ctlr_recv_work(struct work_struct *); 56static void fcoe_ctlr_recv_work(struct work_struct *);
57static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *);
58static void fcoe_ctlr_select(struct fcoe_ctlr *);
57 59
58static void fcoe_ctlr_vn_start(struct fcoe_ctlr *); 60static void fcoe_ctlr_vn_start(struct fcoe_ctlr *);
59static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *); 61static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *);
@@ -176,6 +178,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
176 fip->mode = mode; 178 fip->mode = mode;
177 INIT_LIST_HEAD(&fip->fcfs); 179 INIT_LIST_HEAD(&fip->fcfs);
178 mutex_init(&fip->ctlr_mutex); 180 mutex_init(&fip->ctlr_mutex);
181 spin_lock_init(&fip->ctlr_lock);
179 fip->flogi_oxid = FC_XID_UNKNOWN; 182 fip->flogi_oxid = FC_XID_UNKNOWN;
180 setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); 183 setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
181 INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work); 184 INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work);
@@ -231,17 +234,31 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
231EXPORT_SYMBOL(fcoe_ctlr_destroy); 234EXPORT_SYMBOL(fcoe_ctlr_destroy);
232 235
233/** 236/**
234 * fcoe_ctlr_announce() - announce new selection 237 * fcoe_ctlr_announce() - announce new FCF selection
235 * @fip: The FCoE controller 238 * @fip: The FCoE controller
236 * 239 *
237 * Also sets the destination MAC for FCoE and control packets 240 * Also sets the destination MAC for FCoE and control packets
241 *
242 * Called with neither ctlr_mutex nor ctlr_lock held.
238 */ 243 */
239static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) 244static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
240{ 245{
241 struct fcoe_fcf *sel = fip->sel_fcf; 246 struct fcoe_fcf *sel;
247 struct fcoe_fcf *fcf;
248
249 mutex_lock(&fip->ctlr_mutex);
250 spin_lock_bh(&fip->ctlr_lock);
251
252 kfree_skb(fip->flogi_req);
253 fip->flogi_req = NULL;
254 list_for_each_entry(fcf, &fip->fcfs, list)
255 fcf->flogi_sent = 0;
256
257 spin_unlock_bh(&fip->ctlr_lock);
258 sel = fip->sel_fcf;
242 259
243 if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr)) 260 if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr))
244 return; 261 goto unlock;
245 if (!is_zero_ether_addr(fip->dest_addr)) { 262 if (!is_zero_ether_addr(fip->dest_addr)) {
246 printk(KERN_NOTICE "libfcoe: host%d: " 263 printk(KERN_NOTICE "libfcoe: host%d: "
247 "FIP Fibre-Channel Forwarder MAC %pM deselected\n", 264 "FIP Fibre-Channel Forwarder MAC %pM deselected\n",
@@ -255,6 +272,8 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
255 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); 272 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
256 fip->map_dest = 0; 273 fip->map_dest = 0;
257 } 274 }
275unlock:
276 mutex_unlock(&fip->ctlr_mutex);
258} 277}
259 278
260/** 279/**
@@ -591,6 +610,9 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
591 * The caller must check that the length is a multiple of 4. 610 * The caller must check that the length is a multiple of 4.
592 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). 611 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
593 * The the skb must also be an fc_frame. 612 * The the skb must also be an fc_frame.
613 *
614 * This is called from the lower-level driver with spinlocks held,
615 * so we must not take a mutex here.
594 */ 616 */
595int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, 617int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
596 struct sk_buff *skb) 618 struct sk_buff *skb)
@@ -628,7 +650,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
628 switch (op) { 650 switch (op) {
629 case ELS_FLOGI: 651 case ELS_FLOGI:
630 op = FIP_DT_FLOGI; 652 op = FIP_DT_FLOGI;
631 break; 653 if (fip->mode == FIP_MODE_VN2VN)
654 break;
655 spin_lock_bh(&fip->ctlr_lock);
656 kfree_skb(fip->flogi_req);
657 fip->flogi_req = skb;
658 fip->flogi_req_send = 1;
659 spin_unlock_bh(&fip->ctlr_lock);
660 schedule_work(&fip->timer_work);
661 return -EINPROGRESS;
632 case ELS_FDISC: 662 case ELS_FDISC:
633 if (ntoh24(fh->fh_s_id)) 663 if (ntoh24(fh->fh_s_id))
634 return 0; 664 return 0;
@@ -1088,18 +1118,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
1088 els_op = *(u8 *)(fh + 1); 1118 els_op = *(u8 *)(fh + 1);
1089 1119
1090 if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) && 1120 if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
1091 sub == FIP_SC_REP && els_op == ELS_LS_ACC && 1121 sub == FIP_SC_REP && fip->mode != FIP_MODE_VN2VN) {
1092 fip->mode != FIP_MODE_VN2VN) { 1122 if (els_op == ELS_LS_ACC) {
1093 if (!is_valid_ether_addr(granted_mac)) { 1123 if (!is_valid_ether_addr(granted_mac)) {
1094 LIBFCOE_FIP_DBG(fip, 1124 LIBFCOE_FIP_DBG(fip,
1095 "Invalid MAC address %pM in FIP ELS\n", 1125 "Invalid MAC address %pM in FIP ELS\n",
1096 granted_mac); 1126 granted_mac);
1097 goto drop; 1127 goto drop;
1098 } 1128 }
1099 memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN); 1129 memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
1100 1130
1101 if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) 1131 if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
1102 fip->flogi_oxid = FC_XID_UNKNOWN; 1132 fip->flogi_oxid = FC_XID_UNKNOWN;
1133 if (els_dtype == FIP_DT_FLOGI)
1134 fcoe_ctlr_announce(fip);
1135 }
1136 } else if (els_dtype == FIP_DT_FLOGI &&
1137 !fcoe_ctlr_flogi_retry(fip))
1138 goto drop; /* retrying FLOGI so drop reject */
1103 } 1139 }
1104 1140
1105 if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) && 1141 if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) &&
@@ -1355,12 +1391,15 @@ drop:
1355 * 1391 *
1356 * If there are conflicting advertisements, no FCF can be chosen. 1392 * If there are conflicting advertisements, no FCF can be chosen.
1357 * 1393 *
1394 * If there is already a selected FCF, this will choose a better one or
1395 * an equivalent one that hasn't already been sent a FLOGI.
1396 *
1358 * Called with lock held. 1397 * Called with lock held.
1359 */ 1398 */
1360static void fcoe_ctlr_select(struct fcoe_ctlr *fip) 1399static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1361{ 1400{
1362 struct fcoe_fcf *fcf; 1401 struct fcoe_fcf *fcf;
1363 struct fcoe_fcf *best = NULL; 1402 struct fcoe_fcf *best = fip->sel_fcf;
1364 struct fcoe_fcf *first; 1403 struct fcoe_fcf *first;
1365 1404
1366 first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list); 1405 first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list);
@@ -1377,6 +1416,8 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1377 "or FC-MAP\n"); 1416 "or FC-MAP\n");
1378 return NULL; 1417 return NULL;
1379 } 1418 }
1419 if (fcf->flogi_sent)
1420 continue;
1380 if (!fcoe_ctlr_fcf_usable(fcf)) { 1421 if (!fcoe_ctlr_fcf_usable(fcf)) {
1381 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx " 1422 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
1382 "map %x %svalid %savailable\n", 1423 "map %x %svalid %savailable\n",
@@ -1386,11 +1427,7 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1386 "" : "un"); 1427 "" : "un");
1387 continue; 1428 continue;
1388 } 1429 }
1389 if (!best) { 1430 if (!best || fcf->pri < best->pri || best->flogi_sent)
1390 best = fcf;
1391 continue;
1392 }
1393 if (fcf->pri < best->pri)
1394 best = fcf; 1431 best = fcf;
1395 } 1432 }
1396 fip->sel_fcf = best; 1433 fip->sel_fcf = best;
@@ -1404,6 +1441,121 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1404} 1441}
1405 1442
1406/** 1443/**
1444 * fcoe_ctlr_flogi_send_locked() - send FIP-encapsulated FLOGI to current FCF
1445 * @fip: The FCoE controller
1446 *
1447 * Returns non-zero error if it could not be sent.
1448 *
1449 * Called with ctlr_mutex and ctlr_lock held.
1450 * Caller must verify that fip->sel_fcf is not NULL.
1451 */
1452static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
1453{
1454 struct sk_buff *skb;
1455 struct sk_buff *skb_orig;
1456 struct fc_frame_header *fh;
1457 int error;
1458
1459 skb_orig = fip->flogi_req;
1460 if (!skb_orig)
1461 return -EINVAL;
1462
1463 /*
1464 * Clone and send the FLOGI request. If clone fails, use original.
1465 */
1466 skb = skb_clone(skb_orig, GFP_ATOMIC);
1467 if (!skb) {
1468 skb = skb_orig;
1469 fip->flogi_req = NULL;
1470 }
1471 fh = (struct fc_frame_header *)skb->data;
1472 error = fcoe_ctlr_encaps(fip, fip->lp, FIP_DT_FLOGI, skb,
1473 ntoh24(fh->fh_d_id));
1474 if (error) {
1475 kfree_skb(skb);
1476 return error;
1477 }
1478 fip->send(fip, skb);
1479 fip->sel_fcf->flogi_sent = 1;
1480 return 0;
1481}
1482
1483/**
1484 * fcoe_ctlr_flogi_retry() - resend FLOGI request to a new FCF if possible
1485 * @fip: The FCoE controller
1486 *
1487 * Returns non-zero error code if there's no FLOGI request to retry or
1488 * no alternate FCF available.
1489 */
1490static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
1491{
1492 struct fcoe_fcf *fcf;
1493 int error;
1494
1495 mutex_lock(&fip->ctlr_mutex);
1496 spin_lock_bh(&fip->ctlr_lock);
1497 LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
1498 fcoe_ctlr_select(fip);
1499 fcf = fip->sel_fcf;
1500 if (!fcf || fcf->flogi_sent) {
1501 kfree_skb(fip->flogi_req);
1502 fip->flogi_req = NULL;
1503 error = -ENOENT;
1504 } else {
1505 fcoe_ctlr_solicit(fip, NULL);
1506 error = fcoe_ctlr_flogi_send_locked(fip);
1507 }
1508 spin_unlock_bh(&fip->ctlr_lock);
1509 mutex_unlock(&fip->ctlr_mutex);
1510 return error;
1511}
1512
1513
1514/**
1515 * fcoe_ctlr_flogi_send() - Handle sending of FIP FLOGI.
1516 * @fip: The FCoE controller that timed out
1517 *
1518 * Done here because fcoe_ctlr_els_send() can't get mutex.
1519 *
1520 * Called with ctlr_mutex held. The caller must not hold ctlr_lock.
1521 */
1522static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
1523{
1524 struct fcoe_fcf *fcf;
1525
1526 spin_lock_bh(&fip->ctlr_lock);
1527 fcf = fip->sel_fcf;
1528 if (!fcf || !fip->flogi_req_send)
1529 goto unlock;
1530
1531 LIBFCOE_FIP_DBG(fip, "sending FLOGI\n");
1532
1533 /*
1534 * If this FLOGI is being sent due to a timeout retry
1535 * to the same FCF as before, select a different FCF if possible.
1536 */
1537 if (fcf->flogi_sent) {
1538 LIBFCOE_FIP_DBG(fip, "sending FLOGI - reselect\n");
1539 fcoe_ctlr_select(fip);
1540 fcf = fip->sel_fcf;
1541 if (!fcf || fcf->flogi_sent) {
1542 LIBFCOE_FIP_DBG(fip, "sending FLOGI - clearing\n");
1543 list_for_each_entry(fcf, &fip->fcfs, list)
1544 fcf->flogi_sent = 0;
1545 fcoe_ctlr_select(fip);
1546 fcf = fip->sel_fcf;
1547 }
1548 }
1549 if (fcf) {
1550 fcoe_ctlr_flogi_send_locked(fip);
1551 fip->flogi_req_send = 0;
1552 } else /* XXX */
1553 LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
1554unlock:
1555 spin_unlock_bh(&fip->ctlr_lock);
1556}
1557
1558/**
1407 * fcoe_ctlr_timeout() - FIP timeout handler 1559 * fcoe_ctlr_timeout() - FIP timeout handler
1408 * @arg: The FCoE controller that timed out 1560 * @arg: The FCoE controller that timed out
1409 */ 1561 */
@@ -1455,15 +1607,10 @@ static void fcoe_ctlr_timer_work(struct work_struct *work)
1455 next_timer = fip->sel_time; 1607 next_timer = fip->sel_time;
1456 } 1608 }
1457 1609
1458 if (sel != fcf) { 1610 if (sel && fip->flogi_req_send)
1459 fcf = sel; /* the old FCF may have been freed */ 1611 fcoe_ctlr_flogi_send(fip);
1460 fcoe_ctlr_announce(fip); 1612 else if (!sel && fcf)
1461 if (sel) { 1613 reset = 1;
1462 if (time_after(next_timer, fip->ctlr_ka_time))
1463 next_timer = fip->ctlr_ka_time;
1464 } else
1465 reset = 1;
1466 }
1467 1614
1468 if (sel && !sel->fd_flags) { 1615 if (sel && !sel->fd_flags) {
1469 if (time_after_eq(jiffies, fip->ctlr_ka_time)) { 1616 if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 06f1b5a8ed19..feb6a94c90ea 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -92,10 +92,12 @@ enum fip_state {
92 * @timer_work: &work_struct for doing keep-alives and resets. 92 * @timer_work: &work_struct for doing keep-alives and resets.
93 * @recv_work: &work_struct for receiving FIP frames. 93 * @recv_work: &work_struct for receiving FIP frames.
94 * @fip_recv_list: list of received FIP frames. 94 * @fip_recv_list: list of received FIP frames.
95 * @flogi_req: clone of FLOGI request sent
95 * @rnd_state: state for pseudo-random number generator. 96 * @rnd_state: state for pseudo-random number generator.
96 * @port_id: proposed or selected local-port ID. 97 * @port_id: proposed or selected local-port ID.
97 * @user_mfs: configured maximum FC frame size, including FC header. 98 * @user_mfs: configured maximum FC frame size, including FC header.
98 * @flogi_oxid: exchange ID of most recent fabric login. 99 * @flogi_oxid: exchange ID of most recent fabric login.
100 * @flogi_req_send: send of FLOGI requested
99 * @flogi_count: number of FLOGI attempts in AUTO mode. 101 * @flogi_count: number of FLOGI attempts in AUTO mode.
100 * @map_dest: use the FC_MAP mode for destination MAC addresses. 102 * @map_dest: use the FC_MAP mode for destination MAC addresses.
101 * @spma: supports SPMA server-provided MACs mode 103 * @spma: supports SPMA server-provided MACs mode
@@ -106,6 +108,7 @@ enum fip_state {
106 * @update_mac: LLD-supplied function to handle changes to MAC addresses. 108 * @update_mac: LLD-supplied function to handle changes to MAC addresses.
107 * @get_src_addr: LLD-supplied function to supply a source MAC address. 109 * @get_src_addr: LLD-supplied function to supply a source MAC address.
108 * @ctlr_mutex: lock protecting this structure. 110 * @ctlr_mutex: lock protecting this structure.
111 * @ctlr_lock: spinlock covering flogi_req
109 * 112 *
110 * This structure is used by all FCoE drivers. It contains information 113 * This structure is used by all FCoE drivers. It contains information
111 * needed by all FCoE low-level drivers (LLDs) as well as internal state 114 * needed by all FCoE low-level drivers (LLDs) as well as internal state
@@ -126,12 +129,14 @@ struct fcoe_ctlr {
126 struct work_struct timer_work; 129 struct work_struct timer_work;
127 struct work_struct recv_work; 130 struct work_struct recv_work;
128 struct sk_buff_head fip_recv_list; 131 struct sk_buff_head fip_recv_list;
132 struct sk_buff *flogi_req;
129 133
130 struct rnd_state rnd_state; 134 struct rnd_state rnd_state;
131 u32 port_id; 135 u32 port_id;
132 136
133 u16 user_mfs; 137 u16 user_mfs;
134 u16 flogi_oxid; 138 u16 flogi_oxid;
139 u8 flogi_req_send;
135 u8 flogi_count; 140 u8 flogi_count;
136 u8 map_dest; 141 u8 map_dest;
137 u8 spma; 142 u8 spma;
@@ -143,6 +148,7 @@ struct fcoe_ctlr {
143 void (*update_mac)(struct fc_lport *, u8 *addr); 148 void (*update_mac)(struct fc_lport *, u8 *addr);
144 u8 * (*get_src_addr)(struct fc_lport *); 149 u8 * (*get_src_addr)(struct fc_lport *);
145 struct mutex ctlr_mutex; 150 struct mutex ctlr_mutex;
151 spinlock_t ctlr_lock;
146}; 152};
147 153
148/** 154/**
@@ -155,6 +161,7 @@ struct fcoe_ctlr {
155 * @fcf_mac: Ethernet address of the FCF 161 * @fcf_mac: Ethernet address of the FCF
156 * @vfid: virtual fabric ID 162 * @vfid: virtual fabric ID
157 * @pri: selection priority, smaller values are better 163 * @pri: selection priority, smaller values are better
164 * @flogi_sent: current FLOGI sent to this FCF
158 * @flags: flags received from advertisement 165 * @flags: flags received from advertisement
159 * @fka_period: keep-alive period, in jiffies 166 * @fka_period: keep-alive period, in jiffies
160 * 167 *
@@ -176,6 +183,7 @@ struct fcoe_fcf {
176 u8 fcf_mac[ETH_ALEN]; 183 u8 fcf_mac[ETH_ALEN];
177 184
178 u8 pri; 185 u8 pri;
186 u8 flogi_sent;
179 u16 flags; 187 u16 flags;
180 u32 fka_period; 188 u32 fka_period;
181 u8 fd_flags:1; 189 u8 fd_flags:1;