Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 351244
b: refs/heads/master
c: f1929b0
h: refs/heads/master
v: v3
  • Loading branch information
Ariel Elior authored and David S. Miller committed Jan 2, 2013
1 parent 58c82ac commit c5f9c87
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 99e9d211a40cdd12bda7f50c2014c2fbb8f386f5
refs/heads/master: f1929b016c2161c364e45c21788aaae938ae557c
1 change: 1 addition & 0 deletions trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8626,6 +8626,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode, bool keep_link)

netif_addr_unlock_bh(bp->dev);

bnx2x_iov_chip_cleanup(bp);


/*
Expand Down
123 changes: 123 additions & 0 deletions trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,14 @@ bnx2x_iov_static_resc(struct bnx2x *bp, struct vf_pf_resc_request *resc)
/* num_sbs already set */
}

/* FLR routines: */
static void bnx2x_vf_free_resc(struct bnx2x *bp, struct bnx2x_virtf *vf)
{
/* reset the state variables */
bnx2x_iov_static_resc(bp, &vf->alloc_resc);
vf->state = VF_FREE;
}

/* IOV global initialization routines */
void bnx2x_iov_init_dq(struct bnx2x *bp)
{
Expand Down Expand Up @@ -1947,6 +1955,21 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
return 0;
}

/* called by bnx2x_chip_cleanup */
int bnx2x_iov_chip_cleanup(struct bnx2x *bp)
{
int i;

if (!IS_SRIOV(bp))
return 0;

/* release all the VFs */
for_each_vf(bp, i)
bnx2x_vf_release(bp, BP_VF(bp, i), true); /* blocking */

return 0;
}

/* called by bnx2x_init_hw_func, returns the next ilt line */
int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line)
{
Expand Down Expand Up @@ -2566,6 +2589,106 @@ int bnx2x_vfop_close_cmd(struct bnx2x *bp,
return -ENOMEM;
}

/* VF release can be called either: 1. the VF was acquired but
* not enabled 2. the vf was enabled or in the process of being
* enabled
*/
static void bnx2x_vfop_release(struct bnx2x *bp, struct bnx2x_virtf *vf)
{
struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf);
struct bnx2x_vfop_cmd cmd = {
.done = bnx2x_vfop_release,
.block = false,
};

DP(BNX2X_MSG_IOV, "vfop->rc %d\n", vfop->rc);

if (vfop->rc < 0)
goto op_err;

DP(BNX2X_MSG_IOV, "VF[%d] STATE: %s\n", vf->abs_vfid,
vf->state == VF_FREE ? "Free" :
vf->state == VF_ACQUIRED ? "Acquired" :
vf->state == VF_ENABLED ? "Enabled" :
vf->state == VF_RESET ? "Reset" :
"Unknown");

switch (vf->state) {
case VF_ENABLED:
vfop->rc = bnx2x_vfop_close_cmd(bp, vf, &cmd);
if (vfop->rc)
goto op_err;
return;

case VF_ACQUIRED:
DP(BNX2X_MSG_IOV, "about to free resources\n");
bnx2x_vf_free_resc(bp, vf);
DP(BNX2X_MSG_IOV, "vfop->rc %d\n", vfop->rc);
goto op_done;

case VF_FREE:
case VF_RESET:
/* do nothing */
goto op_done;
default:
bnx2x_vfop_default(vf->state);
}
op_err:
BNX2X_ERR("VF[%d] RELEASE error: rc %d\n", vf->abs_vfid, vfop->rc);
op_done:
bnx2x_vfop_end(bp, vf, vfop);
}

int bnx2x_vfop_release_cmd(struct bnx2x *bp,
struct bnx2x_virtf *vf,
struct bnx2x_vfop_cmd *cmd)
{
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
if (vfop) {
bnx2x_vfop_opset(-1, /* use vf->state */
bnx2x_vfop_release, cmd->done);
return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_release,
cmd->block);
}
return -ENOMEM;
}

/* VF release ~ VF close + VF release-resources
* Release is the ultimate SW shutdown and is called whenever an
* irrecoverable error is encountered.
*/
void bnx2x_vf_release(struct bnx2x *bp, struct bnx2x_virtf *vf, bool block)
{
struct bnx2x_vfop_cmd cmd = {
.done = NULL,
.block = block,
};
int rc;
bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_RELEASE_VF);

rc = bnx2x_vfop_release_cmd(bp, vf, &cmd);
if (rc)
WARN(rc,
"VF[%d] Failed to allocate resources for release op- rc=%d\n",
vf->abs_vfid, rc);
}

static inline void bnx2x_vf_get_sbdf(struct bnx2x *bp,
struct bnx2x_virtf *vf, u32 *sbdf)
{
*sbdf = vf->devfn | (vf->bus << 8);
}

static inline void bnx2x_vf_get_bars(struct bnx2x *bp, struct bnx2x_virtf *vf,
struct bnx2x_vf_bar_info *bar_info)
{
int n;

bar_info->nr_bars = bp->vfdb->sriov.nres;
for (n = 0; n < bar_info->nr_bars; n++)
bar_info->bars[n] = vf->bars[n];
}

