Commit ce30905a authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 19f76f63 3c0d49aa
...@@ -89,6 +89,10 @@ ...@@ -89,6 +89,10 @@
#define BE3_MAX_TX_QS 16 #define BE3_MAX_TX_QS 16
#define BE3_MAX_EVT_QS 16 #define BE3_MAX_EVT_QS 16
#define BE3_SRIOV_MAX_EVT_QS 8 #define BE3_SRIOV_MAX_EVT_QS 8
#define SH_VF_MAX_NIC_EQS 3 /* Skyhawk VFs can have a max of 4 EQs
* and at least 1 is granted to either
* SURF/DPDK
*/
#define MAX_RSS_IFACES 15 #define MAX_RSS_IFACES 15
#define MAX_RX_QS 32 #define MAX_RX_QS 32
...@@ -393,6 +397,10 @@ enum vf_state { ...@@ -393,6 +397,10 @@ enum vf_state {
#define BE_UC_PMAC_COUNT 30 #define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2 #define BE_VF_UC_PMAC_COUNT 2
#define MAX_ERR_RECOVERY_RETRY_COUNT 3
#define ERR_DETECTION_DELAY 1000
#define ERR_RECOVERY_RETRY_DELAY 30000
/* Ethtool set_dump flags */ /* Ethtool set_dump flags */
#define LANCER_INITIATE_FW_DUMP 0x1 #define LANCER_INITIATE_FW_DUMP 0x1
#define LANCER_DELETE_FW_DUMP 0x2 #define LANCER_DELETE_FW_DUMP 0x2
...@@ -530,6 +538,7 @@ struct be_adapter { ...@@ -530,6 +538,7 @@ struct be_adapter {
u16 work_counter; u16 work_counter;
struct delayed_work be_err_detection_work; struct delayed_work be_err_detection_work;
u8 recovery_retries;
u8 err_flags; u8 err_flags;
u32 flags; u32 flags;
u32 cmd_privileges; u32 cmd_privileges;
......
...@@ -65,7 +65,22 @@ static struct be_cmd_priv_map cmd_priv_map[] = { ...@@ -65,7 +65,22 @@ static struct be_cmd_priv_map cmd_priv_map[] = {
CMD_SUBSYSTEM_COMMON, CMD_SUBSYSTEM_COMMON,
BE_PRIV_LNKMGMT | BE_PRIV_VHADM | BE_PRIV_LNKMGMT | BE_PRIV_VHADM |
BE_PRIV_DEVCFG | BE_PRIV_DEVSEC BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
} },
{
OPCODE_LOWLEVEL_HOST_DDR_DMA,
CMD_SUBSYSTEM_LOWLEVEL,
BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
},
{
OPCODE_LOWLEVEL_LOOPBACK_TEST,
CMD_SUBSYSTEM_LOWLEVEL,
BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
},
{
OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
CMD_SUBSYSTEM_LOWLEVEL,
BE_PRIV_DEVCFG | BE_PRIV_DEVSEC
},
}; };
static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem) static 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,7 +251,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
if (base_status != MCC_STATUS_SUCCESS && if (base_status != MCC_STATUS_SUCCESS &&
!be_skip_err_log(opcode, base_status, addl_status)) { !be_skip_err_log(opcode, base_status, addl_status)) {
if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { if (base_status == MCC_STATUS_UNAUTHORIZED_REQUEST ||
addl_status == MCC_ADDL_STATUS_INSUFFICIENT_PRIVILEGES) {
dev_warn(&adapter->pdev->dev, dev_warn(&adapter->pdev->dev,
"VF is not privileged to issue opcode %d-%d\n", "VF is not privileged to issue opcode %d-%d\n",
opcode, subsystem); opcode, subsystem);
...@@ -3168,6 +3184,10 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, ...@@ -3168,6 +3184,10 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
struct be_cmd_req_set_lmode *req; struct be_cmd_req_set_lmode *req;
int status; int status;
if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
CMD_SUBSYSTEM_LOWLEVEL))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -3213,6 +3233,10 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num, ...@@ -3213,6 +3233,10 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
struct be_cmd_resp_loopback_test *resp; struct be_cmd_resp_loopback_test *resp;
int status; int status;
if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_LOOPBACK_TEST,
CMD_SUBSYSTEM_LOWLEVEL))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
...@@ -3259,6 +3283,10 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern, ...@@ -3259,6 +3283,10 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
int status; int status;
int i, j = 0; int i, j = 0;
if (!be_cmd_allowed(adapter, OPCODE_LOWLEVEL_HOST_DDR_DMA,
CMD_SUBSYSTEM_LOWLEVEL))
return -EPERM;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
......
...@@ -68,7 +68,8 @@ enum mcc_addl_status { ...@@ -68,7 +68,8 @@ enum mcc_addl_status {
MCC_ADDL_STATUS_TOO_MANY_INTERFACES = 0x4a, MCC_ADDL_STATUS_TOO_MANY_INTERFACES = 0x4a,
MCC_ADDL_STATUS_INSUFFICIENT_VLANS = 0xab, MCC_ADDL_STATUS_INSUFFICIENT_VLANS = 0xab,
MCC_ADDL_STATUS_INVALID_SIGNATURE = 0x56, MCC_ADDL_STATUS_INVALID_SIGNATURE = 0x56,
MCC_ADDL_STATUS_MISSING_SIGNATURE = 0x57 MCC_ADDL_STATUS_MISSING_SIGNATURE = 0x57,
MCC_ADDL_STATUS_INSUFFICIENT_PRIVILEGES = 0x60
}; };
#define CQE_BASE_STATUS_MASK 0xFFFF #define CQE_BASE_STATUS_MASK 0xFFFF
......
...@@ -720,29 +720,32 @@ static int be_set_phys_id(struct net_device *netdev, ...@@ -720,29 +720,32 @@ static int be_set_phys_id(struct net_device *netdev,
enum ethtool_phys_id_state state) enum ethtool_phys_id_state state)
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
int status = 0;
switch (state) { switch (state) {
case ETHTOOL_ID_ACTIVE: case ETHTOOL_ID_ACTIVE:
be_cmd_get_beacon_state(adapter, adapter->hba_port_num, status = be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
&adapter->beacon_state); &adapter->beacon_state);
return 1; /* cycle on/off once per second */ if (status)
return be_cmd_status(status);
return 1; /* cycle on/off once per second */
case ETHTOOL_ID_ON: case ETHTOOL_ID_ON:
be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num,
BEACON_STATE_ENABLED); 0, 0, BEACON_STATE_ENABLED);
break; break;
case ETHTOOL_ID_OFF: case ETHTOOL_ID_OFF:
be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num,
BEACON_STATE_DISABLED); 0, 0, BEACON_STATE_DISABLED);
break; break;
case ETHTOOL_ID_INACTIVE: case ETHTOOL_ID_INACTIVE:
be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num,
adapter->beacon_state); 0, 0, adapter->beacon_state);
} }
return 0; return be_cmd_status(status);
} }
static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump) static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
......
...@@ -1463,6 +1463,9 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid) ...@@ -1463,6 +1463,9 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
if (lancer_chip(adapter) && vid == 0) if (lancer_chip(adapter) && vid == 0)
return 0; return 0;
if (!test_bit(vid, adapter->vids))
return 0;
clear_bit(vid, adapter->vids); clear_bit(vid, adapter->vids);
adapter->vlans_added--; adapter->vlans_added--;
...@@ -1914,8 +1917,7 @@ static u32 be_get_eq_delay_mult_enc(struct be_eq_obj *eqo) ...@@ -1914,8 +1917,7 @@ static u32 be_get_eq_delay_mult_enc(struct be_eq_obj *eqo)
if (!aic->enable) if (!aic->enable)
return 0; return 0;
if (time_before_eq(now, aic->jiffies) || if (jiffies_to_msecs(now - aic->jiffies) < 1)
jiffies_to_msecs(now - aic->jiffies) < 1)
eqd = aic->prev_eqd; eqd = aic->prev_eqd;
else else
eqd = be_get_new_eqd(eqo); eqd = be_get_new_eqd(eqo);
...@@ -3789,18 +3791,15 @@ static u16 be_calculate_vf_qs(struct be_adapter *adapter, u16 num_vfs) ...@@ -3789,18 +3791,15 @@ static u16 be_calculate_vf_qs(struct be_adapter *adapter, u16 num_vfs)
struct be_resources res = adapter->pool_res; struct be_resources res = adapter->pool_res;
u16 num_vf_qs = 1; u16 num_vf_qs = 1;
/* Distribute the queue resources equally among the PF and it's VFs /* Distribute the queue resources among the PF and it's VFs
* Do not distribute queue resources in multi-channel configuration. * Do not distribute queue resources in multi-channel configuration.
*/ */
if (num_vfs && !be_is_mc(adapter)) { if (num_vfs && !be_is_mc(adapter)) {
/* If number of VFs requested is 8 less than max supported, /* Divide the qpairs evenly among the VFs and the PF, capped
* assign 8 queue pairs to the PF and divide the remaining * at VF-EQ-count. Any remainder qpairs belong to the PF.
* resources evenly among the VFs */
*/ num_vf_qs = min(SH_VF_MAX_NIC_EQS,
if (num_vfs < (be_max_vfs(adapter) - 8)) res.max_rss_qs / (num_vfs + 1));
num_vf_qs = (res.max_rss_qs - 8) / num_vfs;
else
num_vf_qs = res.max_rss_qs / num_vfs;
/* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable /* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable
* interfaces per port. Provide RSS on VFs, only if number * interfaces per port. Provide RSS on VFs, only if number
...@@ -4265,10 +4264,10 @@ static void be_schedule_worker(struct be_adapter *adapter) ...@@ -4265,10 +4264,10 @@ static void be_schedule_worker(struct be_adapter *adapter)
adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
} }
static void be_schedule_err_detection(struct be_adapter *adapter) static void be_schedule_err_detection(struct be_adapter *adapter, u32 delay)
{ {
schedule_delayed_work(&adapter->be_err_detection_work, schedule_delayed_work(&adapter->be_err_detection_work,
msecs_to_jiffies(1000)); msecs_to_jiffies(delay));
adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED; adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED;
} }
...@@ -4859,21 +4858,27 @@ static int be_resume(struct be_adapter *adapter) ...@@ -4859,21 +4858,27 @@ static int be_resume(struct be_adapter *adapter)
static int be_err_recover(struct be_adapter *adapter) static int be_err_recover(struct be_adapter *adapter)
{ {
struct device *dev = &adapter->pdev->dev;
int status; int status;
/* Error recovery is supported only Lancer as of now */
if (!lancer_chip(adapter))
return -EIO;
/* Wait for adapter to reach quiescent state before
* destroying queues
*/
status = be_fw_wait_ready(adapter);
if (status)
goto err;
be_cleanup(adapter);
status = be_resume(adapter); status = be_resume(adapter);
if (status) if (status)
goto err; goto err;
dev_info(dev, "Adapter recovery successful\n");
return 0; return 0;
err: err:
if (be_physfn(adapter))
dev_err(dev, "Adapter recovery failed\n");
else
dev_err(dev, "Re-trying adapter recovery\n");
return status; return status;
} }
...@@ -4882,21 +4887,43 @@ static void be_err_detection_task(struct work_struct *work) ...@@ -4882,21 +4887,43 @@ static void be_err_detection_task(struct work_struct *work)
struct be_adapter *adapter = struct be_adapter *adapter =
container_of(work, struct be_adapter, container_of(work, struct be_adapter,
be_err_detection_work.work); be_err_detection_work.work);
int status = 0; struct device *dev = &adapter->pdev->dev;
int recovery_status;
int delay = ERR_DETECTION_DELAY;
be_detect_error(adapter); be_detect_error(adapter);
if (be_check_error(adapter, BE_ERROR_HW)) { if (be_check_error(adapter, BE_ERROR_HW))
be_cleanup(adapter); recovery_status = be_err_recover(adapter);
else
/* As of now error recovery support is in Lancer only */ goto reschedule_task;
if (lancer_chip(adapter))
status = be_err_recover(adapter); if (!recovery_status) {
adapter->recovery_retries = 0;
dev_info(dev, "Adapter recovery successful\n");
goto reschedule_task;
} else if (be_virtfn(adapter)) {
/* For VFs, check if PF have allocated resources
* every second.
*/
dev_err(dev, "Re-trying adapter recovery\n");
goto reschedule_task;
} else if (adapter->recovery_retries++ <
MAX_ERR_RECOVERY_RETRY_COUNT) {
/* In case of another error during recovery, it takes 30 sec
* for adapter to come out of error. Retry error recovery after
* this time interval.
*/
dev_err(&adapter->pdev->dev, "Re-trying adapter recovery\n");
delay = ERR_RECOVERY_RETRY_DELAY;
goto reschedule_task;
} else {
dev_err(dev, "Adapter recovery failed\n");
} }
/* Always attempt recovery on VFs */ return;
if (!status || be_virtfn(adapter)) reschedule_task:
be_schedule_err_detection(adapter); be_schedule_err_detection(adapter, delay);
} }
static void be_log_sfp_info(struct be_adapter *adapter) static 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,7 +5319,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
be_roce_dev_add(adapter); be_roce_dev_add(adapter);
be_schedule_err_detection(adapter); be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
/* On Die temperature not supported for VF. */ /* On Die temperature not supported for VF. */
if (be_physfn(adapter) && IS_ENABLED(CONFIG_BE2NET_HWMON)) { if (be_physfn(adapter) && IS_ENABLED(CONFIG_BE2NET_HWMON)) {
...@@ -5359,7 +5386,7 @@ static int be_pci_resume(struct pci_dev *pdev) ...@@ -5359,7 +5386,7 @@ static int be_pci_resume(struct pci_dev *pdev)
if (status) if (status)
return status; return status;
be_schedule_err_detection(adapter); be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
if (adapter->wol_en) if (adapter->wol_en)
be_setup_wol(adapter, false); be_setup_wol(adapter, false);
...@@ -5459,7 +5486,7 @@ static void be_eeh_resume(struct pci_dev *pdev) ...@@ -5459,7 +5486,7 @@ static void be_eeh_resume(struct pci_dev *pdev)
if (status) if (status)
goto err; goto err;
be_schedule_err_detection(adapter); be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
return; return;
err: err:
dev_err(&adapter->pdev->dev, "EEH resume failed\n"); dev_err(&adapter->pdev->dev, "EEH resume failed\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment