Skip to content

Commit ac19e03

Browse files
Michal Swiatkowskianguy11
authored andcommitted
ice: allow process VF opcodes in different ways
In switchdev driver shouldn't add MAC, VLAN and promisc filters on iavf demand but should return success to not break normal iavf flow. Achieve that by creating table of functions pointer with default functions used to parse iavf command. While parse iavf command, call correct function from table instead of calling function direct. When port representors are being created change functions in table to new one that behaves correctly for switchdev puprose (ignoring new filters). Change back to default ops when representors are being removed. Co-developed-by: Wojciech Drewek <[email protected]> Signed-off-by: Wojciech Drewek <[email protected]> Signed-off-by: Michal Swiatkowski <[email protected]> Tested-by: Sandeep Penigalapati <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 37165e3 commit ac19e03

File tree

3 files changed

+225
-37
lines changed

3 files changed

+225
-37
lines changed

drivers/net/ethernet/intel/ice/ice_repr.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,24 @@ int ice_repr_add_for_all_vfs(struct ice_pf *pf)
228228
int i;
229229

230230
ice_for_each_vf(pf, i) {
231-
err = ice_repr_add(&pf->vf[i]);
231+
struct ice_vf *vf = &pf->vf[i];
232+
233+
err = ice_repr_add(vf);
232234
if (err)
233235
goto err;
236+
237+
ice_vc_change_ops_to_repr(&vf->vc_ops);
234238
}
239+
235240
return 0;
236241

237242
err:
238-
for (i = i - 1; i >= 0; i--)
239-
ice_repr_rem(&pf->vf[i]);
243+
for (i = i - 1; i >= 0; i--) {
244+
struct ice_vf *vf = &pf->vf[i];
245+
246+
ice_repr_rem(vf);
247+
ice_vc_set_dflt_vf_ops(&vf->vc_ops);
248+
}
240249

241250
return err;
242251
}
@@ -249,6 +258,10 @@ void ice_repr_rem_from_all_vfs(struct ice_pf *pf)
249258
{
250259
int i;
251260

252-
ice_for_each_vf(pf, i)
253-
ice_repr_rem(&pf->vf[i]);
261+
ice_for_each_vf(pf, i) {
262+
struct ice_vf *vf = &pf->vf[i];
263+
264+
ice_repr_rem(vf);
265+
ice_vc_set_dflt_vf_ops(&vf->vc_ops);
266+
}
254267
}

drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c

Lines changed: 175 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,8 @@ static void ice_set_dflt_settings_vfs(struct ice_pf *pf)
18941894
*/
18951895
ice_vf_ctrl_invalidate_vsi(vf);
18961896
ice_vf_fdir_init(vf);
1897+
1898+
ice_vc_set_dflt_vf_ops(&vf->vc_ops);
18971899
}
18981900
}
18991901

@@ -3801,6 +3803,26 @@ static bool ice_is_legacy_umac_expired(struct ice_time_mac *last_added_umac)
38013803
ICE_LEGACY_VF_MAC_CHANGE_EXPIRE_TIME);
38023804
}
38033805

3806+
/**
3807+
* ice_update_legacy_cached_mac - update cached hardware MAC for legacy VF
3808+
* @vf: VF to update
3809+
* @vc_ether_addr: structure from VIRTCHNL with MAC to check
3810+
*
3811+
* only update cached hardware MAC for legacy VF drivers on delete
3812+
* because we cannot guarantee order/type of MAC from the VF driver
3813+
*/
3814+
static void
3815+
ice_update_legacy_cached_mac(struct ice_vf *vf,
3816+
struct virtchnl_ether_addr *vc_ether_addr)
3817+
{
3818+
if (!ice_is_vc_addr_legacy(vc_ether_addr) ||
3819+
ice_is_legacy_umac_expired(&vf->legacy_last_added_umac))
3820+
return;
3821+
3822+
ether_addr_copy(vf->dev_lan_addr.addr, vf->legacy_last_added_umac.addr);
3823+
ether_addr_copy(vf->hw_lan_addr.addr, vf->legacy_last_added_umac.addr);
3824+
}
3825+
38043826
/**
38053827
* ice_vfhw_mac_del - update the VF's cached hardware MAC if allowed
38063828
* @vf: VF to update
@@ -3822,16 +3844,7 @@ ice_vfhw_mac_del(struct ice_vf *vf, struct virtchnl_ether_addr *vc_ether_addr)
38223844
*/
38233845
eth_zero_addr(vf->dev_lan_addr.addr);
38243846

