aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
authorChris Leech <christopher.leech@intel.com>2009-11-03 14:46:29 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:00:58 -0500
commit11b561886643d4e23d0fd58c205d830a448dd0a2 (patch)
tree3d28650e6727589dd672ea3985d2aa2643a99549 /drivers/scsi/fcoe
parentdb36c06cc6802d03bcba08982377f7c03a3cda7f (diff)
[SCSI] libfcoe, fcoe: libfcoe NPIV support
The FIP code in libfcoe needed several changes to support NPIV 1) dst_src_addr needs to be managed per-n_port-ID for FPMA fabrics with NPIV enabled. Managing the MAC address is now handled in fcoe, with some slight changes to update_mac() and a new get_src_addr() function pointer. 2) The libfc elsct_send() hook is used to setup FCoE specific response handlers for FIP encapsulated ELS exchanges. This lets the FCoE specific handling know which VN_Port the exchange is for, and doesn't require tracking OX_IDs. It might be possible to roll back to the full FIP frame in these, but for now I've just stashed the contents of the MAC address descriptor in the skb context block for later use. Also, because fcoe_elsct_send() just passes control on to fc_elsct_send(), all transmits still come through the normal frame_send() path. 3) The NPIV changes added a mutex hold in the keep alive sending, the lport mutex is protecting the vport list. We can't take a mutex from a timer, so move the FIP keep alive logic to the link work struct. Signed-off-by: Chris Leech <christopher.leech@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/fcoe.c147
-rw-r--r--drivers/scsi/fcoe/fcoe.h1
-rw-r--r--drivers/scsi/fcoe/libfcoe.c82
3 files changed, 178 insertions, 52 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 8ca488de492d..a64c398c981e 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -226,7 +226,8 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe,
226} 226}
227 227
228static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb); 228static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb);
229static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new); 229static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr);
230static u8 *fcoe_get_src_mac(struct fc_lport *lport);
230static void fcoe_destroy_work(struct work_struct *work); 231static void fcoe_destroy_work(struct work_struct *work);
231 232
232/** 233/**
@@ -254,6 +255,7 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev)
254 fcoe_ctlr_init(&fcoe->ctlr); 255 fcoe_ctlr_init(&fcoe->ctlr);
255 fcoe->ctlr.send = fcoe_fip_send; 256 fcoe->ctlr.send = fcoe_fip_send;
256 fcoe->ctlr.update_mac = fcoe_update_src_mac; 257 fcoe->ctlr.update_mac = fcoe_update_src_mac;
258 fcoe->ctlr.get_src_addr = fcoe_get_src_mac;
257 259
258 fcoe_interface_setup(fcoe, netdev); 260 fcoe_interface_setup(fcoe, netdev);
259 261
@@ -286,8 +288,6 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
286 /* Delete secondary MAC addresses */ 288 /* Delete secondary MAC addresses */
287 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); 289 memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
288 dev_unicast_delete(netdev, flogi_maddr); 290 dev_unicast_delete(netdev, flogi_maddr);
289 if (!is_zero_ether_addr(fip->data_src_addr))
290 dev_unicast_delete(netdev, fip->data_src_addr);
291 if (fip->spma) 291 if (fip->spma)
292 dev_unicast_delete(netdev, fip->ctl_src_addr); 292 dev_unicast_delete(netdev, fip->ctl_src_addr);
293 dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); 293 dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
@@ -369,26 +369,38 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
369 369
370/** 370/**
371 * fcoe_update_src_mac() - Update Ethernet MAC filters. 371 * fcoe_update_src_mac() - Update Ethernet MAC filters.
372 * @fip: FCoE controller. 372 * @lport: libfc lport
373 * @old: Unicast MAC address to delete if the MAC is non-zero. 373 * @addr: Unicast MAC address to add.
374 * @new: Unicast MAC address to add.
375 * 374 *
376 * Remove any previously-set unicast MAC filter. 375 * Remove any previously-set unicast MAC filter.
377 * Add secondary FCoE MAC address filter for our OUI. 376 * Add secondary FCoE MAC address filter for our OUI.
378 */ 377 */
379static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) 378static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr)
380{ 379{
381 struct fcoe_interface *fcoe; 380 struct fcoe_port *port = lport_priv(lport);
381 struct fcoe_interface *fcoe = port->fcoe;
382 382
383 fcoe = fcoe_from_ctlr(fip);
384 rtnl_lock(); 383 rtnl_lock();
385 if (!is_zero_ether_addr(old)) 384 if (!is_zero_ether_addr(port->data_src_addr))
386 dev_unicast_delete(fcoe->netdev, old); 385 dev_unicast_delete(fcoe->netdev, port->data_src_addr);
387 dev_unicast_add(fcoe->netdev, new); 386 if (!is_zero_ether_addr(addr))
387 dev_unicast_add(fcoe->netdev, addr);
388 memcpy(port->data_src_addr, addr, ETH_ALEN);
388 rtnl_unlock(); 389 rtnl_unlock();
389} 390}
390 391
391/** 392/**
393 * fcoe_get_src_mac() - return the Ethernet source address for an lport
394 * @lport: libfc lport
395 */
396static u8 *fcoe_get_src_mac(struct fc_lport *lport)
397{
398 struct fcoe_port *port = lport_priv(lport);
399
400 return port->data_src_addr;
401}
402
403/**
392 * fcoe_lport_config() - sets up the fc_lport 404 * fcoe_lport_config() - sets up the fc_lport
393 * @lp: ptr to the fc_lport 405 * @lp: ptr to the fc_lport
394 * 406 *
@@ -650,6 +662,11 @@ static void fcoe_if_destroy(struct fc_lport *lport)
650 /* Free existing transmit skbs */ 662 /* Free existing transmit skbs */
651 fcoe_clean_pending_queue(lport); 663 fcoe_clean_pending_queue(lport);
652 664
665 rtnl_lock();
666 if (!is_zero_ether_addr(port->data_src_addr))
667 dev_unicast_delete(netdev, port->data_src_addr);
668 rtnl_unlock();
669
653 /* receives may not be stopped until after this */ 670 /* receives may not be stopped until after this */
654 fcoe_interface_put(fcoe); 671 fcoe_interface_put(fcoe);
655 672
@@ -706,10 +723,16 @@ static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
706 return 0; 723 return 0;
707} 724}
708 725
726static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport,
727 u32 did, struct fc_frame *fp, unsigned int op,
728 void (*resp)(struct fc_seq *, struct fc_frame *, void *),
729 void *arg, u32 timeout);
730
709static struct libfc_function_template fcoe_libfc_fcn_templ = { 731static struct libfc_function_template fcoe_libfc_fcn_templ = {
710 .frame_send = fcoe_xmit, 732 .frame_send = fcoe_xmit,
711 .ddp_setup = fcoe_ddp_setup, 733 .ddp_setup = fcoe_ddp_setup,
712 .ddp_done = fcoe_ddp_done, 734 .ddp_done = fcoe_ddp_done,
735 .elsct_send = fcoe_elsct_send,
713}; 736};
714 737
715/** 738/**
@@ -1226,7 +1249,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1226 } 1249 }
1227 1250
1228 if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) && 1251 if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
1229 fcoe_ctlr_els_send(&fcoe->ctlr, skb)) 1252 fcoe_ctlr_els_send(&fcoe->ctlr, lp, skb))
1230 return 0; 1253 return 0;
1231 1254
1232 sof = fr_sof(fp); 1255 sof = fr_sof(fp);
@@ -1291,7 +1314,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
1291 if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN)) 1314 if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN))
1292 memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN); 1315 memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN);
1293 else 1316 else
1294 memcpy(eh->h_source, fcoe->ctlr.data_src_addr, ETH_ALEN); 1317 memcpy(eh->h_source, port->data_src_addr, ETH_ALEN);
1295 1318
1296 hp = (struct fcoe_hdr *)(eh + 1); 1319 hp = (struct fcoe_hdr *)(eh + 1);
1297 memset(hp, 0, sizeof(*hp)); 1320 memset(hp, 0, sizeof(*hp));
@@ -1464,11 +1487,6 @@ int fcoe_percpu_receive_thread(void *arg)
1464 } 1487 }
1465 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; 1488 fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
1466 } 1489 }
1467 if (unlikely(port->fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
1468 fcoe_ctlr_recv_flogi(&port->fcoe->ctlr, fp, mac)) {
1469 fc_frame_free(fp);
1470 continue;
1471 }
1472 fc_exch_recv(lp, fp); 1490 fc_exch_recv(lp, fp);
1473 } 1491 }
1474 return 0; 1492 return 0;
@@ -2061,3 +2079,94 @@ static void __exit fcoe_exit(void)
2061 fcoe_if_exit(); 2079 fcoe_if_exit();
2062} 2080}
2063module_exit(fcoe_exit); 2081module_exit(fcoe_exit);
2082
2083/**
2084 * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler
2085 * @seq: active sequence in the FLOGI or FDISC exchange
2086 * @fp: response frame, or error encoded in a pointer (timeout)
2087 * @arg: pointer the the fcoe_ctlr structure
2088 *
2089 * This handles MAC address managment for FCoE, then passes control on to
2090 * the libfc FLOGI response handler.
2091 */
2092static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
2093{
2094 struct fcoe_ctlr *fip = arg;
2095 struct fc_exch *exch = fc_seq_exch(seq);
2096 struct fc_lport *lport = exch->lp;
2097 u8 *mac;
2098
2099 if (IS_ERR(fp))
2100 goto done;
2101
2102 mac = fr_cb(fp)->granted_mac;
2103 if (is_zero_ether_addr(mac)) {
2104 /* pre-FIP */
2105 mac = eth_hdr(&fp->skb)->h_source;
2106 if (fcoe_ctlr_recv_flogi(fip, lport, fp, mac)) {
2107 fc_frame_free(fp);
2108 return;
2109 }
2110 } else {
2111 /* FIP, libfcoe has already seen it */
2112 fip->update_mac(lport, fr_cb(fp)->granted_mac);
2113 }
2114done:
2115 fc_lport_flogi_resp(seq, fp, lport);
2116}
2117
2118/**
2119 * fcoe_logo_resp() - FCoE specific LOGO response handler
2120 * @seq: active sequence in the LOGO exchange
2121 * @fp: response frame, or error encoded in a pointer (timeout)
2122 * @arg: pointer the the fcoe_ctlr structure
2123 *
2124 * This handles MAC address managment for FCoE, then passes control on to
2125 * the libfc LOGO response handler.
2126 */
2127static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
2128{
2129 struct fcoe_ctlr *fip = arg;
2130 struct fc_exch *exch = fc_seq_exch(seq);
2131 struct fc_lport *lport = exch->lp;
2132 static u8 zero_mac[ETH_ALEN] = { 0 };
2133
2134 if (!IS_ERR(fp))
2135 fip->update_mac(lport, zero_mac);
2136 fc_lport_logo_resp(seq, fp, lport);
2137}
2138
2139/**
2140 * fcoe_elsct_send - FCoE specific ELS handler
2141 *
2142 * This does special case handling of FIP encapsualted ELS exchanges for FCoE,
2143 * using FCoE specific response handlers and passing the FIP controller as
2144 * the argument (the lport is still available from the exchange).
2145 *
2146 * Most of the work here is just handed off to the libfc routine.
2147 */
2148static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport,
2149 u32 did, struct fc_frame *fp, unsigned int op,
2150 void (*resp)(struct fc_seq *, struct fc_frame *, void *),
2151 void *arg, u32 timeout)
2152{
2153 struct fcoe_port *port = lport_priv(lport);
2154 struct fcoe_interface *fcoe = port->fcoe;
2155 struct fcoe_ctlr *fip = &fcoe->ctlr;
2156 struct fc_frame_header *fh = fc_frame_header_get(fp);
2157
2158 switch (op) {
2159 case ELS_FLOGI:
2160 case ELS_FDISC:
2161 return fc_elsct_send(lport, did, fp, op, fcoe_flogi_resp,
2162 fip, timeout);
2163 case ELS_LOGO:
2164 /* only hook onto fabric logouts, not port logouts */
2165 if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
2166 break;
2167 return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp,
2168 fip, timeout);
2169 }
2170 return fc_elsct_send(lport, did, fp, op, resp, arg, timeout);
2171}
2172
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index a123552847e5..99dfa7c2aeaa 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -104,6 +104,7 @@ struct fcoe_port {
104 u8 fcoe_pending_queue_active; 104 u8 fcoe_pending_queue_active;
105 struct timer_list timer; /* queue timer */ 105 struct timer_list timer; /* queue timer */
106 struct work_struct destroy_work; /* to prevent rtnl deadlocks */ 106 struct work_struct destroy_work; /* to prevent rtnl deadlocks */
107 u8 data_src_addr[ETH_ALEN];
107}; 108};
108 109
109#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) 110#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index d8ea04a29199..6a93ba96569f 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -322,6 +322,7 @@ EXPORT_SYMBOL(fcoe_ctlr_link_down);
322/** 322/**
323 * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF. 323 * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
324 * @fip: FCoE controller. 324 * @fip: FCoE controller.
325 * @lport: libfc fc_lport to send from
325 * @ports: 0 for controller keep-alive, 1 for port keep-alive. 326 * @ports: 0 for controller keep-alive, 1 for port keep-alive.
326 * @sa: source MAC address. 327 * @sa: source MAC address.
327 * 328 *
@@ -332,7 +333,9 @@ EXPORT_SYMBOL(fcoe_ctlr_link_down);
332 * The source MAC is the assigned mapped source address. 333 * The source MAC is the assigned mapped source address.
333 * The destination is the FCF's F-port. 334 * The destination is the FCF's F-port.
334 */ 335 */
335static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) 336static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
337 struct fc_lport *lport,
338 int ports, u8 *sa)
336{ 339{
337 struct sk_buff *skb; 340 struct sk_buff *skb;
338 struct fip_kal { 341 struct fip_kal {
@@ -374,16 +377,14 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
374 kal->mac.fd_desc.fip_dtype = FIP_DT_MAC; 377 kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
375 kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW; 378 kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
376 memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN); 379 memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
377
378 if (ports) { 380 if (ports) {
379 vn = (struct fip_vn_desc *)(kal + 1); 381 vn = (struct fip_vn_desc *)(kal + 1);
380 vn->fd_desc.fip_dtype = FIP_DT_VN_ID; 382 vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
381 vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW; 383 vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
382 memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN); 384 memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
383 hton24(vn->fd_fc_id, fc_host_port_id(lp->host)); 385 hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
384 put_unaligned_be64(lp->wwpn, &vn->fd_wwpn); 386 put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
385 } 387 }
386
387 skb_put(skb, len); 388 skb_put(skb, len);
388 skb->protocol = htons(ETH_P_FIP); 389 skb->protocol = htons(ETH_P_FIP);
389 skb_reset_mac_header(skb); 390 skb_reset_mac_header(skb);
@@ -394,6 +395,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
394/** 395/**
395 * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it. 396 * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
396 * @fip: FCoE controller. 397 * @fip: FCoE controller.
398 * @lport: libfc fc_lport to use for the source address
397 * @dtype: FIP descriptor type for the frame. 399 * @dtype: FIP descriptor type for the frame.
398 * @skb: FCoE ELS frame including FC header but no FCoE headers. 400 * @skb: FCoE ELS frame including FC header but no FCoE headers.
399 * 401 *
@@ -405,7 +407,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
405 * Headroom includes the FIP encapsulation description, FIP header, and 407 * Headroom includes the FIP encapsulation description, FIP header, and
406 * Ethernet header. The tailroom is for the FIP MAC descriptor. 408 * Ethernet header. The tailroom is for the FIP MAC descriptor.
407 */ 409 */
408static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, 410static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
409 u8 dtype, struct sk_buff *skb) 411 u8 dtype, struct sk_buff *skb)
410{ 412{
411 struct fip_encaps_head { 413 struct fip_encaps_head {
@@ -450,7 +452,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
450 mac->fd_desc.fip_dtype = FIP_DT_MAC; 452 mac->fd_desc.fip_dtype = FIP_DT_MAC;
451 mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; 453 mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
452 if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) 454 if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC)
453 memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN); 455 memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
454 else if (fip->spma) 456 else if (fip->spma)
455 memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN); 457 memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
456 458
@@ -463,6 +465,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
463/** 465/**
464 * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate. 466 * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
465 * @fip: FCoE controller. 467 * @fip: FCoE controller.
468 * @lport: libfc fc_lport to send from
466 * @skb: FCoE ELS frame including FC header but no FCoE headers. 469 * @skb: FCoE ELS frame including FC header but no FCoE headers.
467 * 470 *
468 * Returns a non-zero error code if the frame should not be sent. 471 * Returns a non-zero error code if the frame should not be sent.
@@ -471,11 +474,13 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
471 * The caller must check that the length is a multiple of 4. 474 * The caller must check that the length is a multiple of 4.
472 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). 475 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
473 */ 476 */
474int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb) 477int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
478 struct sk_buff *skb)
475{ 479{
476 struct fc_frame_header *fh; 480 struct fc_frame_header *fh;
477 u16 old_xid; 481 u16 old_xid;
478 u8 op; 482 u8 op;
483 u8 mac[ETH_ALEN];
479 484
480 fh = (struct fc_frame_header *)skb->data; 485 fh = (struct fc_frame_header *)skb->data;
481 op = *(u8 *)(fh + 1); 486 op = *(u8 *)(fh + 1);
@@ -530,14 +535,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
530 * FLOGI. 535 * FLOGI.
531 */ 536 */
532 fip->flogi_oxid = FC_XID_UNKNOWN; 537 fip->flogi_oxid = FC_XID_UNKNOWN;
533 fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id); 538 fc_fcoe_set_mac(mac, fh->fh_d_id);
539 fip->update_mac(lport, mac);
534 return 0; 540 return 0;
535 default: 541 default:
536 if (fip->state != FIP_ST_ENABLED) 542 if (fip->state != FIP_ST_ENABLED)
537 goto drop; 543 goto drop;
538 return 0; 544 return 0;
539 } 545 }
540 if (fcoe_ctlr_encaps(fip, op, skb)) 546 if (fcoe_ctlr_encaps(fip, lport, op, skb))
541 goto drop; 547 goto drop;
542 fip->send(fip, skb); 548 fip->send(fip, skb);
543 return -EINPROGRESS; 549 return -EINPROGRESS;
@@ -796,7 +802,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
796{ 802{
797 struct fc_lport *lp = fip->lp; 803 struct fc_lport *lp = fip->lp;
798 struct fip_header *fiph; 804 struct fip_header *fiph;
799 struct fc_frame *fp; 805 struct fc_frame *fp = (struct fc_frame *)skb;
800 struct fc_frame_header *fh = NULL; 806 struct fc_frame_header *fh = NULL;
801 struct fip_desc *desc; 807 struct fip_desc *desc;
802 struct fip_encaps *els; 808 struct fip_encaps *els;
@@ -835,6 +841,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
835 "in FIP ELS\n"); 841 "in FIP ELS\n");
836 goto drop; 842 goto drop;
837 } 843 }
844 memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
838 break; 845 break;
839 case FIP_DT_FLOGI: 846 case FIP_DT_FLOGI:
840 case FIP_DT_FDISC: 847 case FIP_DT_FDISC:
@@ -865,13 +872,10 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
865 goto drop; 872 goto drop;
866 els_op = *(u8 *)(fh + 1); 873 els_op = *(u8 *)(fh + 1);
867 874
868 if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) && 875 if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
869 sub == FIP_SC_REP && fip->flogi_oxid == ntohs(fh->fh_ox_id) && 876 fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
870 els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) { 877 els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac))
871 fip->flogi_oxid = FC_XID_UNKNOWN; 878 fip->flogi_oxid = FC_XID_UNKNOWN;
872 fip->update_mac(fip, fip->data_src_addr, granted_mac);
873 memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
874 }
875 879
876 /* 880 /*
877 * Convert skb into an fc_frame containing only the ELS. 881 * Convert skb into an fc_frame containing only the ELS.
@@ -958,7 +962,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
958 if (dlen < sizeof(*vp)) 962 if (dlen < sizeof(*vp))
959 return; 963 return;
960 if (compare_ether_addr(vp->fd_mac, 964 if (compare_ether_addr(vp->fd_mac,
961 fip->data_src_addr) == 0 && 965 fip->get_src_addr(lp)) == 0 &&
962 get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn && 966 get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
963 ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host)) 967 ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
964 desc_mask &= ~BIT(FIP_DT_VN_ID); 968 desc_mask &= ~BIT(FIP_DT_VN_ID);
@@ -1113,8 +1117,6 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1113 struct fcoe_fcf *sel; 1117 struct fcoe_fcf *sel;
1114 struct fcoe_fcf *fcf; 1118 struct fcoe_fcf *fcf;
1115 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); 1119 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
1116 u8 send_ctlr_ka;
1117 u8 send_port_ka;
1118 1120
1119 spin_lock_bh(&fip->lock); 1121 spin_lock_bh(&fip->lock);
1120 if (fip->state == FIP_ST_DISABLED) { 1122 if (fip->state == FIP_ST_DISABLED) {
@@ -1153,12 +1155,10 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1153 schedule_work(&fip->link_work); 1155 schedule_work(&fip->link_work);
1154 } 1156 }
1155 1157
1156 send_ctlr_ka = 0;
1157 send_port_ka = 0;
1158 if (sel) { 1158 if (sel) {
1159 if (time_after_eq(jiffies, fip->ctlr_ka_time)) { 1159 if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
1160 fip->ctlr_ka_time = jiffies + sel->fka_period; 1160 fip->ctlr_ka_time = jiffies + sel->fka_period;
1161 send_ctlr_ka = 1; 1161 fip->send_ctlr_ka = 1;
1162 } 1162 }
1163 if (time_after(next_timer, fip->ctlr_ka_time)) 1163 if (time_after(next_timer, fip->ctlr_ka_time))
1164 next_timer = fip->ctlr_ka_time; 1164 next_timer = fip->ctlr_ka_time;
@@ -1166,7 +1166,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1166 if (time_after_eq(jiffies, fip->port_ka_time)) { 1166 if (time_after_eq(jiffies, fip->port_ka_time)) {
1167 fip->port_ka_time += jiffies + 1167 fip->port_ka_time += jiffies +
1168 msecs_to_jiffies(FIP_VN_KA_PERIOD); 1168 msecs_to_jiffies(FIP_VN_KA_PERIOD);
1169 send_port_ka = 1; 1169 fip->send_port_ka = 1;
1170 } 1170 }
1171 if (time_after(next_timer, fip->port_ka_time)) 1171 if (time_after(next_timer, fip->port_ka_time))
1172 next_timer = fip->port_ka_time; 1172 next_timer = fip->port_ka_time;
@@ -1176,12 +1176,9 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1176 msecs_to_jiffies(FCOE_CTLR_START_DELAY); 1176 msecs_to_jiffies(FCOE_CTLR_START_DELAY);
1177 mod_timer(&fip->timer, next_timer); 1177 mod_timer(&fip->timer, next_timer);
1178 } 1178 }
1179 if (fip->send_ctlr_ka || fip->send_port_ka)
1180 schedule_work(&fip->link_work);
1179 spin_unlock_bh(&fip->lock); 1181 spin_unlock_bh(&fip->lock);
1180
1181 if (send_ctlr_ka)
1182 fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
1183 if (send_port_ka)
1184 fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
1185} 1182}
1186 1183
1187/** 1184/**
@@ -1196,6 +1193,8 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1196static void fcoe_ctlr_link_work(struct work_struct *work) 1193static void fcoe_ctlr_link_work(struct work_struct *work)
1197{ 1194{
1198 struct fcoe_ctlr *fip; 1195 struct fcoe_ctlr *fip;
1196 struct fc_lport *vport;
1197 u8 *mac;
1199 int link; 1198 int link;
1200 int last_link; 1199 int last_link;
1201 1200
@@ -1212,6 +1211,22 @@ static void fcoe_ctlr_link_work(struct work_struct *work)
1212 else 1211 else
1213 fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT); 1212 fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
1214 } 1213 }
1214
1215 if (fip->send_ctlr_ka) {
1216 fip->send_ctlr_ka = 0;
1217 fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr);
1218 }
1219 if (fip->send_port_ka) {
1220 fip->send_port_ka = 0;
1221 mutex_lock(&fip->lp->lp_mutex);
1222 mac = fip->get_src_addr(fip->lp);
1223 fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac);
1224 list_for_each_entry(vport, &fip->lp->vports, list) {
1225 mac = fip->get_src_addr(vport);
1226 fcoe_ctlr_send_keep_alive(fip, vport, 1, mac);
1227 }
1228 mutex_unlock(&fip->lp->lp_mutex);
1229 }
1215} 1230}
1216 1231
1217/** 1232/**
@@ -1236,6 +1251,7 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
1236/** 1251/**
1237 * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request. 1252 * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
1238 * @fip: FCoE controller. 1253 * @fip: FCoE controller.
1254 * @lport: libfc fc_lport instance received on
1239 * @fp: FC frame. 1255 * @fp: FC frame.
1240 * @sa: Ethernet source MAC address from received FCoE frame. 1256 * @sa: Ethernet source MAC address from received FCoE frame.
1241 * 1257 *
@@ -1248,7 +1264,8 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
1248 * 1264 *
1249 * Return non-zero if the frame should not be delivered to libfc. 1265 * Return non-zero if the frame should not be delivered to libfc.
1250 */ 1266 */
1251int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) 1267int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
1268 struct fc_frame *fp, u8 *sa)
1252{ 1269{
1253 struct fc_frame_header *fh; 1270 struct fc_frame_header *fh;
1254 u8 op; 1271 u8 op;
@@ -1283,11 +1300,9 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
1283 fip->map_dest = 0; 1300 fip->map_dest = 0;
1284 } 1301 }
1285 fip->flogi_oxid = FC_XID_UNKNOWN; 1302 fip->flogi_oxid = FC_XID_UNKNOWN;
1286 memcpy(mac, fip->data_src_addr, ETH_ALEN); 1303 fc_fcoe_set_mac(mac, fh->fh_d_id);
1287 fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id); 1304 fip->update_mac(lport, mac);
1288 spin_unlock_bh(&fip->lock); 1305 spin_unlock_bh(&fip->lock);
1289
1290 fip->update_mac(fip, mac, fip->data_src_addr);
1291 } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { 1306 } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
1292 /* 1307 /*
1293 * Save source MAC for point-to-point responses. 1308 * Save source MAC for point-to-point responses.
@@ -1370,3 +1385,4 @@ int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
1370 return 0; 1385 return 0;
1371} 1386}
1372EXPORT_SYMBOL_GPL(fcoe_libfc_config); 1387EXPORT_SYMBOL_GPL(fcoe_libfc_config);
1388