diff options
-rw-r--r-- | drivers/net/ethernet/qlogic/Kconfig | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 35 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 68 |
9 files changed, 179 insertions, 26 deletions
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig index c14bd3116e45..b8184323faae 100644 --- a/drivers/net/ethernet/qlogic/Kconfig +++ b/drivers/net/ethernet/qlogic/Kconfig | |||
@@ -66,6 +66,17 @@ config QLCNIC_VXLAN | |||
66 | Say Y here if you want to enable hardware offload support for | 66 | Say Y here if you want to enable hardware offload support for |
67 | Virtual eXtensible Local Area Network (VXLAN) in the driver. | 67 | Virtual eXtensible Local Area Network (VXLAN) in the driver. |
68 | 68 | ||
69 | config QLCNIC_HWMON | ||
70 | bool "QLOGIC QLCNIC 82XX and 83XX family HWMON support" | ||
71 | depends on QLCNIC && HWMON | ||
72 | default y | ||
73 | ---help--- | ||
74 | This configuration parameter can be used to read the | ||
75 | board temperature in Converged Ethernet devices | ||
76 | supported by qlcnic. | ||
77 | |||
78 | This data is available via the hwmon sysfs interface. | ||
79 | |||
69 | config QLGE | 80 | config QLGE |
70 | tristate "QLogic QLGE 10Gb Ethernet Driver Support" | 81 | tristate "QLogic QLGE 10Gb Ethernet Driver Support" |
71 | depends on PCI | 82 | depends on PCI |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 7b52a88923ef..09fe9c276f1c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -39,8 +39,8 @@ | |||
39 | 39 | ||
40 | #define _QLCNIC_LINUX_MAJOR 5 | 40 | #define _QLCNIC_LINUX_MAJOR 5 |
41 | #define _QLCNIC_LINUX_MINOR 3 | 41 | #define _QLCNIC_LINUX_MINOR 3 |
42 | #define _QLCNIC_LINUX_SUBVERSION 57 | 42 | #define _QLCNIC_LINUX_SUBVERSION 58 |
43 | #define QLCNIC_LINUX_VERSIONID "5.3.57" | 43 | #define QLCNIC_LINUX_VERSIONID "5.3.58" |
44 | #define QLCNIC_DRV_IDC_VER 0x01 | 44 | #define QLCNIC_DRV_IDC_VER 0x01 |
45 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 45 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
46 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 46 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
@@ -537,6 +537,7 @@ struct qlcnic_hardware_context { | |||
537 | u8 phys_port_id[ETH_ALEN]; | 537 | u8 phys_port_id[ETH_ALEN]; |
538 | u8 lb_mode; | 538 | u8 lb_mode; |
539 | u16 vxlan_port; | 539 | u16 vxlan_port; |
540 | struct device *hwmon_dev; | ||
540 | }; | 541 | }; |
541 | 542 | ||
542 | struct qlcnic_adapter_stats { | 543 | struct qlcnic_adapter_stats { |
@@ -2361,4 +2362,18 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter) | |||
2361 | else | 2362 | else |
2362 | return QLC_DEFAULT_VNIC_COUNT; | 2363 | return QLC_DEFAULT_VNIC_COUNT; |
2363 | } | 2364 | } |
2365 | |||
2366 | #ifdef CONFIG_QLCNIC_HWMON | ||
2367 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *); | ||
2368 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *); | ||
2369 | #else | ||
2370 | static inline void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter) | ||
2371 | { | ||
2372 | return; | ||
2373 | } | ||
2374 | static inline void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter) | ||
2375 | { | ||
2376 | return; | ||
2377 | } | ||
2378 | #endif | ||
2364 | #endif /* __QLCNIC_H_ */ | 2379 | #endif /* __QLCNIC_H_ */ |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index b7cffb46a75d..7c125d7fb547 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -33,6 +33,7 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *); | |||
33 | #define RSS_HASHTYPE_IP_TCP 0x3 | 33 | #define RSS_HASHTYPE_IP_TCP 0x3 |
34 | #define QLC_83XX_FW_MBX_CMD 0 | 34 | #define QLC_83XX_FW_MBX_CMD 0 |
35 | #define QLC_SKIP_INACTIVE_PCI_REGS 7 | 35 | #define QLC_SKIP_INACTIVE_PCI_REGS 7 |
36 | #define QLC_MAX_LEGACY_FUNC_SUPP 8 | ||
36 | 37 | ||
37 | static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { | 38 | static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = { |
38 | {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, | 39 | {QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1}, |
@@ -357,8 +358,15 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) | |||
357 | if (!ahw->intr_tbl) | 358 | if (!ahw->intr_tbl) |
358 | return -ENOMEM; | 359 | return -ENOMEM; |
359 | 360 | ||
360 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) | 361 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { |
362 | if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) { | ||
363 | dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n", | ||
364 | ahw->pci_func); | ||
365 | return -EOPNOTSUPP; | ||
366 | } | ||
367 | |||
361 | qlcnic_83xx_enable_legacy(adapter); | 368 | qlcnic_83xx_enable_legacy(adapter); |
369 | } | ||
362 | 370 | ||
363 | for (i = 0; i < num_msix; i++) { | 371 | for (i = 0; i < num_msix; i++) { |
364 | if (adapter->flags & QLCNIC_MSIX_ENABLED) | 372 | if (adapter->flags & QLCNIC_MSIX_ENABLED) |
@@ -879,6 +887,9 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx, | |||
879 | return 0; | 887 | return 0; |
880 | } | 888 | } |
881 | } | 889 | } |
890 | |||
891 | dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n", | ||
892 | __func__, type); | ||
882 | return -EINVAL; | 893 | return -EINVAL; |
883 | } | 894 | } |
884 | 895 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index ba20c721ee97..34d273794e96 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -2181,6 +2181,8 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) | |||
2181 | max_sds_rings = QLCNIC_MAX_SDS_RINGS; | 2181 | max_sds_rings = QLCNIC_MAX_SDS_RINGS; |
2182 | max_tx_rings = QLCNIC_MAX_TX_RINGS; | 2182 | max_tx_rings = QLCNIC_MAX_TX_RINGS; |
2183 | } else { | 2183 | } else { |
2184 | dev_err(&adapter->pdev->dev, "%s: Invalid opmode %d\n", | ||
2185 | __func__, ret); | ||
2184 | return -EIO; | 2186 | return -EIO; |
2185 | } | 2187 | } |
2186 | 2188 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index c1e11f5715b0..304e247bdf33 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |||
@@ -1027,8 +1027,11 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, | |||
1027 | u32 arg1; | 1027 | u32 arg1; |
1028 | 1028 | ||
1029 | if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC || | 1029 | if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC || |
1030 | !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) | 1030 | !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) { |
1031 | dev_err(&adapter->pdev->dev, "%s: Not a management function\n", | ||
1032 | __func__); | ||
1031 | return err; | 1033 | return err; |
1034 | } | ||
1032 | 1035 | ||
1033 | arg1 = id | (enable_mirroring ? BIT_4 : 0); | 1036 | arg1 = id | (enable_mirroring ? BIT_4 : 0); |
1034 | arg1 |= pci_func << 8; | 1037 | arg1 |= pci_func << 8; |
@@ -1318,8 +1321,12 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, | |||
1318 | u32 arg1, arg2 = 0; | 1321 | u32 arg1, arg2 = 0; |
1319 | u8 pci_func; | 1322 | u8 pci_func; |
1320 | 1323 | ||
1321 | if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) | 1324 | if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) { |
1325 | dev_err(&adapter->pdev->dev, "%s: Not a management function\n", | ||
1326 | __func__); | ||
1322 | return err; | 1327 | return err; |
1328 | } | ||
1329 | |||
1323 | pci_func = esw_cfg->pci_func; | 1330 | pci_func = esw_cfg->pci_func; |
1324 | index = qlcnic_is_valid_nic_func(adapter, pci_func); | 1331 | index = qlcnic_is_valid_nic_func(adapter, pci_func); |
1325 | if (index < 0) | 1332 | if (index < 0) |
@@ -1363,6 +1370,8 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, | |||
1363 | arg1 &= ~(0x0ffff << 16); | 1370 | arg1 &= ~(0x0ffff << 16); |
1364 | break; | 1371 | break; |
1365 | default: | 1372 | default: |
1373 | dev_err(&adapter->pdev->dev, "%s: Invalid opmode 0x%x\n", | ||
1374 | __func__, esw_cfg->op_mode); | ||
1366 | return err; | 1375 | return err; |
1367 | } | 1376 | } |
1368 | 1377 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 173b3d12991f..deb2278b48d5 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -305,7 +305,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
305 | { | 305 | { |
306 | struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data); | 306 | struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data); |
307 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); | 307 | struct ethhdr *phdr = (struct ethhdr *)(skb->data); |
308 | struct net_device *netdev = adapter->netdev; | ||
309 | u16 protocol = ntohs(skb->protocol); | 308 | u16 protocol = ntohs(skb->protocol); |
310 | struct qlcnic_filter *fil, *tmp_fil; | 309 | struct qlcnic_filter *fil, *tmp_fil; |
311 | struct hlist_head *head; | 310 | struct hlist_head *head; |
@@ -330,13 +329,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
330 | return; | 329 | return; |
331 | } | 330 | } |
332 | 331 | ||
333 | if (adapter->fhash.fnum >= adapter->fhash.fmax) { | ||
334 | adapter->stats.mac_filter_limit_overrun++; | ||
335 | netdev_info(netdev, "Can not add more than %d mac-vlan filters, configured %d\n", | ||
336 | adapter->fhash.fmax, adapter->fhash.fnum); | ||
337 | return; | ||
338 | } | ||
339 | |||
340 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); | 332 | memcpy(&src_addr, phdr->h_source, ETH_ALEN); |
341 | hval = qlcnic_mac_hash(src_addr, vlan_id); | 333 | hval = qlcnic_mac_hash(src_addr, vlan_id); |
342 | hindex = hval & (adapter->fhash.fbucket_size - 1); | 334 | hindex = hval & (adapter->fhash.fbucket_size - 1); |
@@ -353,6 +345,11 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, | |||
353 | } | 345 | } |
354 | } | 346 | } |
355 | 347 | ||
348 | if (unlikely(adapter->fhash.fnum >= adapter->fhash.fmax)) { | ||
349 | adapter->stats.mac_filter_limit_overrun++; | ||
350 | return; | ||
351 | } | ||
352 | |||
356 | fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); | 353 | fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); |
357 | if (!fil) | 354 | if (!fil) |
358 | return; | 355 | return; |
@@ -1216,8 +1213,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, | |||
1216 | if (!skb) | 1213 | if (!skb) |
1217 | return buffer; | 1214 | return buffer; |
1218 | 1215 | ||
1219 | if (adapter->drv_mac_learn && | 1216 | if (adapter->rx_mac_learn) { |
1220 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1221 | t_vid = 0; | 1217 | t_vid = 0; |
1222 | is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); | 1218 | is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); |
1223 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); | 1219 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); |
@@ -1293,8 +1289,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
1293 | if (!skb) | 1289 | if (!skb) |
1294 | return buffer; | 1290 | return buffer; |
1295 | 1291 | ||
1296 | if (adapter->drv_mac_learn && | 1292 | if (adapter->rx_mac_learn) { |
1297 | (adapter->flags & QLCNIC_ESWITCH_ENABLED)) { | ||
1298 | t_vid = 0; | 1293 | t_vid = 0; |
1299 | is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); | 1294 | is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0); |
1300 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); | 1295 | qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 73f908a000e9..7023d358baa9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -1014,6 +1014,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) | |||
1014 | 1014 | ||
1015 | if (pfn >= ahw->max_vnic_func) { | 1015 | if (pfn >= ahw->max_vnic_func) { |
1016 | ret = QL_STATUS_INVALID_PARAM; | 1016 | ret = QL_STATUS_INVALID_PARAM; |
1017 | dev_err(&adapter->pdev->dev, "%s: Invalid function 0x%x, max 0x%x\n", | ||
1018 | __func__, pfn, ahw->max_vnic_func); | ||
1017 | goto err_eswitch; | 1019 | goto err_eswitch; |
1018 | } | 1020 | } |
1019 | 1021 | ||
@@ -2052,6 +2054,7 @@ out: | |||
2052 | 2054 | ||
2053 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | 2055 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) |
2054 | { | 2056 | { |
2057 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
2055 | int err = 0; | 2058 | int err = 0; |
2056 | 2059 | ||
2057 | adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), | 2060 | adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), |
@@ -2061,6 +2064,18 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | |||
2061 | goto err_out; | 2064 | goto err_out; |
2062 | } | 2065 | } |
2063 | 2066 | ||
2067 | if (qlcnic_83xx_check(adapter)) { | ||
2068 | ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX; | ||
2069 | ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; | ||
2070 | ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; | ||
2071 | ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; | ||
2072 | ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; | ||
2073 | } else { | ||
2074 | ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; | ||
2075 | ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; | ||
2076 | ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; | ||
2077 | } | ||
2078 | |||
2064 | /* clear stats */ | 2079 | /* clear stats */ |
2065 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | 2080 | memset(&adapter->stats, 0, sizeof(adapter->stats)); |
2066 | err_out: | 2081 | err_out: |
@@ -2517,9 +2532,11 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2517 | case -ENOMEM: | 2532 | case -ENOMEM: |
2518 | dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); | 2533 | dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n"); |
2519 | goto err_out_free_hw; | 2534 | goto err_out_free_hw; |
2535 | case -EOPNOTSUPP: | ||
2536 | dev_err(&pdev->dev, "Adapter initialization failed\n"); | ||
2537 | goto err_out_free_hw; | ||
2520 | default: | 2538 | default: |
2521 | dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n"); | 2539 | dev_err(&pdev->dev, "Adapter initialization failed. Driver will load in maintenance mode to recover the adapter using the application\n"); |
2522 | dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n"); | ||
2523 | goto err_out_maintenance_mode; | 2540 | goto err_out_maintenance_mode; |
2524 | } | 2541 | } |
2525 | } | 2542 | } |
@@ -2593,7 +2610,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2593 | qlcnic_alloc_lb_filters_mem(adapter); | 2610 | qlcnic_alloc_lb_filters_mem(adapter); |
2594 | 2611 | ||
2595 | qlcnic_add_sysfs(adapter); | 2612 | qlcnic_add_sysfs(adapter); |
2596 | 2613 | qlcnic_register_hwmon_dev(adapter); | |
2597 | return 0; | 2614 | return 0; |
2598 | 2615 | ||
2599 | err_out_disable_mbx_intr: | 2616 | err_out_disable_mbx_intr: |
@@ -2700,6 +2717,8 @@ static void qlcnic_remove(struct pci_dev *pdev) | |||
2700 | 2717 | ||
2701 | qlcnic_remove_sysfs(adapter); | 2718 | qlcnic_remove_sysfs(adapter); |
2702 | 2719 | ||
2720 | qlcnic_unregister_hwmon_dev(adapter); | ||
2721 | |||
2703 | qlcnic_cleanup_pci_map(adapter->ahw); | 2722 | qlcnic_cleanup_pci_map(adapter->ahw); |
2704 | 2723 | ||
2705 | qlcnic_release_firmware(adapter); | 2724 | qlcnic_release_firmware(adapter); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 280137991544..c7926ce85fec 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #define QLC_VF_FLOOD_BIT BIT_16 | 16 | #define QLC_VF_FLOOD_BIT BIT_16 |
17 | #define QLC_FLOOD_MODE 0x5 | 17 | #define QLC_FLOOD_MODE 0x5 |
18 | #define QLC_SRIOV_ALLOW_VLAN0 BIT_19 | 18 | #define QLC_SRIOV_ALLOW_VLAN0 BIT_19 |
19 | #define QLC_INTR_COAL_TYPE_MASK 0x7 | ||
19 | 20 | ||
20 | static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); | 21 | static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8); |
21 | 22 | ||
@@ -1178,19 +1179,41 @@ static int qlcnic_sriov_validate_cfg_intrcoal(struct qlcnic_adapter *adapter, | |||
1178 | { | 1179 | { |
1179 | struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; | 1180 | struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; |
1180 | u16 ctx_id, pkts, time; | 1181 | u16 ctx_id, pkts, time; |
1182 | int err = -EINVAL; | ||
1183 | u8 type; | ||
1181 | 1184 | ||
1185 | type = cmd->req.arg[1] & QLC_INTR_COAL_TYPE_MASK; | ||
1182 | ctx_id = cmd->req.arg[1] >> 16; | 1186 | ctx_id = cmd->req.arg[1] >> 16; |
1183 | pkts = cmd->req.arg[2] & 0xffff; | 1187 | pkts = cmd->req.arg[2] & 0xffff; |
1184 | time = cmd->req.arg[2] >> 16; | 1188 | time = cmd->req.arg[2] >> 16; |
1185 | 1189 | ||
1186 | if (ctx_id != vf->rx_ctx_id) | 1190 | switch (type) { |
1187 | return -EINVAL; | 1191 | case QLCNIC_INTR_COAL_TYPE_RX: |
1188 | if (pkts > coal->rx_packets) | 1192 | if (ctx_id != vf->rx_ctx_id || pkts > coal->rx_packets || |
1189 | return -EINVAL; | 1193 | time < coal->rx_time_us) |
1190 | if (time < coal->rx_time_us) | 1194 | goto err_label; |
1191 | return -EINVAL; | 1195 | break; |
1196 | case QLCNIC_INTR_COAL_TYPE_TX: | ||
1197 | if (ctx_id != vf->tx_ctx_id || pkts > coal->tx_packets || | ||
1198 | time < coal->tx_time_us) | ||
1199 | goto err_label; | ||
1200 | break; | ||
1201 | default: | ||
1202 | netdev_err(adapter->netdev, "Invalid coalescing type 0x%x received\n", | ||
1203 | type); | ||
1204 | return err; | ||
1205 | } | ||
1192 | 1206 | ||
1193 | return 0; | 1207 | return 0; |
1208 | |||
1209 | err_label: | ||
1210 | netdev_err(adapter->netdev, "Expected: rx_ctx_id 0x%x rx_packets 0x%x rx_time_us 0x%x tx_ctx_id 0x%x tx_packets 0x%x tx_time_us 0x%x\n", | ||
1211 | vf->rx_ctx_id, coal->rx_packets, coal->rx_time_us, | ||
1212 | vf->tx_ctx_id, coal->tx_packets, coal->tx_time_us); | ||
1213 | netdev_err(adapter->netdev, "Received: ctx_id 0x%x packets 0x%x time_us 0x%x type 0x%x\n", | ||
1214 | ctx_id, pkts, time, type); | ||
1215 | |||
1216 | return err; | ||
1194 | } | 1217 | } |
1195 | 1218 | ||
1196 | static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran, | 1219 | static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index cd346e27f2e1..f5786d5792df 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | |||
@@ -19,6 +19,10 @@ | |||
19 | #include <linux/sysfs.h> | 19 | #include <linux/sysfs.h> |
20 | #include <linux/aer.h> | 20 | #include <linux/aer.h> |
21 | #include <linux/log2.h> | 21 | #include <linux/log2.h> |
22 | #ifdef CONFIG_QLCNIC_HWMON | ||
23 | #include <linux/hwmon.h> | ||
24 | #include <linux/hwmon-sysfs.h> | ||
25 | #endif | ||
22 | 26 | ||
23 | #define QLC_STATUS_UNSUPPORTED_CMD -2 | 27 | #define QLC_STATUS_UNSUPPORTED_CMD -2 |
24 | 28 | ||
@@ -358,6 +362,8 @@ int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) | |||
358 | if (adapter->npars[i].pci_func == pci_func) | 362 | if (adapter->npars[i].pci_func == pci_func) |
359 | return i; | 363 | return i; |
360 | } | 364 | } |
365 | |||
366 | dev_err(&adapter->pdev->dev, "%s: Invalid nic function\n", __func__); | ||
361 | return -EINVAL; | 367 | return -EINVAL; |
362 | } | 368 | } |
363 | 369 | ||
@@ -1243,6 +1249,68 @@ static struct bin_attribute bin_attr_flash = { | |||
1243 | .write = qlcnic_83xx_sysfs_flash_write_handler, | 1249 | .write = qlcnic_83xx_sysfs_flash_write_handler, |
1244 | }; | 1250 | }; |
1245 | 1251 | ||
1252 | #ifdef CONFIG_QLCNIC_HWMON | ||
1253 | |||
1254 | static ssize_t qlcnic_hwmon_show_temp(struct device *dev, | ||
1255 | struct device_attribute *dev_attr, | ||
1256 | char *buf) | ||
1257 | { | ||
1258 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | ||
1259 | unsigned int temperature = 0, value = 0; | ||
1260 | |||
1261 | if (qlcnic_83xx_check(adapter)) | ||
1262 | value = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP); | ||
1263 | else if (qlcnic_82xx_check(adapter)) | ||
1264 | value = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP); | ||
1265 | |||
1266 | temperature = qlcnic_get_temp_val(value); | ||
1267 | /* display millidegree celcius */ | ||
1268 | temperature *= 1000; | ||
1269 | return sprintf(buf, "%u\n", temperature); | ||
1270 | } | ||
1271 | |||
1272 | /* hwmon-sysfs attributes */ | ||
1273 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | ||
1274 | qlcnic_hwmon_show_temp, NULL, 1); | ||
1275 | |||
1276 | static struct attribute *qlcnic_hwmon_attrs[] = { | ||
1277 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1278 | NULL | ||
1279 | }; | ||
1280 | |||
1281 | ATTRIBUTE_GROUPS(qlcnic_hwmon); | ||
1282 | |||
1283 | void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter) | ||
1284 | { | ||
1285 | struct device *dev = &adapter->pdev->dev; | ||
1286 | struct device *hwmon_dev; | ||
1287 | |||
1288 | /* Skip hwmon registration for a VF device */ | ||
1289 | if (qlcnic_sriov_vf_check(adapter)) { | ||
1290 | adapter->ahw->hwmon_dev = NULL; | ||
1291 | return; | ||
1292 | } | ||
1293 | hwmon_dev = hwmon_device_register_with_groups(dev, qlcnic_driver_name, | ||
1294 | adapter, | ||
1295 | qlcnic_hwmon_groups); | ||
1296 | if (IS_ERR(hwmon_dev)) { | ||
1297 | dev_err(dev, "Cannot register with hwmon, err=%ld\n", | ||
1298 | PTR_ERR(hwmon_dev)); | ||
1299 | hwmon_dev = NULL; | ||
1300 | } | ||
1301 | adapter->ahw->hwmon_dev = hwmon_dev; | ||
1302 | } | ||
1303 | |||
1304 | void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter) | ||
1305 | { | ||
1306 | struct device *hwmon_dev = adapter->ahw->hwmon_dev; | ||
1307 | if (hwmon_dev) { | ||
1308 | hwmon_device_unregister(hwmon_dev); | ||
1309 | adapter->ahw->hwmon_dev = NULL; | ||
1310 | } | ||
1311 | } | ||
1312 | #endif | ||
1313 | |||
1246 | void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) | 1314 | void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter) |
1247 | { | 1315 | { |
1248 | struct device *dev = &adapter->pdev->dev; | 1316 | struct device *dev = &adapter->pdev->dev; |