3825-
/* only update cached hardware MAC for legacy VF drivers on delete
3826-
* because we cannot guarantee order/type of MAC from the VF driver
3827-
*/
3828-
if (ice_is_vc_addr_legacy(vc_ether_addr) &&
3829-
!ice_is_legacy_umac_expired(&vf->legacy_last_added_umac)) {
3830-
ether_addr_copy(vf->dev_lan_addr.addr,
3831-
vf->legacy_last_added_umac.addr);
3832-
ether_addr_copy(vf->hw_lan_addr.addr,
3833-
vf->legacy_last_added_umac.addr);
3834-
}
3847+
ice_update_legacy_cached_mac(vf, vc_ether_addr);
38353848
}
38363849

38373850
/**
@@ -4400,6 +4413,133 @@ static int ice_vf_init_vlan_stripping(struct ice_vf *vf)
44004413
return ice_vsi_manage_vlan_stripping(vsi, false);
44014414
}
44024415

4416+
static struct ice_vc_vf_ops ice_vc_vf_dflt_ops = {
4417+
.get_ver_msg = ice_vc_get_ver_msg,
4418+
.get_vf_res_msg = ice_vc_get_vf_res_msg,
4419+
.reset_vf = ice_vc_reset_vf_msg,
4420+
.add_mac_addr_msg = ice_vc_add_mac_addr_msg,
4421+
.del_mac_addr_msg = ice_vc_del_mac_addr_msg,
4422+
.cfg_qs_msg = ice_vc_cfg_qs_msg,
4423+
.ena_qs_msg = ice_vc_ena_qs_msg,
4424+
.dis_qs_msg = ice_vc_dis_qs_msg,
4425+
.request_qs_msg = ice_vc_request_qs_msg,
4426+
.cfg_irq_map_msg = ice_vc_cfg_irq_map_msg,
4427+
.config_rss_key = ice_vc_config_rss_key,
4428+
.config_rss_lut = ice_vc_config_rss_lut,
4429+
.get_stats_msg = ice_vc_get_stats_msg,
4430+
.cfg_promiscuous_mode_msg = ice_vc_cfg_promiscuous_mode_msg,
4431+
.add_vlan_msg = ice_vc_add_vlan_msg,
4432+
.remove_vlan_msg = ice_vc_remove_vlan_msg,
4433+
.ena_vlan_stripping = ice_vc_ena_vlan_stripping,
4434+
.dis_vlan_stripping = ice_vc_dis_vlan_stripping,
4435+
.handle_rss_cfg_msg = ice_vc_handle_rss_cfg,
4436+
.add_fdir_fltr_msg = ice_vc_add_fdir_fltr,
4437+
.del_fdir_fltr_msg = ice_vc_del_fdir_fltr,
4438+
};
4439+
4440+
void ice_vc_set_dflt_vf_ops(struct ice_vc_vf_ops *ops)
4441+
{
4442+
*ops = ice_vc_vf_dflt_ops;
4443+
}
4444+
4445+
static int
4446+
ice_vc_repr_no_action_msg(struct ice_vf __always_unused *vf,
4447+
u8 __always_unused *msg)
4448+
{
4449+
return 0;
4450+
}
4451+
4452+
/**
4453+
* ice_vc_repr_add_mac
4454+
* @vf: pointer to VF
4455+
* @msg: virtchannel message
4456+
*
4457+
* When port representors are created, we do not add MAC rule
4458+
* to firmware, we store it so that PF could report same
4459+
* MAC as VF.
4460+
*/
4461+
static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg)
4462+
{
4463+
enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS;
4464+
struct virtchnl_ether_addr_list *al =
4465+
(struct virtchnl_ether_addr_list *)msg;
4466+
struct ice_vsi *vsi;
4467+
struct ice_pf *pf;
4468+
int i;
4469+
4470+
if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) ||
4471+
!ice_vc_isvalid_vsi_id(vf, al->vsi_id)) {
4472+
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
4473+
goto handle_mac_exit;
4474+
}
4475+
4476+
pf = vf->pf;
4477+
4478+
vsi = ice_get_vf_vsi(vf);
4479+
if (!vsi) {
4480+
v_ret = VIRTCHNL_STATUS_ERR_PARAM;
4481+
goto handle_mac_exit;
4482+
}
4483+
4484+
for (i = 0; i < al->num_elements; i++) {
4485+
u8 *mac_addr = al->list[i].addr;
4486+
4487+
if (!is_unicast_ether_addr(mac_addr) ||
4488+
ether_addr_equal(mac_addr, vf->hw_lan_addr.addr))
4489+
continue;
4490+
4491+
if (vf->pf_set_mac) {
4492+
dev_err(ice_pf_to_dev(pf), "VF attempting to override administratively set MAC address\n");
4493+
v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED;
4494+
goto handle_mac_exit;
4495+
}
4496+
4497+
ice_vfhw_mac_add(vf, &al->list[i]);
4498+
vf->num_mac++;
4499+
break;
4500+
}
4501+
4502+
handle_mac_exit:
4503+
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_ADD_ETH_ADDR,
4504+
v_ret, NULL, 0);
4505+
}
4506+
4507+
/**
4508+
* ice_vc_repr_del_mac - response with success for deleting MAC
4509+
* @vf: pointer to VF
4510+
* @msg: virtchannel message
4511+
*
4512+
* Respond with success to not break normal VF flow.
4513+
* For legacy VF driver try to update cached MAC address.
4514+
*/
4515+
static int
4516+
ice_vc_repr_del_mac(struct ice_vf __always_unused *vf, u8 __always_unused *msg)
4517+
{
4518+
struct virtchnl_ether_addr_list *al =
4519+
(struct virtchnl_ether_addr_list *)msg;
4520+
4521+
ice_update_legacy_cached_mac(vf, &al->list[0]);
4522+
4523+
return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_DEL_ETH_ADDR,
4524+
VIRTCHNL_STATUS_SUCCESS, NULL, 0);
4525+
}
4526+
4527+
static int ice_vc_repr_no_action(struct ice_vf __always_unused *vf)
4528+
{
4529+
return 0;
4530+
}
4531+
4532+
void ice_vc_change_ops_to_repr(struct ice_vc_vf_ops *ops)
4533+
{
4534+
ops->add_mac_addr_msg = ice_vc_repr_add_mac;
4535+
ops->del_mac_addr_msg = ice_vc_repr_del_mac;
4536+
ops->add_vlan_msg = ice_vc_repr_no_action_msg;
4537+
ops->remove_vlan_msg = ice_vc_repr_no_action_msg;
4538+
ops->ena_vlan_stripping = ice_vc_repr_no_action;
4539+
ops->dis_vlan_stripping = ice_vc_repr_no_action;
4540+
ops->cfg_promiscuous_mode_msg = ice_vc_repr_no_action_msg;
4541+
}
4542+
44034543
/**
44044544
* ice_vc_process_vf_msg - Process request from VF
44054545
* @pf: pointer to the PF structure
@@ -4413,6 +4553,7 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
44134553
u32 v_opcode = le32_to_cpu(event->desc.cookie_high);
44144554
s16 vf_id = le16_to_cpu(event->desc.retval);
44154555
u16 msglen = event->msg_len;
4556+
struct ice_vc_vf_ops *ops;
44164557
u8 *msg = event->msg_buf;
44174558
struct ice_vf *vf = NULL;
44184559
struct device *dev;
@@ -4436,6 +4577,8 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
44364577
goto error_handler;
44374578
}
44384579

4580+
ops = &vf->vc_ops;
4581+
44394582
/* Perform basic checks on the msg */
44404583
err = virtchnl_vc_validate_vf_msg(&vf->vf_ver, v_opcode, msg, msglen);
44414584
if (err) {
@@ -4463,75 +4606,75 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event)
44634606

