aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/libfcoe.c
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/libfcoe.c
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/libfcoe.c')
-rw-r--r--drivers/scsi/fcoe/libfcoe.c82
1 files changed, 49 insertions, 33 deletions
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