Skip to content

Commit 9daf820

Browse files
refactormanJeff Kirsher
authored andcommitted
ice: Add support for switch filter programming
A VSI needs traffic directed towards it. This is done by programming filter rules on the switch (embedded vSwitch) element in the hardware, which connects the VSI to the ingress/egress port. This patch introduces data structures and functions necessary to add remove or update switch rules on the switch element. This is a pretty low level function that is generic enough to add a whole range of filters. This patch also introduces two top level functions ice_add_mac and ice_remove mac which through a series of intermediate helper functions eventually call ice_aq_sw_rules to add/delete simple MAC based filters. It's worth noting that one invocation of ice_add_mac/ice_remove_mac is capable of adding/deleting multiple MAC filters. Also worth noting is the fact that the driver maintains a list of currently active filters, so every filter addition/removal causes an update to this list. This is done for a couple of reasons: 1) If two VSIs try to add the same filters, we need to detect it and do things a little differently (i.e. use VSI lists, described below) as the same filter can't be added more than once. 2) In the event of a hardware reset we can simply walk through this list and restore the filters. VSI Lists: In a multi-VSI situation, it's possible that multiple VSIs want to add the same filter rule. For example, two VSIs that want to receive broadcast traffic would both add a filter for destination MAC ff:ff:ff:ff:ff:ff. This can become cumbersome to maintain and so this is handled using a VSI list. A VSI list is resource that can be allocated in the hardware using the ice_aq_alloc_free_res admin queue command. Simply put, a VSI list can be thought of as a subscription list containing a set of VSIs to which the packet should be forwarded, should the filter match. For example, if VSI-0 has already added a broadcast filter, and VSI-1 wants to do the same thing, the filter creation flow will detect this, allocate a VSI list and update the switch rule so that broadcast traffic will now be forwarded to the VSI list which contains VSI-0 and VSI-1. Signed-off-by: Anirudh Venkataramanan <[email protected]> Tested-by: Tony Brelinski <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 3a858ba commit 9daf820

File tree

7 files changed

+1935
-2
lines changed

7 files changed

+1935
-2
lines changed

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* descriptor format. It is shared between Firmware and Software.
99
*/
1010

11+
#define ICE_MAX_VSI 768
1112
#define ICE_AQC_TOPO_MAX_LEVEL_NUM 0x9
1213
#define ICE_AQ_SET_MAC_FRAME_SIZE_MAX 9728
1314

@@ -191,6 +192,46 @@ struct ice_aqc_get_sw_cfg_resp {
191192
struct ice_aqc_get_sw_cfg_resp_elem elements[1];
192193
};
193194

