@@ -119,6 +119,30 @@ static int aq_check_approve_fl3l4(struct aq_nic_s *aq_nic,
119
119
return 0 ;
120
120
}
121
121
122
+ static int __must_check
123
+ aq_check_approve_fl2 (struct aq_nic_s * aq_nic ,
124
+ struct aq_hw_rx_fltrs_s * rx_fltrs ,
125
+ struct ethtool_rx_flow_spec * fsp )
126
+ {
127
+ if (fsp -> location < AQ_RX_FIRST_LOC_FETHERT ||
128
+ fsp -> location > AQ_RX_LAST_LOC_FETHERT ) {
129
+ netdev_err (aq_nic -> ndev ,
130
+ "ethtool: location must be in range [%d, %d]" ,
131
+ AQ_RX_FIRST_LOC_FETHERT ,
132
+ AQ_RX_LAST_LOC_FETHERT );
133
+ return - EINVAL ;
134
+ }
135
+
136
+ if (be16_to_cpu (fsp -> m_ext .vlan_tci ) == VLAN_PRIO_MASK &&
137
+ fsp -> m_u .ether_spec .h_proto == 0U ) {
138
+ netdev_err (aq_nic -> ndev ,
139
+ "ethtool: proto (ether_type) parameter must be specfied" );
140
+ return - EINVAL ;
141
+ }
142
+
143
+ return 0 ;
144
+ }
145
+
122
146
static int __must_check
123
147
aq_check_approve_fvlan (struct aq_nic_s * aq_nic ,
124
148
struct aq_hw_rx_fltrs_s * rx_fltrs ,
@@ -152,6 +176,8 @@ aq_check_filter(struct aq_nic_s *aq_nic,
152
176
if (fsp -> flow_type & FLOW_EXT ) {
153
177
if (be16_to_cpu (fsp -> m_ext .vlan_tci ) == VLAN_VID_MASK ) {
154
178
err = aq_check_approve_fvlan (aq_nic , rx_fltrs , fsp );
179
+ } else if (be16_to_cpu (fsp -> m_ext .vlan_tci ) == VLAN_PRIO_MASK ) {
180
+ err = aq_check_approve_fl2 (aq_nic , rx_fltrs , fsp );
155
181
} else {
156
182
netdev_err (aq_nic -> ndev ,
157
183
"ethtool: invalid vlan mask 0x%x specified" ,
@@ -161,7 +187,7 @@ aq_check_filter(struct aq_nic_s *aq_nic,
161
187
} else {
162
188
switch (fsp -> flow_type & ~FLOW_EXT ) {
163
189
case ETHER_FLOW :
164
- err = - EOPNOTSUPP ;
190
+ err = aq_check_approve_fl2 ( aq_nic , rx_fltrs , fsp ) ;
165
191
break ;
166
192
case TCP_V4_FLOW :
167
193
case UDP_V4_FLOW :
@@ -210,6 +236,10 @@ aq_rule_is_not_support(struct aq_nic_s *aq_nic,
210
236
netdev_err (aq_nic -> ndev ,
211
237
"ethtool: The specified tos tclass are not supported\n" );
212
238
rule_is_not_support = true;
239
+ } else if (fsp -> flow_type & FLOW_MAC_EXT ) {
240
+ netdev_err (aq_nic -> ndev ,
241
+ "ethtool: MAC_EXT is not supported" );
242
+ rule_is_not_support = true;
213
243
}
214
244
215
245
return rule_is_not_support ;
@@ -259,6 +289,48 @@ aq_check_rule(struct aq_nic_s *aq_nic,
259
289
return err ;
260
290
}
261
291
292
+ static void aq_set_data_fl2 (struct aq_nic_s * aq_nic ,
293
+ struct aq_rx_filter * aq_rx_fltr ,
294
+ struct aq_rx_filter_l2 * data , bool add )
295
+ {
296
+ const struct ethtool_rx_flow_spec * fsp = & aq_rx_fltr -> aq_fsp ;
297
+
298
+ memset (data , 0 , sizeof (* data ));
299
+
300
+ data -> location = fsp -> location - AQ_RX_FIRST_LOC_FETHERT ;
301
+
302
+ if (fsp -> ring_cookie != RX_CLS_FLOW_DISC )
303
+ data -> queue = fsp -> ring_cookie ;
304
+ else
305
+ data -> queue = -1 ;
306
+
307
+ data -> ethertype = be16_to_cpu (fsp -> h_u .ether_spec .h_proto );
308
+ data -> user_priority_en = be16_to_cpu (fsp -> m_ext .vlan_tci )
309
+ == VLAN_PRIO_MASK ;
310
+ data -> user_priority = (be16_to_cpu (fsp -> h_ext .vlan_tci )
311
+ & VLAN_PRIO_MASK ) >> VLAN_PRIO_SHIFT ;
312
+ }
313
+
314
+ static int aq_add_del_fether (struct aq_nic_s * aq_nic ,
315
+ struct aq_rx_filter * aq_rx_fltr , bool add )
316
+ {
317
+ struct aq_rx_filter_l2 data ;
318
+ struct aq_hw_s * aq_hw = aq_nic -> aq_hw ;
319
+ const struct aq_hw_ops * aq_hw_ops = aq_nic -> aq_hw_ops ;
320
+
321
+ aq_set_data_fl2 (aq_nic , aq_rx_fltr , & data , add );
322
+
323
+ if (unlikely (!aq_hw_ops -> hw_filter_l2_set ))
324
+ return - EOPNOTSUPP ;
325
+ if (unlikely (!aq_hw_ops -> hw_filter_l2_clear ))
326
+ return - EOPNOTSUPP ;
327
+
328
+ if (add )
329
+ return aq_hw_ops -> hw_filter_l2_set (aq_hw , & data );
330
+ else
331
+ return aq_hw_ops -> hw_filter_l2_clear (aq_hw , & data );
332
+ }
333
+
262
334
static int aq_set_data_fvlan (struct aq_nic_s * aq_nic ,
263
335
struct aq_rx_filter * aq_rx_fltr ,
264
336
struct aq_rx_filter_vlan * aq_vlans , bool add )
@@ -424,13 +496,16 @@ static int aq_add_del_rule(struct aq_nic_s *aq_nic,
424
496
== VLAN_VID_MASK ) {
425
497
aq_rx_fltr -> type = aq_rx_filter_vlan ;
426
498
err = aq_add_del_fvlan (aq_nic , aq_rx_fltr , add );
427
- } else {
428
- err = - EINVAL ;
499
+ } else if (be16_to_cpu (aq_rx_fltr -> aq_fsp .m_ext .vlan_tci )
500
+ == VLAN_PRIO_MASK ) {
501
+ aq_rx_fltr -> type = aq_rx_filter_ethertype ;
502
+ err = aq_add_del_fether (aq_nic , aq_rx_fltr , add );
429
503
}
430
504
} else {
431
505
switch (aq_rx_fltr -> aq_fsp .flow_type & ~FLOW_EXT ) {
432
506
case ETHER_FLOW :
433
- err = - EOPNOTSUPP ;
507
+ aq_rx_fltr -> type = aq_rx_filter_ethertype ;
508
+ err = aq_add_del_fether (aq_nic , aq_rx_fltr , add );
434
509
break ;
435
510
case TCP_V4_FLOW :
436
511
case UDP_V4_FLOW :
0 commit comments