44644607
switch (v_opcode) {
44654608
case VIRTCHNL_OP_VERSION:
4466-
err = ice_vc_get_ver_msg(vf, msg);
4609+
err = ops->get_ver_msg(vf, msg);
44674610
break;
44684611
case VIRTCHNL_OP_GET_VF_RESOURCES:
4469-
err = ice_vc_get_vf_res_msg(vf, msg);
4612+
err = ops->get_vf_res_msg(vf, msg);
44704613
if (ice_vf_init_vlan_stripping(vf))
44714614
dev_err(dev, "Failed to initialize VLAN stripping for VF %d\n",
44724615
vf->vf_id);
44734616
ice_vc_notify_vf_link_state(vf);
44744617
break;
44754618
case VIRTCHNL_OP_RESET_VF:
4476-
ice_vc_reset_vf_msg(vf);
4619+
ops->reset_vf(vf);
44774620
break;
44784621
case VIRTCHNL_OP_ADD_ETH_ADDR:
4479-
err = ice_vc_add_mac_addr_msg(vf, msg);
4622+
err = ops->add_mac_addr_msg(vf, msg);
44804623
break;
44814624
case VIRTCHNL_OP_DEL_ETH_ADDR:
4482-
err = ice_vc_del_mac_addr_msg(vf, msg);
4625+
err = ops->del_mac_addr_msg(vf, msg);
44834626
break;
44844627
case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
4485-
err = ice_vc_cfg_qs_msg(vf, msg);
4628+
err = ops->cfg_qs_msg(vf, msg);
44864629
break;
44874630
case VIRTCHNL_OP_ENABLE_QUEUES:
4488-
err = ice_vc_ena_qs_msg(vf, msg);
4631+
err = ops->ena_qs_msg(vf, msg);
44894632
ice_vc_notify_vf_link_state(vf);
44904633
break;
44914634
case VIRTCHNL_OP_DISABLE_QUEUES:
4492-
err = ice_vc_dis_qs_msg(vf, msg);
4635+
err = ops->dis_qs_msg(vf, msg);
44934636
break;
44944637
case VIRTCHNL_OP_REQUEST_QUEUES:
4495-
err = ice_vc_request_qs_msg(vf, msg);
4638+
err = ops->request_qs_msg(vf, msg);
44964639
break;
44974640
case VIRTCHNL_OP_CONFIG_IRQ_MAP:
4498-
err = ice_vc_cfg_irq_map_msg(vf, msg);
4641+
err = ops->cfg_irq_map_msg(vf, msg);
44994642
break;
45004643
case VIRTCHNL_OP_CONFIG_RSS_KEY:
4501-
err = ice_vc_config_rss_key(vf, msg);
4644+
err = ops->config_rss_key(vf, msg);
45024645
break;
45034646
case VIRTCHNL_OP_CONFIG_RSS_LUT:
4504-
err = ice_vc_config_rss_lut(vf, msg);
4647+
err = ops->config_rss_lut(vf, msg);
45054648
break;
45064649
case VIRTCHNL_OP_GET_STATS:
4507-
err = ice_vc_get_stats_msg(vf, msg);
4650+
err = ops->get_stats_msg(vf, msg);
45084651
break;
45094652
case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
4510-
err = ice_vc_cfg_promiscuous_mode_msg(vf, msg);
4653+
err = ops->cfg_promiscuous_mode_msg(vf, msg);
45114654
break;
45124655
case VIRTCHNL_OP_ADD_VLAN:
4513-
err = ice_vc_add_vlan_msg(vf, msg);
4656+
err = ops->add_vlan_msg(vf, msg);
45144657
break;
45154658
case VIRTCHNL_OP_DEL_VLAN:
4516-
err = ice_vc_remove_vlan_msg(vf, msg);
4659+
err = ops->remove_vlan_msg(vf, msg);
45174660
break;
45184661
case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
4519-
err = ice_vc_ena_vlan_stripping(vf);
4662+
err = ops->ena_vlan_stripping(vf);
45204663
break;
45214664
case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
4522-
err = ice_vc_dis_vlan_stripping(vf);
4665+
err = ops->dis_vlan_stripping(vf);
45234666
break;
45244667
case VIRTCHNL_OP_ADD_FDIR_FILTER:
4525-
err = ice_vc_add_fdir_fltr(vf, msg);
4668+
err = ops->add_fdir_fltr_msg(vf, msg);
45264669
break;
45274670
case VIRTCHNL_OP_DEL_FDIR_FILTER:
4528-
err = ice_vc_del_fdir_fltr(vf, msg);
4671+
err = ops->del_fdir_fltr_msg(vf, msg);
45294672
break;
45304673
case VIRTCHNL_OP_ADD_RSS_CFG:
4531-
err = ice_vc_handle_rss_cfg(vf, msg, true);
4674+
err = ops->handle_rss_cfg_msg(vf, msg, true);
45324675
break;
45334676
case VIRTCHNL_OP_DEL_RSS_CFG:
4534-
err = ice_vc_handle_rss_cfg(vf, msg, false);
4677+
err = ops->handle_rss_cfg_msg(vf, msg, false);
45354678
break;
45364679
case VIRTCHNL_OP_UNKNOWN:
45374680
default:

0 commit comments

Comments
 (0)