@@ -54,6 +54,8 @@ MODULE_LICENSE("GPL v2");
5454static void fcoe_ctlr_timeout (unsigned long );
5555static void fcoe_ctlr_timer_work (struct work_struct * );
5656static void fcoe_ctlr_recv_work (struct work_struct * );
57+ static int fcoe_ctlr_flogi_retry (struct fcoe_ctlr * );
58+ static void fcoe_ctlr_select (struct fcoe_ctlr * );
5759
5860static void fcoe_ctlr_vn_start (struct fcoe_ctlr * );
5961static 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)
176178 fip -> mode = mode ;
177179 INIT_LIST_HEAD (& fip -> fcfs );
178180 mutex_init (& fip -> ctlr_mutex );
181+ spin_lock_init (& fip -> ctlr_lock );
179182 fip -> flogi_oxid = FC_XID_UNKNOWN ;
180183 setup_timer (& fip -> timer , fcoe_ctlr_timeout , (unsigned long )fip );
181184 INIT_WORK (& fip -> timer_work , fcoe_ctlr_timer_work );
@@ -231,17 +234,31 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
231234EXPORT_SYMBOL (fcoe_ctlr_destroy );
232235
233236/**
234- * fcoe_ctlr_announce() - announce new selection
237+ * fcoe_ctlr_announce() - announce new FCF selection
235238 * @fip: The FCoE controller
236239 *
237240 * Also sets the destination MAC for FCoE and control packets
241+ *
242+ * Called with neither ctlr_mutex nor ctlr_lock held.
238243 */
239244static void fcoe_ctlr_announce (struct fcoe_ctlr * fip )
240245{
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 ;
242259
243260 if (sel && !compare_ether_addr (sel -> fcf_mac , fip -> dest_addr ))
244- return ;
261+ goto unlock ;
245262 if (!is_zero_ether_addr (fip -> dest_addr )) {
246263 printk (KERN_NOTICE "libfcoe: host%d: "
247264 "FIP Fibre-Channel Forwarder MAC %pM deselected\n" ,
@@ -255,6 +272,8 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
255272 memcpy (fip -> dest_addr , sel -> fcf_mac , ETH_ALEN );
256273 fip -> map_dest = 0 ;
257274 }
275+ unlock :
276+ mutex_unlock (& fip -> ctlr_mutex );
258277}
259278
260279/**
@@ -591,6 +610,9 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
591610 * The caller must check that the length is a multiple of 4.
592611 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
593612 * 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.
594616 */
595617int fcoe_ctlr_els_send (struct fcoe_ctlr * fip , struct fc_lport * lport ,
596618 struct sk_buff * skb )
@@ -628,7 +650,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
628650 switch (op ) {
629651 case ELS_FLOGI :
630652 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 ;
632662 case ELS_FDISC :
633663 if (ntoh24 (fh -> fh_s_id ))
634664 return 0 ;
@@ -1088,18 +1118,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
10881118 els_op = * (u8 * )(fh + 1 );
10891119
10901120 if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC ) &&
1091- sub == FIP_SC_REP && els_op == ELS_LS_ACC &&
1092- fip -> mode != FIP_MODE_VN2VN ) {
1093- if (!is_valid_ether_addr (granted_mac )) {
1094- LIBFCOE_FIP_DBG (fip ,
1095- "Invalid MAC address %pM in FIP ELS\n" ,
1096- granted_mac );
1097- goto drop ;
1098- }
1099- memcpy (fr_cb (fp )-> granted_mac , granted_mac , ETH_ALEN );
1121+ sub == FIP_SC_REP && fip -> mode != FIP_MODE_VN2VN ) {
1122+ if ( els_op == ELS_LS_ACC ) {
1123+ if (!is_valid_ether_addr (granted_mac )) {
1124+ LIBFCOE_FIP_DBG (fip ,
1125+ "Invalid MAC address %pM in FIP ELS\n" ,
1126+ granted_mac );
1127+ goto drop ;
1128+ }
1129+ memcpy (fr_cb (fp )-> granted_mac , granted_mac , ETH_ALEN );
11001130
1101- if (fip -> flogi_oxid == ntohs (fh -> fh_ox_id ))
1102- fip -> flogi_oxid = FC_XID_UNKNOWN ;
1131+ if (fip -> flogi_oxid == ntohs (fh -> fh_ox_id )) {
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 */
11031139 }
11041140
11051141 if ((desc_cnt == 0 ) || ((els_op != ELS_LS_RJT ) &&
@@ -1355,12 +1391,15 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
13551391 *
13561392 * If there are conflicting advertisements, no FCF can be chosen.
13571393 *
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+ *
13581397 * Called with lock held.
13591398 */
13601399static void fcoe_ctlr_select (struct fcoe_ctlr * fip )
13611400{
13621401 struct fcoe_fcf * fcf ;
1363- struct fcoe_fcf * best = NULL ;
1402+ struct fcoe_fcf * best = fip -> sel_fcf ;
13641403 struct fcoe_fcf * first ;
13651404
13661405 first = list_first_entry (& fip -> fcfs , struct fcoe_fcf , list );
@@ -1377,6 +1416,8 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
13771416 "or FC-MAP\n" );
13781417 return NULL ;
13791418 }
1419+ if (fcf -> flogi_sent )
1420+ continue ;
13801421 if (!fcoe_ctlr_fcf_usable (fcf )) {
13811422 LIBFCOE_FIP_DBG (fip , "FCF for fab %16.16llx "
13821423 "map %x %svalid %savailable\n" ,
@@ -1386,11 +1427,7 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
13861427 "" : "un" );
13871428 continue ;
13881429 }
1389- if (!best ) {
1390- best = fcf ;
1391- continue ;
1392- }
1393- if (fcf -> pri < best -> pri )
1430+ if (!best || fcf -> pri < best -> pri || best -> flogi_sent )
13941431 best = fcf ;
13951432 }
13961433 fip -> sel_fcf = best ;
@@ -1403,6 +1440,121 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
14031440 }
14041441}
14051442
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+ */
1452+ static 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+ */
1490+ static 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+ */
1522+ static 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" );
1554+ unlock :
1555+ spin_unlock_bh (& fip -> ctlr_lock );
1556+ }
1557+
14061558/**
14071559 * fcoe_ctlr_timeout() - FIP timeout handler
14081560 * @arg: The FCoE controller that timed out
@@ -1455,15 +1607,10 @@ static void fcoe_ctlr_timer_work(struct work_struct *work)
14551607 next_timer = fip -> sel_time ;
14561608 }
14571609
1458- if (sel != fcf ) {
1459- fcf = sel ; /* the old FCF may have been freed */
1460- fcoe_ctlr_announce (fip );
1461- if (sel ) {
1462- if (time_after (next_timer , fip -> ctlr_ka_time ))
1463- next_timer = fip -> ctlr_ka_time ;
1464- } else
1465- reset = 1 ;
1466- }
1610+ if (sel && fip -> flogi_req_send )
1611+ fcoe_ctlr_flogi_send (fip );
1612+ else if (!sel && fcf )
1613+ reset = 1 ;
14671614
14681615 if (sel && !sel -> fd_flags ) {
14691616 if (time_after_eq (jiffies , fip -> ctlr_ka_time )) {
0 commit comments