Skip to content

Commit 26d6804

Browse files
committed
Merge branch 'qed-Use-trust-mode-to-override-forced-MAC'
Shahed Shaikh says: ==================== qed* : Use trust mode to override forced MAC This patchset adds a support to override forced MAC (MAC set by PF for a VF) when trust mode is enabled using First patch adds a real change to use .ndo_set_vf_trust to override forced MAC and allow user to change VFs from VF interface itself. Second patch takes care of a corner case, where MAC change from VF won't take effect when VF interface is down, by introducing a new TLV (a way to send message from VF to PF) to give a hint to PF to update its bulletin board. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 2ed0212 + 809c45a commit 26d6804

File tree

6 files changed

+306
-18
lines changed

6 files changed

+306
-18
lines changed

drivers/net/ethernet/qlogic/qed/qed_l2.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2850,6 +2850,24 @@ static int qed_fp_cqe_completion(struct qed_dev *dev,
28502850
cqe);
28512851
}
28522852

2853+
static int qed_req_bulletin_update_mac(struct qed_dev *cdev, u8 *mac)
2854+
{
2855+
int i, ret;
2856+
2857+
if (IS_PF(cdev))
2858+
return 0;
2859+
2860+
for_each_hwfn(cdev, i) {
2861+
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
2862+
2863+
ret = qed_vf_pf_bulletin_update_mac(p_hwfn, mac);
2864+
if (ret)
2865+
return ret;
2866+
}
2867+
2868+
return 0;
2869+
}
2870+
28532871
#ifdef CONFIG_QED_SRIOV
28542872
extern const struct qed_iov_hv_ops qed_iov_ops_pass;
28552873
#endif
@@ -2887,6 +2905,7 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
28872905
.ntuple_filter_config = &qed_ntuple_arfs_filter_config,
28882906
.configure_arfs_searcher = &qed_configure_arfs_searcher,
28892907
.get_coalesce = &qed_get_coalesce,
2908+
.req_bulletin_update_mac = &qed_req_bulletin_update_mac,
28902909
};
28912910

28922911
const struct qed_eth_ops *qed_get_eth_ops(void)

drivers/net/ethernet/qlogic/qed/qed_sriov.c

Lines changed: 231 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int qed_sriov_eqe_event(struct qed_hwfn *p_hwfn,
4848
u8 opcode,
4949
__le16 echo,
5050
union event_ring_data *data, u8 fw_return_code);
51-
51+
static int qed_iov_bulletin_set_mac(struct qed_hwfn *p_hwfn, u8 *mac, int vfid);
5252

