From patchwork Thu Nov 15 16:47:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v2, net-next, 03/22] bnx2x: Add to VF <-> PF channel the release request X-Patchwork-Submitter: Ariel Elior X-Patchwork-Id: 199344 X-Patchwork-Delegate: davem@davemloft.net Message-Id: <1352998067-9707-4-git-send-email-ariele@broadcom.com> To: "David Miller" Cc: netdev , "Ariel Elior" , "Eilon Greenstein" Date: Thu, 15 Nov 2012 18:47:28 +0200 From: "Ariel Elior" List-Id: VF driver uses this request when removed. The PF driver reclaims all resources allocated for that VF at this time. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 + drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 45 ++++++++++++++++++++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h | 14 +++++++ 3 files changed, 60 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 3de66ef..d6f4e0e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -2221,6 +2221,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int bnx2x_get_vf_id(struct bnx2x *bp, u32 *vf_id); int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping); int __devinit bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count); +int __devexit bnx2x_vfpf_release(struct bnx2x *bp); /* Congestion management fairness mode */ #define CMNG_FNS_NONE 0 #define CMNG_FNS_MINMAX 1 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 89092b0..0ee0572 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12280,6 +12280,9 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->sp_rtnl_task); + /* send message via vfpf channel to release the resources of this vf */ + if (IS_VF(bp)) + bnx2x_vfpf_release(bp); if (bp->regview) iounmap(bp->regview); @@ -13266,3 +13269,45 @@ int __devinit bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, return 0; } + +int __devexit bnx2x_vfpf_release(struct bnx2x *bp) +{ + struct vfpf_release_tlv *req = &bp->vf2pf_mbox->req.release; + struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp; + u32 rc = 0, vf_id; + + /* clear mailbox and prep first tlv */ + bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_RELEASE, sizeof(*req)); + + if (bnx2x_get_vf_id(bp, &vf_id)) + return -EAGAIN; + + req->vf_id = vf_id; + + /* add list termination tlv */ + bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END, + sizeof(struct channel_list_end_tlv)); + + /* output tlvs list */ + bnx2x_dp_tlv_list(bp, req); + + /* send release request */ + rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping); + + /* PF timeout */ + if (rc) + return rc; + + /* PF released us */ + if (resp->hdr.status == PFVF_STATUS_SUCCESS) { + DP(BNX2X_MSG_SP, "vf released\n"); + + /* PF reports error */ + } else { + BNX2X_ERR("PF failed our release request - are we out of sync? response status: %d\n", + resp->hdr.status); + return -EAGAIN; + } + + return 0; +} diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h index 8f124fe..79eedd3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h @@ -67,6 +67,10 @@ struct pfvf_tlv { u8 padding[3]; }; +/* response tlv used for most tlvs */ +struct pfvf_general_resp_tlv { + struct pfvf_tlv hdr; +}; /* used to terminate and pad a tlv list */ struct channel_list_end_tlv { struct channel_tlv tl; @@ -124,17 +128,26 @@ struct pfvf_acquire_resp_tlv { } resc; }; +/* release the VF's acquired resources */ +struct vfpf_release_tlv { + struct vfpf_first_tlv first_tlv; + u16 vf_id; /* for debug */ + u8 padding[2]; +}; + struct tlv_buffer_size { u8 tlv_buffer[TLV_BUFFER_SIZE]; }; union vfpf_tlvs { struct vfpf_first_tlv first_tlv; struct vfpf_acquire_tlv acquire; + struct vfpf_release_tlv release; struct channel_list_end_tlv list_end; struct tlv_buffer_size tlv_buf_size; }; union pfvf_tlvs { + struct pfvf_general_resp_tlv general_resp; struct pfvf_acquire_resp_tlv acquire_resp; struct channel_list_end_tlv list_end; struct tlv_buffer_size tlv_buf_size; @@ -142,6 +155,7 @@ union pfvf_tlvs { enum channel_tlvs { CHANNEL_TLV_NONE, /* ends tlv sequence */ CHANNEL_TLV_ACQUIRE, + CHANNEL_TLV_RELEASE, CHANNEL_TLV_LIST_END, CHANNEL_TLV_MAX };