diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_main.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 372 |
1 files changed, 319 insertions, 53 deletions
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 1003eb76fda..655bccd7f8f 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -35,14 +35,14 @@ | |||
35 | #include <linux/inetdevice.h> | 35 | #include <linux/inetdevice.h> |
36 | #include <linux/sysfs.h> | 36 | #include <linux/sysfs.h> |
37 | 37 | ||
38 | MODULE_DESCRIPTION("QLogic 10 GbE Converged Ethernet Driver"); | 38 | MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver"); |
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | MODULE_VERSION(QLCNIC_LINUX_VERSIONID); | 40 | MODULE_VERSION(QLCNIC_LINUX_VERSIONID); |
41 | MODULE_FIRMWARE(QLCNIC_UNIFIED_ROMIMAGE_NAME); | 41 | MODULE_FIRMWARE(QLCNIC_UNIFIED_ROMIMAGE_NAME); |
42 | 42 | ||
43 | char qlcnic_driver_name[] = "qlcnic"; | 43 | char qlcnic_driver_name[] = "qlcnic"; |
44 | static const char qlcnic_driver_string[] = "QLogic Converged Ethernet Driver v" | 44 | static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " |
45 | QLCNIC_LINUX_VERSIONID; | 45 | "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; |
46 | 46 | ||
47 | static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG; | 47 | static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG; |
48 | 48 | ||
@@ -65,6 +65,10 @@ static int load_fw_file; | |||
65 | module_param(load_fw_file, int, 0644); | 65 | module_param(load_fw_file, int, 0644); |
66 | MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); | 66 | MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); |
67 | 67 | ||
68 | static int qlcnic_config_npars; | ||
69 | module_param(qlcnic_config_npars, int, 0644); | ||
70 | MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled"); | ||
71 | |||
68 | static int __devinit qlcnic_probe(struct pci_dev *pdev, | 72 | static int __devinit qlcnic_probe(struct pci_dev *pdev, |
69 | const struct pci_device_id *ent); | 73 | const struct pci_device_id *ent); |
70 | static void __devexit qlcnic_remove(struct pci_dev *pdev); | 74 | static void __devexit qlcnic_remove(struct pci_dev *pdev); |
@@ -79,6 +83,7 @@ static void qlcnic_schedule_work(struct qlcnic_adapter *adapter, | |||
79 | work_func_t func, int delay); | 83 | work_func_t func, int delay); |
80 | static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); | 84 | static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); |
81 | static int qlcnic_poll(struct napi_struct *napi, int budget); | 85 | static int qlcnic_poll(struct napi_struct *napi, int budget); |
86 | static int qlcnic_rx_poll(struct napi_struct *napi, int budget); | ||
82 | #ifdef CONFIG_NET_POLL_CONTROLLER | 87 | #ifdef CONFIG_NET_POLL_CONTROLLER |
83 | static void qlcnic_poll_controller(struct net_device *netdev); | 88 | static void qlcnic_poll_controller(struct net_device *netdev); |
84 | #endif | 89 | #endif |
@@ -99,7 +104,14 @@ static irqreturn_t qlcnic_msix_intr(int irq, void *data); | |||
99 | 104 | ||
100 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); | 105 | static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); |
101 | static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); | 106 | static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); |
102 | 107 | static int qlcnic_start_firmware(struct qlcnic_adapter *); | |
108 | |||
109 | static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); | ||
110 | static void qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *); | ||
111 | static int qlcnicvf_set_ilb_mode(struct qlcnic_adapter *); | ||
112 | static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); | ||
113 | static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); | ||
114 | static int qlcnicvf_start_firmware(struct qlcnic_adapter *); | ||
103 | /* PCI Device ID Table */ | 115 | /* PCI Device ID Table */ |
104 | #define ENTRY(device) \ | 116 | #define ENTRY(device) \ |
105 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ | 117 | {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ |
@@ -120,12 +132,6 @@ qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, | |||
120 | struct qlcnic_host_tx_ring *tx_ring) | 132 | struct qlcnic_host_tx_ring *tx_ring) |
121 | { | 133 | { |
122 | writel(tx_ring->producer, tx_ring->crb_cmd_producer); | 134 | writel(tx_ring->producer, tx_ring->crb_cmd_producer); |
123 | |||
124 | if (qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH) { | ||
125 | netif_stop_queue(adapter->netdev); | ||
126 | smp_mb(); | ||
127 | adapter->stats.xmit_off++; | ||
128 | } | ||
129 | } | 135 | } |
130 | 136 | ||
131 | static const u32 msi_tgt_status[8] = { | 137 | static const u32 msi_tgt_status[8] = { |
@@ -184,8 +190,13 @@ qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
184 | 190 | ||
185 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 191 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
186 | sds_ring = &recv_ctx->sds_rings[ring]; | 192 | sds_ring = &recv_ctx->sds_rings[ring]; |
187 | netif_napi_add(netdev, &sds_ring->napi, | 193 | |
188 | qlcnic_poll, QLCNIC_NETDEV_WEIGHT); | 194 | if (ring == adapter->max_sds_rings - 1) |
195 | netif_napi_add(netdev, &sds_ring->napi, qlcnic_poll, | ||
196 | QLCNIC_NETDEV_WEIGHT/adapter->max_sds_rings); | ||
197 | else | ||
198 | netif_napi_add(netdev, &sds_ring->napi, | ||
199 | qlcnic_rx_poll, QLCNIC_NETDEV_WEIGHT*2); | ||
189 | } | 200 | } |
190 | 201 | ||
191 | return 0; | 202 | return 0; |
@@ -307,19 +318,14 @@ static void qlcnic_init_msix_entries(struct qlcnic_adapter *adapter, int count) | |||
307 | static int | 318 | static int |
308 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) | 319 | qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) |
309 | { | 320 | { |
310 | int i; | 321 | u8 mac_addr[ETH_ALEN]; |
311 | unsigned char *p; | ||
312 | u64 mac_addr; | ||
313 | struct net_device *netdev = adapter->netdev; | 322 | struct net_device *netdev = adapter->netdev; |
314 | struct pci_dev *pdev = adapter->pdev; | 323 | struct pci_dev *pdev = adapter->pdev; |
315 | 324 | ||
316 | if (qlcnic_get_mac_addr(adapter, &mac_addr) != 0) | 325 | if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0) |
317 | return -EIO; | 326 | return -EIO; |
318 | 327 | ||
319 | p = (unsigned char *)&mac_addr; | 328 | memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); |
320 | for (i = 0; i < 6; i++) | ||
321 | netdev->dev_addr[i] = *(p + 5 - i); | ||
322 | |||
323 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | 329 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); |
324 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | 330 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); |
325 | 331 | ||
@@ -371,6 +377,33 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
371 | #endif | 377 | #endif |
372 | }; | 378 | }; |
373 | 379 | ||
380 | static struct qlcnic_nic_template qlcnic_ops = { | ||
381 | .get_mac_addr = qlcnic_get_mac_addr, | ||
382 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
383 | .config_led = qlcnic_config_led, | ||
384 | .set_ilb_mode = qlcnic_set_ilb_mode, | ||
385 | .clear_ilb_mode = qlcnic_clear_ilb_mode, | ||
386 | .start_firmware = qlcnic_start_firmware | ||
387 | }; | ||
388 | |||
389 | static struct qlcnic_nic_template qlcnic_pf_ops = { | ||
390 | .get_mac_addr = qlcnic_get_mac_address, | ||
391 | .config_bridged_mode = qlcnic_config_bridged_mode, | ||
392 | .config_led = qlcnic_config_led, | ||
393 | .set_ilb_mode = qlcnic_set_ilb_mode, | ||
394 | .clear_ilb_mode = qlcnic_clear_ilb_mode, | ||
395 | .start_firmware = qlcnic_start_firmware | ||
396 | }; | ||
397 | |||
398 | static struct qlcnic_nic_template qlcnic_vf_ops = { | ||
399 | .get_mac_addr = qlcnic_get_mac_address, | ||
400 | .config_bridged_mode = qlcnicvf_config_bridged_mode, | ||
401 | .config_led = qlcnicvf_config_led, | ||
402 | .set_ilb_mode = qlcnicvf_set_ilb_mode, | ||
403 | .clear_ilb_mode = qlcnicvf_clear_ilb_mode, | ||
404 | .start_firmware = qlcnicvf_start_firmware | ||
405 | }; | ||
406 | |||
374 | static void | 407 | static void |
375 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) | 408 | qlcnic_setup_intr(struct qlcnic_adapter *adapter) |
376 | { | 409 | { |
@@ -453,6 +486,121 @@ qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter) | |||
453 | } | 486 | } |
454 | 487 | ||
455 | static int | 488 | static int |
489 | qlcnic_set_function_modes(struct qlcnic_adapter *adapter) | ||
490 | { | ||
491 | u8 id; | ||
492 | u32 ref_count; | ||
493 | int i, ret = 1; | ||
494 | u32 data = QLCNIC_MGMT_FUNC; | ||
495 | void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; | ||
496 | |||
497 | /* If other drivers are not in use set their privilege level */ | ||
498 | ref_count = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); | ||
499 | ret = qlcnic_api_lock(adapter); | ||
500 | if (ret) | ||
501 | goto err_lock; | ||
502 | if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func)) | ||
503 | goto err_npar; | ||
504 | |||
505 | if (qlcnic_config_npars) { | ||
506 | for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { | ||
507 | id = adapter->npars[i].id; | ||
508 | if (adapter->npars[i].type != QLCNIC_TYPE_NIC || | ||
509 | id == adapter->ahw.pci_func) | ||
510 | continue; | ||
511 | data |= (qlcnic_config_npars & | ||
512 | QLC_DEV_SET_DRV(0xf, id)); | ||
513 | } | ||
514 | } else { | ||
515 | data = readl(priv_op); | ||
516 | data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw.pci_func)) | | ||
517 | (QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC, | ||
518 | adapter->ahw.pci_func)); | ||
519 | } | ||
520 | writel(data, priv_op); | ||
521 | err_npar: | ||
522 | qlcnic_api_unlock(adapter); | ||
523 | err_lock: | ||
524 | return ret; | ||
525 | } | ||
526 | |||
527 | static u32 | ||
528 | qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) | ||
529 | { | ||
530 | void __iomem *msix_base_addr; | ||
531 | void __iomem *priv_op; | ||
532 | u32 func; | ||
533 | u32 msix_base; | ||
534 | u32 op_mode, priv_level; | ||
535 | |||
536 | /* Determine FW API version */ | ||
537 | adapter->fw_hal_version = readl(adapter->ahw.pci_base0 + QLCNIC_FW_API); | ||
538 | if (adapter->fw_hal_version == ~0) { | ||
539 | adapter->nic_ops = &qlcnic_ops; | ||
540 | adapter->fw_hal_version = QLCNIC_FW_BASE; | ||
541 | adapter->ahw.pci_func = PCI_FUNC(adapter->pdev->devfn); | ||
542 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
543 | dev_info(&adapter->pdev->dev, | ||
544 | "FW does not support nic partion\n"); | ||
545 | return adapter->fw_hal_version; | ||
546 | } | ||
547 | |||
548 | /* Find PCI function number */ | ||
549 | pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func); | ||
550 | msix_base_addr = adapter->ahw.pci_base0 + QLCNIC_MSIX_BASE; | ||
551 | msix_base = readl(msix_base_addr); | ||
552 | func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; | ||
553 | adapter->ahw.pci_func = func; | ||
554 | |||
555 | qlcnic_get_nic_info(adapter, adapter->ahw.pci_func); | ||
556 | |||
557 | if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
558 | adapter->nic_ops = &qlcnic_ops; | ||
559 | return adapter->fw_hal_version; | ||
560 | } | ||
561 | |||
562 | /* Determine function privilege level */ | ||
563 | priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; | ||
564 | op_mode = readl(priv_op); | ||
565 | if (op_mode == QLC_DEV_DRV_DEFAULT) | ||
566 | priv_level = QLCNIC_MGMT_FUNC; | ||
567 | else | ||
568 | priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); | ||
569 | |||
570 | switch (priv_level) { | ||
571 | case QLCNIC_MGMT_FUNC: | ||
572 | adapter->op_mode = QLCNIC_MGMT_FUNC; | ||
573 | adapter->nic_ops = &qlcnic_pf_ops; | ||
574 | qlcnic_get_pci_info(adapter); | ||
575 | /* Set privilege level for other functions */ | ||
576 | qlcnic_set_function_modes(adapter); | ||
577 | dev_info(&adapter->pdev->dev, | ||
578 | "HAL Version: %d, Management function\n", | ||
579 | adapter->fw_hal_version); | ||
580 | break; | ||
581 | case QLCNIC_PRIV_FUNC: | ||
582 | adapter->op_mode = QLCNIC_PRIV_FUNC; | ||
583 | dev_info(&adapter->pdev->dev, | ||
584 | "HAL Version: %d, Privileged function\n", | ||
585 | adapter->fw_hal_version); | ||
586 | adapter->nic_ops = &qlcnic_pf_ops; | ||
587 | break; | ||
588 | case QLCNIC_NON_PRIV_FUNC: | ||
589 | adapter->op_mode = QLCNIC_NON_PRIV_FUNC; | ||
590 | dev_info(&adapter->pdev->dev, | ||
591 | "HAL Version: %d Non Privileged function\n", | ||
592 | adapter->fw_hal_version); | ||
593 | adapter->nic_ops = &qlcnic_vf_ops; | ||
594 | break; | ||
595 | default: | ||
596 | dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n", | ||
597 | priv_level); | ||
598 | return 0; | ||
599 | } | ||
600 | return adapter->fw_hal_version; | ||
601 | } | ||
602 | |||
603 | static int | ||
456 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | 604 | qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) |
457 | { | 605 | { |
458 | void __iomem *mem_ptr0 = NULL; | 606 | void __iomem *mem_ptr0 = NULL; |
@@ -460,7 +608,6 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | |||
460 | unsigned long mem_len, pci_len0 = 0; | 608 | unsigned long mem_len, pci_len0 = 0; |
461 | 609 | ||
462 | struct pci_dev *pdev = adapter->pdev; | 610 | struct pci_dev *pdev = adapter->pdev; |
463 | int pci_func = adapter->ahw.pci_func; | ||
464 | 611 | ||
465 | /* remap phys address */ | 612 | /* remap phys address */ |
466 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 613 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
@@ -483,8 +630,13 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) | |||
483 | adapter->ahw.pci_base0 = mem_ptr0; | 630 | adapter->ahw.pci_base0 = mem_ptr0; |
484 | adapter->ahw.pci_len0 = pci_len0; | 631 | adapter->ahw.pci_len0 = pci_len0; |
485 | 632 | ||
633 | if (!qlcnic_get_driver_mode(adapter)) { | ||
634 | iounmap(adapter->ahw.pci_base0); | ||
635 | return -EIO; | ||
636 | } | ||
637 | |||
486 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, | 638 | adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, |
487 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(pci_func))); | 639 | QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); |
488 | 640 | ||
489 | return 0; | 641 | return 0; |
490 | } | 642 | } |
@@ -509,7 +661,7 @@ static void get_brd_name(struct qlcnic_adapter *adapter, char *name) | |||
509 | } | 661 | } |
510 | 662 | ||
511 | if (!found) | 663 | if (!found) |
512 | name = "Unknown"; | 664 | sprintf(name, "%pM Gigabit Ethernet", adapter->mac_addr); |
513 | } | 665 | } |
514 | 666 | ||
515 | static void | 667 | static void |
@@ -553,8 +705,6 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
553 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", | 705 | dev_info(&pdev->dev, "firmware v%d.%d.%d\n", |
554 | fw_major, fw_minor, fw_build); | 706 | fw_major, fw_minor, fw_build); |
555 | 707 | ||
556 | adapter->capabilities = QLCRD32(adapter, CRB_FW_CAPABILITIES_1); | ||
557 | |||
558 | adapter->flags &= ~QLCNIC_LRO_ENABLED; | 708 | adapter->flags &= ~QLCNIC_LRO_ENABLED; |
559 | 709 | ||
560 | if (adapter->ahw.port_type == QLCNIC_XGBE) { | 710 | if (adapter->ahw.port_type == QLCNIC_XGBE) { |
@@ -565,6 +715,8 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) | |||
565 | adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; | 715 | adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; |
566 | } | 716 | } |
567 | 717 | ||
718 | qlcnic_get_nic_info(adapter, adapter->ahw.pci_func); | ||
719 | |||
568 | adapter->msix_supported = !!use_msi_x; | 720 | adapter->msix_supported = !!use_msi_x; |
569 | adapter->rss_supported = !!use_msi_x; | 721 | adapter->rss_supported = !!use_msi_x; |
570 | 722 | ||
@@ -591,8 +743,12 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) | |||
591 | 743 | ||
592 | if (load_fw_file) | 744 | if (load_fw_file) |
593 | qlcnic_request_firmware(adapter); | 745 | qlcnic_request_firmware(adapter); |
594 | else | 746 | else { |
747 | if (qlcnic_check_flash_fw_ver(adapter)) | ||
748 | goto err_out; | ||
749 | |||
595 | adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; | 750 | adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; |
751 | } | ||
596 | 752 | ||
597 | err = qlcnic_need_fw_reset(adapter); | 753 | err = qlcnic_need_fw_reset(adapter); |
598 | if (err < 0) | 754 | if (err < 0) |
@@ -633,6 +789,10 @@ wait_init: | |||
633 | 789 | ||
634 | qlcnic_check_options(adapter); | 790 | qlcnic_check_options(adapter); |
635 | 791 | ||
792 | if (adapter->flags & QLCNIC_ESWITCH_ENABLED && | ||
793 | adapter->op_mode != QLCNIC_NON_PRIV_FUNC) | ||
794 | qlcnic_dev_set_npar_ready(adapter); | ||
795 | |||
636 | adapter->need_fw_reset = 0; | 796 | adapter->need_fw_reset = 0; |
637 | 797 | ||
638 | qlcnic_release_firmware(adapter); | 798 | qlcnic_release_firmware(adapter); |
@@ -971,18 +1131,17 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, | |||
971 | adapter->max_mc_count = 38; | 1131 | adapter->max_mc_count = 38; |
972 | 1132 | ||
973 | netdev->netdev_ops = &qlcnic_netdev_ops; | 1133 | netdev->netdev_ops = &qlcnic_netdev_ops; |
974 | netdev->watchdog_timeo = 2*HZ; | 1134 | netdev->watchdog_timeo = 5*HZ; |
975 | 1135 | ||
976 | qlcnic_change_mtu(netdev, netdev->mtu); | 1136 | qlcnic_change_mtu(netdev, netdev->mtu); |
977 | 1137 | ||
978 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); | 1138 | SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); |
979 | 1139 | ||
980 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | 1140 | netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
981 | netdev->features |= (NETIF_F_GRO); | 1141 | NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6); |
982 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); | ||
983 | 1142 | ||
984 | netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | 1143 | netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | |
985 | netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); | 1144 | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6); |
986 | 1145 | ||
987 | if (pci_using_dac) { | 1146 | if (pci_using_dac) { |
988 | netdev->features |= NETIF_F_HIGHDMA; | 1147 | netdev->features |= NETIF_F_HIGHDMA; |
@@ -1036,7 +1195,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1036 | struct net_device *netdev = NULL; | 1195 | struct net_device *netdev = NULL; |
1037 | struct qlcnic_adapter *adapter = NULL; | 1196 | struct qlcnic_adapter *adapter = NULL; |
1038 | int err; | 1197 | int err; |
1039 | int pci_func_id = PCI_FUNC(pdev->devfn); | ||
1040 | uint8_t revision_id; | 1198 | uint8_t revision_id; |
1041 | uint8_t pci_using_dac; | 1199 | uint8_t pci_using_dac; |
1042 | 1200 | ||
@@ -1072,7 +1230,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1072 | adapter->netdev = netdev; | 1230 | adapter->netdev = netdev; |
1073 | adapter->pdev = pdev; | 1231 | adapter->pdev = pdev; |
1074 | adapter->dev_rst_time = jiffies; | 1232 | adapter->dev_rst_time = jiffies; |
1075 | adapter->ahw.pci_func = pci_func_id; | ||
1076 | 1233 | ||
1077 | revision_id = pdev->revision; | 1234 | revision_id = pdev->revision; |
1078 | adapter->ahw.revision_id = revision_id; | 1235 | adapter->ahw.revision_id = revision_id; |
@@ -1088,7 +1245,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1088 | goto err_out_free_netdev; | 1245 | goto err_out_free_netdev; |
1089 | 1246 | ||
1090 | /* This will be reset for mezz cards */ | 1247 | /* This will be reset for mezz cards */ |
1091 | adapter->portnum = pci_func_id; | 1248 | adapter->portnum = adapter->ahw.pci_func; |
1092 | 1249 | ||
1093 | err = qlcnic_get_board_info(adapter); | 1250 | err = qlcnic_get_board_info(adapter); |
1094 | if (err) { | 1251 | if (err) { |
@@ -1102,7 +1259,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1102 | if (qlcnic_setup_idc_param(adapter)) | 1259 | if (qlcnic_setup_idc_param(adapter)) |
1103 | goto err_out_iounmap; | 1260 | goto err_out_iounmap; |
1104 | 1261 | ||
1105 | err = qlcnic_start_firmware(adapter); | 1262 | err = adapter->nic_ops->start_firmware(adapter); |
1106 | if (err) { | 1263 | if (err) { |
1107 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); | 1264 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n"); |
1108 | goto err_out_decr_ref; | 1265 | goto err_out_decr_ref; |
@@ -1175,6 +1332,11 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) | |||
1175 | 1332 | ||
1176 | qlcnic_detach(adapter); | 1333 | qlcnic_detach(adapter); |
1177 | 1334 | ||
1335 | if (adapter->npars != NULL) | ||
1336 | kfree(adapter->npars); | ||
1337 | if (adapter->eswitch != NULL) | ||
1338 | kfree(adapter->eswitch); | ||
1339 | |||
1178 | qlcnic_clr_all_drv_state(adapter); | 1340 | qlcnic_clr_all_drv_state(adapter); |
1179 | 1341 | ||
1180 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 1342 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
@@ -1263,7 +1425,7 @@ qlcnic_resume(struct pci_dev *pdev) | |||
1263 | pci_set_master(pdev); | 1425 | pci_set_master(pdev); |
1264 | pci_restore_state(pdev); | 1426 | pci_restore_state(pdev); |
1265 | 1427 | ||
1266 | err = qlcnic_start_firmware(adapter); | 1428 | err = adapter->nic_ops->start_firmware(adapter); |
1267 | if (err) { | 1429 | if (err) { |
1268 | dev_err(&pdev->dev, "failed to start firmware\n"); | 1430 | dev_err(&pdev->dev, "failed to start firmware\n"); |
1269 | return err; | 1431 | return err; |
@@ -1340,11 +1502,11 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1340 | u8 opcode = TX_ETHER_PKT; | 1502 | u8 opcode = TX_ETHER_PKT; |
1341 | __be16 protocol = skb->protocol; | 1503 | __be16 protocol = skb->protocol; |
1342 | u16 flags = 0, vid = 0; | 1504 | u16 flags = 0, vid = 0; |
1343 | u32 producer; | ||
1344 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; | 1505 | int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; |
1345 | struct cmd_desc_type0 *hwdesc; | 1506 | struct cmd_desc_type0 *hwdesc; |
1346 | struct vlan_ethhdr *vh; | 1507 | struct vlan_ethhdr *vh; |
1347 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1508 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1509 | u32 producer = tx_ring->producer; | ||
1348 | 1510 | ||
1349 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { | 1511 | if (protocol == cpu_to_be16(ETH_P_8021Q)) { |
1350 | 1512 | ||
@@ -1360,6 +1522,11 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1360 | vlan_oob = 1; | 1522 | vlan_oob = 1; |
1361 | } | 1523 | } |
1362 | 1524 | ||
1525 | if (*(skb->data) & BIT_0) { | ||
1526 | flags |= BIT_0; | ||
1527 | memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN); | ||
1528 | } | ||
1529 | |||
1363 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && | 1530 | if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && |
1364 | skb_shinfo(skb)->gso_size > 0) { | 1531 | skb_shinfo(skb)->gso_size > 0) { |
1365 | 1532 | ||
@@ -1409,7 +1576,6 @@ qlcnic_tso_check(struct net_device *netdev, | |||
1409 | /* For LSO, we need to copy the MAC/IP/TCP headers into | 1576 | /* For LSO, we need to copy the MAC/IP/TCP headers into |
1410 | * the descriptor ring | 1577 | * the descriptor ring |
1411 | */ | 1578 | */ |
1412 | producer = tx_ring->producer; | ||
1413 | copied = 0; | 1579 | copied = 0; |
1414 | offset = 2; | 1580 | offset = 2; |
1415 | 1581 | ||
@@ -1537,10 +1703,15 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1537 | /* 4 fragments per cmd des */ | 1703 | /* 4 fragments per cmd des */ |
1538 | no_of_desc = (frag_count + 3) >> 2; | 1704 | no_of_desc = (frag_count + 3) >> 2; |
1539 | 1705 | ||
1540 | if (unlikely(no_of_desc + 2 > qlcnic_tx_avail(tx_ring))) { | 1706 | if (unlikely(qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH)) { |
1541 | netif_stop_queue(netdev); | 1707 | netif_stop_queue(netdev); |
1542 | adapter->stats.xmit_off++; | 1708 | smp_mb(); |
1543 | return NETDEV_TX_BUSY; | 1709 | if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) |
1710 | netif_start_queue(netdev); | ||
1711 | else { | ||
1712 | adapter->stats.xmit_off++; | ||
1713 | return NETDEV_TX_BUSY; | ||
1714 | } | ||
1544 | } | 1715 | } |
1545 | 1716 | ||
1546 | producer = tx_ring->producer; | 1717 | producer = tx_ring->producer; |
@@ -1846,14 +2017,12 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter) | |||
1846 | smp_mb(); | 2017 | smp_mb(); |
1847 | 2018 | ||
1848 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 2019 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
1849 | __netif_tx_lock(tx_ring->txq, smp_processor_id()); | ||
1850 | if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { | 2020 | if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH) { |
1851 | netif_wake_queue(netdev); | 2021 | netif_wake_queue(netdev); |
1852 | adapter->tx_timeo_cnt = 0; | ||
1853 | adapter->stats.xmit_on++; | 2022 | adapter->stats.xmit_on++; |
1854 | } | 2023 | } |
1855 | __netif_tx_unlock(tx_ring->txq); | ||
1856 | } | 2024 | } |
2025 | adapter->tx_timeo_cnt = 0; | ||
1857 | } | 2026 | } |
1858 | /* | 2027 | /* |
1859 | * If everything is freed up to consumer then check if the ring is full | 2028 | * If everything is freed up to consumer then check if the ring is full |
@@ -1898,6 +2067,25 @@ static int qlcnic_poll(struct napi_struct *napi, int budget) | |||
1898 | return work_done; | 2067 | return work_done; |
1899 | } | 2068 | } |
1900 | 2069 | ||
2070 | static int qlcnic_rx_poll(struct napi_struct *napi, int budget) | ||
2071 | { | ||
2072 | struct qlcnic_host_sds_ring *sds_ring = | ||
2073 | container_of(napi, struct qlcnic_host_sds_ring, napi); | ||
2074 | |||
2075 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
2076 | int work_done; | ||
2077 | |||
2078 | work_done = qlcnic_process_rcv_ring(sds_ring, budget); | ||
2079 | |||
2080 | if (work_done < budget) { | ||
2081 | napi_complete(&sds_ring->napi); | ||
2082 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) | ||
2083 | qlcnic_enable_int(sds_ring); | ||
2084 | } | ||
2085 | |||
2086 | return work_done; | ||
2087 | } | ||
2088 | |||
1901 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2089 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1902 | static void qlcnic_poll_controller(struct net_device *netdev) | 2090 | static void qlcnic_poll_controller(struct net_device *netdev) |
1903 | { | 2091 | { |
@@ -2109,7 +2297,7 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2109 | { | 2297 | { |
2110 | struct qlcnic_adapter *adapter = container_of(work, | 2298 | struct qlcnic_adapter *adapter = container_of(work, |
2111 | struct qlcnic_adapter, fw_work.work); | 2299 | struct qlcnic_adapter, fw_work.work); |
2112 | u32 dev_state = 0xf; | 2300 | u32 dev_state = 0xf, npar_state; |
2113 | 2301 | ||
2114 | if (qlcnic_api_lock(adapter)) | 2302 | if (qlcnic_api_lock(adapter)) |
2115 | goto err_ret; | 2303 | goto err_ret; |
@@ -2122,6 +2310,19 @@ qlcnic_fwinit_work(struct work_struct *work) | |||
2122 | return; | 2310 | return; |
2123 | } | 2311 | } |
2124 | 2312 | ||
2313 | if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { | ||
2314 | npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2315 | if (npar_state == QLCNIC_DEV_NPAR_RDY) { | ||
2316 | qlcnic_api_unlock(adapter); | ||
2317 | goto wait_npar; | ||
2318 | } else { | ||
2319 | qlcnic_schedule_work(adapter, qlcnic_fwinit_work, | ||
2320 | FW_POLL_DELAY); | ||
2321 | qlcnic_api_unlock(adapter); | ||
2322 | return; | ||
2323 | } | ||
2324 | } | ||
2325 | |||
2125 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { | 2326 | if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { |
2126 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", | 2327 | dev_err(&adapter->pdev->dev, "Reset:Failed to get ack %d sec\n", |
2127 | adapter->reset_ack_timeo); | 2328 | adapter->reset_ack_timeo); |
@@ -2154,7 +2355,7 @@ skip_ack_check: | |||
2154 | 2355 | ||
2155 | qlcnic_api_unlock(adapter); | 2356 | qlcnic_api_unlock(adapter); |
2156 | 2357 | ||
2157 | if (!qlcnic_start_firmware(adapter)) { | 2358 | if (!adapter->nic_ops->start_firmware(adapter)) { |
2158 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2359 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2159 | return; | 2360 | return; |
2160 | } | 2361 | } |
@@ -2163,6 +2364,7 @@ skip_ack_check: | |||
2163 | 2364 | ||
2164 | qlcnic_api_unlock(adapter); | 2365 | qlcnic_api_unlock(adapter); |
2165 | 2366 | ||
2367 | wait_npar: | ||
2166 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); | 2368 | dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); |
2167 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); | 2369 | QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); |
2168 | 2370 | ||
@@ -2177,7 +2379,7 @@ skip_ack_check: | |||
2177 | break; | 2379 | break; |
2178 | 2380 | ||
2179 | default: | 2381 | default: |
2180 | if (!qlcnic_start_firmware(adapter)) { | 2382 | if (!adapter->nic_ops->start_firmware(adapter)) { |
2181 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); | 2383 | qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); |
2182 | return; | 2384 | return; |
2183 | } | 2385 | } |
@@ -2251,6 +2453,26 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) | |||
2251 | qlcnic_api_unlock(adapter); | 2453 | qlcnic_api_unlock(adapter); |
2252 | } | 2454 | } |
2253 | 2455 | ||
2456 | /* Transit to NPAR READY state from NPAR NOT READY state */ | ||
2457 | static void | ||
2458 | qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) | ||
2459 | { | ||
2460 | u32 state; | ||
2461 | |||
2462 | if (qlcnic_api_lock(adapter)) | ||
2463 | return; | ||
2464 | |||
2465 | state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); | ||
2466 | |||
2467 | if (state != QLCNIC_DEV_NPAR_RDY) { | ||
2468 | QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, | ||
2469 | QLCNIC_DEV_NPAR_RDY); | ||
2470 | QLCDB(adapter, DRV, "NPAR READY state set\n"); | ||
2471 | } | ||
2472 | |||
2473 | qlcnic_api_unlock(adapter); | ||
2474 | } | ||
2475 | |||
2254 | static void | 2476 | static void |
2255 | qlcnic_schedule_work(struct qlcnic_adapter *adapter, | 2477 | qlcnic_schedule_work(struct qlcnic_adapter *adapter, |
2256 | work_func_t func, int delay) | 2478 | work_func_t func, int delay) |
@@ -2365,6 +2587,46 @@ reschedule: | |||
2365 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); | 2587 | qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); |
2366 | } | 2588 | } |
2367 | 2589 | ||
2590 | static int | ||
2591 | qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) | ||
2592 | { | ||
2593 | int err; | ||
2594 | |||
2595 | err = qlcnic_can_start_firmware(adapter); | ||
2596 | if (err) | ||
2597 | return err; | ||
2598 | |||
2599 | qlcnic_check_options(adapter); | ||
2600 | |||
2601 | adapter->need_fw_reset = 0; | ||
2602 | |||
2603 | return err; | ||
2604 | } | ||
2605 | |||
2606 | static int | ||
2607 | qlcnicvf_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable) | ||
2608 | { | ||
2609 | return -EOPNOTSUPP; | ||
2610 | } | ||
2611 | |||
2612 | static int | ||
2613 | qlcnicvf_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate) | ||
2614 | { | ||
2615 | return -EOPNOTSUPP; | ||
2616 | } | ||
2617 | |||
2618 | static int | ||
2619 | qlcnicvf_set_ilb_mode(struct qlcnic_adapter *adapter) | ||
2620 | { | ||
2621 | return -EOPNOTSUPP; | ||
2622 | } | ||
2623 | |||
2624 | static void | ||
2625 | qlcnicvf_clear_ilb_mode(struct qlcnic_adapter *adapter) | ||
2626 | { | ||
2627 | return; | ||
2628 | } | ||
2629 | |||
2368 | static ssize_t | 2630 | static ssize_t |
2369 | qlcnic_store_bridged_mode(struct device *dev, | 2631 | qlcnic_store_bridged_mode(struct device *dev, |
2370 | struct device_attribute *attr, const char *buf, size_t len) | 2632 | struct device_attribute *attr, const char *buf, size_t len) |
@@ -2382,7 +2644,7 @@ qlcnic_store_bridged_mode(struct device *dev, | |||
2382 | if (strict_strtoul(buf, 2, &new)) | 2644 | if (strict_strtoul(buf, 2, &new)) |
2383 | goto err_out; | 2645 | goto err_out; |
2384 | 2646 | ||
2385 | if (!qlcnic_config_bridged_mode(adapter, !!new)) | 2647 | if (!adapter->nic_ops->config_bridged_mode(adapter, !!new)) |
2386 | ret = len; | 2648 | ret = len; |
2387 | 2649 | ||
2388 | err_out: | 2650 | err_out: |
@@ -2464,7 +2726,8 @@ qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, | |||
2464 | } | 2726 | } |
2465 | 2727 | ||
2466 | static ssize_t | 2728 | static ssize_t |
2467 | qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, | 2729 | qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj, |
2730 | struct bin_attribute *attr, | ||
2468 | char *buf, loff_t offset, size_t size) | 2731 | char *buf, loff_t offset, size_t size) |
2469 | { | 2732 | { |
2470 | struct device *dev = container_of(kobj, struct device, kobj); | 2733 | struct device *dev = container_of(kobj, struct device, kobj); |
@@ -2488,7 +2751,8 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, | |||
2488 | } | 2751 | } |
2489 | 2752 | ||
2490 | static ssize_t | 2753 | static ssize_t |
2491 | qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, | 2754 | qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj, |
2755 | struct bin_attribute *attr, | ||
2492 | char *buf, loff_t offset, size_t size) | 2756 | char *buf, loff_t offset, size_t size) |
2493 | { | 2757 | { |
2494 | struct device *dev = container_of(kobj, struct device, kobj); | 2758 | struct device *dev = container_of(kobj, struct device, kobj); |
@@ -2525,7 +2789,8 @@ qlcnic_sysfs_validate_mem(struct qlcnic_adapter *adapter, | |||
2525 | } | 2789 | } |
2526 | 2790 | ||
2527 | static ssize_t | 2791 | static ssize_t |
2528 | qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, | 2792 | qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj, |
2793 | struct bin_attribute *attr, | ||
2529 | char *buf, loff_t offset, size_t size) | 2794 | char *buf, loff_t offset, size_t size) |
2530 | { | 2795 | { |
2531 | struct device *dev = container_of(kobj, struct device, kobj); | 2796 | struct device *dev = container_of(kobj, struct device, kobj); |
@@ -2546,7 +2811,8 @@ qlcnic_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr, | |||
2546 | } | 2811 | } |
2547 | 2812 | ||
2548 | static ssize_t | 2813 | static ssize_t |
2549 | qlcnic_sysfs_write_mem(struct kobject *kobj, struct bin_attribute *attr, | 2814 | qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj, |
2815 | struct bin_attribute *attr, | ||
2550 | char *buf, loff_t offset, size_t size) | 2816 | char *buf, loff_t offset, size_t size) |
2551 | { | 2817 | { |
2552 | struct device *dev = container_of(kobj, struct device, kobj); | 2818 | struct device *dev = container_of(kobj, struct device, kobj); |