Commit 076d1329 authored by Ariel Elior's avatar Ariel Elior Committed by David S. Miller

bnx2x: Fix VF flr flow

When a VF originating from a given PF is flr-ed, that PF gets an interrupt
from the chip management and takes a part in the flr process.

This patch fixes several corner cases in which the driver performs its part
of the flr flow out-of-order, causing the FW to assert due to badly timed
messages received from the driver.
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarAriel Elior <ariele@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 14e48144
...@@ -618,7 +618,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -618,7 +618,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf)
&vlan_mac->user_req.vlan_mac_flags, &vlan_mac->user_req.vlan_mac_flags,
&vlan_mac->ramrod_flags); &vlan_mac->ramrod_flags);
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
case BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE: case BNX2X_VFOP_VLAN_MAC_CONFIG_SINGLE:
/* next state */ /* next state */
...@@ -629,7 +629,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -629,7 +629,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf)
if (vfop->rc == -EEXIST) if (vfop->rc == -EEXIST)
vfop->rc = 0; vfop->rc = 0;
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
case BNX2X_VFOP_VLAN_MAC_CHK_DONE: case BNX2X_VFOP_VLAN_MAC_CHK_DONE:
vfop->rc = !!obj->raw.check_pending(&obj->raw); vfop->rc = !!obj->raw.check_pending(&obj->raw);
...@@ -646,7 +646,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -646,7 +646,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf)
set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags); set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags);
vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac); vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac);
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
case BNX2X_VFOP_VLAN_CONFIG_LIST: case BNX2X_VFOP_VLAN_CONFIG_LIST:
/* next state */ /* next state */
...@@ -658,7 +658,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -658,7 +658,7 @@ static void bnx2x_vfop_vlan_mac(struct bnx2x *bp, struct bnx2x_virtf *vf)
set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags); set_bit(RAMROD_CONT, &vlan_mac->ramrod_flags);
vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac); vfop->rc = bnx2x_config_vlan_mac(bp, vlan_mac);
} }
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE); bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
default: default:
bnx2x_vfop_default(state); bnx2x_vfop_default(state);
...@@ -1024,25 +1024,35 @@ static void bnx2x_vfop_qflr(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -1024,25 +1024,35 @@ static void bnx2x_vfop_qflr(struct bnx2x *bp, struct bnx2x_virtf *vf)
case BNX2X_VFOP_QFLR_CLR_VLAN: case BNX2X_VFOP_QFLR_CLR_VLAN:
/* vlan-clear-all: driver-only, don't consume credit */ /* vlan-clear-all: driver-only, don't consume credit */
vfop->state = BNX2X_VFOP_QFLR_CLR_MAC; vfop->state = BNX2X_VFOP_QFLR_CLR_MAC;
if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj)))
vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, qid, if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj))) {
true); /* the vlan_mac vfop will re-schedule us */
if (vfop->rc) vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd,
goto op_err; qid, true);
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); if (vfop->rc)
goto op_err;
return;
} else {
/* need to reschedule ourselves */
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
}
case BNX2X_VFOP_QFLR_CLR_MAC: case BNX2X_VFOP_QFLR_CLR_MAC:
/* mac-clear-all: driver only consume credit */ /* mac-clear-all: driver only consume credit */
vfop->state = BNX2X_VFOP_QFLR_TERMINATE; vfop->state = BNX2X_VFOP_QFLR_TERMINATE;
if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj))) if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj))) {
vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, qid, /* the vlan_mac vfop will re-schedule us */
true); vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd,
DP(BNX2X_MSG_IOV, qid, true);
"VF[%d] vfop->rc after bnx2x_vfop_mac_delall_cmd was %d", if (vfop->rc)
vf->abs_vfid, vfop->rc); goto op_err;
if (vfop->rc) return;
goto op_err;
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT); } else {
/* need to reschedule ourselves */
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
}
case BNX2X_VFOP_QFLR_TERMINATE: case BNX2X_VFOP_QFLR_TERMINATE:
qstate = &vfop->op_p->qctor.qstate; qstate = &vfop->op_p->qctor.qstate;
...@@ -2384,8 +2394,9 @@ int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem) ...@@ -2384,8 +2394,9 @@ int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem)
goto get_vf; goto get_vf;
case EVENT_RING_OPCODE_MALICIOUS_VF: case EVENT_RING_OPCODE_MALICIOUS_VF:
abs_vfid = elem->message.data.malicious_vf_event.vf_id; abs_vfid = elem->message.data.malicious_vf_event.vf_id;
DP(BNX2X_MSG_IOV, "Got VF MALICIOUS notification abs_vfid=%d err_id=0x%x\n", BNX2X_ERR("Got VF MALICIOUS notification abs_vfid=%d err_id=0x%x\n",
abs_vfid, elem->message.data.malicious_vf_event.err_id); abs_vfid,
elem->message.data.malicious_vf_event.err_id);
goto get_vf; goto get_vf;
default: default:
return 1; return 1;
...@@ -2437,15 +2448,9 @@ int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem) ...@@ -2437,15 +2448,9 @@ int bnx2x_iov_eq_sp_event(struct bnx2x *bp, union event_ring_elem *elem)
bnx2x_vf_handle_filters_eqe(bp, vf); bnx2x_vf_handle_filters_eqe(bp, vf);
break; break;
case EVENT_RING_OPCODE_VF_FLR: case EVENT_RING_OPCODE_VF_FLR:
DP(BNX2X_MSG_IOV, "got VF [%d] FLR notification\n",
vf->abs_vfid);
/* Do nothing for now */
break;
case EVENT_RING_OPCODE_MALICIOUS_VF: case EVENT_RING_OPCODE_MALICIOUS_VF:
DP(BNX2X_MSG_IOV, "Got VF MALICIOUS notification abs_vfid=%d error id %x\n",
abs_vfid, elem->message.data.malicious_vf_event.err_id);
/* Do nothing for now */ /* Do nothing for now */
break; return 0;
} }
/* SRIOV: reschedule any 'in_progress' operations */ /* SRIOV: reschedule any 'in_progress' operations */
bnx2x_iov_sp_event(bp, cid, false); bnx2x_iov_sp_event(bp, cid, false);
......
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