19 static u32 adapter_count;
23 #define DRV_MODULE_NAME "bnx2fc"
24 #define DRV_MODULE_VERSION BNX2FC_VERSION
25 #define DRV_MODULE_RELDATE "Jun 04, 2012"
38 #define BNX2FC_MAX_QUEUE_DEPTH 256
39 #define BNX2FC_MIN_QUEUE_DEPTH 32
40 #define FCOE_WORD_TO_BYTE 4
62 static int bnx2fc_enable(
struct net_device *netdev);
63 static int bnx2fc_disable(
struct net_device *netdev);
65 static void bnx2fc_recv_frame(
struct sk_buff *
skb);
71 static int bnx2fc_bind_adapter_devices(
struct bnx2fc_hba *hba);
72 static void bnx2fc_unbind_adapter_devices(
struct bnx2fc_hba *hba);
73 static int bnx2fc_bind_pcidev(
struct bnx2fc_hba *hba);
74 static void bnx2fc_unbind_pcidev(
struct bnx2fc_hba *hba);
76 struct device *parent,
int npiv);
85 static int bnx2fc_fw_init(
struct bnx2fc_hba *hba);
86 static void bnx2fc_fw_destroy(
struct bnx2fc_hba *hba);
90 static int __init bnx2fc_mod_init(
void);
91 static void __exit bnx2fc_mod_exit(
void);
98 unsigned long action,
void *hcpu);
101 .notifier_call = bnx2fc_cpu_callback,
115 static void bnx2fc_get_lesb(
struct fc_lport *lport,
118 struct net_device *netdev = bnx2fc_netdev(lport);
125 struct fcoe_ctlr *
fip = fcoe_ctlr_device_priv(ctlr_dev);
133 ctlr_dev->
lesb.lesb_link_fail =
135 ctlr_dev->
lesb.lesb_vlink_fail =
137 ctlr_dev->
lesb.lesb_miss_fka =
139 ctlr_dev->
lesb.lesb_symb_err =
141 ctlr_dev->
lesb.lesb_err_block =
143 ctlr_dev->
lesb.lesb_fcs_error =
152 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
158 static void bnx2fc_clean_rx_queue(
struct fc_lport *
lp)
170 for (skb = head; skb != (
struct sk_buff *)list;
173 fr = fcoe_dev_from_skb(skb);
175 __skb_unlink(skb, list);
185 spin_lock(&bnx2fc_global_lock);
187 spin_unlock(&bnx2fc_global_lock);
192 static void bnx2fc_abort_io(
struct fc_lport *lport)
202 static void bnx2fc_cleanup(
struct fc_lport *lport)
217 if (tgt->
port == port) {
229 static int bnx2fc_xmit_l2_frame(
struct bnx2fc_rport *tgt,
236 fh = fc_frame_header_get(fp);
238 "r_ctl = 0x%x\n", rdata->
ids.port_id,
243 switch (fc_frame_payload_op(fp)) {
261 "rctl 0x%x thru non-offload path\n",
292 unsigned int hlen, tlen, elen;
295 port = (
struct fcoe_port *)lport_priv(lport);
296 interface = port->
priv;
298 hba = interface->
hba;
300 fh = fc_frame_header_get(fp);
310 if (!ctlr->sel_fcf) {
339 rc = bnx2fc_xmit_l2_frame(tgt, fp);
348 elen =
sizeof(
struct ethhdr);
357 if (skb_is_nonlinear(skb)) {
363 frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
369 memset(cp, 0,
sizeof(*cp));
372 if (skb_is_nonlinear(skb)) {
379 skb_reset_mac_header(skb);
380 skb_reset_network_header(skb);
400 memset(hp, 0,
sizeof(*hp));
410 skb_shinfo(skb)->gso_type = 0;
411 skb_shinfo(skb)->gso_size = 0;
474 skb_set_transport_header(skb,
sizeof(
struct fcoe_hdr));
479 fr = fcoe_dev_from_skb(skb);
497 static int bnx2fc_l2_rcv_thread(
void *
arg)
509 bnx2fc_recv_frame(skb);
520 static void bnx2fc_recv_frame(
struct sk_buff *skb)
535 fr = fcoe_dev_from_skb(skb);
543 if (skb_is_nonlinear(skb))
545 mac = eth_hdr(skb)->h_source;
546 dest_mac = eth_hdr(skb)->h_dest;
549 hp = (
struct fcoe_hdr *) skb_network_header(skb);
567 fr_eof(fp) = crc_eof.fcoe_eof;
568 fr_crc(fp) = crc_eof.fcoe_crc32;
569 if (pskb_trim(skb, fr_len)) {
575 fh = fc_frame_header_get(fp);
579 port = lport_priv(vn_port);
597 switch (fc_frame_payload_op(fp)) {
647 list_splice_init(&p->
work_list, &work_list);
651 list_del_init(&work->
list);
669 struct fc_lport *lport = shost_priv(shost);
670 struct fcoe_port *port = lport_priv(lport);
706 static int bnx2fc_shost_config(
struct fc_lport *lport,
struct device *dev)
708 struct fcoe_port *port = lport_priv(lport);
718 shost->
transportt = bnx2fc_vport_xport_template;
720 shost->
transportt = bnx2fc_transport_template;
723 rc = scsi_add_host(lport->
host, dev);
737 static void bnx2fc_link_speed_update(
struct fc_lport *lport)
739 struct fcoe_port *port = lport_priv(lport);
753 switch (ethtool_cmd_speed(&ecmd)) {
766 static int bnx2fc_link_ok(
struct fc_lport *lport)
768 struct fcoe_port *port = lport_priv(lport);
774 if ((dev->
flags &
IFF_UP) && netif_carrier_ok(dev))
806 port = lport_priv(lport);
807 interface = port->
priv;
809 hba = interface->
hba;
813 !hba->
phys_dev->ethtool_ops->get_pauseparam)
823 bnx2fc_link_speed_update(lport);
830 fc_set_wwnn(lport, wwnn);
837 fc_set_wwpn(lport, wwpn);
843 static void bnx2fc_destroy_timer(
unsigned long data)
848 "Destroy compl not received!!\n");
863 static void bnx2fc_indicate_netevent(
void *
context,
unsigned long event,
871 int wait_for_upload = 0;
872 u32 link_possible = 1;
881 "hba is not UP!!\n");
903 if (interface->
hba == hba &&
905 __bnx2fc_destroy(interface);
918 if (interface->
hba != hba)
924 interface->
netdev->name, event);
926 bnx2fc_link_speed_update(lport);
928 if (link_possible && !bnx2fc_link_ok(lport)) {
946 get_cpu())->LinkFailureCount++;
954 if (wait_for_upload) {
958 "num_ofld_sess = %d\n",
972 static int bnx2fc_libfc_config(
struct fc_lport *lport)
976 memcpy(&lport->
tt, &bnx2fc_libfc_fcn_templ,
985 static int bnx2fc_em_config(
struct fc_lport *lport)
1002 static int bnx2fc_lport_config(
struct fc_lport *lport)
1019 if (fc_lport_init_stats(lport))
1061 static void bnx2fc_update_src_mac(
struct fc_lport *lport,
u8 *
addr)
1063 struct fcoe_port *port = lport_priv(lport);
1073 static u8 *bnx2fc_get_src_mac(
struct fc_lport *lport)
1077 port = (
struct fcoe_port *)lport_priv(lport);
1093 static int bnx2fc_vport_create(
struct fc_vport *vport,
bool disabled)
1096 struct fc_lport *n_port = shost_priv(shost);
1097 struct fcoe_port *port = lport_priv(n_port);
1108 "WWPN (0x%s) already exists\n",
1115 "this interface\n");
1120 vn_port = bnx2fc_if_create(interface, &vport->
dev, 1);
1124 if (IS_ERR(vn_port)) {
1147 if (blport->
lport == lport) {
1155 static int bnx2fc_vport_destroy(
struct fc_vport *vport)
1158 struct fc_lport *n_port = shost_priv(shost);
1160 struct fcoe_port *port = lport_priv(vn_port);
1167 if (v_port->vport == vport) {
1178 bnx2fc_free_vport(interface->
hba, port->
lport);
1179 bnx2fc_port_shutdown(port->
lport);
1180 bnx2fc_interface_put(interface);
1207 int sel_san_mac = 0;
1219 (is_valid_ether_addr(ha->
addr))) {
1244 static int bnx2fc_attach_transport(
void)
1246 bnx2fc_transport_template =
1249 if (bnx2fc_transport_template ==
NULL) {
1254 bnx2fc_vport_xport_template =
1256 if (bnx2fc_vport_xport_template ==
NULL) {
1258 "Failed to attach FC transport for vport\n");
1260 bnx2fc_transport_template =
NULL;
1265 static void bnx2fc_release_transport(
void)
1269 bnx2fc_transport_template =
NULL;
1270 bnx2fc_vport_xport_template =
NULL;
1273 static void bnx2fc_interface_release(
struct kref *
kref)
1285 netdev = interface->
netdev;
1297 static inline void bnx2fc_interface_get(
struct bnx2fc_interface *interface)
1299 kref_get(&interface->
kref);
1302 static inline void bnx2fc_interface_put(
struct bnx2fc_interface *interface)
1304 kref_put(&interface->
kref, bnx2fc_interface_release);
1306 static void bnx2fc_hba_destroy(
struct bnx2fc_hba *hba)
1314 bnx2fc_unbind_pcidev(hba);
1341 rc = bnx2fc_bind_pcidev(hba);
1350 kzalloc(
sizeof(
struct bnx2fc_rport *) * BNX2FC_NUM_MAX_SESS,
1383 INIT_LIST_HEAD(&hba->
vports);
1390 bnx2fc_unbind_pcidev(hba);
1406 size = (
sizeof(*interface) +
sizeof(
struct fcoe_ctlr));
1413 ctlr = fcoe_ctlr_device_priv(ctlr_dev);
1414 interface = fcoe_ctlr_priv(ctlr);
1416 kref_init(&interface->
kref);
1417 interface->
hba = hba;
1418 interface->
netdev = netdev;
1422 ctlr->
send = bnx2fc_fip_send;
1427 rc = bnx2fc_interface_setup(interface);
1449 struct device *parent,
int npiv)
1468 lport = libfc_host_alloc(&bnx2fc_shost_template,
sizeof(*port));
1476 shost = lport->
host;
1477 port = lport_priv(lport);
1483 rc = bnx2fc_lport_config(lport);
1494 rc = bnx2fc_net_config(lport, interface->
netdev);
1500 rc = bnx2fc_shost_config(lport, parent);
1503 interface->
netdev->name);
1508 rc = bnx2fc_libfc_config(lport);
1517 rc = bnx2fc_em_config(lport);
1520 n_port = shost_priv(shost);
1529 bnx2fc_interface_get(interface);
1531 hba = interface->
hba;
1560 struct fcoe_port *port = lport_priv(lport);
1569 bnx2fc_net_cleanup(interface);
1571 bnx2fc_free_vport(hba, lport);
1574 static void bnx2fc_if_destroy(
struct fc_lport *lport)
1578 bnx2fc_clean_rx_queue(lport);
1591 fc_lport_free_stats(lport);
1601 struct fcoe_port *port = lport_priv(lport);
1603 bnx2fc_interface_cleanup(interface);
1604 bnx2fc_stop(interface);
1606 bnx2fc_interface_put(interface);
1620 static int bnx2fc_destroy(
struct net_device *netdev)
1630 interface = bnx2fc_interface_lookup(netdev);
1632 if (!interface || !ctlr->
lp) {
1639 __bnx2fc_destroy(interface);
1654 lport = port->
lport;
1658 bnx2fc_if_destroy(lport);
1661 static void bnx2fc_unbind_adapter_devices(
struct bnx2fc_hba *hba)
1673 static int bnx2fc_bind_adapter_devices(
struct bnx2fc_hba *hba)
1683 bnx2fc_unbind_adapter_devices(hba);
1687 static int bnx2fc_bind_pcidev(
struct bnx2fc_hba *hba)
1703 static void bnx2fc_unbind_pcidev(
struct bnx2fc_hba *hba)
1715 static int bnx2fc_ulp_get_stats(
void *
handle)
1751 static void bnx2fc_ulp_start(
void *handle)
1761 bnx2fc_fw_init(hba);
1766 if (interface->
hba == hba) {
1771 lport->
tt.frame_send = bnx2fc_xmit;
1772 bnx2fc_start_disc(interface);
1779 static void bnx2fc_port_shutdown(
struct fc_lport *lport)
1796 bnx2fc_port_shutdown(lport);
1801 FC_PORTTYPE_UNKNOWN;
1810 #define BNX2FC_INIT_POLL_TIME (1000 / HZ)
1814 rc = bnx2fc_bind_adapter_devices(hba);
1817 "bnx2fc_bind_adapter_devices failed - rc = %d\n", rc);
1824 "bnx2fc_send_fw_fcoe_init_msg failed - rc = %d\n", rc);
1833 msleep(BNX2FC_INIT_POLL_TIME);
1838 hba->cnic->netdev->name);
1848 bnx2fc_unbind_adapter_devices(hba);
1853 static void bnx2fc_fw_destroy(
struct bnx2fc_hba *hba)
1873 bnx2fc_unbind_adapter_devices(hba);
1885 static void bnx2fc_ulp_stop(
void *handle)
1896 if (interface->
hba == hba)
1897 bnx2fc_stop(interface);
1909 bnx2fc_fw_destroy(hba);
1930 if (!bnx2fc_link_ok(lport) && interface->
enabled) {
1941 if (++wait_cnt > 12)
1962 static void bnx2fc_ulp_init(
struct cnic_dev *dev)
1972 " flags: %lx fcoe_conn: %d\n",
1977 hba = bnx2fc_hba_create(dev);
2000 static int bnx2fc_disable(
struct net_device *netdev)
2009 interface = bnx2fc_interface_lookup(netdev);
2011 if (!interface || !ctlr->
lp) {
2026 static int bnx2fc_enable(
struct net_device *netdev)
2035 interface = bnx2fc_interface_lookup(netdev);
2037 if (!interface || !ctlr->
lp) {
2040 }
else if (!bnx2fc_link_ok(ctlr->
lp)) {
2092 memset(&drvinfo, 0,
sizeof(drvinfo));
2093 phys_dev->
ethtool_ops->get_drvinfo(phys_dev, &drvinfo);
2106 hba = bnx2fc_hba_lookup(phys_dev);
2113 if (bnx2fc_interface_lookup(netdev)) {
2140 lport = bnx2fc_if_create(interface, &interface->
hba->pcidev->dev, 0);
2156 if (!bnx2fc_link_ok(lport)) {
2163 bnx2fc_start_disc(interface);
2169 bnx2fc_interface_put(interface);
2178 bnx2fc_net_cleanup(interface);
2179 bnx2fc_interface_put(interface);
2201 if (hba->
cnic == cnic)
2214 if (interface->
netdev == netdev)
2239 static void bnx2fc_ulp_exit(
struct cnic_dev *dev)
2253 hba = bnx2fc_find_hba_for_cnic(dev);
2261 list_del_init(&hba->
list);
2266 if (interface->hba == hba)
2267 __bnx2fc_destroy(interface);
2270 bnx2fc_ulp_stop(hba);
2274 bnx2fc_hba_destroy(hba);
2286 struct fc_lport *lport = shost_priv(shost);
2292 static bool bnx2fc_match(
struct net_device *netdev)
2300 if (bnx2fc_hba_lookup(phys_dev)) {
2314 .match = bnx2fc_match,
2315 .create = bnx2fc_create,
2316 .destroy = bnx2fc_destroy,
2317 .enable = bnx2fc_enable,
2318 .disable = bnx2fc_disable,
2327 static void bnx2fc_percpu_thread_create(
unsigned int cpu)
2332 p = &
per_cpu(bnx2fc_percpu, cpu);
2336 "bnx2fc_thread/%d", cpu);
2338 if (
likely(!IS_ERR(thread))) {
2345 static void bnx2fc_percpu_thread_destroy(
unsigned int cpu)
2354 p = &
per_cpu(bnx2fc_percpu, cpu);
2362 list_del_init(&work->
list);
2385 unsigned long action,
void *hcpu)
2387 unsigned cpu = (
unsigned long)hcpu;
2392 printk(
PFX "CPU %x online: Create Rx thread\n", cpu);
2393 bnx2fc_percpu_thread_create(cpu);
2397 printk(
PFX "CPU %x offline: Remove Rx thread\n", cpu);
2398 bnx2fc_percpu_thread_destroy(cpu);
2412 static int __init bnx2fc_mod_init(
void)
2417 unsigned int cpu = 0;
2426 "if libfcoe is loaded\n");
2430 INIT_LIST_HEAD(&adapter_list);
2431 INIT_LIST_HEAD(&if_list);
2436 rc = bnx2fc_attach_transport();
2450 "bnx2fc_l2_thread");
2451 if (IS_ERR(l2_thread)) {
2452 rc = PTR_ERR(l2_thread);
2461 p = &
per_cpu(bnx2fc_percpu, cpu);
2467 bnx2fc_percpu_thread_create(cpu);
2480 bnx2fc_release_transport();
2487 static void __exit bnx2fc_mod_exit(
void)
2494 unsigned int cpu = 0;
2503 list_splice(&adapter_list, &to_be_deleted);
2504 INIT_LIST_HEAD(&adapter_list);
2510 list_del_init(&hba->
list);
2513 bnx2fc_ulp_stop(hba);
2517 hba->
cnic->unregister_device(hba->
cnic,
2519 bnx2fc_hba_destroy(hba);
2540 bnx2fc_percpu_thread_destroy(cpu);
2548 bnx2fc_release_transport();
2559 .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb,
2560 .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb,
2561 .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb,
2562 .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb,
2563 .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb,
2564 .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb,
2567 .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id,
2571 .show_host_node_name = 1,
2572 .show_host_port_name = 1,
2573 .show_host_supported_classes = 1,
2574 .show_host_supported_fc4s = 1,
2575 .show_host_active_fc4s = 1,
2576 .show_host_maxframe_size = 1,
2578 .show_host_port_id = 1,
2579 .show_host_supported_speeds = 1,
2581 .show_host_speed = 1,
2582 .show_host_port_type = 1,
2584 .show_host_port_state = 1,
2585 .show_host_symbolic_name = 1,
2589 .show_rport_maxframe_size = 1,
2590 .show_rport_supported_classes = 1,
2592 .show_host_fabric_name = 1,
2593 .show_starget_node_name = 1,
2594 .show_starget_port_name = 1,
2595 .show_starget_port_id = 1,
2597 .show_rport_dev_loss_tmo = 1,
2598 .get_fc_host_stats = bnx2fc_get_host_stats,
2600 .issue_fc_host_lip = bnx2fc_fcoe_reset,
2604 .vport_create = bnx2fc_vport_create,
2605 .vport_delete = bnx2fc_vport_destroy,
2606 .vport_disable = bnx2fc_vport_disable,
2611 .show_host_node_name = 1,
2612 .show_host_port_name = 1,
2613 .show_host_supported_classes = 1,
2614 .show_host_supported_fc4s = 1,
2615 .show_host_active_fc4s = 1,
2616 .show_host_maxframe_size = 1,
2618 .show_host_port_id = 1,
2619 .show_host_supported_speeds = 1,
2621 .show_host_speed = 1,
2622 .show_host_port_type = 1,
2624 .show_host_port_state = 1,
2625 .show_host_symbolic_name = 1,
2629 .show_rport_maxframe_size = 1,
2630 .show_rport_supported_classes = 1,
2632 .show_host_fabric_name = 1,
2633 .show_starget_node_name = 1,
2634 .show_starget_port_name = 1,
2635 .show_starget_port_id = 1,
2637 .show_rport_dev_loss_tmo = 1,
2639 .issue_fc_host_lip = bnx2fc_fcoe_reset,
2649 .name =
"Broadcom Offload FCoE Initiator",
2667 .frame_send = bnx2fc_xmit,
2669 .fcp_abort_io = bnx2fc_abort_io,
2670 .fcp_cleanup = bnx2fc_cleanup,
2671 .get_lesb = bnx2fc_get_lesb,
2681 .cnic_init = bnx2fc_ulp_init,
2682 .cnic_exit = bnx2fc_ulp_exit,
2683 .cnic_start = bnx2fc_ulp_start,
2684 .cnic_stop = bnx2fc_ulp_stop,
2686 .indicate_netevent = bnx2fc_indicate_netevent,
2687 .cnic_get_stats = bnx2fc_ulp_get_stats,