@@ -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
@@ -3803,6 +3820,40 @@ static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
3803
3820
__qed_vf_get_link_caps (p_hwfn , p_caps , p_bulletin );
3804
3821
}
3805
3822
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
+
3806
3857
static void qed_iov_process_mbx_req (struct qed_hwfn * p_hwfn ,
3807
3858
struct qed_ptt * p_ptt , int vfid )
3808
3859
{
@@ -3882,6 +3933,9 @@ static void qed_iov_process_mbx_req(struct qed_hwfn *p_hwfn,
3882
3933
case CHANNEL_TLV_COALESCE_READ :
3883
3934
qed_iov_vf_pf_get_coalesce (p_hwfn , p_ptt , p_vf );
3884
3935
break ;
3936
+ case CHANNEL_TLV_BULLETIN_UPDATE_MAC :
3937
+ qed_iov_vf_pf_bulletin_update_mac (p_hwfn , p_ptt , p_vf );
3938
+ break ;
3885
3939
}
3886
3940
} else if (qed_iov_tlv_supported (mbx -> first_tlv .tl .type )) {
3887
3941
DP_VERBOSE (p_hwfn , QED_MSG_IOV ,
@@ -4081,16 +4135,60 @@ static void qed_iov_bulletin_set_forced_mac(struct qed_hwfn *p_hwfn,
4081
4135
return ;
4082
4136
}
4083
4137
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
+
4085
4150
memcpy (vf_info -> bulletin .p_virt -> mac , mac , ETH_ALEN );
4086
4151
4087
4152
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
4153
4091
4154
qed_iov_configure_vport_forced (p_hwfn , vf_info , feature );
4092
4155
}
4093
4156
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
+
4094
4192
static void qed_iov_bulletin_set_forced_vlan (struct qed_hwfn * p_hwfn ,
4095
4193
u16 pvid , int vfid )
4096
4194
{
@@ -4204,6 +4302,21 @@ static int qed_iov_spoofchk_set(struct qed_hwfn *p_hwfn, int vfid, bool val)
4204
4302
return rc ;
4205
4303
}
4206
4304
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
+
4207
4320
static u8 * qed_iov_bulletin_get_forced_mac (struct qed_hwfn * p_hwfn ,
4208
4321
u16 rel_vf_id )
4209
4322
{
@@ -4493,8 +4606,12 @@ static int qed_sriov_pf_set_mac(struct qed_dev *cdev, u8 *mac, int vfid)
4493
4606
if (!vf_info )
4494
4607
continue ;
4495
4608
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
+
4498
4615
qed_schedule_iov (hwfn , QED_IOV_WQ_SET_UNICAST_FILTER_FLAG );
4499
4616
}
4500
4617
@@ -4802,6 +4919,33 @@ static void qed_handle_vf_msg(struct qed_hwfn *hwfn)
4802
4919
qed_ptt_release (hwfn , ptt );
4803
4920
}
4804
4921
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
+
4805
4949
static void qed_handle_pf_set_vf_unicast (struct qed_hwfn * hwfn )
4806
4950
{
4807
4951
int i ;
@@ -4816,18 +4960,20 @@ static void qed_handle_pf_set_vf_unicast(struct qed_hwfn *hwfn)
4816
4960
continue ;
4817
4961
4818
4962
/* 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 )) {
4822
4969
DP_VERBOSE (hwfn ,
4823
4970
QED_MSG_IOV ,
4824
4971
"Handling PF setting of VF MAC to VF 0x%02x [Abs 0x%02x]\n" ,
4825
4972
i ,
4826
4973
hwfn -> cdev -> p_iov_info -> first_vf_in_pf + i );
4827
4974
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 );
4831
4977
update = true;
4832
4978
}
4833
4979
@@ -4867,6 +5013,72 @@ static void qed_handle_bulletin_post(struct qed_hwfn *hwfn)
4867
5013
qed_ptt_release (hwfn , ptt );
4868
5014
}
4869
5015
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
+
4870
5082
static void qed_iov_handle_trust_change (struct qed_hwfn * hwfn )
4871
5083
{
4872
5084
struct qed_sp_vport_update_params params ;
@@ -4890,6 +5102,9 @@ static void qed_iov_handle_trust_change(struct qed_hwfn *hwfn)
4890
5102
continue ;
4891
5103
vf_info -> is_trusted_configured = vf_info -> is_trusted_request ;
4892
5104
5105
+ /* Handle forced MAC mode */
5106
+ qed_update_mac_for_vf_trust_change (hwfn , i );
5107
+
4893
5108
/* Validate that the VF has a configured vport */
4894
5109
vf = qed_iov_get_vf_info (hwfn , i , true);
4895
5110
if (!vf -> vport_instance )
0 commit comments