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.c143
1 files changed, 18 insertions, 125 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index d22275bf57f8..648a2fc04271 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -71,9 +71,6 @@ DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
71/* Function Prototyes */ 71/* Function Prototyes */
72static int fcoe_check_wait_queue(struct fc_lport *); 72static int fcoe_check_wait_queue(struct fc_lport *);
73static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *); 73static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
74#ifdef CONFIG_HOTPLUG_CPU
75static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
76#endif /* CONFIG_HOTPLUG_CPU */
77static int fcoe_device_notification(struct notifier_block *, ulong, void *); 74static int fcoe_device_notification(struct notifier_block *, ulong, void *);
78static void fcoe_dev_setup(void); 75static void fcoe_dev_setup(void);
79static void fcoe_dev_cleanup(void); 76static void fcoe_dev_cleanup(void);
@@ -83,87 +80,6 @@ static struct notifier_block fcoe_notifier = {
83 .notifier_call = fcoe_device_notification, 80 .notifier_call = fcoe_device_notification,
84}; 81};
85 82
86
87#ifdef CONFIG_HOTPLUG_CPU
88static struct notifier_block fcoe_cpu_notifier = {
89 .notifier_call = fcoe_cpu_callback,
90};
91
92/**
93 * fcoe_create_percpu_data() - creates the associated cpu data
94 * @cpu: index for the cpu where fcoe cpu data will be created
95 *
96 * create percpu stats block, from cpu add notifier
97 *
98 * Returns: none
99 */
100static void fcoe_create_percpu_data(unsigned int cpu)
101{
102 struct fc_lport *lp;
103 struct fcoe_softc *fc;
104
105 write_lock_bh(&fcoe_hostlist_lock);
106 list_for_each_entry(fc, &fcoe_hostlist, list) {
107 lp = fc->lp;
108 if (lp->dev_stats[cpu] == NULL)
109 lp->dev_stats[cpu] =
110 kzalloc(sizeof(struct fcoe_dev_stats),
111 GFP_KERNEL);
112 }
113 write_unlock_bh(&fcoe_hostlist_lock);
114}
115
116/**
117 * fcoe_destroy_percpu_data() - destroys the associated cpu data
118 * @cpu: index for the cpu where fcoe cpu data will destroyed
119 *
120 * destroy percpu stats block called by cpu add/remove notifier
121 *
122 * Retuns: none
123 */
124static void fcoe_destroy_percpu_data(unsigned int cpu)
125{
126 struct fc_lport *lp;
127 struct fcoe_softc *fc;
128
129 write_lock_bh(&fcoe_hostlist_lock);
130 list_for_each_entry(fc, &fcoe_hostlist, list) {
131 lp = fc->lp;
132 kfree(lp->dev_stats[cpu]);
133 lp->dev_stats[cpu] = NULL;
134 }
135 write_unlock_bh(&fcoe_hostlist_lock);
136}
137
138/**
139 * fcoe_cpu_callback() - fcoe cpu hotplug event callback
140 * @nfb: callback data block
141 * @action: event triggering the callback
142 * @hcpu: index for the cpu of this event
143 *
144 * this creates or destroys per cpu data for fcoe
145 *
146 * Returns NOTIFY_OK always.
147 */
148static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
149 void *hcpu)
150{
151 unsigned int cpu = (unsigned long)hcpu;
152
153 switch (action) {
154 case CPU_ONLINE:
155 fcoe_create_percpu_data(cpu);
156 break;
157 case CPU_DEAD:
158 fcoe_destroy_percpu_data(cpu);
159 break;
160 default:
161 break;
162 }
163 return NOTIFY_OK;
164}
165#endif /* CONFIG_HOTPLUG_CPU */
166
167/** 83/**
168 * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ 84 * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
169 * @skb: the receive skb 85 * @skb: the receive skb
@@ -181,7 +97,6 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
181 struct fc_lport *lp; 97 struct fc_lport *lp;
182 struct fcoe_rcv_info *fr; 98 struct fcoe_rcv_info *fr;
183 struct fcoe_softc *fc; 99 struct fcoe_softc *fc;
184 struct fcoe_dev_stats *stats;
185 struct fc_frame_header *fh; 100 struct fc_frame_header *fh;
186 struct fcoe_percpu_s *fps; 101 struct fcoe_percpu_s *fps;
187 unsigned short oxid; 102 unsigned short oxid;
@@ -252,13 +167,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
252 167
253 return 0; 168 return 0;
254err: 169err:
255#ifdef CONFIG_SMP 170 fc_lport_get_stats(lp)->ErrorFrames++;
256 stats = lp->dev_stats[smp_processor_id()];
257#else
258 stats = lp->dev_stats[0];
259#endif
260 if (stats)
261 stats->ErrorFrames++;
262 171
263err2: 172err2:
264 kfree_skb(skb); 173 kfree_skb(skb);
@@ -495,11 +404,9 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
495 } 404 }
496#endif 405#endif
497 /* update tx stats: regardless if LLD fails */ 406 /* update tx stats: regardless if LLD fails */
498 stats = lp->dev_stats[smp_processor_id()]; 407 stats = fc_lport_get_stats(lp);
499 if (stats) { 408 stats->TxFrames++;
500 stats->TxFrames++; 409 stats->TxWords += wlen;
501 stats->TxWords += wlen;
502 }
503 410
504 /* send down to lld */ 411 /* send down to lld */
505 fr_dev(fp) = lp; 412 fr_dev(fp) = lp;
@@ -565,8 +472,6 @@ int fcoe_percpu_receive_thread(void *arg)
565 continue; 472 continue;
566 } 473 }
567 474
568 stats = lp->dev_stats[smp_processor_id()];
569
570 if (unlikely(debug_fcoe)) { 475 if (unlikely(debug_fcoe)) {
571 FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p " 476 FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
572 "tail:%p end:%p sum:%d dev:%s", 477 "tail:%p end:%p sum:%d dev:%s",
@@ -593,13 +498,16 @@ int fcoe_percpu_receive_thread(void *arg)
593 hp = (struct fcoe_hdr *) skb_network_header(skb); 498 hp = (struct fcoe_hdr *) skb_network_header(skb);
594 fh = (struct fc_frame_header *) skb_transport_header(skb); 499 fh = (struct fc_frame_header *) skb_transport_header(skb);
595 500
501 stats = fc_lport_get_stats(lp);
596 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { 502 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
597 if (stats) { 503 if (stats->ErrorFrames < 5)
598 if (stats->ErrorFrames < 5) 504 printk(KERN_WARNING "FCoE version "
599 FC_DBG("unknown FCoE version %x", 505 "mismatch: The frame has "
600 FC_FCOE_DECAPS_VER(hp)); 506 "version %x, but the "
601 stats->ErrorFrames++; 507 "initiator supports version "
602 } 508 "%x\n", FC_FCOE_DECAPS_VER(hp),
509 FC_FCOE_VER);
510 stats->ErrorFrames++;
603 kfree_skb(skb); 511 kfree_skb(skb);
604 continue; 512 continue;
605 } 513 }
@@ -607,10 +515,8 @@ int fcoe_percpu_receive_thread(void *arg)
607 skb_pull(skb, sizeof(struct fcoe_hdr)); 515 skb_pull(skb, sizeof(struct fcoe_hdr));
608 fr_len = skb->len - sizeof(struct fcoe_crc_eof); 516 fr_len = skb->len - sizeof(struct fcoe_crc_eof);
609 517
610 if (stats) { 518 stats->RxFrames++;
611 stats->RxFrames++; 519 stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
612 stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
613 }
614 520
615 fp = (struct fc_frame *)skb; 521 fp = (struct fc_frame *)skb;
616 fc_frame_init(fp); 522 fc_frame_init(fp);
@@ -885,9 +791,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
885 if (new_link_up) 791 if (new_link_up)
886 fc_linkup(lp); 792 fc_linkup(lp);
887 else { 793 else {
888 stats = lp->dev_stats[smp_processor_id()]; 794 stats = fc_lport_get_stats(lp);
889 if (stats) 795 stats->LinkFailureCount++;
890 stats->LinkFailureCount++;
891 fc_linkdown(lp); 796 fc_linkdown(lp);
892 fcoe_clean_pending_queue(lp); 797 fcoe_clean_pending_queue(lp);
893 } 798 }
@@ -1371,10 +1276,6 @@ static int __init fcoe_init(void)
1371 INIT_LIST_HEAD(&fcoe_hostlist); 1276 INIT_LIST_HEAD(&fcoe_hostlist);
1372 rwlock_init(&fcoe_hostlist_lock); 1277 rwlock_init(&fcoe_hostlist_lock);
1373 1278
1374#ifdef CONFIG_HOTPLUG_CPU
1375 register_cpu_notifier(&fcoe_cpu_notifier);
1376#endif /* CONFIG_HOTPLUG_CPU */
1377
1378 for_each_possible_cpu(cpu) { 1279 for_each_possible_cpu(cpu) {
1379 p = &per_cpu(fcoe_percpu, cpu); 1280 p = &per_cpu(fcoe_percpu, cpu);
1380 skb_queue_head_init(&p->fcoe_rx_list); 1281 skb_queue_head_init(&p->fcoe_rx_list);
@@ -1430,17 +1331,9 @@ static void __exit fcoe_exit(void)
1430 struct fcoe_percpu_s *p; 1331 struct fcoe_percpu_s *p;
1431 struct sk_buff *skb; 1332 struct sk_buff *skb;
1432 1333
1433 /*
1434 * Stop all call back interfaces
1435 */
1436#ifdef CONFIG_HOTPLUG_CPU
1437 unregister_cpu_notifier(&fcoe_cpu_notifier);
1438#endif /* CONFIG_HOTPLUG_CPU */
1439 fcoe_dev_cleanup(); 1334 fcoe_dev_cleanup();
1440 1335
1441 /* 1336 /* Stop the timer */
1442 * stop timer
1443 */
1444 del_timer_sync(&fcoe_timer); 1337 del_timer_sync(&fcoe_timer);
1445 1338
1446 /* releases the associated fcoe transport for each lport */ 1339 /* releases the associated fcoe transport for each lport */