aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/fcoe/fcoe.c147
-rw-r--r--drivers/scsi/fcoe/fcoe.h1
-rw-r--r--drivers/scsi/fcoe/libfcoe.c82
-rw-r--r--drivers/scsi/libfc/fc_elsct.c3
-rw-r--r--drivers/scsi/libfc/fc_lport.c6
-rw-r--r--include/scsi/fc_frame.h3
-rw-r--r--include/scsi/libfc.h10
-rw-r--r--include/scsi/libfcoe.h15
8 files changed, 207 insertions, 60 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
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index 92984587ff4d..aae54fe3b299 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -31,7 +31,7 @@
31/* 31/*
32 * fc_elsct_send - sends ELS/CT frame 32 * fc_elsct_send - sends ELS/CT frame
33 */ 33 */
34static struct fc_seq *fc_elsct_send(struct fc_lport *lport, 34struct fc_seq *fc_elsct_send(struct fc_lport *lport,
35 u32 did, 35 u32 did,
36 struct fc_frame *fp, 36 struct fc_frame *fp,
37 unsigned int op, 37 unsigned int op,
@@ -63,6 +63,7 @@ static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
63 63
64 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); 64 return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
65} 65}
66EXPORT_SYMBOL(fc_elsct_send);
66 67
67int fc_elsct_init(struct fc_lport *lport) 68int fc_elsct_init(struct fc_lport *lport)
68{ 69{
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index ccba67ca68a1..807f5b3e4efe 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1320,7 +1320,7 @@ static void fc_lport_timeout(struct work_struct *work)
1320 * held, but it will lock, call an _enter_* function or fc_lport_error 1320 * held, but it will lock, call an _enter_* function or fc_lport_error
1321 * and then unlock the lport. 1321 * and then unlock the lport.
1322 */ 1322 */
1323static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, 1323void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1324 void *lp_arg) 1324 void *lp_arg)
1325{ 1325{
1326 struct fc_lport *lport = lp_arg; 1326 struct fc_lport *lport = lp_arg;
@@ -1357,6 +1357,7 @@ out:
1357err: 1357err:
1358 mutex_unlock(&lport->lp_mutex); 1358 mutex_unlock(&lport->lp_mutex);
1359} 1359}
1360EXPORT_SYMBOL(fc_lport_logo_resp);
1360 1361
1361/** 1362/**
1362 * fc_rport_enter_logo() - Logout of the fabric 1363 * fc_rport_enter_logo() - Logout of the fabric
@@ -1397,7 +1398,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
1397 * held, but it will lock, call an _enter_* function or fc_lport_error 1398 * held, but it will lock, call an _enter_* function or fc_lport_error
1398 * and then unlock the lport. 1399 * and then unlock the lport.
1399 */ 1400 */
1400static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, 1401void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
1401 void *lp_arg) 1402 void *lp_arg)
1402{ 1403{
1403 struct fc_lport *lport = lp_arg; 1404 struct fc_lport *lport = lp_arg;
@@ -1480,6 +1481,7 @@ out:
1480err: 1481err:
1481 mutex_unlock(&lport->lp_mutex); 1482 mutex_unlock(&lport->lp_mutex);
1482} 1483}
1484EXPORT_SYMBOL(fc_lport_flogi_resp);
1483 1485
1484/** 1486/**
1485 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager 1487 * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 148126dcf9e9..ab2f8d41761b 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -28,6 +28,8 @@
28#include <scsi/fc/fc_fcp.h> 28#include <scsi/fc/fc_fcp.h>
29#include <scsi/fc/fc_encaps.h> 29#include <scsi/fc/fc_encaps.h>
30 30
31#include <linux/if_ether.h>
32
31/* 33/*
32 * The fc_frame interface is used to pass frame data between functions. 34 * The fc_frame interface is used to pass frame data between functions.
33 * The frame includes the data buffer, length, and SOF / EOF delimiter types. 35 * The frame includes the data buffer, length, and SOF / EOF delimiter types.
@@ -67,6 +69,7 @@ struct fcoe_rcv_info {
67 enum fc_sof fr_sof; /* start of frame delimiter */ 69 enum fc_sof fr_sof; /* start of frame delimiter */
68 enum fc_eof fr_eof; /* end of frame delimiter */ 70 enum fc_eof fr_eof; /* end of frame delimiter */
69 u8 fr_flags; /* flags - see below */ 71 u8 fr_flags; /* flags - see below */
72 u8 granted_mac[ETH_ALEN]; /* FCoE MAC address */
70}; 73};
71 74
72 75
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index dfeb1ee4f03f..dad66ce8673d 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -900,6 +900,16 @@ void fc_fcp_destroy(struct fc_lport *);
900 * Initializes ELS/CT interface 900 * Initializes ELS/CT interface
901 */ 901 */
902int fc_elsct_init(struct fc_lport *lp); 902int fc_elsct_init(struct fc_lport *lp);
903struct fc_seq *fc_elsct_send(struct fc_lport *lport,
904 u32 did,
905 struct fc_frame *fp,
906 unsigned int op,
907 void (*resp)(struct fc_seq *,
908 struct fc_frame *fp,
909 void *arg),
910 void *arg, u32 timer_msec);
911void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *);
912void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *);
903 913
904 914
905/* 915/*
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index b2410605b740..8ef5e209c216 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -74,11 +74,13 @@ enum fip_state {
74 * @last_link: last link state reported to libfc. 74 * @last_link: last link state reported to libfc.
75 * @map_dest: use the FC_MAP mode for destination MAC addresses. 75 * @map_dest: use the FC_MAP mode for destination MAC addresses.
76 * @spma: supports SPMA server-provided MACs mode 76 * @spma: supports SPMA server-provided MACs mode
77 * @send_ctlr_ka: need to send controller keep alive
78 * @send_port_ka: need to send port keep alives
77 * @dest_addr: MAC address of the selected FC forwarder. 79 * @dest_addr: MAC address of the selected FC forwarder.
78 * @ctl_src_addr: the native MAC address of our local port. 80 * @ctl_src_addr: the native MAC address of our local port.
79 * @data_src_addr: the assigned MAC address for the local port after FLOGI.
80 * @send: LLD-supplied function to handle sending of FIP Ethernet frames. 81 * @send: LLD-supplied function to handle sending of FIP Ethernet frames.
81 * @update_mac: LLD-supplied function to handle changes to MAC addresses. 82 * @update_mac: LLD-supplied function to handle changes to MAC addresses.
83 * @get_src_addr: LLD-supplied function to supply a source MAC address.
82 * @lock: lock protecting this structure. 84 * @lock: lock protecting this structure.
83 * 85 *
84 * This structure is used by all FCoE drivers. It contains information 86 * This structure is used by all FCoE drivers. It contains information
@@ -106,12 +108,14 @@ struct fcoe_ctlr {
106 u8 last_link; 108 u8 last_link;
107 u8 map_dest; 109 u8 map_dest;
108 u8 spma; 110 u8 spma;
111 u8 send_ctlr_ka;
112 u8 send_port_ka;
109 u8 dest_addr[ETH_ALEN]; 113 u8 dest_addr[ETH_ALEN];
110 u8 ctl_src_addr[ETH_ALEN]; 114 u8 ctl_src_addr[ETH_ALEN];
111 u8 data_src_addr[ETH_ALEN];
112 115
113 void (*send)(struct fcoe_ctlr *, struct sk_buff *); 116 void (*send)(struct fcoe_ctlr *, struct sk_buff *);
114 void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new); 117 void (*update_mac)(struct fc_lport *, u8 *addr);
118 u8 * (*get_src_addr)(struct fc_lport *);
115 spinlock_t lock; 119 spinlock_t lock;
116}; 120};
117 121
@@ -155,9 +159,10 @@ void fcoe_ctlr_init(struct fcoe_ctlr *);
155void fcoe_ctlr_destroy(struct fcoe_ctlr *); 159void fcoe_ctlr_destroy(struct fcoe_ctlr *);
156void fcoe_ctlr_link_up(struct fcoe_ctlr *); 160void fcoe_ctlr_link_up(struct fcoe_ctlr *);
157int fcoe_ctlr_link_down(struct fcoe_ctlr *); 161int fcoe_ctlr_link_down(struct fcoe_ctlr *);
158int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *); 162int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct fc_lport *, struct sk_buff *);
159void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *); 163void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *);
160int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa); 164int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *lport,
165 struct fc_frame *fp, u8 *sa);
161 166
162/* libfcoe funcs */ 167/* libfcoe funcs */
163u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); 168u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int);