void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
enum channel_tlvs tlv)
{
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ struct bnx2x_vf_bar {
u32 size;
};

struct bnx2x_vf_bar_info {
struct bnx2x_vf_bar bars[PCI_SRIOV_NUM_BARS];
u8 nr_bars;
};

/* vf queue (used both for rx or tx) */
struct bnx2x_vf_queue {
struct eth_context *cxt;
Expand Down Expand Up @@ -429,6 +434,7 @@ void bnx2x_iov_remove_one(struct bnx2x *bp);
void bnx2x_iov_free_mem(struct bnx2x *bp);
int bnx2x_iov_alloc_mem(struct bnx2x *bp);
int bnx2x_iov_nic_init(struct bnx2x *bp);
int bnx2x_iov_chip_cleanup(struct bnx2x *bp);
void bnx2x_iov_init_dq(struct bnx2x *bp);
void bnx2x_iov_init_dmae(struct bnx2x *bp);
void bnx2x_iov_set_queue_sp_obj(struct bnx2x *bp, int vf_cid,
Expand Down Expand Up @@ -546,6 +552,11 @@ static inline void bnx2x_vfop_end(struct bnx2x *bp, struct bnx2x_virtf *vf,
if (vfop->done) {
DP(BNX2X_MSG_IOV, "calling done handler\n");
vfop->done(bp, vf);
} else {
/* there is no done handler for the operation to unlock
* the mutex. Must have gotten here from PF initiated VF RELEASE
*/
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_RELEASE_VF);
}

DP(BNX2X_MSG_IOV, "done handler complete. vf->op_rc %d, vfop->rc %d\n",
Expand Down Expand Up @@ -661,6 +672,16 @@ int bnx2x_vfop_close_cmd(struct bnx2x *bp,
struct bnx2x_virtf *vf,
struct bnx2x_vfop_cmd *cmd);

int bnx2x_vfop_release_cmd(struct bnx2x *bp,
struct bnx2x_virtf *vf,
struct bnx2x_vfop_cmd *cmd);

/* VF release ~ VF close + VF release-resources
*
* Release is the ultimate SW shutdown and is called whenever an
* irrecoverable error is encountered.
*/
void bnx2x_vf_release(struct bnx2x *bp, struct bnx2x_virtf *vf, bool block);
int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid);
u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf);
/* VF FLR helpers */
Expand Down
25 changes: 24 additions & 1 deletion trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)
if (rc) {
BNX2X_ERR("Failed to copy response body to VF %d\n",
vf->abs_vfid);
return;
goto mbx_error;
}
vf_addr -= sizeof(u64);
pf_addr -= sizeof(u64);
Expand All @@ -255,8 +255,12 @@ static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)
if (rc) {
BNX2X_ERR("Failed to copy response status to VF %d\n",
vf->abs_vfid);
goto mbx_error;
}
return;

mbx_error:
bnx2x_vf_release(bp, vf, false); /* non blocking */
}

static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
Expand Down Expand Up @@ -819,6 +823,21 @@ static void bnx2x_vf_mbx_close_vf(struct bnx2x *bp, struct bnx2x_virtf *vf,
bnx2x_vf_mbx_resp(bp, vf);
}

static void bnx2x_vf_mbx_release_vf(struct bnx2x *bp, struct bnx2x_virtf *vf,
struct bnx2x_vf_mbx *mbx)
{
struct bnx2x_vfop_cmd cmd = {
.done = bnx2x_vf_mbx_resp,
.block = false,
};

DP(BNX2X_MSG_IOV, "VF[%d] VF_RELEASE\n", vf->abs_vfid);

vf->op_rc = bnx2x_vfop_release_cmd(bp, vf, &cmd);
if (vf->op_rc)
bnx2x_vf_mbx_resp(bp, vf);
}

/* dispatch request */
static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf,
struct bnx2x_vf_mbx *mbx)
Expand Down Expand Up @@ -852,6 +871,9 @@ static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf,
case CHANNEL_TLV_CLOSE:
bnx2x_vf_mbx_close_vf(bp, vf, mbx);
break;
case CHANNEL_TLV_RELEASE:
bnx2x_vf_mbx_release_vf(bp, vf, mbx);
break;
}

} else {
Expand Down Expand Up @@ -942,6 +964,7 @@ void bnx2x_vf_mbx(struct bnx2x *bp, struct vf_pf_event_data *vfpf_event)
goto mbx_done;

mbx_error:
bnx2x_vf_release(bp, vf, false); /* non blocking */
mbx_done:
return;
}
1 change: 1 addition & 0 deletions trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ enum channel_tlvs {
CHANNEL_TLV_TEARDOWN_Q,
CHANNEL_TLV_CLOSE,
CHANNEL_TLV_RELEASE,
CHANNEL_TLV_PF_RELEASE_VF,
CHANNEL_TLV_LIST_END,
CHANNEL_TLV_MAX
};
Expand Down

0 comments on commit c5f9c87

Please sign in to comment.