5353
static u8 qed_vf_calculate_legacy(struct qed_vf_info *p_vf)
5454
{
@@ -1790,7 +1790,8 @@ static int qed_iov_configure_vport_forced(struct qed_hwfn *p_hwfn,
17901790
if (!p_vf->vport_instance)
17911791
return -EINVAL;
17921792

1793-
if (events & BIT(MAC_ADDR_FORCED)) {
1793+
if ((events & BIT(MAC_ADDR_FORCED)) ||
1794+
p_vf->p_vf_info.is_trusted_configured) {
17941795
/* Since there's no way [currently] of removing the MAC,
17951796
* we can always assume this means we need to force it.
17961797
*/
@@ -1809,8 +1810,12 @@ static int qed_iov_configure_vport_forced(struct qed_hwfn *p_hwfn,
18091810
"PF failed to configure MAC for VF\n");
18101811
return rc;
18111812
}
1812-
1813-
p_vf->configured_features |= 1 << MAC_ADDR_FORCED;
1813+
if (p_vf->p_vf_info.is_trusted_configured)
1814+
p_vf->configured_features |=
1815+
BIT(VFPF_BULLETIN_MAC_ADDR);
1816+
else
1817+
p_vf->configured_features |=
1818+
BIT(MAC_ADDR_FORCED);
18141819
}
18151820

18161821
if (events & BIT(VLAN_ADDR_FORCED)) {
@@ -3170,6 +3175,10 @@ static int qed_iov_vf_update_mac_shadow(struct qed_hwfn *p_hwfn,
31703175
if (p_vf->bulletin.p_virt->valid_bitmap & BIT(MAC_ADDR_FORCED))
31713176
return 0;
31723177

3178+
/* Don't keep track of shadow copy since we don't intend to restore. */
3179+
if (p_vf->p_vf_info.is_trusted_configured)
3180+
return 0;
3181+
31733182
/* First remove entries and then add new ones */
31743183
if (p_params->opcode == QED_FILTER_REMOVE) {
31753184
for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
@@ -3244,9 +3253,17 @@ static int qed_iov_chk_ucast(struct qed_hwfn *hwfn,
32443253

32453254
/* No real decision to make; Store the configured MAC */
32463255
if (params->type == QED_FILTER_MAC ||
3247-
params->type == QED_FILTER_MAC_VLAN)
3256+
params->type == QED_FILTER_MAC_VLAN) {
32483257
ether_addr_copy(vf->mac, params->mac);
32493258

3259+
if (vf->is_trusted_configured) {
3260+
qed_iov_bulletin_set_mac(hwfn, vf->mac, vfid);
3261+
3262+
/* Update and post bulleitin again */
3263+
qed_schedule_iov(hwfn, QED_IOV_WQ_BULLETIN_UPDATE_FLAG);
3264+
}
3265+
}
3266+
32503267
return 0;
32513268
}
32523269

@@ -3803,6 +3820,40 @@ static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
38033820
__qed_vf_get_link_caps(p_hwfn, p_caps, p_bulletin);
38043821
}
38053822

3823+
static int
3824+
qed_iov_vf_pf_bulletin_update_mac(struct qed_hwfn *p_hwfn,
3825+
struct qed_ptt *p_ptt,
3826+
struct qed_vf_info *p_vf)
3827+
{
3828+
struct qed_bulletin_content *p_bulletin = p_vf->bulletin.p_virt;
3829+
struct qed_iov_vf_mbx *mbx = &p_vf->vf_mbx;
3830+
struct vfpf_bulletin_update_mac_tlv *p_req;
3831+
u8 status = PFVF_STATUS_SUCCESS;
3832+
int rc = 0;
3833+
3834+
if (!p_vf->p_vf_info.is_trusted_configured) {
3835+
DP_VERBOSE(p_hwfn,
3836+
QED_MSG_IOV,
3837+
"Blocking bulletin update request from untrusted VF[%d]\n",
3838+
p_vf->abs_vf_id);
3839+
status = PFVF_STATUS_NOT_SUPPORTED;
3840+
rc = -EINVAL;
3841+
goto send_status;
3842+
}
3843+
3844+
p_req = &mbx->req_virt->bulletin_update_mac;
3845+
ether_addr_copy(p_bulletin->mac, p_req->mac);
3846+
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
3847+
"Updated bulletin of VF[%d] with requested MAC[%pM]\n",
3848+
p_vf->abs_vf_id, p_req->mac);
3849+
3850+
send_status:
3851+
qed_iov_prepare_resp(p_hwfn, p_ptt, p_vf,
3852+
CHANNEL_TLV_BULLETIN_UPDATE_MAC,
3853+
sizeof(struct pfvf_def_resp_tlv), status);
3854+
return rc;
3855+
}
3856+
38063857
static void qed_iov_process_mbx_req(struct qed_hwfn *p_hwfn,
38073858
struct qed_ptt *p_ptt, int vfid)
38083859
{
@@ -3882,6 +3933,9 @@ static void qed_iov_process_mbx_req(struct qed_hwfn *p_hwfn,
38823933
case CHANNEL_TLV_COALESCE_READ:
38833934
qed_iov_vf_pf_get_coalesce(p_hwfn, p_ptt, p_vf);
38843935
break;
3936+
case CHANNEL_TLV_BULLETIN_UPDATE_MAC:
3937+
qed_iov_vf_pf_bulletin_update_mac(p_hwfn, p_ptt, p_vf);
3938+
break;
38853939
}
38863940
} else if (qed_iov_tlv_supported(mbx->first_tlv.tl.type)) {
38873941
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
@@ -4081,16 +4135,60 @@ static void qed_iov_bulletin_set_forced_mac(struct qed_hwfn *p_hwfn,
40814135
return;
40824136
}
40834137

4084-
feature = 1 << MAC_ADDR_FORCED;
4138+
if (vf_info->p_vf_info.is_trusted_configured) {
4139+
feature = BIT(VFPF_BULLETIN_MAC_ADDR);
4140+
/* Trust mode will disable Forced MAC */
4141+
vf_info->bulletin.p_virt->valid_bitmap &=
4142+
~BIT(MAC_ADDR_FORCED);
4143+
} else {
4144+
feature = BIT(MAC_ADDR_FORCED);
4145+
/* Forced MAC will disable MAC_ADDR */
4146+
vf_info->bulletin.p_virt->valid_bitmap &=
4147+
~BIT(VFPF_BULLETIN_MAC_ADDR);
4148+
}
4149+
40854150
memcpy(vf_info->bulletin.p_virt->mac, mac, ETH_ALEN);
40864151

40874152
vf_info->bulletin.p_virt->valid_bitmap |= feature;
4088-
/* Forced MAC will disable MAC_ADDR */
4089-
vf_info->bulletin.p_virt->valid_bitmap &= ~BIT(VFPF_BULLETIN_MAC_ADDR);
40904153

40914154
qed_iov_configure_vport_forced(p_hwfn, vf_info, feature);
40924155
}
40934156

4157+
static int qed_iov_bulletin_set_mac(struct qed_hwfn *p_hwfn, u8 *mac, int vfid)
4158+
{
4159+
struct qed_vf_info *vf_info;
4160+
u64 feature;
4161+
4162+
vf_info = qed_iov_get_vf_info(p_hwfn, (u16)vfid, true);
4163+
if (!vf_info) {
4164+
DP_NOTICE(p_hwfn->cdev, "Can not set MAC, invalid vfid [%d]\n",
4165+
vfid);
4166+
return -EINVAL;
4167+
}
4168+
4169+
if (vf_info->b_malicious) {
4170+
DP_NOTICE(p_hwfn->cdev, "Can't set MAC to malicious VF [%d]\n",
4171+
vfid);
4172+
return -EINVAL;
4173+
}
4174+
4175+
if (vf_info->bulletin.p_virt->valid_bitmap & BIT(MAC_ADDR_FORCED)) {
4176+
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
4177+
"Can not set MAC, Forced MAC is configured\n");
4178+
return -EINVAL;
4179+
}
4180+
4181+
feature = BIT(VFPF_BULLETIN_MAC_ADDR);
4182+
ether_addr_copy(vf_info->bulletin.p_virt->mac, mac);
4183+
4184+
vf_info->bulletin.p_virt->valid_bitmap |= feature;
4185+
4186+
if (vf_info->p_vf_info.is_trusted_configured)
4187+
qed_iov_configure_vport_forced(p_hwfn, vf_info, feature);
4188+
4189+
return 0;
4190+
}
4191+
40944192
static void qed_iov_bulletin_set_forced_vlan(struct qed_hwfn *p_hwfn,
40954193
u16 pvid, int vfid)
40964194
{
@@ -4204,6 +4302,21 @@ static int qed_iov_spoofchk_set(struct qed_hwfn *p_hwfn, int vfid, bool val)
42044302
return rc;
42054303
}
42064304

4305+
static u8 *qed_iov_bulletin_get_mac(struct qed_hwfn *p_hwfn, u16 rel_vf_id)
4306+
{
4307+
struct qed_vf_info *p_vf;
4308+
4309+
p_vf = qed_iov_get_vf_info(p_hwfn, rel_vf_id, true);
4310+
if (!p_vf || !p_vf->bulletin.p_virt)
4311+
return NULL;
4312+
4313+
if (!(p_vf->bulletin.p_virt->valid_bitmap &
4314+
BIT(VFPF_BULLETIN_MAC_ADDR)))
4315+
return NULL;
4316+
4317+
return p_vf->bulletin.p_virt->mac;
4318+
}
4319+
42074320
static u8 *qed_iov_bulletin_get_forced_mac(struct qed_hwfn *p_hwfn,
42084321
u16 rel_vf_id)
42094322
{
@@ -4493,8 +4606,12 @@ static int qed_sriov_pf_set_mac(struct qed_dev *cdev, u8 *mac, int vfid)
44934606
if (!vf_info)
44944607
continue;
44954608

4496-
/* Set the forced MAC, and schedule the IOV task */
4497-
ether_addr_copy(vf_info->forced_mac, mac);
4609+
/* Set the MAC, and schedule the IOV task */
4610+
if (vf_info->is_trusted_configured)
4611+
ether_addr_copy(vf_info->mac, mac);
4612+
else
4613+
ether_addr_copy(vf_info->forced_mac, mac);
4614+
44984615
qed_schedule_iov(hwfn, QED_IOV_WQ_SET_UNICAST_FILTER_FLAG);
44994616
}
45004617

@@ -4802,6 +4919,33 @@ static void qed_handle_vf_msg(struct qed_hwfn *hwfn)
48024919
qed_ptt_release(hwfn, ptt);
48034920
}
48044921

