|
@@ -951,6 +951,7 @@ static void ice_handle_mdd_event(struct ice_pf *pf)
|
|
|
struct ice_hw *hw = &pf->hw;
|
|
|
bool mdd_detected = false;
|
|
|
u32 reg;
|
|
|
+ int i;
|
|
|
|
|
|
if (!test_bit(__ICE_MDD_EVENT_PENDING, pf->state))
|
|
|
return;
|
|
@@ -1040,6 +1041,51 @@ static void ice_handle_mdd_event(struct ice_pf *pf)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /* see if one of the VFs needs to be reset */
|
|
|
+ for (i = 0; i < pf->num_alloc_vfs && mdd_detected; i++) {
|
|
|
+ struct ice_vf *vf = &pf->vf[i];
|
|
|
+
|
|
|
+ reg = rd32(hw, VP_MDET_TX_PQM(i));
|
|
|
+ if (reg & VP_MDET_TX_PQM_VALID_M) {
|
|
|
+ wr32(hw, VP_MDET_TX_PQM(i), 0xFFFF);
|
|
|
+ vf->num_mdd_events++;
|
|
|
+ dev_info(&pf->pdev->dev, "TX driver issue detected on VF %d\n",
|
|
|
+ i);
|
|
|
+ }
|
|
|
+
|
|
|
+ reg = rd32(hw, VP_MDET_TX_TCLAN(i));
|
|
|
+ if (reg & VP_MDET_TX_TCLAN_VALID_M) {
|
|
|
+ wr32(hw, VP_MDET_TX_TCLAN(i), 0xFFFF);
|
|
|
+ vf->num_mdd_events++;
|
|
|
+ dev_info(&pf->pdev->dev, "TX driver issue detected on VF %d\n",
|
|
|
+ i);
|
|
|
+ }
|
|
|
+
|
|
|
+ reg = rd32(hw, VP_MDET_TX_TDPU(i));
|
|
|
+ if (reg & VP_MDET_TX_TDPU_VALID_M) {
|
|
|
+ wr32(hw, VP_MDET_TX_TDPU(i), 0xFFFF);
|
|
|
+ vf->num_mdd_events++;
|
|
|
+ dev_info(&pf->pdev->dev, "TX driver issue detected on VF %d\n",
|
|
|
+ i);
|
|
|
+ }
|
|
|
+
|
|
|
+ reg = rd32(hw, VP_MDET_RX(i));
|
|
|
+ if (reg & VP_MDET_RX_VALID_M) {
|
|
|
+ wr32(hw, VP_MDET_RX(i), 0xFFFF);
|
|
|
+ vf->num_mdd_events++;
|
|
|
+ dev_info(&pf->pdev->dev, "RX driver issue detected on VF %d\n",
|
|
|
+ i);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (vf->num_mdd_events > ICE_DFLT_NUM_MDD_EVENTS_ALLOWED) {
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "Too many MDD events on VF %d, disabled\n", i);
|
|
|
+ dev_info(&pf->pdev->dev,
|
|
|
+ "Use PF Control I/F to re-enable the VF\n");
|
|
|
+ set_bit(ICE_VF_STATE_DIS, vf->vf_states);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* re-enable MDD interrupt cause */
|
|
|
clear_bit(__ICE_MDD_EVENT_PENDING, pf->state);
|
|
|
reg = rd32(hw, PFINT_OICR_ENA);
|