diff options
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 14 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_ctx.c | 7 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_init.c | 35 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 35 |
4 files changed, 72 insertions, 19 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 7d31caaf2fa8..9970cff598d1 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -51,8 +51,8 @@ | |||
51 | 51 | ||
52 | #define _QLCNIC_LINUX_MAJOR 5 | 52 | #define _QLCNIC_LINUX_MAJOR 5 |
53 | #define _QLCNIC_LINUX_MINOR 0 | 53 | #define _QLCNIC_LINUX_MINOR 0 |
54 | #define _QLCNIC_LINUX_SUBVERSION 4 | 54 | #define _QLCNIC_LINUX_SUBVERSION 5 |
55 | #define QLCNIC_LINUX_VERSIONID "5.0.4" | 55 | #define QLCNIC_LINUX_VERSIONID "5.0.5" |
56 | #define QLCNIC_DRV_IDC_VER 0x01 | 56 | #define QLCNIC_DRV_IDC_VER 0x01 |
57 | 57 | ||
58 | #define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 58 | #define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
@@ -68,6 +68,7 @@ | |||
68 | #define QLCNIC_DECODE_VERSION(v) \ | 68 | #define QLCNIC_DECODE_VERSION(v) \ |
69 | QLCNIC_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16)) | 69 | QLCNIC_VERSION_CODE(((v) & 0xff), (((v) >> 8) & 0xff), ((v) >> 16)) |
70 | 70 | ||
71 | #define QLCNIC_MIN_FW_VERSION QLCNIC_VERSION_CODE(4, 4, 2) | ||
71 | #define QLCNIC_NUM_FLASH_SECTORS (64) | 72 | #define QLCNIC_NUM_FLASH_SECTORS (64) |
72 | #define QLCNIC_FLASH_SECTOR_SIZE (64 * 1024) | 73 | #define QLCNIC_FLASH_SECTOR_SIZE (64 * 1024) |
73 | #define QLCNIC_FLASH_TOTAL_SIZE (QLCNIC_NUM_FLASH_SECTORS \ | 74 | #define QLCNIC_FLASH_TOTAL_SIZE (QLCNIC_NUM_FLASH_SECTORS \ |
@@ -567,6 +568,7 @@ struct qlcnic_recv_context { | |||
567 | #define QLCNIC_CAP0_LSO (1 << 6) | 568 | #define QLCNIC_CAP0_LSO (1 << 6) |
568 | #define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) | 569 | #define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) |
569 | #define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) | 570 | #define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) |
571 | #define QLCNIC_CAP0_VALIDOFF (1 << 11) | ||
570 | 572 | ||
571 | /* | 573 | /* |
572 | * Context state | 574 | * Context state |
@@ -602,9 +604,10 @@ struct qlcnic_hostrq_rx_ctx { | |||
602 | __le32 sds_ring_offset; /* Offset to SDS config */ | 604 | __le32 sds_ring_offset; /* Offset to SDS config */ |
603 | __le16 num_rds_rings; /* Count of RDS rings */ | 605 | __le16 num_rds_rings; /* Count of RDS rings */ |
604 | __le16 num_sds_rings; /* Count of SDS rings */ | 606 | __le16 num_sds_rings; /* Count of SDS rings */ |
605 | __le16 rsvd1; /* Padding */ | 607 | __le16 valid_field_offset; |
606 | __le16 rsvd2; /* Padding */ | 608 | u8 txrx_sds_binding; |
607 | u8 reserved[128]; /* reserve space for future expansion*/ | 609 | u8 msix_handler; |
610 | u8 reserved[128]; /* reserve space for future expansion*/ | ||
608 | /* MUST BE 64-bit aligned. | 611 | /* MUST BE 64-bit aligned. |
609 | The following is packed: | 612 | The following is packed: |
610 | - N hostrq_rds_rings | 613 | - N hostrq_rds_rings |
@@ -1109,6 +1112,7 @@ void qlcnic_request_firmware(struct qlcnic_adapter *adapter); | |||
1109 | void qlcnic_release_firmware(struct qlcnic_adapter *adapter); | 1112 | void qlcnic_release_firmware(struct qlcnic_adapter *adapter); |
1110 | int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter); | 1113 | int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter); |
1111 | int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter); | 1114 | int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter); |
1115 | int qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter); | ||
1112 | 1116 | ||
1113 | int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp); | 1117 | int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp); |
1114 | int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr, | 1118 | int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr, |
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 90ed6fbaee34..7c96c8e06c3f 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c | |||
@@ -152,9 +152,14 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
152 | 152 | ||
153 | prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); | 153 | prq->host_rsp_dma_addr = cpu_to_le64(cardrsp_phys_addr); |
154 | 154 | ||
155 | cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN); | 155 | cap = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN |
156 | | QLCNIC_CAP0_VALIDOFF); | ||
156 | cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); | 157 | cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); |
157 | 158 | ||
159 | prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx, | ||
160 | msix_handler); | ||
161 | prq->txrx_sds_binding = nsds_rings - 1; | ||
162 | |||
158 | prq->capabilities[0] = cpu_to_le32(cap); | 163 | prq->capabilities[0] = cpu_to_le32(cap); |
159 | prq->host_int_crb_mode = | 164 | prq->host_int_crb_mode = |
160 | cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED); | 165 | cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED); |
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 317750d67931..2bd00d54dd3f 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c | |||
@@ -543,16 +543,34 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) { | |||
543 | return 0; | 543 | return 0; |
544 | } | 544 | } |
545 | 545 | ||
546 | int | ||
547 | qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter) | ||
548 | { | ||
549 | u32 ver = -1, min_ver; | ||
550 | |||
551 | qlcnic_rom_fast_read(adapter, QLCNIC_FW_VERSION_OFFSET, (int *)&ver); | ||
552 | |||
553 | ver = QLCNIC_DECODE_VERSION(ver); | ||
554 | min_ver = QLCNIC_MIN_FW_VERSION; | ||
555 | |||
556 | if (ver < min_ver) { | ||
557 | dev_err(&adapter->pdev->dev, | ||
558 | "firmware version %d.%d.%d unsupported." | ||
559 | "Min supported version %d.%d.%d\n", | ||
560 | _major(ver), _minor(ver), _build(ver), | ||
561 | _major(min_ver), _minor(min_ver), _build(min_ver)); | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
546 | static int | 568 | static int |
547 | qlcnic_has_mn(struct qlcnic_adapter *adapter) | 569 | qlcnic_has_mn(struct qlcnic_adapter *adapter) |
548 | { | 570 | { |
549 | u32 capability, flashed_ver; | 571 | u32 capability; |
550 | capability = 0; | 572 | capability = 0; |
551 | 573 | ||
552 | qlcnic_rom_fast_read(adapter, | ||
553 | QLCNIC_FW_VERSION_OFFSET, (int *)&flashed_ver); | ||
554 | flashed_ver = QLCNIC_DECODE_VERSION(flashed_ver); | ||
555 | |||
556 | capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY); | 574 | capability = QLCRD32(adapter, QLCNIC_PEG_TUNE_CAPABILITY); |
557 | if (capability & QLCNIC_PEG_TUNE_MN_PRESENT) | 575 | if (capability & QLCNIC_PEG_TUNE_MN_PRESENT) |
558 | return 1; | 576 | return 1; |
@@ -1006,7 +1024,7 @@ static int | |||
1006 | qlcnic_validate_firmware(struct qlcnic_adapter *adapter) | 1024 | qlcnic_validate_firmware(struct qlcnic_adapter *adapter) |
1007 | { | 1025 | { |
1008 | __le32 val; | 1026 | __le32 val; |
1009 | u32 ver, min_ver, bios, min_size; | 1027 | u32 ver, bios, min_size; |
1010 | struct pci_dev *pdev = adapter->pdev; | 1028 | struct pci_dev *pdev = adapter->pdev; |
1011 | const struct firmware *fw = adapter->fw; | 1029 | const struct firmware *fw = adapter->fw; |
1012 | u8 fw_type = adapter->fw_type; | 1030 | u8 fw_type = adapter->fw_type; |
@@ -1028,12 +1046,9 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter) | |||
1028 | return -EINVAL; | 1046 | return -EINVAL; |
1029 | 1047 | ||
1030 | val = qlcnic_get_fw_version(adapter); | 1048 | val = qlcnic_get_fw_version(adapter); |
1031 | |||
1032 | min_ver = QLCNIC_VERSION_CODE(4, 0, 216); | ||
1033 | |||
1034 | ver = QLCNIC_DECODE_VERSION(val); | 1049 | ver = QLCNIC_DECODE_VERSION(val); |
1035 | 1050 | ||
1036 | if ((_major(ver) > _QLCNIC_LINUX_MAJOR) || (ver < min_ver)) { | 1051 | if (ver < QLCNIC_MIN_FW_VERSION) { |
1037 | dev_err(&pdev->dev, | 1052 | dev_err(&pdev->dev, |
1038 | "%s: firmware version %d.%d.%d unsupported\n", | 1053 | "%s: firmware version %d.%d.%d unsupported\n", |
1039 | fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); | 1054 | fw_name[fw_type], _major(ver), _minor(ver), _build(ver)); |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 28ed28c1cbcc..06d2dfd646fe 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -83,6 +83,7 @@ static void qlcnic_schedule_work(struct qlcnic_adapter *adapter, | |||
83 | work_func_t func, int delay); | 83 | work_func_t func, int delay); |
84 | static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); | 84 | static void qlcnic_cancel_fw_work(struct qlcnic_adapter *adapter); |
85 | 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); | ||
86 | #ifdef CONFIG_NET_POLL_CONTROLLER | 87 | #ifdef CONFIG_NET_POLL_CONTROLLER |
87 | static void qlcnic_poll_controller(struct net_device *netdev); | 88 | static void qlcnic_poll_controller(struct net_device *netdev); |
88 | #endif | 89 | #endif |
@@ -195,8 +196,13 @@ qlcnic_napi_add(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
195 | 196 | ||
196 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 197 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
197 | sds_ring = &recv_ctx->sds_rings[ring]; | 198 | sds_ring = &recv_ctx->sds_rings[ring]; |
198 | netif_napi_add(netdev, &sds_ring->napi, | 199 | |
199 | qlcnic_poll, QLCNIC_NETDEV_WEIGHT); | 200 | if (ring == adapter->max_sds_rings - 1) |
201 | netif_napi_add(netdev, &sds_ring->napi, qlcnic_poll, | ||
202 | QLCNIC_NETDEV_WEIGHT/adapter->max_sds_rings); | ||
203 | else | ||
204 | netif_napi_add(netdev, &sds_ring->napi, | ||
205 | qlcnic_rx_poll, QLCNIC_NETDEV_WEIGHT*2); | ||
200 | } | 206 | } |
201 | 207 | ||
202 | return 0; | 208 | return 0; |
@@ -743,8 +749,12 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) | |||
743 | 749 | ||
744 | if (load_fw_file) | 750 | if (load_fw_file) |
745 | qlcnic_request_firmware(adapter); | 751 | qlcnic_request_firmware(adapter); |
746 | else | 752 | else { |
753 | if (qlcnic_check_flash_fw_ver(adapter)) | ||
754 | goto err_out; | ||
755 | |||
747 | adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; | 756 | adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; |
757 | } | ||
748 | 758 | ||
749 | err = qlcnic_need_fw_reset(adapter); | 759 | err = qlcnic_need_fw_reset(adapter); |
750 | if (err < 0) | 760 | if (err < 0) |
@@ -2060,6 +2070,25 @@ static int qlcnic_poll(struct napi_struct *napi, int budget) | |||
2060 | return work_done; | 2070 | return work_done; |
2061 | } | 2071 | } |
2062 | 2072 | ||
2073 | static int qlcnic_rx_poll(struct napi_struct *napi, int budget) | ||
2074 | { | ||
2075 | struct qlcnic_host_sds_ring *sds_ring = | ||
2076 | container_of(napi, struct qlcnic_host_sds_ring, napi); | ||
2077 | |||
2078 | struct qlcnic_adapter *adapter = sds_ring->adapter; | ||
2079 | int work_done; | ||
2080 | |||
2081 | work_done = qlcnic_process_rcv_ring(sds_ring, budget); | ||
2082 | |||
2083 | if (work_done < budget) { | ||
2084 | napi_complete(&sds_ring->napi); | ||
2085 | if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) | ||
2086 | qlcnic_enable_int(sds_ring); | ||
2087 | } | ||
2088 | |||
2089 | return work_done; | ||
2090 | } | ||
2091 | |||
2063 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2092 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2064 | static void qlcnic_poll_controller(struct net_device *netdev) | 2093 | static void qlcnic_poll_controller(struct net_device *netdev) |
2065 | { | 2094 | { |