Skip to content

Commit

Permalink
bnx2x: Add support in PF driver for RSC
Browse files Browse the repository at this point in the history
This provides PF-side support for VFs assigned to a VM running windows
2012 with the RSC feature enabled.

Signed-off-by: Michal Kalderon <michals@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michal Kalderon authored and David S. Miller committed Feb 13, 2014
1 parent ba72f32 commit 14a94eb
Show file tree
Hide file tree
Showing 8 changed files with 329 additions and 48 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,7 @@ struct bnx2x_slowpath {
union {
struct client_init_ramrod_data init_data;
struct client_update_ramrod_data update_data;
struct tpa_update_ramrod_data tpa_data;
} q_rdata;

union {
Expand Down
21 changes: 17 additions & 4 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1814,6 +1814,11 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe)
drv_cmd = BNX2X_Q_CMD_EMPTY;
break;

case (RAMROD_CMD_ID_ETH_TPA_UPDATE):
DP(BNX2X_MSG_SP, "got tpa update ramrod CID=%d\n", cid);
drv_cmd = BNX2X_Q_CMD_UPDATE_TPA;
break;

default:
BNX2X_ERR("unexpected MC reply (%d) on fp[%d]\n",
command, fp->index);
Expand Down Expand Up @@ -3644,10 +3649,18 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) |
HW_CID(bp, cid));

type = (cmd_type << SPE_HDR_CONN_TYPE_SHIFT) & SPE_HDR_CONN_TYPE;

type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) &
SPE_HDR_FUNCTION_ID);
/* In some cases, type may already contain the func-id
* mainly in SRIOV related use cases, so we add it here only
* if it's not already set.
*/
if (!(cmd_type & SPE_HDR_FUNCTION_ID)) {
type = (cmd_type << SPE_HDR_CONN_TYPE_SHIFT) &
SPE_HDR_CONN_TYPE;
type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) &
SPE_HDR_FUNCTION_ID);
} else {
type = cmd_type;
}

spe->hdr.type = cpu_to_le16(type);

Expand Down
145 changes: 102 additions & 43 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2277,11 +2277,11 @@ static int bnx2x_set_rx_mode_e2(struct bnx2x *bp,
data->header.rule_cnt, p->rx_accept_flags,
p->tx_accept_flags);

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

