net/bnx2x: fix reading VF id
The logic to read vf_id used by ACQUIRE/TEARDOWN_Q/RELEASE TLVs,
multiplexed return value to convey vf_id value and status of read vf_id
API. This lets to segfault at dev_start() as resources are not properly
cleaned and re-allocated.
Fix read vf_id API to differentiate between vf_id value and return
status. Adjust the status checking accordingly.
Added bnx2x_vf_teardown_queue() API and moved relevant code from
bnx2x_vf_unload() to new API.
Fixes: 540a211084
("bnx2x: driver core")
Cc: stable@dpdk.org
Signed-off-by: Rasesh Mody <rmody@marvell.com>
This commit is contained in:
parent
6bee9d5f45
commit
e0c103a79c
@ -2015,6 +2015,8 @@ bnx2x_nic_unload(struct bnx2x_softc *sc, uint32_t unload_mode, uint8_t keep_link
|
||||
uint8_t global = FALSE;
|
||||
uint32_t val;
|
||||
|
||||
PMD_INIT_FUNC_TRACE(sc);
|
||||
|
||||
PMD_DRV_LOG(DEBUG, sc, "Starting NIC unload...");
|
||||
|
||||
/* mark driver as unloaded in shmem2 */
|
||||
|
@ -162,20 +162,26 @@ static inline uint16_t bnx2x_check_me_flags(uint32_t val)
|
||||
#define BNX2X_ME_ANSWER_DELAY 100
|
||||
#define BNX2X_ME_ANSWER_TRIES 10
|
||||
|
||||
static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc)
|
||||
static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc, uint32_t *vf_id)
|
||||
{
|
||||
uint32_t val;
|
||||
uint8_t i = 0;
|
||||
|
||||
while (i <= BNX2X_ME_ANSWER_TRIES) {
|
||||
val = BNX2X_DB_READ(DOORBELL_ADDR(sc, 0));
|
||||
if (bnx2x_check_me_flags(val))
|
||||
return VF_ID(val);
|
||||
if (bnx2x_check_me_flags(val)) {
|
||||
PMD_DRV_LOG(DEBUG, sc,
|
||||
"valid register value: 0x%08x", val);
|
||||
*vf_id = VF_ID(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DELAY_MS(BNX2X_ME_ANSWER_DELAY);
|
||||
i++;
|
||||
}
|
||||
|
||||
PMD_DRV_LOG(ERR, sc, "Invalid register value: 0x%08x", val);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -240,14 +246,13 @@ int bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
|
||||
int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count)
|
||||
{
|
||||
struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
|
||||
int vf_id;
|
||||
uint32_t vf_id;
|
||||
int rc;
|
||||
|
||||
bnx2x_vf_close(sc);
|
||||
bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
|
||||
|
||||
vf_id = bnx2x_read_vf_id(sc);
|
||||
if (vf_id < 0) {
|
||||
if (bnx2x_read_vf_id(sc, &vf_id)) {
|
||||
rc = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
@ -318,25 +323,30 @@ bnx2x_vf_close(struct bnx2x_softc *sc)
|
||||
{
|
||||
struct vf_release_tlv *query;
|
||||
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
|
||||
int vf_id = bnx2x_read_vf_id(sc);
|
||||
uint32_t vf_id;
|
||||
int rc;
|
||||
|
||||
if (vf_id >= 0) {
|
||||
query = &sc->vf2pf_mbox->query[0].release;
|
||||
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
|
||||
sizeof(*query));
|
||||
query = &sc->vf2pf_mbox->query[0].release;
|
||||
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
|
||||
sizeof(*query));
|
||||
|
||||
query->vf_id = vf_id;
|
||||
bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
|
||||
BNX2X_VF_TLV_LIST_END,
|
||||
sizeof(struct channel_list_end_tlv));
|
||||
|
||||
rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
|
||||
if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
|
||||
PMD_DRV_LOG(ERR, sc, "Failed to release VF");
|
||||
|
||||
bnx2x_vf_finalize(sc, &query->first_tlv);
|
||||
if (bnx2x_read_vf_id(sc, &vf_id)) {
|
||||
rc = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
query->vf_id = vf_id;
|
||||
|
||||
bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
|
||||
BNX2X_VF_TLV_LIST_END,
|
||||
sizeof(struct channel_list_end_tlv));
|
||||
|
||||
rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
|
||||
if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
|
||||
PMD_DRV_LOG(ERR, sc, "Failed to release VF");
|
||||
|
||||
out:
|
||||
bnx2x_vf_finalize(sc, &query->first_tlv);
|
||||
}
|
||||
|
||||
/* Let PF know the VF status blocks phys_addrs */
|
||||
@ -347,6 +357,8 @@ bnx2x_vf_init(struct bnx2x_softc *sc)
|
||||
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
|
||||
int i, rc;
|
||||
|
||||
PMD_INIT_FUNC_TRACE(sc);
|
||||
|
||||
query = &sc->vf2pf_mbox->query[0].init;
|
||||
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
|
||||
sizeof(*query));
|
||||
@ -383,51 +395,38 @@ bnx2x_vf_unload(struct bnx2x_softc *sc)
|
||||
{
|
||||
struct vf_close_tlv *query;
|
||||
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
|
||||
struct vf_q_op_tlv *query_op;
|
||||
int i, vf_id, rc;
|
||||
uint32_t vf_id;
|
||||
int i, rc;
|
||||
|
||||
vf_id = bnx2x_read_vf_id(sc);
|
||||
if (vf_id > 0) {
|
||||
FOR_EACH_QUEUE(sc, i) {
|
||||
query_op = &sc->vf2pf_mbox->query[0].q_op;
|
||||
bnx2x_vf_prep(sc, &query_op->first_tlv,
|
||||
BNX2X_VF_TLV_TEARDOWN_Q,
|
||||
sizeof(*query_op));
|
||||
PMD_INIT_FUNC_TRACE(sc);
|
||||
|
||||
query_op->vf_qid = i;
|
||||
FOR_EACH_QUEUE(sc, i)
|
||||
bnx2x_vf_teardown_queue(sc, i);
|
||||
|
||||
bnx2x_add_tlv(sc, query_op,
|
||||
query_op->first_tlv.tl.length,
|
||||
BNX2X_VF_TLV_LIST_END,
|
||||
sizeof(struct channel_list_end_tlv));
|
||||
bnx2x_vf_set_mac(sc, false);
|
||||
|
||||
rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
|
||||
if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
|
||||
PMD_DRV_LOG(ERR, sc,
|
||||
"Bad reply for vf_q %d teardown", i);
|
||||
query = &sc->vf2pf_mbox->query[0].close;
|
||||
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
|
||||
sizeof(*query));
|
||||
|
||||
bnx2x_vf_finalize(sc, &query_op->first_tlv);
|
||||
}
|
||||
|
||||
bnx2x_vf_set_mac(sc, false);
|
||||
|
||||
query = &sc->vf2pf_mbox->query[0].close;
|
||||
bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
|
||||
sizeof(*query));
|
||||
|
||||
query->vf_id = vf_id;
|
||||
|
||||
bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
|
||||
BNX2X_VF_TLV_LIST_END,
|
||||
sizeof(struct channel_list_end_tlv));
|
||||
|
||||
rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
|
||||
if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
|
||||
PMD_DRV_LOG(ERR, sc,
|
||||
"Bad reply from PF for close message");
|
||||
|
||||
bnx2x_vf_finalize(sc, &query->first_tlv);
|
||||
if (bnx2x_read_vf_id(sc, &vf_id)) {
|
||||
rc = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
query->vf_id = vf_id;
|
||||
|
||||
bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
|
||||
BNX2X_VF_TLV_LIST_END,
|
||||
sizeof(struct channel_list_end_tlv));
|
||||
|
||||
rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
|
||||
if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
|
||||
PMD_DRV_LOG(ERR, sc,
|
||||
"Bad reply from PF for close message");
|
||||
|
||||
out:
|
||||
bnx2x_vf_finalize(sc, &query->first_tlv);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
@ -521,6 +520,35 @@ bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int lead
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnx2x_vf_teardown_queue(struct bnx2x_softc *sc, int qid)
|
||||
{
|
||||
struct vf_q_op_tlv *query_op;
|
||||
struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
|
||||
int rc;
|
||||
|
||||
query_op = &sc->vf2pf_mbox->query[0].q_op;
|
||||
bnx2x_vf_prep(sc, &query_op->first_tlv,
|
||||
BNX2X_VF_TLV_TEARDOWN_Q,
|
||||
sizeof(*query_op));
|
||||
|
||||
query_op->vf_qid = qid;
|
||||
|
||||
bnx2x_add_tlv(sc, query_op,
|
||||
query_op->first_tlv.tl.length,
|
||||
BNX2X_VF_TLV_LIST_END,
|
||||
sizeof(struct channel_list_end_tlv));
|
||||
|
||||
rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
|
||||
if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
|
||||
PMD_DRV_LOG(ERR, sc,
|
||||
"Bad reply for vf_q %d teardown", qid);
|
||||
|
||||
bnx2x_vf_finalize(sc, &query_op->first_tlv);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
|
||||
{
|
||||
|
@ -328,6 +328,7 @@ struct bnx2x_vf_mbx_msg {
|
||||
union resp_tlvs resp;
|
||||
};
|
||||
|
||||
int bnx2x_vf_teardown_queue(struct bnx2x_softc *sc, int qid);
|
||||
int bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set);
|
||||
int bnx2x_vf_config_rss(struct bnx2x_softc *sc, struct ecore_config_rss_params *params);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user