aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/libfcoe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe/libfcoe.c')
-rw-r--r--drivers/scsi/fcoe/libfcoe.c111
1 files changed, 53 insertions, 58 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 3440da48d169..50aaa4bcfc50 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -51,7 +51,7 @@ MODULE_LICENSE("GPL v2");
51#define FCOE_CTLR_DEF_FKA FIP_DEF_FKA /* default keep alive (mS) */ 51#define FCOE_CTLR_DEF_FKA FIP_DEF_FKA /* default keep alive (mS) */
52 52
53static void fcoe_ctlr_timeout(unsigned long); 53static void fcoe_ctlr_timeout(unsigned long);
54static void fcoe_ctlr_link_work(struct work_struct *); 54static void fcoe_ctlr_timer_work(struct work_struct *);
55static void fcoe_ctlr_recv_work(struct work_struct *); 55static void fcoe_ctlr_recv_work(struct work_struct *);
56 56
57static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS; 57static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;
@@ -116,7 +116,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip)
116 spin_lock_init(&fip->lock); 116 spin_lock_init(&fip->lock);
117 fip->flogi_oxid = FC_XID_UNKNOWN; 117 fip->flogi_oxid = FC_XID_UNKNOWN;
118 setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); 118 setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
119 INIT_WORK(&fip->link_work, fcoe_ctlr_link_work); 119 INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work);
120 INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work); 120 INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work);
121 skb_queue_head_init(&fip->fip_recv_list); 121 skb_queue_head_init(&fip->fip_recv_list);
122} 122}
@@ -164,7 +164,7 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
164 fcoe_ctlr_reset_fcfs(fip); 164 fcoe_ctlr_reset_fcfs(fip);
165 spin_unlock_bh(&fip->lock); 165 spin_unlock_bh(&fip->lock);
166 del_timer_sync(&fip->timer); 166 del_timer_sync(&fip->timer);
167 cancel_work_sync(&fip->link_work); 167 cancel_work_sync(&fip->timer_work);
168} 168}
169EXPORT_SYMBOL(fcoe_ctlr_destroy); 169EXPORT_SYMBOL(fcoe_ctlr_destroy);
170 170
@@ -257,14 +257,10 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
257{ 257{
258 spin_lock_bh(&fip->lock); 258 spin_lock_bh(&fip->lock);
259 if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) { 259 if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) {
260 fip->last_link = 1;
261 fip->link = 1;
262 spin_unlock_bh(&fip->lock); 260 spin_unlock_bh(&fip->lock);
263 fc_linkup(fip->lp); 261 fc_linkup(fip->lp);
264 } else if (fip->state == FIP_ST_LINK_WAIT) { 262 } else if (fip->state == FIP_ST_LINK_WAIT) {
265 fip->state = fip->mode; 263 fip->state = fip->mode;
266 fip->last_link = 1;
267 fip->link = 1;
268 spin_unlock_bh(&fip->lock); 264 spin_unlock_bh(&fip->lock);
269 if (fip->state == FIP_ST_AUTO) 265 if (fip->state == FIP_ST_AUTO)
270 LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n"); 266 LIBFCOE_FIP_DBG(fip, "%s", "setting AUTO mode.\n");
@@ -306,9 +302,7 @@ int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
306 LIBFCOE_FIP_DBG(fip, "link down.\n"); 302 LIBFCOE_FIP_DBG(fip, "link down.\n");
307 spin_lock_bh(&fip->lock); 303 spin_lock_bh(&fip->lock);
308 fcoe_ctlr_reset(fip); 304 fcoe_ctlr_reset(fip);
309 link_dropped = fip->link; 305 link_dropped = fip->state != FIP_ST_LINK_WAIT;
310 fip->link = 0;
311 fip->last_link = 0;
312 fip->state = FIP_ST_LINK_WAIT; 306 fip->state = FIP_ST_LINK_WAIT;
313 spin_unlock_bh(&fip->lock); 307 spin_unlock_bh(&fip->lock);
314 308
@@ -349,7 +343,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
349 343
350 fcf = fip->sel_fcf; 344 fcf = fip->sel_fcf;
351 lp = fip->lp; 345 lp = fip->lp;
352 if (!fcf || !fc_host_port_id(lp->host)) 346 if (!fcf || !lp->port_id)
353 return; 347 return;
354 348
355 len = sizeof(*kal) + ports * sizeof(*vn); 349 len = sizeof(*kal) + ports * sizeof(*vn);
@@ -380,8 +374,8 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip,
380 vn->fd_desc.fip_dtype = FIP_DT_VN_ID; 374 vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
381 vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW; 375 vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
382 memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN); 376 memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
383 hton24(vn->fd_fc_id, fc_host_port_id(lp->host)); 377 hton24(vn->fd_fc_id, lport->port_id);
384 put_unaligned_be64(lp->wwpn, &vn->fd_wwpn); 378 put_unaligned_be64(lport->wwpn, &vn->fd_wwpn);
385 } 379 }
386 skb_put(skb, len); 380 skb_put(skb, len);
387 skb->protocol = htons(ETH_P_FIP); 381 skb->protocol = htons(ETH_P_FIP);
@@ -445,13 +439,18 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
445 cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW; 439 cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
446 440
447 mac = (struct fip_mac_desc *)skb_put(skb, sizeof(*mac)); 441 mac = (struct fip_mac_desc *)skb_put(skb, sizeof(*mac));
448 memset(mac, 0, sizeof(mac)); 442 memset(mac, 0, sizeof(*mac));
449 mac->fd_desc.fip_dtype = FIP_DT_MAC; 443 mac->fd_desc.fip_dtype = FIP_DT_MAC;
450 mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; 444 mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
451 if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) 445 if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) {
452 memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN); 446 memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN);
453 else if (fip->spma) 447 } else if (fip_flags & FIP_FL_SPMA) {
448 LIBFCOE_FIP_DBG(fip, "FLOGI/FDISC sent with SPMA\n");
454 memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN); 449 memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
450 } else {
451 LIBFCOE_FIP_DBG(fip, "FLOGI/FDISC sent with FPMA\n");
452 /* FPMA only FLOGI must leave the MAC desc set to all 0s */
453 }
455 454
456 skb->protocol = htons(ETH_P_FIP); 455 skb->protocol = htons(ETH_P_FIP);
457 skb_reset_mac_header(skb); 456 skb_reset_mac_header(skb);
@@ -556,7 +555,7 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send);
556 * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller 555 * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller
557 * @fip: The FCoE controller to free FCFs on 556 * @fip: The FCoE controller to free FCFs on
558 * 557 *
559 * Called with lock held. 558 * Called with lock held and preemption disabled.
560 * 559 *
561 * An FCF is considered old if we have missed three advertisements. 560 * An FCF is considered old if we have missed three advertisements.
562 * That is, there have been no valid advertisement from it for three 561 * That is, there have been no valid advertisement from it for three
@@ -573,17 +572,20 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
573 struct fcoe_fcf *next; 572 struct fcoe_fcf *next;
574 unsigned long sel_time = 0; 573 unsigned long sel_time = 0;
575 unsigned long mda_time = 0; 574 unsigned long mda_time = 0;
575 struct fcoe_dev_stats *stats;
576 576
577 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { 577 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
578 mda_time = fcf->fka_period + (fcf->fka_period >> 1); 578 mda_time = fcf->fka_period + (fcf->fka_period >> 1);
579 if ((fip->sel_fcf == fcf) && 579 if ((fip->sel_fcf == fcf) &&
580 (time_after(jiffies, fcf->time + mda_time))) { 580 (time_after(jiffies, fcf->time + mda_time))) {
581 mod_timer(&fip->timer, jiffies + mda_time); 581 mod_timer(&fip->timer, jiffies + mda_time);
582 fc_lport_get_stats(fip->lp)->MissDiscAdvCount++; 582 stats = per_cpu_ptr(fip->lp->dev_stats,
583 smp_processor_id());
584 stats->MissDiscAdvCount++;
583 printk(KERN_INFO "libfcoe: host%d: Missing Discovery " 585 printk(KERN_INFO "libfcoe: host%d: Missing Discovery "
584 "Advertisement for fab %llx count %lld\n", 586 "Advertisement for fab %16.16llx count %lld\n",
585 fip->lp->host->host_no, fcf->fabric_name, 587 fip->lp->host->host_no, fcf->fabric_name,
586 fc_lport_get_stats(fip->lp)->MissDiscAdvCount); 588 stats->MissDiscAdvCount);
587 } 589 }
588 if (time_after(jiffies, fcf->time + fcf->fka_period * 3 + 590 if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
589 msecs_to_jiffies(FIP_FCF_FUZZ * 3))) { 591 msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
@@ -593,7 +595,9 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
593 WARN_ON(!fip->fcf_count); 595 WARN_ON(!fip->fcf_count);
594 fip->fcf_count--; 596 fip->fcf_count--;
595 kfree(fcf); 597 kfree(fcf);
596 fc_lport_get_stats(fip->lp)->VLinkFailureCount++; 598 stats = per_cpu_ptr(fip->lp->dev_stats,
599 smp_processor_id());
600 stats->VLinkFailureCount++;
597 } else if (fcoe_ctlr_mtu_valid(fcf) && 601 } else if (fcoe_ctlr_mtu_valid(fcf) &&
598 (!sel_time || time_before(sel_time, fcf->time))) { 602 (!sel_time || time_before(sel_time, fcf->time))) {
599 sel_time = fcf->time; 603 sel_time = fcf->time;
@@ -776,7 +780,8 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
776 mtu_valid = fcoe_ctlr_mtu_valid(fcf); 780 mtu_valid = fcoe_ctlr_mtu_valid(fcf);
777 fcf->time = jiffies; 781 fcf->time = jiffies;
778 if (!found) { 782 if (!found) {
779 LIBFCOE_FIP_DBG(fip, "New FCF for fab %llx map %x val %d\n", 783 LIBFCOE_FIP_DBG(fip, "New FCF for fab %16.16llx "
784 "map %x val %d\n",
780 fcf->fabric_name, fcf->fc_map, mtu_valid); 785 fcf->fabric_name, fcf->fc_map, mtu_valid);
781 } 786 }
782 787
@@ -906,9 +911,10 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
906 fr_eof(fp) = FC_EOF_T; 911 fr_eof(fp) = FC_EOF_T;
907 fr_dev(fp) = lport; 912 fr_dev(fp) = lport;
908 913
909 stats = fc_lport_get_stats(lport); 914 stats = per_cpu_ptr(lport->dev_stats, get_cpu());
910 stats->RxFrames++; 915 stats->RxFrames++;
911 stats->RxWords += skb->len / FIP_BPW; 916 stats->RxWords += skb->len / FIP_BPW;
917 put_cpu();
912 918
913 fc_exch_recv(lport, fp); 919 fc_exch_recv(lport, fp);
914 return; 920 return;
@@ -942,9 +948,8 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
942 u32 desc_mask; 948 u32 desc_mask;
943 949
944 LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); 950 LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
945 if (!fcf) 951
946 return; 952 if (!fcf || !lport->port_id)
947 if (!fcf || !fc_host_port_id(lport->host))
948 return; 953 return;
949 954
950 /* 955 /*
@@ -982,8 +987,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
982 if (compare_ether_addr(vp->fd_mac, 987 if (compare_ether_addr(vp->fd_mac,
983 fip->get_src_addr(lport)) == 0 && 988 fip->get_src_addr(lport)) == 0 &&
984 get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn && 989 get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn &&
985 ntoh24(vp->fd_fc_id) == 990 ntoh24(vp->fd_fc_id) == lport->port_id)
986 fc_host_port_id(lport->host))
987 desc_mask &= ~BIT(FIP_DT_VN_ID); 991 desc_mask &= ~BIT(FIP_DT_VN_ID);
988 break; 992 break;
989 default: 993 default:
@@ -1006,7 +1010,8 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
1006 LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); 1010 LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
1007 1011
1008 spin_lock_bh(&fip->lock); 1012 spin_lock_bh(&fip->lock);
1009 fc_lport_get_stats(lport)->VLinkFailureCount++; 1013 per_cpu_ptr(lport->dev_stats,
1014 smp_processor_id())->VLinkFailureCount++;
1010 fcoe_ctlr_reset(fip); 1015 fcoe_ctlr_reset(fip);
1011 spin_unlock_bh(&fip->lock); 1016 spin_unlock_bh(&fip->lock);
1012 1017
@@ -1102,15 +1107,17 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1102 struct fcoe_fcf *best = NULL; 1107 struct fcoe_fcf *best = NULL;
1103 1108
1104 list_for_each_entry(fcf, &fip->fcfs, list) { 1109 list_for_each_entry(fcf, &fip->fcfs, list) {
1105 LIBFCOE_FIP_DBG(fip, "consider FCF for fab %llx VFID %d map %x " 1110 LIBFCOE_FIP_DBG(fip, "consider FCF for fab %16.16llx "
1106 "val %d\n", fcf->fabric_name, fcf->vfid, 1111 "VFID %d map %x val %d\n",
1112 fcf->fabric_name, fcf->vfid,
1107 fcf->fc_map, fcoe_ctlr_mtu_valid(fcf)); 1113 fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
1108 if (!fcoe_ctlr_fcf_usable(fcf)) { 1114 if (!fcoe_ctlr_fcf_usable(fcf)) {
1109 LIBFCOE_FIP_DBG(fip, "FCF for fab %llx map %x %svalid " 1115 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
1110 "%savailable\n", fcf->fabric_name, 1116 "map %x %svalid %savailable\n",
1111 fcf->fc_map, (fcf->flags & FIP_FL_SOL) 1117 fcf->fabric_name, fcf->fc_map,
1112 ? "" : "in", (fcf->flags & FIP_FL_AVAIL) 1118 (fcf->flags & FIP_FL_SOL) ? "" : "in",
1113 ? "" : "un"); 1119 (fcf->flags & FIP_FL_AVAIL) ?
1120 "" : "un");
1114 continue; 1121 continue;
1115 } 1122 }
1116 if (!best) { 1123 if (!best) {
@@ -1175,7 +1182,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1175 "Starting FCF discovery.\n", 1182 "Starting FCF discovery.\n",
1176 fip->lp->host->host_no); 1183 fip->lp->host->host_no);
1177 fip->reset_req = 1; 1184 fip->reset_req = 1;
1178 schedule_work(&fip->link_work); 1185 schedule_work(&fip->timer_work);
1179 } 1186 }
1180 } 1187 }
1181 1188
@@ -1201,43 +1208,31 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1201 mod_timer(&fip->timer, next_timer); 1208 mod_timer(&fip->timer, next_timer);
1202 } 1209 }
1203 if (fip->send_ctlr_ka || fip->send_port_ka) 1210 if (fip->send_ctlr_ka || fip->send_port_ka)
1204 schedule_work(&fip->link_work); 1211 schedule_work(&fip->timer_work);
1205 spin_unlock_bh(&fip->lock); 1212 spin_unlock_bh(&fip->lock);
1206} 1213}
1207 1214
1208/** 1215/**
1209 * fcoe_ctlr_link_work() - Worker thread function for link changes 1216 * fcoe_ctlr_timer_work() - Worker thread function for timer work
1210 * @work: Handle to a FCoE controller 1217 * @work: Handle to a FCoE controller
1211 * 1218 *
1212 * See if the link status has changed and if so, report it. 1219 * Sends keep-alives and resets which must not
1213 *
1214 * This is here because fc_linkup() and fc_linkdown() must not
1215 * be called from the timer directly, since they use a mutex. 1220 * be called from the timer directly, since they use a mutex.
1216 */ 1221 */
1217static void fcoe_ctlr_link_work(struct work_struct *work) 1222static void fcoe_ctlr_timer_work(struct work_struct *work)
1218{ 1223{
1219 struct fcoe_ctlr *fip; 1224 struct fcoe_ctlr *fip;
1220 struct fc_lport *vport; 1225 struct fc_lport *vport;
1221 u8 *mac; 1226 u8 *mac;
1222 int link;
1223 int last_link;
1224 int reset; 1227 int reset;
1225 1228
1226 fip = container_of(work, struct fcoe_ctlr, link_work); 1229 fip = container_of(work, struct fcoe_ctlr, timer_work);
1227 spin_lock_bh(&fip->lock); 1230 spin_lock_bh(&fip->lock);
1228 last_link = fip->last_link;
1229 link = fip->link;
1230 fip->last_link = link;
1231 reset = fip->reset_req; 1231 reset = fip->reset_req;
1232 fip->reset_req = 0; 1232 fip->reset_req = 0;
1233 spin_unlock_bh(&fip->lock); 1233 spin_unlock_bh(&fip->lock);
1234 1234
1235 if (last_link != link) { 1235 if (reset)
1236 if (link)
1237 fc_linkup(fip->lp);
1238 else
1239 fc_linkdown(fip->lp);
1240 } else if (reset && link)
1241 fc_lport_reset(fip->lp); 1236 fc_lport_reset(fip->lp);
1242 1237
1243 if (fip->send_ctlr_ka) { 1238 if (fip->send_ctlr_ka) {
@@ -1334,9 +1329,9 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport,
1334 if (fip->state == FIP_ST_AUTO || fip->state == FIP_ST_NON_FIP) { 1329 if (fip->state == FIP_ST_AUTO || fip->state == FIP_ST_NON_FIP) {
1335 memcpy(fip->dest_addr, sa, ETH_ALEN); 1330 memcpy(fip->dest_addr, sa, ETH_ALEN);
1336 fip->map_dest = 0; 1331 fip->map_dest = 0;
1337 if (fip->state == FIP_ST_NON_FIP) 1332 if (fip->state == FIP_ST_AUTO)
1338 LIBFCOE_FIP_DBG(fip, "received FLOGI REQ, " 1333 LIBFCOE_FIP_DBG(fip, "received non-FIP FLOGI. "
1339 "using non-FIP mode\n"); 1334 "Setting non-FIP mode\n");
1340 fip->state = FIP_ST_NON_FIP; 1335 fip->state = FIP_ST_NON_FIP;
1341 } 1336 }
1342 spin_unlock_bh(&fip->lock); 1337 spin_unlock_bh(&fip->lock);