diff options
author | David S. Miller <davem@davemloft.net> | 2014-08-02 18:59:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-02 18:59:22 -0400 |
commit | 58e70b59407a2407d7033588ebf0186fd65fa963 (patch) | |
tree | a044460f3c86fa21bb1628935897538b90dc7fff | |
parent | 7e32aa4d8cc075e5109170ae8c43be550cebb14a (diff) | |
parent | f0613380152a9290b68390ce60ba400ed25c780d (diff) |
Merge branch 'be2net-next'
Sathya Perla says:
====================
be2net: patch set
Patch 1 fixes a regression caused by a previous commit on net-next.
Old versions of BE3 FW may not support cmds to re-provision (and hence
optimize) resources/queues in SR-IOV config. Do not treat this FW cmd
failure as fatal and fail the function initialization. Instead, just
enable SR-IOV with the resources provided by the FW.
Patch 2 ignores a VF mac address setting if the new mac is already active
on the VF.
Patch 3 adds support to delete a FW-dump via ethtool on Lancer adapters.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 73 |
5 files changed, 108 insertions, 42 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 0048ef8e5f35..811f1351db7a 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -383,8 +383,10 @@ enum vf_state { | |||
383 | 383 | ||
384 | #define BE_UC_PMAC_COUNT 30 | 384 | #define BE_UC_PMAC_COUNT 30 |
385 | #define BE_VF_UC_PMAC_COUNT 2 | 385 | #define BE_VF_UC_PMAC_COUNT 2 |
386 | |||
386 | /* Ethtool set_dump flags */ | 387 | /* Ethtool set_dump flags */ |
387 | #define LANCER_INITIATE_FW_DUMP 0x1 | 388 | #define LANCER_INITIATE_FW_DUMP 0x1 |
389 | #define LANCER_DELETE_FW_DUMP 0x2 | ||
388 | 390 | ||
389 | struct phy_info { | 391 | struct phy_info { |
390 | u8 transceiver; | 392 | u8 transceiver; |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 791094c33535..4370ec1952ac 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -2240,6 +2240,34 @@ err_unlock: | |||
2240 | return status; | 2240 | return status; |
2241 | } | 2241 | } |
2242 | 2242 | ||
2243 | int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name) | ||
2244 | { | ||
2245 | struct lancer_cmd_req_delete_object *req; | ||
2246 | struct be_mcc_wrb *wrb; | ||
2247 | int status; | ||
2248 | |||
2249 | spin_lock_bh(&adapter->mcc_lock); | ||
2250 | |||
2251 | wrb = wrb_from_mccq(adapter); | ||
2252 | if (!wrb) { | ||
2253 | status = -EBUSY; | ||
2254 | goto err; | ||
2255 | } | ||
2256 | |||
2257 | req = embedded_payload(wrb); | ||
2258 | |||
2259 | be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2260 | OPCODE_COMMON_DELETE_OBJECT, | ||
2261 | sizeof(*req), wrb, NULL); | ||
2262 | |||
2263 | strcpy(req->object_name, obj_name); | ||
2264 | |||
2265 | status = be_mcc_notify_wait(adapter); | ||
2266 | err: | ||
2267 | spin_unlock_bh(&adapter->mcc_lock); | ||
2268 | return status; | ||
2269 | } | ||
2270 | |||
2243 | int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | 2271 | int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, |
2244 | u32 data_size, u32 data_offset, const char *obj_name, | 2272 | u32 data_size, u32 data_offset, const char *obj_name, |
2245 | u32 *data_read, u32 *eof, u8 *addn_status) | 2273 | u32 *data_read, u32 *eof, u8 *addn_status) |
@@ -3805,13 +3833,19 @@ bool dump_present(struct be_adapter *adapter) | |||
3805 | 3833 | ||
3806 | int lancer_initiate_dump(struct be_adapter *adapter) | 3834 | int lancer_initiate_dump(struct be_adapter *adapter) |
3807 | { | 3835 | { |
3836 | struct device *dev = &adapter->pdev->dev; | ||
3808 | int status; | 3837 | int status; |
3809 | 3838 | ||
3839 | if (dump_present(adapter)) { | ||
3840 | dev_info(dev, "Previous dump not cleared, not forcing dump\n"); | ||
3841 | return -EEXIST; | ||
3842 | } | ||
3843 | |||
3810 | /* give firmware reset and diagnostic dump */ | 3844 | /* give firmware reset and diagnostic dump */ |
3811 | status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK | | 3845 | status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK | |
3812 | PHYSDEV_CONTROL_DD_MASK); | 3846 | PHYSDEV_CONTROL_DD_MASK); |
3813 | if (status < 0) { | 3847 | if (status < 0) { |
3814 | dev_err(&adapter->pdev->dev, "Firmware reset failed\n"); | 3848 | dev_err(dev, "FW reset failed\n"); |
3815 | return status; | 3849 | return status; |
3816 | } | 3850 | } |
3817 | 3851 | ||
@@ -3820,13 +3854,21 @@ int lancer_initiate_dump(struct be_adapter *adapter) | |||
3820 | return status; | 3854 | return status; |
3821 | 3855 | ||
3822 | if (!dump_present(adapter)) { | 3856 | if (!dump_present(adapter)) { |
3823 | dev_err(&adapter->pdev->dev, "Dump image not present\n"); | 3857 | dev_err(dev, "FW dump not generated\n"); |
3824 | return -1; | 3858 | return -EIO; |
3825 | } | 3859 | } |
3826 | 3860 | ||
3827 | return 0; | 3861 | return 0; |
3828 | } | 3862 | } |
3829 | 3863 | ||
3864 | int lancer_delete_dump(struct be_adapter *adapter) | ||
3865 | { | ||
3866 | int status; | ||
3867 | |||
3868 | status = lancer_cmd_delete_object(adapter, LANCER_FW_DUMP_FILE); | ||
3869 | return be_cmd_status(status); | ||
3870 | } | ||
3871 | |||
3830 | /* Uses sync mcc */ | 3872 | /* Uses sync mcc */ |
3831 | int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) | 3873 | int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain) |
3832 | { | 3874 | { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 03e8a15c6922..5284b825bba2 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -231,6 +231,7 @@ struct be_mcc_mailbox { | |||
231 | #define OPCODE_COMMON_GET_FN_PRIVILEGES 170 | 231 | #define OPCODE_COMMON_GET_FN_PRIVILEGES 170 |
232 | #define OPCODE_COMMON_READ_OBJECT 171 | 232 | #define OPCODE_COMMON_READ_OBJECT 171 |
233 | #define OPCODE_COMMON_WRITE_OBJECT 172 | 233 | #define OPCODE_COMMON_WRITE_OBJECT 172 |
234 | #define OPCODE_COMMON_DELETE_OBJECT 174 | ||
234 | #define OPCODE_COMMON_MANAGE_IFACE_FILTERS 193 | 235 | #define OPCODE_COMMON_MANAGE_IFACE_FILTERS 193 |
235 | #define OPCODE_COMMON_GET_IFACE_LIST 194 | 236 | #define OPCODE_COMMON_GET_IFACE_LIST 194 |
236 | #define OPCODE_COMMON_ENABLE_DISABLE_VF 196 | 237 | #define OPCODE_COMMON_ENABLE_DISABLE_VF 196 |
@@ -1253,6 +1254,13 @@ struct lancer_cmd_resp_read_object { | |||
1253 | u32 eof; | 1254 | u32 eof; |
1254 | }; | 1255 | }; |
1255 | 1256 | ||
1257 | struct lancer_cmd_req_delete_object { | ||
1258 | struct be_cmd_req_hdr hdr; | ||
1259 | u32 rsvd1; | ||
1260 | u32 rsvd2; | ||
1261 | u8 object_name[104]; | ||
1262 | }; | ||
1263 | |||
1256 | /************************ WOL *******************************/ | 1264 | /************************ WOL *******************************/ |
1257 | struct be_cmd_req_acpi_wol_magic_config{ | 1265 | struct be_cmd_req_acpi_wol_magic_config{ |
1258 | struct be_cmd_req_hdr hdr; | 1266 | struct be_cmd_req_hdr hdr; |
@@ -2067,6 +2075,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | |||
2067 | int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, | 2075 | int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, |
2068 | u32 data_size, u32 data_offset, const char *obj_name, | 2076 | u32 data_size, u32 data_offset, const char *obj_name, |
2069 | u32 *data_read, u32 *eof, u8 *addn_status); | 2077 | u32 *data_read, u32 *eof, u8 *addn_status); |
2078 | int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name); | ||
2070 | int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, | 2079 | int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, |
2071 | u16 optype, int offset); | 2080 | u16 optype, int offset); |
2072 | int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, | 2081 | int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, |
@@ -2120,6 +2129,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter, | |||
2120 | struct be_fat_conf_params *cfgs); | 2129 | struct be_fat_conf_params *cfgs); |
2121 | int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask); | 2130 | int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask); |
2122 | int lancer_initiate_dump(struct be_adapter *adapter); | 2131 | int lancer_initiate_dump(struct be_adapter *adapter); |
2132 | int lancer_delete_dump(struct be_adapter *adapter); | ||
2123 | bool dump_present(struct be_adapter *adapter); | 2133 | bool dump_present(struct be_adapter *adapter); |
2124 | int lancer_test_and_set_rdy_state(struct be_adapter *adapter); | 2134 | int lancer_test_and_set_rdy_state(struct be_adapter *adapter); |
2125 | int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); | 2135 | int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name); |
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 25f516d6eb9e..0cd3311409a8 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c | |||
@@ -681,22 +681,21 @@ static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump) | |||
681 | struct device *dev = &adapter->pdev->dev; | 681 | struct device *dev = &adapter->pdev->dev; |
682 | int status; | 682 | int status; |
683 | 683 | ||
684 | if (!lancer_chip(adapter)) { | 684 | if (!lancer_chip(adapter) || |
685 | dev_err(dev, "FW dump not supported\n"); | 685 | !check_privilege(adapter, MAX_PRIVILEGES)) |
686 | return -EOPNOTSUPP; | 686 | return -EOPNOTSUPP; |
687 | } | ||
688 | |||
689 | if (dump_present(adapter)) { | ||
690 | dev_err(dev, "Previous dump not cleared, not forcing dump\n"); | ||
691 | return 0; | ||
692 | } | ||
693 | 687 | ||
694 | switch (dump->flag) { | 688 | switch (dump->flag) { |
695 | case LANCER_INITIATE_FW_DUMP: | 689 | case LANCER_INITIATE_FW_DUMP: |
696 | status = lancer_initiate_dump(adapter); | 690 | status = lancer_initiate_dump(adapter); |
697 | if (!status) | 691 | if (!status) |
698 | dev_info(dev, "F/w dump initiated successfully\n"); | 692 | dev_info(dev, "FW dump initiated successfully\n"); |
699 | break; | 693 | break; |
694 | case LANCER_DELETE_FW_DUMP: | ||
695 | status = lancer_delete_dump(adapter); | ||
696 | if (!status) | ||
697 | dev_info(dev, "FW dump deleted successfully\n"); | ||
698 | break; | ||
700 | default: | 699 | default: |
701 | dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag); | 700 | dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag); |
702 | return -EINVAL; | 701 | return -EINVAL; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 9c50814f1e95..db4ff14ff18f 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -1270,6 +1270,12 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) | |||
1270 | if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs) | 1270 | if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs) |
1271 | return -EINVAL; | 1271 | return -EINVAL; |
1272 | 1272 | ||
1273 | /* Proceed further only if user provided MAC is different | ||
1274 | * from active MAC | ||
1275 | */ | ||
1276 | if (ether_addr_equal(mac, vf_cfg->mac_addr)) | ||
1277 | return 0; | ||
1278 | |||
1273 | if (BEx_chip(adapter)) { | 1279 | if (BEx_chip(adapter)) { |
1274 | be_cmd_pmac_del(adapter, vf_cfg->if_handle, vf_cfg->pmac_id, | 1280 | be_cmd_pmac_del(adapter, vf_cfg->if_handle, vf_cfg->pmac_id, |
1275 | vf + 1); | 1281 | vf + 1); |
@@ -3342,22 +3348,17 @@ static int be_get_sriov_config(struct be_adapter *adapter) | |||
3342 | { | 3348 | { |
3343 | struct device *dev = &adapter->pdev->dev; | 3349 | struct device *dev = &adapter->pdev->dev; |
3344 | struct be_resources res = {0}; | 3350 | struct be_resources res = {0}; |
3345 | int status, max_vfs, old_vfs; | 3351 | int max_vfs, old_vfs; |
3346 | |||
3347 | status = be_cmd_get_profile_config(adapter, &res, 0); | ||
3348 | if (status) | ||
3349 | return status; | ||
3350 | |||
3351 | adapter->pool_res = res; | ||
3352 | 3352 | ||
3353 | /* Some old versions of BE3 FW don't report max_vfs value */ | 3353 | /* Some old versions of BE3 FW don't report max_vfs value */ |
3354 | be_cmd_get_profile_config(adapter, &res, 0); | ||
3355 | |||
3354 | if (BE3_chip(adapter) && !res.max_vfs) { | 3356 | if (BE3_chip(adapter) && !res.max_vfs) { |
3355 | max_vfs = pci_sriov_get_totalvfs(adapter->pdev); | 3357 | max_vfs = pci_sriov_get_totalvfs(adapter->pdev); |
3356 | res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; | 3358 | res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0; |
3357 | } | 3359 | } |
3358 | 3360 | ||
3359 | adapter->pool_res.max_vfs = res.max_vfs; | 3361 | adapter->pool_res = res; |
3360 | pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter)); | ||
3361 | 3362 | ||
3362 | if (!be_max_vfs(adapter)) { | 3363 | if (!be_max_vfs(adapter)) { |
3363 | if (num_vfs) | 3364 | if (num_vfs) |
@@ -3366,6 +3367,8 @@ static int be_get_sriov_config(struct be_adapter *adapter) | |||
3366 | return 0; | 3367 | return 0; |
3367 | } | 3368 | } |
3368 | 3369 | ||
3370 | pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter)); | ||
3371 | |||
3369 | /* validate num_vfs module param */ | 3372 | /* validate num_vfs module param */ |
3370 | old_vfs = pci_num_vf(adapter->pdev); | 3373 | old_vfs = pci_num_vf(adapter->pdev); |
3371 | if (old_vfs) { | 3374 | if (old_vfs) { |
@@ -3423,6 +3426,35 @@ static int be_get_resources(struct be_adapter *adapter) | |||
3423 | return 0; | 3426 | return 0; |
3424 | } | 3427 | } |
3425 | 3428 | ||
3429 | static void be_sriov_config(struct be_adapter *adapter) | ||
3430 | { | ||
3431 | struct device *dev = &adapter->pdev->dev; | ||
3432 | int status; | ||
3433 | |||
3434 | status = be_get_sriov_config(adapter); | ||
3435 | if (status) { | ||
3436 | dev_err(dev, "Failed to query SR-IOV configuration\n"); | ||
3437 | dev_err(dev, "SR-IOV cannot be enabled\n"); | ||
3438 | return; | ||
3439 | } | ||
3440 | |||
3441 | /* When the HW is in SRIOV capable configuration, the PF-pool | ||
3442 | * resources are equally distributed across the max-number of | ||
3443 | * VFs. The user may request only a subset of the max-vfs to be | ||
3444 | * enabled. Based on num_vfs, redistribute the resources across | ||
3445 | * num_vfs so that each VF will have access to more number of | ||
3446 | * resources. This facility is not available in BE3 FW. | ||
3447 | * Also, this is done by FW in Lancer chip. | ||
3448 | */ | ||
3449 | if (be_max_vfs(adapter) && !pci_num_vf(adapter->pdev)) { | ||
3450 | status = be_cmd_set_sriov_config(adapter, | ||
3451 | adapter->pool_res, | ||
3452 | adapter->num_vfs); | ||
3453 | if (status) | ||
3454 | dev_err(dev, "Failed to optimize SR-IOV resources\n"); | ||
3455 | } | ||
3456 | } | ||
3457 | |||
3426 | static int be_get_config(struct be_adapter *adapter) | 3458 | static int be_get_config(struct be_adapter *adapter) |
3427 | { | 3459 | { |
3428 | u16 profile_id; | 3460 | u16 profile_id; |
@@ -3439,27 +3471,8 @@ static int be_get_config(struct be_adapter *adapter) | |||
3439 | "Using profile 0x%x\n", profile_id); | 3471 | "Using profile 0x%x\n", profile_id); |
3440 | } | 3472 | } |
3441 | 3473 | ||
3442 | if (!BE2_chip(adapter) && be_physfn(adapter)) { | 3474 | if (!BE2_chip(adapter) && be_physfn(adapter)) |
3443 | status = be_get_sriov_config(adapter); | 3475 | be_sriov_config(adapter); |
3444 | if (status) | ||
3445 | return status; | ||
3446 | |||
3447 | /* When the HW is in SRIOV capable configuration, the PF-pool | ||
3448 | * resources are equally distributed across the max-number of | ||
3449 | * VFs. The user may request only a subset of the max-vfs to be | ||
3450 | * enabled. Based on num_vfs, redistribute the resources across | ||
3451 | * num_vfs so that each VF will have access to more number of | ||
3452 | * resources. This facility is not available in BE3 FW. | ||
3453 | * Also, this is done by FW in Lancer chip. | ||
3454 | */ | ||
3455 | if (!pci_num_vf(adapter->pdev)) { | ||
3456 | status = be_cmd_set_sriov_config(adapter, | ||
3457 | adapter->pool_res, | ||
3458 | adapter->num_vfs); | ||
3459 | if (status) | ||
3460 | return status; | ||
3461 | } | ||
3462 | } | ||
3463 | 3476 | ||
3464 | status = be_get_resources(adapter); | 3477 | status = be_get_resources(adapter); |
3465 | if (status) | 3478 | if (status) |