|
@@ -1463,6 +1463,9 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
|
|
|
if (lancer_chip(adapter) && vid == 0)
|
|
|
return 0;
|
|
|
|
|
|
+ if (!test_bit(vid, adapter->vids))
|
|
|
+ return 0;
|
|
|
+
|
|
|
clear_bit(vid, adapter->vids);
|
|
|
adapter->vlans_added--;
|
|
|
|
|
@@ -1914,8 +1917,7 @@ static u32 be_get_eq_delay_mult_enc(struct be_eq_obj *eqo)
|
|
|
if (!aic->enable)
|
|
|
return 0;
|
|
|
|
|
|
- if (time_before_eq(now, aic->jiffies) ||
|
|
|
- jiffies_to_msecs(now - aic->jiffies) < 1)
|
|
|
+ if (jiffies_to_msecs(now - aic->jiffies) < 1)
|
|
|
eqd = aic->prev_eqd;
|
|
|
else
|
|
|
eqd = be_get_new_eqd(eqo);
|
|
@@ -3789,18 +3791,15 @@ static u16 be_calculate_vf_qs(struct be_adapter *adapter, u16 num_vfs)
|
|
|
struct be_resources res = adapter->pool_res;
|
|
|
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.
|
|
|
*/
|
|
|
if (num_vfs && !be_is_mc(adapter)) {
|
|
|
- /* If number of VFs requested is 8 less than max supported,
|
|
|
- * assign 8 queue pairs to the PF and divide the remaining
|
|
|
- * resources evenly among the VFs
|
|
|
- */
|
|
|
- if (num_vfs < (be_max_vfs(adapter) - 8))
|
|
|
- num_vf_qs = (res.max_rss_qs - 8) / num_vfs;
|
|
|
- else
|
|
|
- num_vf_qs = res.max_rss_qs / num_vfs;
|
|
|
+ /* Divide the qpairs evenly among the VFs and the PF, capped
|
|
|
+ * at VF-EQ-count. Any remainder qpairs belong to the PF.
|
|
|
+ */
|
|
|
+ num_vf_qs = min(SH_VF_MAX_NIC_EQS,
|
|
|
+ res.max_rss_qs / (num_vfs + 1));
|
|
|
|
|
|
/* Skyhawk-R chip supports only MAX_RSS_IFACES RSS capable
|
|
|
* interfaces per port. Provide RSS on VFs, only if number
|
|
@@ -4265,10 +4264,10 @@ static void be_schedule_worker(struct be_adapter *adapter)
|
|
|
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,
|
|
|
- msecs_to_jiffies(1000));
|
|
|
+ msecs_to_jiffies(delay));
|
|
|
adapter->flags |= BE_FLAGS_ERR_DETECTION_SCHEDULED;
|
|
|
}
|
|
|
|
|
@@ -4859,21 +4858,27 @@ static int be_resume(struct be_adapter *adapter)
|
|
|
|
|
|
static int be_err_recover(struct be_adapter *adapter)
|
|
|
{
|
|
|
- struct device *dev = &adapter->pdev->dev;
|
|
|
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);
|
|
|
if (status)
|
|
|
goto err;
|
|
|
|
|
|
- dev_info(dev, "Adapter recovery successful\n");
|
|
|
return 0;
|
|
|
err:
|
|
|
- if (be_physfn(adapter))
|
|
|
- dev_err(dev, "Adapter recovery failed\n");
|
|
|
- else
|
|
|
- dev_err(dev, "Re-trying adapter recovery\n");
|
|
|
-
|
|
|
return status;
|
|
|
}
|
|
|
|
|
@@ -4882,21 +4887,43 @@ static void be_err_detection_task(struct work_struct *work)
|
|
|
struct be_adapter *adapter =
|
|
|
container_of(work, struct be_adapter,
|
|
|
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);
|
|
|
|
|
|
- if (be_check_error(adapter, BE_ERROR_HW)) {
|
|
|
- be_cleanup(adapter);
|
|
|
-
|
|
|
- /* As of now error recovery support is in Lancer only */
|
|
|
- if (lancer_chip(adapter))
|
|
|
- status = be_err_recover(adapter);
|
|
|
+ if (be_check_error(adapter, BE_ERROR_HW))
|
|
|
+ recovery_status = be_err_recover(adapter);
|
|
|
+ else
|
|
|
+ goto reschedule_task;
|
|
|
+
|
|
|
+ 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 */
|
|
|
- if (!status || be_virtfn(adapter))
|
|
|
- be_schedule_err_detection(adapter);
|
|
|
+ return;
|
|
|
+reschedule_task:
|
|
|
+ be_schedule_err_detection(adapter, delay);
|
|
|
}
|
|
|
|
|
|
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)
|
|
|
|
|
|
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. */
|
|
|
if (be_physfn(adapter) && IS_ENABLED(CONFIG_BE2NET_HWMON)) {
|
|
@@ -5359,7 +5386,7 @@ static int be_pci_resume(struct pci_dev *pdev)
|
|
|
if (status)
|
|
|
return status;
|
|
|
|
|
|
- be_schedule_err_detection(adapter);
|
|
|
+ be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
|
|
|
|
|
|
if (adapter->wol_en)
|
|
|
be_setup_wol(adapter, false);
|
|
@@ -5459,7 +5486,7 @@ static void be_eeh_resume(struct pci_dev *pdev)
|
|
|
if (status)
|
|
|
goto err;
|
|
|
|
|
|
- be_schedule_err_detection(adapter);
|
|
|
+ be_schedule_err_detection(adapter, ERR_DETECTION_DELAY);
|
|
|
return;
|
|
|
err:
|
|
|
dev_err(&adapter->pdev->dev, "EEH resume failed\n");
|