@@ -48,7 +48,7 @@ static int qed_sriov_eqe_event(struct qed_hwfn *p_hwfn,
48
48
u8 opcode ,
49
49
__le16 echo ,
50
50
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 );
52
52
53
53
static u8 qed_vf_calculate_legacy (struct qed_vf_info * p_vf )
54
54
{
@@ -1790,7 +1790,8 @@ static int qed_iov_configure_vport_forced(struct qed_hwfn *p_hwfn,
1790
1790
if (!p_vf -> vport_instance )
1791
1791
return - EINVAL ;
1792
1792
1793
- if (events & BIT (MAC_ADDR_FORCED )) {
1793
+ if ((events & BIT (MAC_ADDR_FORCED )) ||
1794
+ p_vf -> p_vf_info .is_trusted_configured ) {
1794
1795
/* Since there's no way [currently] of removing the MAC,
1795
1796
* we can always assume this means we need to force it.
1796
1797
*/
@@ -1809,8 +1810,12 @@ static int qed_iov_configure_vport_forced(struct qed_hwfn *p_hwfn,
1809
1810
"PF failed to configure MAC for VF\n" );
1810
1811
return rc ;
1811
1812
}
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 );
1814
1819
}
1815
1820
1816
1821
if (events & BIT (VLAN_ADDR_FORCED )) {
@@ -3170,6 +3175,10 @@ static int qed_iov_vf_update_mac_shadow(struct qed_hwfn *p_hwfn,
3170
3175
if (p_vf -> bulletin .p_virt -> valid_bitmap & BIT (MAC_ADDR_FORCED ))
3171
3176
return 0 ;
3172
3177
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
+
3173
3182
/* First remove entries and then add new ones */
3174
3183
if (p_params -> opcode == QED_FILTER_REMOVE ) {
3175
3184
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,
3244
3253
3245
3254
/* No real decision to make; Store the configured MAC */
3246
3255
if (params -> type == QED_FILTER_MAC ||
3247
- params -> type == QED_FILTER_MAC_VLAN )
3256
+ params -> type == QED_FILTER_MAC_VLAN ) {
3248
3257
ether_addr_copy (vf -> mac , params -> mac );
3249
3258
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
+
3250
3267
return 0 ;
3251
3268
}
3252
3269
@@ -4081,16 +4098,60 @@ static void qed_iov_bulletin_set_forced_mac(struct qed_hwfn *p_hwfn,
4081
4098
return ;
4082
4099
}
4083
4100
4084
- feature = 1 << MAC_ADDR_FORCED ;
4101
+ if (vf_info -> p_vf_info .is_trusted_configured ) {
4102
+ feature = BIT (VFPF_BULLETIN_MAC_ADDR );
4103
+ /* Trust mode will disable Forced MAC */
4104
+ vf_info -> bulletin .p_virt -> valid_bitmap &=
4105
+ ~BIT (MAC_ADDR_FORCED );
4106
+ } else {
4107
+ feature = BIT (MAC_ADDR_FORCED );
4108
+ /* Forced MAC will disable MAC_ADDR */
4109
+ vf_info -> bulletin .p_virt -> valid_bitmap &=
4110
+ ~BIT (VFPF_BULLETIN_MAC_ADDR );
4111
+ }
4112
+
4085
4113
memcpy (vf_info -> bulletin .p_virt -> mac , mac , ETH_ALEN );
4086
4114
4087
4115
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 );
4090
4116
4091
4117
qed_iov_configure_vport_forced (p_hwfn , vf_info , feature );
4092
4118
}
4093
4119
4120
+ static int qed_iov_bulletin_set_mac (struct qed_hwfn * p_hwfn , u8 * mac , int vfid )
4121
+ {
4122
+ struct qed_vf_info * vf_info ;
4123
+ u64 feature ;
4124
+
4125
+ vf_info = qed_iov_get_vf_info (p_hwfn , (u16 )vfid , true);
4126
+ if (!vf_info ) {
4127
+ DP_NOTICE (p_hwfn -> cdev , "Can not set MAC, invalid vfid [%d]\n" ,
4128
+ vfid );
4129
+ return - EINVAL ;
4130
+ }
4131
+
4132
+ if (vf_info -> b_malicious ) {
4133
+ DP_NOTICE (p_hwfn -> cdev , "Can't set MAC to malicious VF [%d]\n" ,
4134
+ vfid );
4135
+ return - EINVAL ;
4136
+ }
4137
+
4138
+ if (vf_info -> bulletin .p_virt -> valid_bitmap & BIT (MAC_ADDR_FORCED )) {
4139
+ DP_VERBOSE (p_hwfn , QED_MSG_IOV ,
4140
+ "Can not set MAC, Forced MAC is configured\n" );
4141
+ return - EINVAL ;
4142
+ }
4143
+
4144
+ feature = BIT (VFPF_BULLETIN_MAC_ADDR );
4145
+ ether_addr_copy (vf_info -> bulletin .p_virt -> mac , mac );
4146
+
4147
+ vf_info -> bulletin .p_virt -> valid_bitmap |= feature ;
4148
+
4149
+ if (vf_info -> p_vf_info .is_trusted_configured )
4150
+ qed_iov_configure_vport_forced (p_hwfn , vf_info , feature );
4151
+
4152
+ return 0 ;
4153
+ }
4154
+
4094
4155
static void qed_iov_bulletin_set_forced_vlan (struct qed_hwfn * p_hwfn ,
4095
4156
u16 pvid , int vfid )
4096
4157
{
@@ -4204,6 +4265,21 @@ static int qed_iov_spoofchk_set(struct qed_hwfn *p_hwfn, int vfid, bool val)
4204
4265
return rc ;
4205
4266
}
4206
4267
4268
+ static u8 * qed_iov_bulletin_get_mac (struct qed_hwfn * p_hwfn , u16 rel_vf_id )
4269
+ {
4270
+ struct qed_vf_info * p_vf ;
4271
+
4272
+ p_vf = qed_iov_get_vf_info (p_hwfn , rel_vf_id , true);
4273
+ if (!p_vf || !p_vf -> bulletin .p_virt )
4274
+ return NULL ;
4275
+
4276
+ if (!(p_vf -> bulletin .p_virt -> valid_bitmap &
4277
+ BIT (VFPF_BULLETIN_MAC_ADDR )))
4278
+ return NULL ;
4279
+
4280
+ return p_vf -> bulletin .p_virt -> mac ;
4281
+ }
4282
+
4207
4283
static u8 * qed_iov_bulletin_get_forced_mac (struct qed_hwfn * p_hwfn ,
4208
4284
u16 rel_vf_id )
4209
4285
{
@@ -4493,8 +4569,12 @@ static int qed_sriov_pf_set_mac(struct qed_dev *cdev, u8 *mac, int vfid)
4493
4569
if (!vf_info )
4494
4570
continue ;
4495
4571
4496
- /* Set the forced MAC, and schedule the IOV task */
4497
- ether_addr_copy (vf_info -> forced_mac , mac );
4572
+ /* Set the MAC, and schedule the IOV task */
4573
+ if (vf_info -> is_trusted_configured )
4574
+ ether_addr_copy (vf_info -> mac , mac );
4575
+ else
4576
+ ether_addr_copy (vf_info -> forced_mac , mac );
4577
+
4498
4578
qed_schedule_iov (hwfn , QED_IOV_WQ_SET_UNICAST_FILTER_FLAG );
4499
4579
}
4500
4580
@@ -4802,6 +4882,33 @@ static void qed_handle_vf_msg(struct qed_hwfn *hwfn)
4802
4882
qed_ptt_release (hwfn , ptt );
4803
4883
}
4804
4884
4885
+ static bool qed_pf_validate_req_vf_mac (struct qed_hwfn * hwfn ,
4886
+ u8 * mac ,
4887
+ struct qed_public_vf_info * info )
4888
+ {
4889
+ if (info -> is_trusted_configured ) {
4890
+ if (is_valid_ether_addr (info -> mac ) &&
4891
+ (!mac || !ether_addr_equal (mac , info -> mac )))
4892
+ return true;
4893
+ } else {
4894
+ if (is_valid_ether_addr (info -> forced_mac ) &&
4895
+ (!mac || !ether_addr_equal (mac , info -> forced_mac )))
4896
+ return true;
4897
+ }
4898
+
4899
+ return false;
4900
+ }
4901
+
4902
+ static void qed_set_bulletin_mac (struct qed_hwfn * hwfn ,
4903
+ struct qed_public_vf_info * info ,
4904
+ int vfid )
4905
+ {
4906
+ if (info -> is_trusted_configured )
4907
+ qed_iov_bulletin_set_mac (hwfn , info -> mac , vfid );
4908
+ else
4909
+ qed_iov_bulletin_set_forced_mac (hwfn , info -> forced_mac , vfid );
4910
+ }
4911
+
4805
4912
static void qed_handle_pf_set_vf_unicast (struct qed_hwfn * hwfn )
4806
4913
{
4807
4914
int i ;
@@ -4816,18 +4923,20 @@ static void qed_handle_pf_set_vf_unicast(struct qed_hwfn *hwfn)
4816
4923
continue ;
4817
4924
4818
4925
/* 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 ))) {
4926
+ if (info -> is_trusted_configured )
4927
+ mac = qed_iov_bulletin_get_mac (hwfn , i );
4928
+ else
4929
+ mac = qed_iov_bulletin_get_forced_mac (hwfn , i );
4930
+
4931
+ if (qed_pf_validate_req_vf_mac (hwfn , mac , info )) {
4822
4932
DP_VERBOSE (hwfn ,
4823
4933
QED_MSG_IOV ,
4824
4934
"Handling PF setting of VF MAC to VF 0x%02x [Abs 0x%02x]\n" ,
4825
4935
i ,
4826
4936
hwfn -> cdev -> p_iov_info -> first_vf_in_pf + i );
4827
4937
4828
- /* Update bulletin board with forced MAC */
4829
- qed_iov_bulletin_set_forced_mac (hwfn ,
4830
- info -> forced_mac , i );
4938
+ /* Update bulletin board with MAC */
4939
+ qed_set_bulletin_mac (hwfn , info , i );
4831
4940
update = true;
4832
4941
}
4833
4942
@@ -4867,6 +4976,72 @@ static void qed_handle_bulletin_post(struct qed_hwfn *hwfn)
4867
4976
qed_ptt_release (hwfn , ptt );
4868
4977
}
4869
4978
4979
+ static void qed_update_mac_for_vf_trust_change (struct qed_hwfn * hwfn , int vf_id )
4980
+ {
4981
+ struct qed_public_vf_info * vf_info ;
4982
+ struct qed_vf_info * vf ;
4983
+ u8 * force_mac ;
4984
+ int i ;
4985
+
4986
+ vf_info = qed_iov_get_public_vf_info (hwfn , vf_id , true);
4987
+ vf = qed_iov_get_vf_info (hwfn , vf_id , true);
4988
+
4989
+ if (!vf_info || !vf )
4990
+ return ;
4991
+
4992
+ /* Force MAC converted to generic MAC in case of VF trust on */
4993
+ if (vf_info -> is_trusted_configured &&
4994
+ (vf -> bulletin .p_virt -> valid_bitmap & BIT (MAC_ADDR_FORCED ))) {
4995
+ force_mac = qed_iov_bulletin_get_forced_mac (hwfn , vf_id );
4996
+
4997
+ if (force_mac ) {
4998
+ /* Clear existing shadow copy of MAC to have a clean
4999
+ * slate.
5000
+ */
5001
+ for (i = 0 ; i < QED_ETH_VF_NUM_MAC_FILTERS ; i ++ ) {
5002
+ if (ether_addr_equal (vf -> shadow_config .macs [i ],
5003
+ vf_info -> mac )) {
5004
+ memset (vf -> shadow_config .macs [i ], 0 ,
5005
+ ETH_ALEN );
5006
+ DP_VERBOSE (hwfn , QED_MSG_IOV ,
5007
+ "Shadow MAC %pM removed for VF 0x%02x, VF trust mode is ON\n" ,
5008
+ vf_info -> mac , vf_id );
5009
+ break ;
5010
+ }
5011
+ }
5012
+
5013
+ ether_addr_copy (vf_info -> mac , force_mac );
5014
+ memset (vf_info -> forced_mac , 0 , ETH_ALEN );
5015
+ vf -> bulletin .p_virt -> valid_bitmap &=
5016
+ ~BIT (MAC_ADDR_FORCED );
5017
+ qed_schedule_iov (hwfn , QED_IOV_WQ_BULLETIN_UPDATE_FLAG );
5018
+ }
5019
+ }
5020
+
5021
+ /* Update shadow copy with VF MAC when trust mode is turned off */
5022
+ if (!vf_info -> is_trusted_configured ) {
5023
+ u8 empty_mac [ETH_ALEN ];
5024
+
5025
+ memset (empty_mac , 0 , ETH_ALEN );
5026
+ for (i = 0 ; i < QED_ETH_VF_NUM_MAC_FILTERS ; i ++ ) {
5027
+ if (ether_addr_equal (vf -> shadow_config .macs [i ],
5028
+ empty_mac )) {
5029
+ ether_addr_copy (vf -> shadow_config .macs [i ],
5030
+ vf_info -> mac );
5031
+ DP_VERBOSE (hwfn , QED_MSG_IOV ,
5032
+ "Shadow is updated with %pM for VF 0x%02x, VF trust mode is OFF\n" ,
5033
+ vf_info -> mac , vf_id );
5034
+ break ;
5035
+ }
5036
+ }
5037
+ /* Clear bulletin when trust mode is turned off,
5038
+ * to have a clean slate for next (normal) operations.
5039
+ */
5040
+ qed_iov_bulletin_set_mac (hwfn , empty_mac , vf_id );
5041
+ qed_schedule_iov (hwfn , QED_IOV_WQ_BULLETIN_UPDATE_FLAG );
5042
+ }
5043
+ }
5044
+
4870
5045
static void qed_iov_handle_trust_change (struct qed_hwfn * hwfn )
4871
5046
{
4872
5047
struct qed_sp_vport_update_params params ;
@@ -4890,6 +5065,9 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
4890
5065
continue ;
4891
5066
vf_info -> is_trusted_configured = vf_info -> is_trusted_request ;
4892
5067
5068
+ /* Handle forced MAC mode */
5069
+ qed_update_mac_for_vf_trust_change (hwfn , i );
5070
+
4893
5071
/* Validate that the VF has a configured vport */
4894
5072
vf = qed_iov_get_vf_info (hwfn , i , true);
4895
5073
if (!vf -> vport_instance )
0 commit comments