/* Send a ramrod */
Expand Down Expand Up @@ -2982,11 +2982,11 @@ static int bnx2x_mcast_setup_e2(struct bnx2x *bp,
raw->clear_pending(raw);
return 0;
} else {
/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

/* Send a ramrod */
Expand Down Expand Up @@ -3466,11 +3466,11 @@ static int bnx2x_mcast_setup_e1(struct bnx2x *bp,
raw->clear_pending(raw);
return 0;
} else {
/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

/* Send a ramrod */
Expand Down Expand Up @@ -4091,11 +4091,11 @@ static int bnx2x_setup_rss(struct bnx2x *bp,
data->capabilities |= ETH_RSS_UPDATE_RAMROD_DATA_UPDATE_RSS_KEY;
}

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

/* Send a ramrod */
Expand Down Expand Up @@ -4587,13 +4587,12 @@ static inline int bnx2x_q_send_setup_e1x(struct bnx2x *bp,
/* Fill the ramrod data */
bnx2x_q_fill_setup_data_cmn(bp, params, rdata);

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX],
U64_HI(data_mapping),
U64_LO(data_mapping), ETH_CONNECTION_TYPE);
Expand All @@ -4615,13 +4614,12 @@ static inline int bnx2x_q_send_setup_e2(struct bnx2x *bp,
bnx2x_q_fill_setup_data_cmn(bp, params, rdata);
bnx2x_q_fill_setup_data_e2(bp, params, rdata);

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

return bnx2x_sp_post(bp, ramrod, o->cids[BNX2X_PRIMARY_CID_INDEX],
U64_HI(data_mapping),
U64_LO(data_mapping), ETH_CONNECTION_TYPE);
Expand Down Expand Up @@ -4659,13 +4657,12 @@ static inline int bnx2x_q_send_setup_tx_only(struct bnx2x *bp,
o->cids[cid_index], rdata->general.client_id,
rdata->general.sp_client_id, rdata->general.cos);

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

return bnx2x_sp_post(bp, ramrod, o->cids[cid_index],
U64_HI(data_mapping),
U64_LO(data_mapping), ETH_CONNECTION_TYPE);
Expand Down Expand Up @@ -4760,13 +4757,12 @@ static inline int bnx2x_q_send_update(struct bnx2x *bp,
/* Fill the ramrod data */
bnx2x_q_fill_update_data(bp, o, update_params, rdata);

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/

return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_UPDATE,
o->cids[cid_index], U64_HI(data_mapping),
U64_LO(data_mapping), ETH_CONNECTION_TYPE);
Expand Down Expand Up @@ -4813,11 +4809,62 @@ static inline int bnx2x_q_send_activate(struct bnx2x *bp,
return bnx2x_q_send_update(bp, params);
}

static void bnx2x_q_fill_update_tpa_data(struct bnx2x *bp,
struct bnx2x_queue_sp_obj *obj,
struct bnx2x_queue_update_tpa_params *params,
struct tpa_update_ramrod_data *data)
{
data->client_id = obj->cl_id;
data->complete_on_both_clients = params->complete_on_both_clients;
data->dont_verify_rings_pause_thr_flg =
params->dont_verify_thr;
data->max_agg_size = cpu_to_le16(params->max_agg_sz);
data->max_sges_for_packet = params->max_sges_pkt;
data->max_tpa_queues = params->max_tpa_queues;
data->sge_buff_size = cpu_to_le16(params->sge_buff_sz);
data->sge_page_base_hi = cpu_to_le32(U64_HI(params->sge_map));
data->sge_page_base_lo = cpu_to_le32(U64_LO(params->sge_map));
data->sge_pause_thr_high = cpu_to_le16(params->sge_pause_thr_high);
data->sge_pause_thr_low = cpu_to_le16(params->sge_pause_thr_low);
data->tpa_mode = params->tpa_mode;
data->update_ipv4 = params->update_ipv4;
data->update_ipv6 = params->update_ipv6;
}

static inline int bnx2x_q_send_update_tpa(struct bnx2x *bp,
struct bnx2x_queue_state_params *params)
{
/* TODO: Not implemented yet. */
return -1;
struct bnx2x_queue_sp_obj *o = params->q_obj;
struct tpa_update_ramrod_data *rdata =
(struct tpa_update_ramrod_data *)o->rdata;
dma_addr_t data_mapping = o->rdata_mapping;
struct bnx2x_queue_update_tpa_params *update_tpa_params =
&params->params.update_tpa;
u16 type;

/* Clear the ramrod data */
memset(rdata, 0, sizeof(*rdata));

/* Fill the ramrod data */
bnx2x_q_fill_update_tpa_data(bp, o, update_tpa_params, rdata);

/* Add the function id inside the type, so that sp post function
* doesn't automatically add the PF func-id, this is required
* for operations done by PFs on behalf of their VFs
*/
type = ETH_CONNECTION_TYPE |
((o->func_id) << SPE_HDR_FUNCTION_ID_SHIFT);

/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/
return bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TPA_UPDATE,
o->cids[BNX2X_PRIMARY_CID_INDEX],
U64_HI(data_mapping),
U64_LO(data_mapping), type);
}

static inline int bnx2x_q_send_halt(struct bnx2x *bp,
Expand Down Expand Up @@ -5647,6 +5694,12 @@ static inline int bnx2x_func_send_switch_update(struct bnx2x *bp,
rdata->tx_switch_suspend = switch_update_params->suspend;
rdata->echo = SWITCH_UPDATE;

/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/
return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0,
U64_HI(data_mapping),
U64_LO(data_mapping), NONE_CONNECTION_TYPE);
Expand Down Expand Up @@ -5674,11 +5727,11 @@ static inline int bnx2x_func_send_afex_update(struct bnx2x *bp,
rdata->allowed_priorities = afex_update_params->allowed_priorities;
rdata->echo = AFEX_UPDATE;

/* No need for an explicit memory barrier here as long we would
* need to ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read and we will have to put a full memory barrier there
* (inside bnx2x_sp_post()).
/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/
DP(BNX2X_MSG_SP,
"afex: sending func_update vif_id 0x%x dvlan 0x%x prio 0x%x\n",
Expand Down Expand Up @@ -5763,6 +5816,12 @@ static inline int bnx2x_func_send_tx_start(struct bnx2x *bp,
rdata->traffic_type_to_priority_cos[i] =
tx_start_params->traffic_type_to_priority_cos[i];

/* No need for an explicit memory barrier here as long as we
* ensure the ordering of writing to the SPQ element
* and updating of the SPQ producer which involves a memory
* read. If the memory read is removed we will have to put a
* full memory barrier there (inside bnx2x_sp_post()).
*/
return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0,
U64_HI(data_mapping),
U64_LO(data_mapping), NONE_CONNECTION_TYPE);
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,24 @@ struct bnx2x_queue_update_params {
u8 cid_index;
};

struct bnx2x_queue_update_tpa_params {
dma_addr_t sge_map;
u8 update_ipv4;
u8 update_ipv6;
u8 max_tpa_queues;
u8 max_sges_pkt;
u8 complete_on_both_clients;
u8 dont_verify_thr;
u8 tpa_mode;
u8 _pad;

u16 sge_buff_sz;
u16 max_agg_sz;

u16 sge_pause_thr_low;
u16 sge_pause_thr_high;
};

struct rxq_pause_params {
u16 bd_th_lo;
u16 bd_th_hi;
Expand Down Expand Up @@ -987,6 +1005,7 @@ struct bnx2x_queue_state_params {
/* Params according to the current command */
union {
struct bnx2x_queue_update_params update;
struct bnx2x_queue_update_tpa_params update_tpa;
struct bnx2x_queue_setup_params setup;
struct bnx2x_queue_init_params init;
struct bnx2x_queue_setup_tx_only_params tx_only;
Expand Down
Loading

0 comments on commit 14a94eb

Please sign in to comment.