aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-02-07 13:55:29 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-07 13:55:29 -0500
commitce30905aa1a97745e73c9c847dfae19442693b64 (patch)
treeb499fad5d9d25f7bca76dafe6d3539cd5edabcd9
parent19f76f63507fa87f56eb3d864318c5c65268bb46 (diff)
parent3c0d49aaa67e1990f4c081892e9bb69070853919 (diff)
Merge branch 'be2net-non-critical-fixes'
Sriharsha Basavapatna says: ==================== be2net patch-set v2 changes: Patch-4: Changed a tab to space in be.h Patches-6,7,8: Updated commit log summary line: benet --> be2net Hi David, The following patch set contains a few non-critical bug fixes. Please consider applying this to the net-next tree. Thanks. Patch-1 fixes be_set_phys_id() ethtool function to return an error code. Patch-2 fixes a warning when some commands fail for VFs. Patch-3 fixes be_vlan_rem_vid() to verify vlan being removed is in the list. Patch-4 improves SRIOV queue distribution logic. Patch-5 avoids running self test on VFs. Patch-6 fixes error recovery in Lancer to clean up after moving to ready state. Patch-7 adds retry logic to error recovery in case of recovery failures Patch-8 fixes time interval used in eq delay computation routine ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h9
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c32
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h3
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c23
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c93
5 files changed, 114 insertions, 46 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index cf837831304b..515e206589cc 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -89,6 +89,10 @@
89#define BE3_MAX_TX_QS 16 89#define BE3_MAX_TX_QS 16
90#define BE3_MAX_EVT_QS 16 90#define BE3_MAX_EVT_QS 16
91#define BE3_SRIOV_MAX_EVT_QS 8 91#define BE3_SRIOV_MAX_EVT_QS 8
92#define SH_VF_MAX_NIC_EQS 3 /* Skyhawk VFs can have a max of 4 EQs
93 * and at least 1 is granted to either
94 * SURF/DPDK
95 */
92 96
93#define MAX_RSS_IFACES 15 97#define MAX_RSS_IFACES 15
94#define MAX_RX_QS 32 98#define MAX_RX_QS 32
@@ -393,6 +397,10 @@ enum vf_state {
393#define BE_UC_PMAC_COUNT 30 397#define BE_UC_PMAC_COUNT 30
394#define BE_VF_UC_PMAC_COUNT 2 398#define BE_VF_UC_PMAC_COUNT 2
395 399
400#define MAX_ERR_RECOVERY_RETRY_COUNT 3
401#define ERR_DETECTION_DELAY 1000
402#define ERR_RECOVERY_RETRY_DELAY 30000
403
396/* Ethtool set_dump flags */ 404/* Ethtool set_dump flags */
397#define LANCER_INITIATE_FW_DUMP 0x1 405#define LANCER_INITIATE_FW_DUMP 0x1
398#define LANCER_DELETE_FW_DUMP 0x2 406#define LANCER_DELETE_FW_DUMP 0x2
@@ -530,6 +538,7 @@ struct be_adapter {
530 u16 work_counter; 538 u16 work_counter;
531 539
532 struct delayed_work be_err_detection_work; 540 struct delayed_work be_err_detection_work;
541 u8 recovery_retries;
533 u8 err_flags; 542 u8 err_flags;
534 u32 flags; 543 u32 flags;
535 u32 cmd_privileges; 544 u32 cmd_privileges;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index b63d8ad2e115..7d51d4733890 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -65,7 +65,22 @@ static struct be_cmd_priv_map cmd_priv_map[] = {
65 CMD_SUBSYSTEM_COMMON, 65 CMD_SUBSYSTEM_COMMON,
66 BE_PRIV_LNKMGMT | BE_PRIV_VHADM | 66 BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
67 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC 67 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
68 } 68 },
69 {
70 OPCODE_LOWLEVEL_HOST_DDR_DMA,
71 CMD_SUBSYSTEM_LOWLEVEL,
72 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
73 },
74 {
75 OPCODE_LOWLEVEL_LOOPBACK_TEST,
76 CMD_SUBSYSTEM_LOWLEVEL,
77 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
78 },
79 {
80 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
81 CMD_SUBSYSTEM_LOWLEVEL,
82 BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
83 },
69}; 84};
70 85
71static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem) 86static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem)
@@ -236,7 +251,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
236 251
237 if (base_status != MCC_STATUS_SUCCESS && 252 if (base_status != MCC_STATUS_SUCCESS &&
238 !be_skip_err_log(opcode, base_status, addl_status)) { 253 !be_skip_err_log(opcode, base_status, addl_status)) {
239 if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { 254 if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST ||
255 addl_status == MCC_ADDL_STATUS_INSUFFICIENT_PRIVILEGES) {
240 dev_warn(&adapter->pdev->dev, 256 dev_warn(&adapter->pdev->dev,
241 "VF is not privileged to issue opcode %d-%d\n", 257 "VF is not privileged to issue opcode %d-%d\n",
242 opcode, subsystem); 258 opcode, subsystem);
@@ -3168,6 +3184,10 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
3168 struct be_cmd_req_set_lmode *req; 3184 struct be_cmd_req_set_lmode *req;
3169 int status; 3185 int status;
3170 3186
3187 if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
3188 CMD_SUBSYSTEM_LOWLEVEL))
3189 return -EPERM;
3190
3171 spin_lock_bh(&adapter->mcc_lock); 3191 spin_lock_bh(&adapter->mcc_lock);
3172 3192
3173 wrb = wrb_from_mccq(adapter); 3193 wrb = wrb_from_mccq(adapter);
@@ -3213,6 +3233,10 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
3213 struct be_cmd_resp_loopback_test *resp; 3233 struct be_cmd_resp_loopback_test *resp;
3214 int status; 3234 int status;
3215 3235
3236 if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_LOOPBACK_TEST,
3237 CMD_SUBSYSTEM_LOWLEVEL))
3238 return -EPERM;
3239
3216 spin_lock_bh(&adapter->mcc_lock); 3240 spin_lock_bh(&adapter->mcc_lock);
3217 3241
3218 wrb = wrb_from_mccq(adapter); 3242 wrb = wrb_from_mccq(adapter);
@@ -3259,6 +3283,10 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
3259 int status; 3283 int status;
3260 int i, j = 0; 3284 int i, j = 0;
3261 3285
3286 if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_HOST_DDR_DMA,
3287 CMD_SUBSYSTEM_LOWLEVEL))
3288 return -EPERM;
3289
3262 spin_lock_bh(&adapter->mcc_lock); 3290 spin_lock_bh(&adapter->mcc_lock);
3263 3291
3264 wrb = wrb_from_mccq(adapter); 3292 wrb = wrb_from_mccq(adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 241819b36ca7..f260ef3329a1 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -68,7 +68,8 @@ enum mcc_addl_status {
68 MCC_ADDL_STATUS_TOO_MANY_INTERFACES = 0x4a, 68 MCC_ADDL_STATUS_TOO_MANY_INTERFACES = 0x4a,
69 MCC_ADDL_STATUS_INSUFFICIENT_VLANS = 0xab, 69 MCC_ADDL_STATUS_INSUFFICIENT_VLANS = 0xab,
70 MCC_ADDL_STATUS_INVALID_SIGNATURE = 0x56, 70 MCC_ADDL_STATUS_INVALID_SIGNATURE = 0x56,
71 MCC_ADDL_STATUS_MISSING_SIGNATURE = 0x57 71 MCC_ADDL_STATUS_MISSING_SIGNATURE = 0x57,
72 MCC_ADDL_STATUS_INSUFFICIENT_PRIVILEGES = 0x60
72}; 73};
73 74
74#define CQE_BASE_STATUS_MASK 0xFFFF 75#define CQE_BASE_STATUS_MASK 0xFFFF
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index a19ac441336f..2ff691636dac 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -720,29 +720,32 @@ static int be_set_phys_id(struct net_device *netdev,
720 enum ethtool_phys_id_state state) 720 enum ethtool_phys_id_state state)
721{ 721{
722 struct be_adapter *adapter = netdev_priv(netdev); 722 struct be_adapter *adapter = netdev_priv(netdev);
723 int status = 0;
723 724
724 switch (state) { 725 switch (state) {
725 case ETHTOOL_ID_ACTIVE: 726 case ETHTOOL_ID_ACTIVE:
726 be_cmd_get_beacon_state(adapter, adapter->hba_port_num, 727 status = be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
727 &adapter->beacon_state); 728 &adapter->beacon_state);
728 return 1; /* cycle on/off once per second */ 729 if (status)
730 return be_cmd_status(status);
731 return 1; /* cycle on/off once per second */
729 732
730 case ETHTOOL_ID_ON: 733 case ETHTOOL_ID_ON:
731 be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, 734 status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num,
732 BEACON_STATE_ENABLED); 735 0, 0, BEACON_STATE_ENABLED);
733 break; 736 break;
734 737
735 case ETHTOOL_ID_OFF: 738 case ETHTOOL_ID_OFF:
736 be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, 739 status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num,
737 BEACON_STATE_DISABLED); 740 0, 0, BEACON_STATE_DISABLED);
738 break; 741 break;
739 742
740 case ETHTOOL_ID_INACTIVE: 743 case ETHTOOL_ID_INACTIVE:
741 be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, 744 status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num,
742 adapter->beacon_state); 745 0, 0, adapter->beacon_state);
743 } 746 }
744 747
745 return 0; 748 return be_cmd_status(status);
746} 749}
747 750
748static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump) 751static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index f99de3657ce3..9c1fc9dcea25 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1463,6 +1463,9 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
1463 if (lancer_chip(adapter) && vid == 0) 1463 if (lancer_chip(adapter) && vid == 0)
1464 return 0; 1464 return 0;
1465 1465
1466 if (!test_bit(vid, adapter->vids))
1467 return 0;
1468
1466 clear_bit(vid, adapter->vids); 1469 clear_bit(vid, adapter->vids);
1467 adapter->vlans_added--; 1470 adapter->vlans_added--;
1468 1471
@@ -1914,8 +1917,7 @@ static u32 be_get_eq_delay_mult_enc(struct be_eq_obj *eqo)
1914 if (!aic->enable) 1917 if (!aic->enable)
1915 return 0; 1918 return 0;
1916 1919
1917 if (time_before_eq(now, aic->jiffies) || 1920 if (jiffies_to_msecs(now - aic->jiffies) < 1)
1918 jiffies_to_msecs(now - aic->jiffies) < 1)
1919 eqd = aic->prev_eqd; 1921 eqd = aic->prev_eqd;
1920 else 1922 else
1921 eqd = be_get_new_eqd(eqo); 1923 eqd = be_get_new_eqd(eqo);
@@ -3789,18 +3791,15 @@ static u16 be_calculate_vf_qs(struct be_adapter *adapter, u16 num_vfs)
3789 struct be_resources res = adapter->pool_res; 3791 struct be_resources res = adapter->pool_res;
3790 u16 num_vf_qs = 1; 3792 u16 num_vf_qs = 1;
3791 3793
3792 /* Distribute the queue resources equally among the PF and it's VFs 3794 /* Distribute the queue resources among the PF and it's VFs
3793 * Do not distribute queue resources in multi-channel configuration. 3795 * Do not distribute queue resources in multi-channel configuration.
3794 */ 3796 */
3795 if (num_vfs && !be_is_mc(adapter)) { 3797 if (num_vfs && !be_is_mc(adapter)) {
3796 /* If number of VFs requested is 8 less than max supported, 3798 /* Divide the qpairs evenly among the VFs and the PF, capped
3797 * assign 8 queue pairs to the PF and divide the remaining 3799 * at VF-EQ-count. Any remainder qpairs belong to the PF.
3798 * resources evenly among the VFs 3800 */
3799 */ 3801 num_vf_qs = min(SH_VF_MAX_NIC_EQS,
3800 if (num_vfs < (be_max_vfs(adapter) - 8)) 3802 res.max_rss_qs / (num_vfs + 1));
3801 num_vf_qs = (res.max_rss_qs - 8) / num_vfs;
3802 else
3803 num_vf_qs = res.max_rss_qs / num_vfs;
3804 3803
3805 /* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable 3804 /* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable
3806 * interfaces per port. Provide RSS on VFs, only if number 3805 * interfaces per port. Provide RSS on VFs, only if number
@@ -4265,10 +4264,10 @@ static void be_schedule_worker(struct be_adapter *adapter)
4265 adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; 4264 adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
4266} 4265}
4267 4266
4268static void be_schedule_err_detection(struct be_adapter *adapter) 4267static void be_schedule_err_detection(struct be_adapter *adapter, u32 delay)
4269{ 4268{
4270 schedule_delayed_work(&adapter->be_err_detection_work, 4269 schedule_delayed_work(&adapter->be_err_detection_work,
4271 msecs_to_jiffies(1000)); 4270 msecs_to_jiffies(delay));
4272 adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED; 4271 adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED;
4273} 4272}
4274 4273
@@ -4859,21 +4858,27 @@ static int be_resume(struct be_adapter *adapter)
4859 4858
4860static int be_err_recover(struct be_adapter *adapter) 4859static int be_err_recover(struct be_adapter *adapter)
4861{ 4860{
4862 struct device *dev = &adapter->pdev->dev;
4863 int status; 4861 int status;
4864 4862
4863 /* Error recovery is supported only Lancer as of now */
4864 if (!lancer_chip(adapter))
4865 return -EIO;
4866
4867 /* Wait for adapter to reach quiescent state before
4868 * destroying queues
4869 */
4870 status = be_fw_wait_ready(adapter);
4871 if (status)
4872 goto err;
4873
4874 be_cleanup(adapter);
4875
4865 status = be_resume(adapter); 4876 status = be_resume(adapter);
4866 if (status) 4877 if (status)
4867 goto err; 4878 goto err;
4868 4879
4869 dev_info(dev, "Adapter recovery successful\n");
4870 return 0; 4880 return 0;
4871err: 4881err:
4872 if (be_physfn(adapter))
4873 dev_err(dev, "Adapter recovery failed\n");
4874 else
4875 dev_err(dev, "Re-trying adapter recovery\n");
4876
4877 return status; 4882 return status;
4878} 4883}
4879 4884
@@ -4882,21 +4887,43 @@ static void be_err_detection_task(struct work_struct *work)
4882 struct be_adapter *adapter = 4887 struct be_adapter *adapter =
4883 container_of(work, struct be_adapter, 4888 container_of(work, struct be_adapter,
4884 be_err_detection_work.work); 4889 be_err_detection_work.work);
4885 int status = 0; 4890 struct device *dev = &adapter->pdev->dev;
4891 int recovery_status;
4892 int delay = ERR_DETECTION_DELAY;
4886 4893
4887 be_detect_error(adapter); 4894 be_detect_error(adapter);
4888 4895
4889 if (be_check_error(adapter, BE_ERROR_HW)) { 4896 if (be_check_error(adapter, BE_ERROR_HW))
4890 be_cleanup(adapter); 4897 recovery_status = be_err_recover(adapter);
4891 4898 else
4892 /* As of now error recovery support is in Lancer only */ 4899 goto reschedule_task;
4893 if (lancer_chip(adapter)) 4900
4894 status = be_err_recover(adapter); 4901 if (!recovery_status) {
4902 adapter->recovery_retries = 0;
4903 dev_info(dev, "Adapter recovery successful\n");
4904 goto reschedule_task;
4905 } else if (be_virtfn(adapter)) {
4906 /* For VFs, check if PF have allocated resources
4907 * every second.
4908 */
4909 dev_err(dev, "Re-trying adapter recovery\n");
4910 goto reschedule_task;
4911 } else if (adapter->recovery_retries++ <
4912 MAX_ERR_RECOVERY_RETRY_COUNT) {
4913 /* In case of another error during recovery, it takes 30 sec
4914 * for adapter to come out of error. Retry error recovery after
4915 * this time interval.
4916 */
4917 dev_err(&adapter->pdev->dev, "Re-trying adapter recovery\n");
4918 delay = ERR_RECOVERY_RETRY_DELAY;
4919 goto reschedule_task;
4920 } else {
4921 dev_err(dev, "Adapter recovery failed\n");
4895 } 4922 }
4896 4923
4897 /* Always attempt recovery on VFs */ 4924 return;
4898 if (!status || be_virtfn(adapter)) 4925reschedule_task:
4899 be_schedule_err_detection(adapter); 4926 be_schedule_err_detection(adapter, delay);
4900} 4927}
4901 4928
4902static void be_log_sfp_info(struct be_adapter *adapter) 4929static void be_log_sfp_info(struct be_adapter *adapter)
@@ -5292,7 +5319,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
5292 5319
5293 be_roce_dev_add(adapter); 5320 be_roce_dev_add(adapter);
5294 5321
5295 be_schedule_err_detection(adapter); 5322 be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
5296 5323
5297 /* On Die temperature not supported for VF. */ 5324 /* On Die temperature not supported for VF. */
5298 if (be_physfn(adapter) && IS_ENABLED(CONFIG_BE2NET_HWMON)) { 5325 if (be_physfn(adapter) && IS_ENABLED(CONFIG_BE2NET_HWMON)) {
@@ -5359,7 +5386,7 @@ static int be_pci_resume(struct pci_dev *pdev)
5359 if (status) 5386 if (status)
5360 return status; 5387 return status;
5361 5388
5362 be_schedule_err_detection(adapter); 5389 be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
5363 5390
5364 if (adapter->wol_en) 5391 if (adapter->wol_en)
5365 be_setup_wol(adapter, false); 5392 be_setup_wol(adapter, false);
@@ -5459,7 +5486,7 @@ static void be_eeh_resume(struct pci_dev *pdev)
5459 if (status) 5486 if (status)
5460 goto err; 5487 goto err;
5461 5488
5462 be_schedule_err_detection(adapter); 5489 be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
5463 return; 5490 return;
5464err: 5491err:
5465 dev_err(&adapter->pdev->dev, "EEH resume failed\n"); 5492 dev_err(&adapter->pdev->dev, "EEH resume failed\n");