4922+
static bool qed_pf_validate_req_vf_mac(struct qed_hwfn *hwfn,
4923+
u8 *mac,
4924+
struct qed_public_vf_info *info)
4925+
{
4926+
if (info->is_trusted_configured) {
4927+
if (is_valid_ether_addr(info->mac) &&
4928+
(!mac || !ether_addr_equal(mac, info->mac)))
4929+
return true;
4930+
} else {
4931+
if (is_valid_ether_addr(info->forced_mac) &&
4932+
(!mac || !ether_addr_equal(mac, info->forced_mac)))
4933+
return true;
4934+
}
4935+
4936+
return false;
4937+
}
4938+
4939+
static void qed_set_bulletin_mac(struct qed_hwfn *hwfn,
4940+
struct qed_public_vf_info *info,
4941+
int vfid)
4942+
{
4943+
if (info->is_trusted_configured)
4944+
qed_iov_bulletin_set_mac(hwfn, info->mac, vfid);
4945+
else
4946+
qed_iov_bulletin_set_forced_mac(hwfn, info->forced_mac, vfid);
4947+
}
4948+
48054949
static void qed_handle_pf_set_vf_unicast(struct qed_hwfn *hwfn)
48064950
{
48074951
int i;
@@ -4816,18 +4960,20 @@ static void qed_handle_pf_set_vf_unicast(struct qed_hwfn *hwfn)
48164960
continue;
48174961

48184962
/* Update data on bulletin board */
4819-
mac = qed_iov_bulletin_get_forced_mac(hwfn, i);
4820-
if (is_valid_ether_addr(info->forced_mac) &&
4821-
(!mac || !ether_addr_equal(mac, info->forced_mac))) {
4963+
if (info->is_trusted_configured)
4964+
mac = qed_iov_bulletin_get_mac(hwfn, i);
4965+
else
4966+
mac = qed_iov_bulletin_get_forced_mac(hwfn, i);
4967+
4968+
if (qed_pf_validate_req_vf_mac(hwfn, mac, info)) {
48224969
DP_VERBOSE(hwfn,
48234970
QED_MSG_IOV,
48244971
"Handling PF setting of VF MAC to VF 0x%02x [Abs 0x%02x]\n",
48254972
i,
48264973
hwfn->cdev->p_iov_info->first_vf_in_pf + i);
48274974

4828-
/* Update bulletin board with forced MAC */
4829-
qed_iov_bulletin_set_forced_mac(hwfn,
4830-
info->forced_mac, i);
4975+
/* Update bulletin board with MAC */
4976+
qed_set_bulletin_mac(hwfn, info, i);
48314977
update = true;
48324978
}
48334979

@@ -4867,6 +5013,72 @@ static void qed_handle_bulletin_post(struct qed_hwfn *hwfn)
48675013
qed_ptt_release(hwfn, ptt);
48685014
}
48695015

5016+
static void qed_update_mac_for_vf_trust_change(struct qed_hwfn *hwfn, int vf_id)
5017+
{
5018+
struct qed_public_vf_info *vf_info;
5019+
struct qed_vf_info *vf;
5020+
u8 *force_mac;
5021+
int i;
5022+
5023+
vf_info = qed_iov_get_public_vf_info(hwfn, vf_id, true);
5024+
vf = qed_iov_get_vf_info(hwfn, vf_id, true);
5025+
5026+
if (!vf_info || !vf)
5027+
return;
5028+
5029+
/* Force MAC converted to generic MAC in case of VF trust on */
5030+
if (vf_info->is_trusted_configured &&
5031+
(vf->bulletin.p_virt->valid_bitmap & BIT(MAC_ADDR_FORCED))) {
5032+
force_mac = qed_iov_bulletin_get_forced_mac(hwfn, vf_id);
5033+
5034+
if (force_mac) {
5035+
/* Clear existing shadow copy of MAC to have a clean
5036+
* slate.
5037+
*/
5038+
for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
5039+
if (ether_addr_equal(vf->shadow_config.macs[i],
5040+
vf_info->mac)) {
5041+
memset(vf->shadow_config.macs[i], 0,
5042+
ETH_ALEN);
5043+
DP_VERBOSE(hwfn, QED_MSG_IOV,
5044+
"Shadow MAC %pM removed for VF 0x%02x, VF trust mode is ON\n",
5045+
vf_info->mac, vf_id);
5046+
break;
5047+
}
5048+
}
5049+
5050+
ether_addr_copy(vf_info->mac, force_mac);
5051+
memset(vf_info->forced_mac, 0, ETH_ALEN);
5052+
vf->bulletin.p_virt->valid_bitmap &=
5053+
~BIT(MAC_ADDR_FORCED);
5054+
qed_schedule_iov(hwfn, QED_IOV_WQ_BULLETIN_UPDATE_FLAG);
5055+
}
5056+
}
5057+
5058+
/* Update shadow copy with VF MAC when trust mode is turned off */
5059+
if (!vf_info->is_trusted_configured) {
5060+
u8 empty_mac[ETH_ALEN];
5061+
5062+
memset(empty_mac, 0, ETH_ALEN);
5063+
for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
5064+
if (ether_addr_equal(vf->shadow_config.macs[i],
5065+
empty_mac)) {
5066+
ether_addr_copy(vf->shadow_config.macs[i],
5067+
vf_info->mac);
5068+
DP_VERBOSE(hwfn, QED_MSG_IOV,
5069+
"Shadow is updated with %pM for VF 0x%02x, VF trust mode is OFF\n",
5070+
vf_info->mac, vf_id);
5071+
break;
5072+
}
5073+
}
5074+
/* Clear bulletin when trust mode is turned off,
5075+
* to have a clean slate for next (normal) operations.
5076+
*/
5077+
qed_iov_bulletin_set_mac(hwfn, empty_mac, vf_id);
5078+
qed_schedule_iov(hwfn, QED_IOV_WQ_BULLETIN_UPDATE_FLAG);
5079+
}
5080+
}
5081+
48705082
static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
48715083
{
48725084
struct qed_sp_vport_update_params params;
@@ -4890,6 +5102,9 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
48905102
continue;
48915103
vf_info->is_trusted_configured = vf_info->is_trusted_request;
48925104

5105+
/* Handle forced MAC mode */
5106+
qed_update_mac_for_vf_trust_change(hwfn, i);
5107+
48935108
/* Validate that the VF has a configured vport */
48945109
vf = qed_iov_get_vf_info(hwfn, i, true);
48955110
if (!vf->vport_instance)

0 commit comments

Comments
 (0)