|
@@ -178,26 +178,59 @@ static struct qed_vf_info *qed_iov_get_vf_info(struct qed_hwfn *p_hwfn,
|
|
|
return vf;
|
|
|
}
|
|
|
|
|
|
+enum qed_iov_validate_q_mode {
|
|
|
+ QED_IOV_VALIDATE_Q_NA,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE,
|
|
|
+ QED_IOV_VALIDATE_Q_DISABLE,
|
|
|
+};
|
|
|
+
|
|
|
+static bool qed_iov_validate_queue_mode(struct qed_hwfn *p_hwfn,
|
|
|
+ struct qed_vf_info *p_vf,
|
|
|
+ u16 qid,
|
|
|
+ enum qed_iov_validate_q_mode mode,
|
|
|
+ bool b_is_tx)
|
|
|
+{
|
|
|
+ if (mode == QED_IOV_VALIDATE_Q_NA)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if ((b_is_tx && p_vf->vf_queues[qid].p_tx_cid) ||
|
|
|
+ (!b_is_tx && p_vf->vf_queues[qid].p_rx_cid))
|
|
|
+ return mode == QED_IOV_VALIDATE_Q_ENABLE;
|
|
|
+
|
|
|
+ /* In case we haven't found any valid cid, then its disabled */
|
|
|
+ return mode == QED_IOV_VALIDATE_Q_DISABLE;
|
|
|
+}
|
|
|
+
|
|
|
static bool qed_iov_validate_rxq(struct qed_hwfn *p_hwfn,
|
|
|
- struct qed_vf_info *p_vf, u16 rx_qid)
|
|
|
+ struct qed_vf_info *p_vf,
|
|
|
+ u16 rx_qid,
|
|
|
+ enum qed_iov_validate_q_mode mode)
|
|
|
{
|
|
|
- if (rx_qid >= p_vf->num_rxqs)
|
|
|
+ if (rx_qid >= p_vf->num_rxqs) {
|
|
|
DP_VERBOSE(p_hwfn,
|
|
|
QED_MSG_IOV,
|
|
|
"VF[0x%02x] - can't touch Rx queue[%04x]; Only 0x%04x are allocated\n",
|
|
|
p_vf->abs_vf_id, rx_qid, p_vf->num_rxqs);
|
|
|
- return rx_qid < p_vf->num_rxqs;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return qed_iov_validate_queue_mode(p_hwfn, p_vf, rx_qid, mode, false);
|
|
|
}
|
|
|
|
|
|
static bool qed_iov_validate_txq(struct qed_hwfn *p_hwfn,
|
|
|
- struct qed_vf_info *p_vf, u16 tx_qid)
|
|
|
+ struct qed_vf_info *p_vf,
|
|
|
+ u16 tx_qid,
|
|
|
+ enum qed_iov_validate_q_mode mode)
|
|
|
{
|
|
|
- if (tx_qid >= p_vf->num_txqs)
|
|
|
+ if (tx_qid >= p_vf->num_txqs) {
|
|
|
DP_VERBOSE(p_hwfn,
|
|
|
QED_MSG_IOV,
|
|
|
"VF[0x%02x] - can't touch Tx queue[%04x]; Only 0x%04x are allocated\n",
|
|
|
p_vf->abs_vf_id, tx_qid, p_vf->num_txqs);
|
|
|
- return tx_qid < p_vf->num_txqs;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return qed_iov_validate_queue_mode(p_hwfn, p_vf, tx_qid, mode, true);
|
|
|
}
|
|
|
|
|
|
static bool qed_iov_validate_sb(struct qed_hwfn *p_hwfn,
|
|
@@ -217,6 +250,34 @@ static bool qed_iov_validate_sb(struct qed_hwfn *p_hwfn,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static bool qed_iov_validate_active_rxq(struct qed_hwfn *p_hwfn,
|
|
|
+ struct qed_vf_info *p_vf)
|
|
|
+{
|
|
|
+ u8 i;
|
|
|
+
|
|
|
+ for (i = 0; i < p_vf->num_rxqs; i++)
|
|
|
+ if (qed_iov_validate_queue_mode(p_hwfn, p_vf, i,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE,
|
|
|
+ false))
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static bool qed_iov_validate_active_txq(struct qed_hwfn *p_hwfn,
|
|
|
+ struct qed_vf_info *p_vf)
|
|
|
+{
|
|
|
+ u8 i;
|
|
|
+
|
|
|
+ for (i = 0; i < p_vf->num_txqs; i++)
|
|
|
+ if (qed_iov_validate_queue_mode(p_hwfn, p_vf, i,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE,
|
|
|
+ true))
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
static int qed_iov_post_vf_bulletin(struct qed_hwfn *p_hwfn,
|
|
|
int vfid, struct qed_ptt *p_ptt)
|
|
|
{
|
|
@@ -693,6 +754,11 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
|
|
|
u32 igu_vf_conf = IGU_VF_CONF_FUNC_EN;
|
|
|
int rc;
|
|
|
|
|
|
+ /* It's possible VF was previously considered malicious -
|
|
|
+ * clear the indication even if we're only going to disable VF.
|
|
|
+ */
|
|
|
+ vf->b_malicious = false;
|
|
|
+
|
|
|
if (vf->to_disable)
|
|
|
return 0;
|
|
|
|
|
@@ -705,9 +771,6 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
qed_iov_vf_igu_reset(p_hwfn, p_ptt, vf);
|
|
|
|
|
|
- /* It's possible VF was previously considered malicious */
|
|
|
- vf->b_malicious = false;
|
|
|
-
|
|
|
rc = qed_mcp_config_vf_msix(p_hwfn, p_ptt, vf->abs_vf_id, vf->num_sbs);
|
|
|
if (rc)
|
|
|
return rc;
|
|
@@ -1134,13 +1197,17 @@ static void qed_iov_send_response(struct qed_hwfn *p_hwfn,
|
|
|
(sizeof(union pfvf_tlvs) - sizeof(u64)) / 4,
|
|
|
¶ms);
|
|
|
|
|
|
- qed_dmae_host2host(p_hwfn, p_ptt, mbx->reply_phys,
|
|
|
- mbx->req_virt->first_tlv.reply_address,
|
|
|
- sizeof(u64) / 4, ¶ms);
|
|
|
-
|
|
|
+ /* Once PF copies the rc to the VF, the latter can continue
|
|
|
+ * and send an additional message. So we have to make sure the
|
|
|
+ * channel would be re-set to ready prior to that.
|
|
|
+ */
|
|
|
REG_WR(p_hwfn,
|
|
|
GTT_BAR0_MAP_REG_USDM_RAM +
|
|
|
USTORM_VF_PF_CHANNEL_READY_OFFSET(eng_vf_id), 1);
|
|
|
+
|
|
|
+ qed_dmae_host2host(p_hwfn, p_ptt, mbx->reply_phys,
|
|
|
+ mbx->req_virt->first_tlv.reply_address,
|
|
|
+ sizeof(u64) / 4, ¶ms);
|
|
|
}
|
|
|
|
|
|
static u16 qed_iov_vport_to_tlv(struct qed_hwfn *p_hwfn,
|
|
@@ -1749,6 +1816,8 @@ static void qed_iov_vf_mbx_start_vport(struct qed_hwfn *p_hwfn,
|
|
|
vf->state = VF_ENABLED;
|
|
|
start = &mbx->req_virt->start_vport;
|
|
|
|
|
|
+ qed_iov_enable_vf_traffic(p_hwfn, p_ptt, vf);
|
|
|
+
|
|
|
/* Initialize Status block in CAU */
|
|
|
for (sb_id = 0; sb_id < vf->num_sbs; sb_id++) {
|
|
|
if (!start->sb_addr[sb_id]) {
|
|
@@ -1762,7 +1831,6 @@ static void qed_iov_vf_mbx_start_vport(struct qed_hwfn *p_hwfn,
|
|
|
start->sb_addr[sb_id],
|
|
|
vf->igu_sbs[sb_id], vf->abs_vf_id, 1);
|
|
|
}
|
|
|
- qed_iov_enable_vf_traffic(p_hwfn, p_ptt, vf);
|
|
|
|
|
|
vf->mtu = start->mtu;
|
|
|
vf->shadow_config.inner_vlan_removal = start->inner_vlan_removal;
|
|
@@ -1819,6 +1887,16 @@ static void qed_iov_vf_mbx_stop_vport(struct qed_hwfn *p_hwfn,
|
|
|
vf->vport_instance--;
|
|
|
vf->spoof_chk = false;
|
|
|
|
|
|
+ if ((qed_iov_validate_active_rxq(p_hwfn, vf)) ||
|
|
|
+ (qed_iov_validate_active_txq(p_hwfn, vf))) {
|
|
|
+ vf->b_malicious = true;
|
|
|
+ DP_NOTICE(p_hwfn,
|
|
|
+ "VF [%02x] - considered malicious; Unable to stop RX/TX queuess\n",
|
|
|
+ vf->abs_vf_id);
|
|
|
+ status = PFVF_STATUS_MALICIOUS;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
rc = qed_sp_vport_stop(p_hwfn, vf->opaque_fid, vf->vport_id);
|
|
|
if (rc) {
|
|
|
DP_ERR(p_hwfn, "qed_iov_vf_mbx_stop_vport returned error %d\n",
|
|
@@ -1830,6 +1908,7 @@ static void qed_iov_vf_mbx_stop_vport(struct qed_hwfn *p_hwfn,
|
|
|
vf->configured_features = 0;
|
|
|
memset(&vf->shadow_config, 0, sizeof(vf->shadow_config));
|
|
|
|
|
|
+out:
|
|
|
qed_iov_prepare_resp(p_hwfn, p_ptt, vf, CHANNEL_TLV_VPORT_TEARDOWN,
|
|
|
sizeof(struct pfvf_def_resp_tlv), status);
|
|
|
}
|
|
@@ -1886,7 +1965,8 @@ static void qed_iov_vf_mbx_start_rxq(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
req = &mbx->req_virt->start_rxq;
|
|
|
|
|
|
- if (!qed_iov_validate_rxq(p_hwfn, vf, req->rx_qid) ||
|
|
|
+ if (!qed_iov_validate_rxq(p_hwfn, vf, req->rx_qid,
|
|
|
+ QED_IOV_VALIDATE_Q_DISABLE) ||
|
|
|
!qed_iov_validate_sb(p_hwfn, vf, req->hw_sb))
|
|
|
goto out;
|
|
|
|
|
@@ -2000,7 +2080,8 @@ static void qed_iov_vf_mbx_start_txq(struct qed_hwfn *p_hwfn,
|
|
|
memset(¶ms, 0, sizeof(params));
|
|
|
req = &mbx->req_virt->start_txq;
|
|
|
|
|
|
- if (!qed_iov_validate_txq(p_hwfn, vf, req->tx_qid) ||
|
|
|
+ if (!qed_iov_validate_txq(p_hwfn, vf, req->tx_qid,
|
|
|
+ QED_IOV_VALIDATE_Q_DISABLE) ||
|
|
|
!qed_iov_validate_sb(p_hwfn, vf, req->hw_sb))
|
|
|
goto out;
|
|
|
|
|
@@ -2037,57 +2118,53 @@ out:
|
|
|
|
|
|
static int qed_iov_vf_stop_rxqs(struct qed_hwfn *p_hwfn,
|
|
|
struct qed_vf_info *vf,
|
|
|
- u16 rxq_id, u8 num_rxqs, bool cqe_completion)
|
|
|
+ u16 rxq_id, bool cqe_completion)
|
|
|
{
|
|
|
struct qed_vf_q_info *p_queue;
|
|
|
int rc = 0;
|
|
|
- int qid;
|
|
|
|
|
|
- if (rxq_id + num_rxqs > ARRAY_SIZE(vf->vf_queues))
|
|
|
+ if (!qed_iov_validate_rxq(p_hwfn, vf, rxq_id,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE)) {
|
|
|
+ DP_VERBOSE(p_hwfn,
|
|
|
+ QED_MSG_IOV,
|
|
|
+ "VF[%d] Tried Closing Rx 0x%04x which is inactive\n",
|
|
|
+ vf->relative_vf_id, rxq_id);
|
|
|
return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
- for (qid = rxq_id; qid < rxq_id + num_rxqs; qid++) {
|
|
|
- p_queue = &vf->vf_queues[qid];
|
|
|
+ p_queue = &vf->vf_queues[rxq_id];
|
|
|
|
|
|
- if (!p_queue->p_rx_cid)
|
|
|
- continue;
|
|
|
-
|
|
|
- rc = qed_eth_rx_queue_stop(p_hwfn,
|
|
|
- p_queue->p_rx_cid,
|
|
|
- false, cqe_completion);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ rc = qed_eth_rx_queue_stop(p_hwfn,
|
|
|
+ p_queue->p_rx_cid,
|
|
|
+ false, cqe_completion);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
|
|
|
- vf->vf_queues[qid].p_rx_cid = NULL;
|
|
|
- vf->num_active_rxqs--;
|
|
|
- }
|
|
|
+ p_queue->p_rx_cid = NULL;
|
|
|
+ vf->num_active_rxqs--;
|
|
|
|
|
|
- return rc;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int qed_iov_vf_stop_txqs(struct qed_hwfn *p_hwfn,
|
|
|
- struct qed_vf_info *vf, u16 txq_id, u8 num_txqs)
|
|
|
+ struct qed_vf_info *vf, u16 txq_id)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
struct qed_vf_q_info *p_queue;
|
|
|
- int qid;
|
|
|
+ int rc = 0;
|
|
|
|
|
|
- if (txq_id + num_txqs > ARRAY_SIZE(vf->vf_queues))
|
|
|
+ if (!qed_iov_validate_txq(p_hwfn, vf, txq_id,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- for (qid = txq_id; qid < txq_id + num_txqs; qid++) {
|
|
|
- p_queue = &vf->vf_queues[qid];
|
|
|
- if (!p_queue->p_tx_cid)
|
|
|
- continue;
|
|
|
+ p_queue = &vf->vf_queues[txq_id];
|
|
|
|
|
|
- rc = qed_eth_tx_queue_stop(p_hwfn, p_queue->p_tx_cid);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ rc = qed_eth_tx_queue_stop(p_hwfn, p_queue->p_tx_cid);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
|
|
|
- p_queue->p_tx_cid = NULL;
|
|
|
- }
|
|
|
+ p_queue->p_tx_cid = NULL;
|
|
|
|
|
|
- return rc;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void qed_iov_vf_mbx_stop_rxqs(struct qed_hwfn *p_hwfn,
|
|
@@ -2096,20 +2173,28 @@ static void qed_iov_vf_mbx_stop_rxqs(struct qed_hwfn *p_hwfn,
|
|
|
{
|
|
|
u16 length = sizeof(struct pfvf_def_resp_tlv);
|
|
|
struct qed_iov_vf_mbx *mbx = &vf->vf_mbx;
|
|
|
- u8 status = PFVF_STATUS_SUCCESS;
|
|
|
+ u8 status = PFVF_STATUS_FAILURE;
|
|
|
struct vfpf_stop_rxqs_tlv *req;
|
|
|
int rc;
|
|
|
|
|
|
- /* We give the option of starting from qid != 0, in this case we
|
|
|
- * need to make sure that qid + num_qs doesn't exceed the actual
|
|
|
- * amount of queues that exist.
|
|
|
+ /* There has never been an official driver that used this interface
|
|
|
+ * for stopping multiple queues, and it is now considered deprecated.
|
|
|
+ * Validate this isn't used here.
|
|
|
*/
|
|
|
req = &mbx->req_virt->stop_rxqs;
|
|
|
- rc = qed_iov_vf_stop_rxqs(p_hwfn, vf, req->rx_qid,
|
|
|
- req->num_rxqs, req->cqe_completion);
|
|
|
- if (rc)
|
|
|
- status = PFVF_STATUS_FAILURE;
|
|
|
+ if (req->num_rxqs != 1) {
|
|
|
+ DP_VERBOSE(p_hwfn, QED_MSG_IOV,
|
|
|
+ "Odd; VF[%d] tried stopping multiple Rx queues\n",
|
|
|
+ vf->relative_vf_id);
|
|
|
+ status = PFVF_STATUS_NOT_SUPPORTED;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
|
|
|
+ rc = qed_iov_vf_stop_rxqs(p_hwfn, vf, req->rx_qid,
|
|
|
+ req->cqe_completion);
|
|
|
+ if (!rc)
|
|
|
+ status = PFVF_STATUS_SUCCESS;
|
|
|
+out:
|
|
|
qed_iov_prepare_resp(p_hwfn, p_ptt, vf, CHANNEL_TLV_STOP_RXQS,
|
|
|
length, status);
|
|
|
}
|
|
@@ -2120,19 +2205,27 @@ static void qed_iov_vf_mbx_stop_txqs(struct qed_hwfn *p_hwfn,
|
|
|
{
|
|
|
u16 length = sizeof(struct pfvf_def_resp_tlv);
|
|
|
struct qed_iov_vf_mbx *mbx = &vf->vf_mbx;
|
|
|
- u8 status = PFVF_STATUS_SUCCESS;
|
|
|
+ u8 status = PFVF_STATUS_FAILURE;
|
|
|
struct vfpf_stop_txqs_tlv *req;
|
|
|
int rc;
|
|
|
|
|
|
- /* We give the option of starting from qid != 0, in this case we
|
|
|
- * need to make sure that qid + num_qs doesn't exceed the actual
|
|
|
- * amount of queues that exist.
|
|
|
+ /* There has never been an official driver that used this interface
|
|
|
+ * for stopping multiple queues, and it is now considered deprecated.
|
|
|
+ * Validate this isn't used here.
|
|
|
*/
|
|
|
req = &mbx->req_virt->stop_txqs;
|
|
|
- rc = qed_iov_vf_stop_txqs(p_hwfn, vf, req->tx_qid, req->num_txqs);
|
|
|
- if (rc)
|
|
|
- status = PFVF_STATUS_FAILURE;
|
|
|
+ if (req->num_txqs != 1) {
|
|
|
+ DP_VERBOSE(p_hwfn, QED_MSG_IOV,
|
|
|
+ "Odd; VF[%d] tried stopping multiple Tx queues\n",
|
|
|
+ vf->relative_vf_id);
|
|
|
+ status = PFVF_STATUS_NOT_SUPPORTED;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ rc = qed_iov_vf_stop_txqs(p_hwfn, vf, req->tx_qid);
|
|
|
+ if (!rc)
|
|
|
+ status = PFVF_STATUS_SUCCESS;
|
|
|
|
|
|
+out:
|
|
|
qed_iov_prepare_resp(p_hwfn, p_ptt, vf, CHANNEL_TLV_STOP_TXQS,
|
|
|
length, status);
|
|
|
}
|
|
@@ -2157,22 +2250,17 @@ static void qed_iov_vf_mbx_update_rxqs(struct qed_hwfn *p_hwfn,
|
|
|
complete_event_flg = !!(req->flags & VFPF_RXQ_UPD_COMPLETE_EVENT_FLAG);
|
|
|
|
|
|
/* Validate inputs */
|
|
|
- if (req->num_rxqs + req->rx_qid > QED_MAX_VF_CHAINS_PER_PF ||
|
|
|
- !qed_iov_validate_rxq(p_hwfn, vf, req->rx_qid)) {
|
|
|
- DP_INFO(p_hwfn, "VF[%d]: Incorrect Rxqs [%04x, %02x]\n",
|
|
|
- vf->relative_vf_id, req->rx_qid, req->num_rxqs);
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < req->num_rxqs; i++) {
|
|
|
- qid = req->rx_qid + i;
|
|
|
- if (!vf->vf_queues[qid].p_rx_cid) {
|
|
|
- DP_INFO(p_hwfn,
|
|
|
- "VF[%d] rx_qid = %d isn`t active!\n",
|
|
|
- vf->relative_vf_id, qid);
|
|
|
+ for (i = req->rx_qid; i < req->rx_qid + req->num_rxqs; i++)
|
|
|
+ if (!qed_iov_validate_rxq(p_hwfn, vf, i,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE)) {
|
|
|
+ DP_INFO(p_hwfn, "VF[%d]: Incorrect Rxqs [%04x, %02x]\n",
|
|
|
+ vf->relative_vf_id, req->rx_qid, req->num_rxqs);
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ /* Prepare the handlers */
|
|
|
+ for (i = 0; i < req->num_rxqs; i++) {
|
|
|
+ qid = req->rx_qid + i;
|
|
|
handlers[i] = vf->vf_queues[qid].p_rx_cid;
|
|
|
}
|
|
|
|
|
@@ -2388,7 +2476,8 @@ qed_iov_vp_update_rss_param(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
for (i = 0; i < table_size; i++) {
|
|
|
q_idx = p_rss_tlv->rss_ind_table[i];
|
|
|
- if (!qed_iov_validate_rxq(p_hwfn, vf, q_idx)) {
|
|
|
+ if (!qed_iov_validate_rxq(p_hwfn, vf, q_idx,
|
|
|
+ QED_IOV_VALIDATE_Q_ENABLE)) {
|
|
|
DP_VERBOSE(p_hwfn,
|
|
|
QED_MSG_IOV,
|
|
|
"VF[%d]: Omitting RSS due to wrong queue %04x\n",
|
|
@@ -2397,15 +2486,6 @@ qed_iov_vp_update_rss_param(struct qed_hwfn *p_hwfn,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- if (!vf->vf_queues[q_idx].p_rx_cid) {
|
|
|
- DP_VERBOSE(p_hwfn,
|
|
|
- QED_MSG_IOV,
|
|
|
- "VF[%d]: Omitting RSS due to inactive queue %08x\n",
|
|
|
- vf->relative_vf_id, q_idx);
|
|
|
- b_reject = true;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
p_rss->rss_ind_table[i] = vf->vf_queues[q_idx].p_rx_cid;
|
|
|
}
|
|
|
|
|
@@ -3058,9 +3138,10 @@ qed_iov_vf_flr_cleanup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-int qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
|
|
|
+bool qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
|
|
|
{
|
|
|
- u16 i, found = 0;
|
|
|
+ bool found = false;
|
|
|
+ u16 i;
|
|
|
|
|
|
DP_VERBOSE(p_hwfn, QED_MSG_IOV, "Marking FLR-ed VFs\n");
|
|
|
for (i = 0; i < (VF_MAX_STATIC / 32); i++)
|
|
@@ -3070,7 +3151,7 @@ int qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
|
|
|
|
|
|
if (!p_hwfn->cdev->p_iov_info) {
|
|
|
DP_NOTICE(p_hwfn, "VF flr but no IOV\n");
|
|
|
- return 0;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
/* Mark VFs */
|
|
@@ -3099,7 +3180,7 @@ int qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
|
|
|
* VF flr until ACKs, we're safe.
|
|
|
*/
|
|
|
p_flr[rel_vf_id / 64] |= 1ULL << (rel_vf_id % 64);
|
|
|
- found = 1;
|
|
|
+ found = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3305,11 +3386,17 @@ static void qed_sriov_vfpf_malicious(struct qed_hwfn *p_hwfn,
|
|
|
if (!p_vf)
|
|
|
return;
|
|
|
|
|
|
- DP_INFO(p_hwfn,
|
|
|
- "VF [%d] - Malicious behavior [%02x]\n",
|
|
|
- p_vf->abs_vf_id, p_data->err_id);
|
|
|
+ if (!p_vf->b_malicious) {
|
|
|
+ DP_NOTICE(p_hwfn,
|
|
|
+ "VF [%d] - Malicious behavior [%02x]\n",
|
|
|
+ p_vf->abs_vf_id, p_data->err_id);
|
|
|
|
|
|
- p_vf->b_malicious = true;
|
|
|
+ p_vf->b_malicious = true;
|
|
|
+ } else {
|
|
|
+ DP_INFO(p_hwfn,
|
|
|
+ "VF [%d] - Malicious behavior [%02x]\n",
|
|
|
+ p_vf->abs_vf_id, p_data->err_id);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int qed_sriov_eqe_event(struct qed_hwfn *p_hwfn,
|
|
@@ -3858,6 +3945,7 @@ static int qed_get_vf_config(struct qed_dev *cdev,
|
|
|
|
|
|
void qed_inform_vf_link_state(struct qed_hwfn *hwfn)
|
|
|
{
|
|
|
+ struct qed_hwfn *lead_hwfn = QED_LEADING_HWFN(hwfn->cdev);
|
|
|
struct qed_mcp_link_capabilities caps;
|
|
|
struct qed_mcp_link_params params;
|
|
|
struct qed_mcp_link_state link;
|
|
@@ -3874,9 +3962,15 @@ void qed_inform_vf_link_state(struct qed_hwfn *hwfn)
|
|
|
if (!vf_info)
|
|
|
continue;
|
|
|
|
|
|
- memcpy(¶ms, qed_mcp_get_link_params(hwfn), sizeof(params));
|
|
|
- memcpy(&link, qed_mcp_get_link_state(hwfn), sizeof(link));
|
|
|
- memcpy(&caps, qed_mcp_get_link_capabilities(hwfn),
|
|
|
+ /* Only hwfn0 is actually interested in the link speed.
|
|
|
+ * But since only it would receive an MFW indication of link,
|
|
|
+ * need to take configuration from it - otherwise things like
|
|
|
+ * rate limiting for hwfn1 VF would not work.
|
|
|
+ */
|
|
|
+ memcpy(¶ms, qed_mcp_get_link_params(lead_hwfn),
|
|
|
+ sizeof(params));
|
|
|
+ memcpy(&link, qed_mcp_get_link_state(lead_hwfn), sizeof(link));
|
|
|
+ memcpy(&caps, qed_mcp_get_link_capabilities(lead_hwfn),
|
|
|
sizeof(caps));
|
|
|
|
|
|
/* Modify link according to the VF's configured link state */
|