195+
/* These resource type defines are used for all switch resource
196+
* commands where a resource type is required, such as:
197+
* Get Resource Allocation command (indirect 0x0204)
198+
* Allocate Resources command (indirect 0x0208)
199+
* Free Resources command (indirect 0x0209)
200+
* Get Allocated Resource Descriptors Command (indirect 0x020A)
201+
*/
202+
#define ICE_AQC_RES_TYPE_VSI_LIST_REP 0x03
203+
#define ICE_AQC_RES_TYPE_VSI_LIST_PRUNE 0x04
204+
205+
/* Allocate Resources command (indirect 0x0208)
206+
* Free Resources command (indirect 0x0209)
207+
*/
208+
struct ice_aqc_alloc_free_res_cmd {
209+
__le16 num_entries; /* Number of Resource entries */
210+
u8 reserved[6];
211+
__le32 addr_high;
212+
__le32 addr_low;
213+
};
214+
215+
/* Resource descriptor */
216+
struct ice_aqc_res_elem {
217+
union {
218+
__le16 sw_resp;
219+
__le16 flu_resp;
220+
} e;
221+
};
222+
223+
/* Buffer for Allocate/Free Resources commands */
224+
struct ice_aqc_alloc_free_res_elem {
225+
__le16 res_type; /* Types defined above cmd 0x0204 */
226+
#define ICE_AQC_RES_TYPE_SHARED_S 7
227+
#define ICE_AQC_RES_TYPE_SHARED_M (0x1 << ICE_AQC_RES_TYPE_SHARED_S)
228+
#define ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_S 8
229+
#define ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_M \
230+
(0xF << ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_S)
231+
__le16 num_elems;
232+
struct ice_aqc_res_elem elem[1];
233+
};
234+
194235
/* Add VSI (indirect 0x0210)
195236
* Update VSI (indirect 0x0211)
196237
* Get VSI (indirect 0x0212)
@@ -384,6 +425,202 @@ struct ice_aqc_vsi_props {
384425
u8 reserved[24];
385426
};
386427

428+
/* Add/Update/Remove/Get switch rules (indirect 0x02A0, 0x02A1, 0x02A2, 0x02A3)
429+
*/
430+
struct ice_aqc_sw_rules {
431+
/* ops: add switch rules, referring the number of rules.
432+
* ops: update switch rules, referring the number of filters
433+
* ops: remove switch rules, referring the entry index.
434+
* ops: get switch rules, referring to the number of filters.
435+
*/
436+
__le16 num_rules_fltr_entry_index;
437+
u8 reserved[6];
438+
__le32 addr_high;
439+
__le32 addr_low;
440+
};
441+
442+
/* Add/Update/Get/Remove lookup Rx/Tx command/response entry
443+
* This structures describes the lookup rules and associated actions. "index"
444+
* is returned as part of a response to a successful Add command, and can be
445+
* used to identify the rule for Update/Get/Remove commands.
446+
*/
447+
struct ice_sw_rule_lkup_rx_tx {
448+
__le16 recipe_id;
449+
#define ICE_SW_RECIPE_LOGICAL_PORT_FWD 10
450+
/* Source port for LOOKUP_RX and source VSI in case of LOOKUP_TX */
451+
__le16 src;
452+
__le32 act;
453+
454+
/* Bit 0:1 - Action type */
455+
#define ICE_SINGLE_ACT_TYPE_S 0x00
456+
#define ICE_SINGLE_ACT_TYPE_M (0x3 << ICE_SINGLE_ACT_TYPE_S)
457+
458+
/* Bit 2 - Loop back enable
459+
* Bit 3 - LAN enable
460+
*/
461+
#define ICE_SINGLE_ACT_LB_ENABLE BIT(2)
462+
#define ICE_SINGLE_ACT_LAN_ENABLE BIT(3)
463+
464+
/* Action type = 0 - Forward to VSI or VSI list */
465+
#define ICE_SINGLE_ACT_VSI_FORWARDING 0x0
466+
467+
#define ICE_SINGLE_ACT_VSI_ID_S 4
468+
#define ICE_SINGLE_ACT_VSI_ID_M (0x3FF << ICE_SINGLE_ACT_VSI_ID_S)
469+
#define ICE_SINGLE_ACT_VSI_LIST_ID_S 4
470+
#define ICE_SINGLE_ACT_VSI_LIST_ID_M (0x3FF << ICE_SINGLE_ACT_VSI_LIST_ID_S)
471+
/* This bit needs to be set if action is forward to VSI list */
472+
#define ICE_SINGLE_ACT_VSI_LIST BIT(14)
473+
#define ICE_SINGLE_ACT_VALID_BIT BIT(17)
474+
#define ICE_SINGLE_ACT_DROP BIT(18)
475+
476+
/* Action type = 1 - Forward to Queue of Queue group */
477+
#define ICE_SINGLE_ACT_TO_Q 0x1
478+
#define ICE_SINGLE_ACT_Q_INDEX_S 4
479+
#define ICE_SINGLE_ACT_Q_INDEX_M (0x7FF << ICE_SINGLE_ACT_Q_INDEX_S)
480+
#define ICE_SINGLE_ACT_Q_REGION_S 15
481+
#define ICE_SINGLE_ACT_Q_REGION_M (0x7 << ICE_SINGLE_ACT_Q_REGION_S)
482+
#define ICE_SINGLE_ACT_Q_PRIORITY BIT(18)
483+
484+
/* Action type = 2 - Prune */
485+
#define ICE_SINGLE_ACT_PRUNE 0x2
486+
#define ICE_SINGLE_ACT_EGRESS BIT(15)
487+
#define ICE_SINGLE_ACT_INGRESS BIT(16)
488+
#define ICE_SINGLE_ACT_PRUNET BIT(17)
489+
/* Bit 18 should be set to 0 for this action */
490+
491+
/* Action type = 2 - Pointer */
492+
#define ICE_SINGLE_ACT_PTR 0x2
493+
#define ICE_SINGLE_ACT_PTR_VAL_S 4
494+
#define ICE_SINGLE_ACT_PTR_VAL_M (0x1FFF << ICE_SINGLE_ACT_PTR_VAL_S)
495+
/* Bit 18 should be set to 1 */
496+
#define ICE_SINGLE_ACT_PTR_BIT BIT(18)
497+
498+
/* Action type = 3 - Other actions. Last two bits
499+
* are other action identifier
500+
*/
501+
#define ICE_SINGLE_ACT_OTHER_ACTS 0x3
502+
#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_S 17
503+
#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_M \
504+
(0x3 << \ ICE_SINGLE_OTHER_ACT_IDENTIFIER_S)
505+
506+
/* Bit 17:18 - Defines other actions */
507+
/* Other action = 0 - Mirror VSI */
508+
#define ICE_SINGLE_OTHER_ACT_MIRROR 0
509+
#define ICE_SINGLE_ACT_MIRROR_VSI_ID_S 4
510+
#define ICE_SINGLE_ACT_MIRROR_VSI_ID_M \
511+
(0x3FF << ICE_SINGLE_ACT_MIRROR_VSI_ID_S)
512+
513+
/* Other action = 3 - Set Stat count */
514+
#define ICE_SINGLE_OTHER_ACT_STAT_COUNT 3
515+
#define ICE_SINGLE_ACT_STAT_COUNT_INDEX_S 4
516+
#define ICE_SINGLE_ACT_STAT_COUNT_INDEX_M \
517+
(0x7F << ICE_SINGLE_ACT_STAT_COUNT_INDEX_S)
518+
519+
__le16 index; /* The index of the rule in the lookup table */
520+
/* Length and values of the header to be matched per recipe or
521+
* lookup-type
522+
*/
523+
__le16 hdr_len;
524+
u8 hdr[1];
525+
} __packed;
526+
527+
/* Add/Update/Remove large action command/response entry
528+
* "index" is returned as part of a response to a successful Add command, and
529+
* can be used to identify the action for Update/Get/Remove commands.
530+
*/
531+
struct ice_sw_rule_lg_act {
532+
__le16 index; /* Index in large action table */
533+
__le16 size;
534+
__le32 act[1]; /* array of size for actions */
535+
/* Max number of large actions */
536+
#define ICE_MAX_LG_ACT 4
537+
/* Bit 0:1 - Action type */
538+
#define ICE_LG_ACT_TYPE_S 0
539+
#define ICE_LG_ACT_TYPE_M (0x7 << ICE_LG_ACT_TYPE_S)
540+
541+
/* Action type = 0 - Forward to VSI or VSI list */
542+
#define ICE_LG_ACT_VSI_FORWARDING 0
543+
#define ICE_LG_ACT_VSI_ID_S 3
544+
#define ICE_LG_ACT_VSI_ID_M (0x3FF << ICE_LG_ACT_VSI_ID_S)
545+
#define ICE_LG_ACT_VSI_LIST_ID_S 3
546+
#define ICE_LG_ACT_VSI_LIST_ID_M (0x3FF << ICE_LG_ACT_VSI_LIST_ID_S)
547+
/* This bit needs to be set if action is forward to VSI list */
548+
#define ICE_LG_ACT_VSI_LIST BIT(13)
549+
550+
#define ICE_LG_ACT_VALID_BIT BIT(16)
551+
552+
/* Action type = 1 - Forward to Queue of Queue group */
553+
#define ICE_LG_ACT_TO_Q 0x1
554+
#define ICE_LG_ACT_Q_INDEX_S 3
555+
#define ICE_LG_ACT_Q_INDEX_M (0x7FF << ICE_LG_ACT_Q_INDEX_S)
556+
#define ICE_LG_ACT_Q_REGION_S 14
557+
#define ICE_LG_ACT_Q_REGION_M (0x7 << ICE_LG_ACT_Q_REGION_S)
558+
#define ICE_LG_ACT_Q_PRIORITY_SET BIT(17)
559+
560+
/* Action type = 2 - Prune */
561+
#define ICE_LG_ACT_PRUNE 0x2
562+
#define ICE_LG_ACT_EGRESS BIT(14)
563+
#define ICE_LG_ACT_INGRESS BIT(15)
564+
#define ICE_LG_ACT_PRUNET BIT(16)
565+
566+
/* Action type = 3 - Mirror VSI */
567+
#define ICE_LG_OTHER_ACT_MIRROR 0x3
568+
#define ICE_LG_ACT_MIRROR_VSI_ID_S 3
569+
#define ICE_LG_ACT_MIRROR_VSI_ID_M (0x3FF << ICE_LG_ACT_MIRROR_VSI_ID_S)
570+
571+
/* Action type = 5 - Large Action */
572+
#define ICE_LG_ACT_GENERIC 0x5
573+
#define ICE_LG_ACT_GENERIC_VALUE_S 3
574+
#define ICE_LG_ACT_GENERIC_VALUE_M (0xFFFF << ICE_LG_ACT_GENERIC_VALUE_S)
575+
#define ICE_LG_ACT_GENERIC_OFFSET_S 19
576+
#define ICE_LG_ACT_GENERIC_OFFSET_M (0x7 << ICE_LG_ACT_GENERIC_OFFSET_S)
577+
#define ICE_LG_ACT_GENERIC_PRIORITY_S 22
578+
#define ICE_LG_ACT_GENERIC_PRIORITY_M (0x7 << ICE_LG_ACT_GENERIC_PRIORITY_S)
579+
580+
/* Action = 7 - Set Stat count */
581+
#define ICE_LG_ACT_STAT_COUNT 0x7
582+
#define ICE_LG_ACT_STAT_COUNT_S 3
583+
#define ICE_LG_ACT_STAT_COUNT_M (0x7F << ICE_LG_ACT_STAT_COUNT_S)
584+
};
585+
586+
/* Add/Update/Remove VSI list command/response entry
587+
* "index" is returned as part of a response to a successful Add command, and
588+
* can be used to identify the VSI list for Update/Get/Remove commands.
589+
*/
590+
struct ice_sw_rule_vsi_list {
591+
__le16 index; /* Index of VSI/Prune list */
592+
__le16 number_vsi;
593+
__le16 vsi[1]; /* Array of number_vsi VSI numbers */
594+
};
595+
596+
/* Query VSI list command/response entry */
597+
struct ice_sw_rule_vsi_list_query {
598+
__le16 index;
599+
DECLARE_BITMAP(vsi_list, ICE_MAX_VSI);
600+
} __packed;
601+
602+
/* Add switch rule response:
603+
* Content of return buffer is same as the input buffer. The status field and
604+
* LUT index are updated as part of the response
605+
*/
606+
struct ice_aqc_sw_rules_elem {
607+
__le16 type; /* Switch rule type, one of T_... */
608+
#define ICE_AQC_SW_RULES_T_LKUP_RX 0x0
609+
#define ICE_AQC_SW_RULES_T_LKUP_TX 0x1
610+
#define ICE_AQC_SW_RULES_T_LG_ACT 0x2
611+
#define ICE_AQC_SW_RULES_T_VSI_LIST_SET 0x3
612+
#define ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR 0x4
613+
#define ICE_AQC_SW_RULES_T_PRUNE_LIST_SET 0x5
614+
#define ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR 0x6
615+
__le16 status;
616+
union {
617+
struct ice_sw_rule_lkup_rx_tx lkup_tx_rx;
618+
struct ice_sw_rule_lg_act lg_act;
619+
struct ice_sw_rule_vsi_list vsi_list;
620+
struct ice_sw_rule_vsi_list_query vsi_list_query;
621+
} __packed pdata;
622+
};
623+
387624
/* Get Default Topology (indirect 0x0400) */
388625
struct ice_aqc_get_topo {
389626
u8 port_num;
@@ -766,11 +1003,13 @@ struct ice_aq_desc {
7661003
struct ice_aqc_list_caps get_cap;
7671004
struct ice_aqc_get_phy_caps get_phy;
7681005
struct ice_aqc_get_sw_cfg get_sw_conf;
1006+
struct ice_aqc_sw_rules sw_rules;
7691007
struct ice_aqc_get_topo get_topo;
7701008
struct ice_aqc_query_txsched_res query_sched_res;
7711009
struct ice_aqc_add_move_delete_elem add_move_delete_elem;
7721010
struct ice_aqc_nvm nvm;
7731011
struct ice_aqc_add_get_update_free_vsi vsi_cmd;
1012+
struct ice_aqc_alloc_free_res_cmd sw_res_ctrl;
7741013
struct ice_aqc_get_link_status get_link_status;
7751014
} params;
7761015
};
@@ -821,10 +1060,20 @@ enum ice_adminq_opc {
8211060
/* internal switch commands */
8221061
ice_aqc_opc_get_sw_cfg = 0x0200,
8231062

1063+
/* Alloc/Free/Get Resources */
1064+
ice_aqc_opc_alloc_res = 0x0208,
1065+
ice_aqc_opc_free_res = 0x0209,
1066+
8241067
/* VSI commands */
8251068
ice_aqc_opc_add_vsi = 0x0210,
8261069
ice_aqc_opc_update_vsi = 0x0211,
8271070
ice_aqc_opc_free_vsi = 0x0213,
1071+
1072+
/* switch rules population commands */
1073+
ice_aqc_opc_add_sw_rules = 0x02A0,
1074+
ice_aqc_opc_update_sw_rules = 0x02A1,
1075+
ice_aqc_opc_remove_sw_rules = 0x02A2,
1076+
8281077
ice_aqc_opc_clear_pf_cfg = 0x02A4,
8291078

8301079
/* transmit scheduler commands */

0 commit comments

Comments
 (0)