forked from mirrors/linux
		
	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 <anirudh.venkataramanan@intel.com> Tested-by: Tony Brelinski <tonyx.brelinski@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
		
							parent
							
								
									3a858ba392
								
							
						
					
					
						commit
						9daf8208dd
					
				
					 7 changed files with 1935 additions and 2 deletions
				
			
		| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
 * descriptor format.  It is shared between Firmware and Software.
 | 
					 * descriptor format.  It is shared between Firmware and Software.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ICE_MAX_VSI			768
 | 
				
			||||||
#define ICE_AQC_TOPO_MAX_LEVEL_NUM	0x9
 | 
					#define ICE_AQC_TOPO_MAX_LEVEL_NUM	0x9
 | 
				
			||||||
#define ICE_AQ_SET_MAC_FRAME_SIZE_MAX	9728
 | 
					#define ICE_AQ_SET_MAC_FRAME_SIZE_MAX	9728
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,6 +192,46 @@ struct ice_aqc_get_sw_cfg_resp {
 | 
				
			||||||
	struct ice_aqc_get_sw_cfg_resp_elem elements[1];
 | 
						struct ice_aqc_get_sw_cfg_resp_elem elements[1];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* These resource type defines are used for all switch resource
 | 
				
			||||||
 | 
					 * commands where a resource type is required, such as:
 | 
				
			||||||
 | 
					 * Get Resource Allocation command (indirect 0x0204)
 | 
				
			||||||
 | 
					 * Allocate Resources command (indirect 0x0208)
 | 
				
			||||||
 | 
					 * Free Resources command (indirect 0x0209)
 | 
				
			||||||
 | 
					 * Get Allocated Resource Descriptors Command (indirect 0x020A)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define ICE_AQC_RES_TYPE_VSI_LIST_REP			0x03
 | 
				
			||||||
 | 
					#define ICE_AQC_RES_TYPE_VSI_LIST_PRUNE			0x04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Allocate Resources command (indirect 0x0208)
 | 
				
			||||||
 | 
					 * Free Resources command (indirect 0x0209)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_aqc_alloc_free_res_cmd {
 | 
				
			||||||
 | 
						__le16 num_entries; /* Number of Resource entries */
 | 
				
			||||||
 | 
						u8 reserved[6];
 | 
				
			||||||
 | 
						__le32 addr_high;
 | 
				
			||||||
 | 
						__le32 addr_low;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Resource descriptor */
 | 
				
			||||||
 | 
					struct ice_aqc_res_elem {
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							__le16 sw_resp;
 | 
				
			||||||
 | 
							__le16 flu_resp;
 | 
				
			||||||
 | 
						} e;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Buffer for Allocate/Free Resources commands */
 | 
				
			||||||
 | 
					struct ice_aqc_alloc_free_res_elem {
 | 
				
			||||||
 | 
						__le16 res_type; /* Types defined above cmd 0x0204 */
 | 
				
			||||||
 | 
					#define ICE_AQC_RES_TYPE_SHARED_S	7
 | 
				
			||||||
 | 
					#define ICE_AQC_RES_TYPE_SHARED_M	(0x1 << ICE_AQC_RES_TYPE_SHARED_S)
 | 
				
			||||||
 | 
					#define ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_S	8
 | 
				
			||||||
 | 
					#define ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_M	\
 | 
				
			||||||
 | 
									(0xF << ICE_AQC_RES_TYPE_VSI_PRUNE_LIST_S)
 | 
				
			||||||
 | 
						__le16 num_elems;
 | 
				
			||||||
 | 
						struct ice_aqc_res_elem elem[1];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Add VSI (indirect 0x0210)
 | 
					/* Add VSI (indirect 0x0210)
 | 
				
			||||||
 * Update VSI (indirect 0x0211)
 | 
					 * Update VSI (indirect 0x0211)
 | 
				
			||||||
 * Get VSI (indirect 0x0212)
 | 
					 * Get VSI (indirect 0x0212)
 | 
				
			||||||
| 
						 | 
					@ -384,6 +425,202 @@ struct ice_aqc_vsi_props {
 | 
				
			||||||
	u8 reserved[24];
 | 
						u8 reserved[24];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add/Update/Remove/Get switch rules (indirect 0x02A0, 0x02A1, 0x02A2, 0x02A3)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_aqc_sw_rules {
 | 
				
			||||||
 | 
						/* ops: add switch rules, referring the number of rules.
 | 
				
			||||||
 | 
						 * ops: update switch rules, referring the number of filters
 | 
				
			||||||
 | 
						 * ops: remove switch rules, referring the entry index.
 | 
				
			||||||
 | 
						 * ops: get switch rules, referring to the number of filters.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						__le16 num_rules_fltr_entry_index;
 | 
				
			||||||
 | 
						u8 reserved[6];
 | 
				
			||||||
 | 
						__le32 addr_high;
 | 
				
			||||||
 | 
						__le32 addr_low;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add/Update/Get/Remove lookup Rx/Tx command/response entry
 | 
				
			||||||
 | 
					 * This structures describes the lookup rules and associated actions.  "index"
 | 
				
			||||||
 | 
					 * is returned as part of a response to a successful Add command, and can be
 | 
				
			||||||
 | 
					 * used to identify the rule for Update/Get/Remove commands.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_sw_rule_lkup_rx_tx {
 | 
				
			||||||
 | 
						__le16 recipe_id;
 | 
				
			||||||
 | 
					#define ICE_SW_RECIPE_LOGICAL_PORT_FWD		10
 | 
				
			||||||
 | 
						/* Source port for LOOKUP_RX and source VSI in case of LOOKUP_TX */
 | 
				
			||||||
 | 
						__le16 src;
 | 
				
			||||||
 | 
						__le32 act;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bit 0:1 - Action type */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_TYPE_S	0x00
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_TYPE_M	(0x3 << ICE_SINGLE_ACT_TYPE_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bit 2 - Loop back enable
 | 
				
			||||||
 | 
						 * Bit 3 - LAN enable
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_LB_ENABLE	BIT(2)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_LAN_ENABLE	BIT(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 0 - Forward to VSI or VSI list */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VSI_FORWARDING	0x0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VSI_ID_S		4
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VSI_ID_M		(0x3FF << ICE_SINGLE_ACT_VSI_ID_S)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VSI_LIST_ID_S	4
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VSI_LIST_ID_M	(0x3FF << ICE_SINGLE_ACT_VSI_LIST_ID_S)
 | 
				
			||||||
 | 
						/* This bit needs to be set if action is forward to VSI list */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VSI_LIST		BIT(14)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_VALID_BIT	BIT(17)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_DROP		BIT(18)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 1 - Forward to Queue of Queue group */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_TO_Q		0x1
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_Q_INDEX_S	4
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_Q_INDEX_M	(0x7FF << ICE_SINGLE_ACT_Q_INDEX_S)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_Q_REGION_S	15
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_Q_REGION_M	(0x7 << ICE_SINGLE_ACT_Q_REGION_S)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_Q_PRIORITY	BIT(18)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 2 - Prune */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_PRUNE		0x2
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_EGRESS		BIT(15)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_INGRESS		BIT(16)
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_PRUNET		BIT(17)
 | 
				
			||||||
 | 
						/* Bit 18 should be set to 0 for this action */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 2 - Pointer */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_PTR		0x2
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_PTR_VAL_S	4
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_PTR_VAL_M	(0x1FFF << ICE_SINGLE_ACT_PTR_VAL_S)
 | 
				
			||||||
 | 
						/* Bit 18 should be set to 1 */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_PTR_BIT		BIT(18)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 3 - Other actions. Last two bits
 | 
				
			||||||
 | 
						 * are other action identifier
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_OTHER_ACTS		0x3
 | 
				
			||||||
 | 
					#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_S	17
 | 
				
			||||||
 | 
					#define ICE_SINGLE_OTHER_ACT_IDENTIFIER_M	\
 | 
				
			||||||
 | 
									(0x3 << \ ICE_SINGLE_OTHER_ACT_IDENTIFIER_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bit 17:18 - Defines other actions */
 | 
				
			||||||
 | 
						/* Other action = 0 - Mirror VSI */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_OTHER_ACT_MIRROR		0
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_MIRROR_VSI_ID_S	4
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_MIRROR_VSI_ID_M	\
 | 
				
			||||||
 | 
									(0x3FF << ICE_SINGLE_ACT_MIRROR_VSI_ID_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Other action = 3 - Set Stat count */
 | 
				
			||||||
 | 
					#define ICE_SINGLE_OTHER_ACT_STAT_COUNT		3
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_STAT_COUNT_INDEX_S	4
 | 
				
			||||||
 | 
					#define ICE_SINGLE_ACT_STAT_COUNT_INDEX_M	\
 | 
				
			||||||
 | 
									(0x7F << ICE_SINGLE_ACT_STAT_COUNT_INDEX_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__le16 index; /* The index of the rule in the lookup table */
 | 
				
			||||||
 | 
						/* Length and values of the header to be matched per recipe or
 | 
				
			||||||
 | 
						 * lookup-type
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						__le16 hdr_len;
 | 
				
			||||||
 | 
						u8 hdr[1];
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add/Update/Remove large action command/response entry
 | 
				
			||||||
 | 
					 * "index" is returned as part of a response to a successful Add command, and
 | 
				
			||||||
 | 
					 * can be used to identify the action for Update/Get/Remove commands.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_sw_rule_lg_act {
 | 
				
			||||||
 | 
						__le16 index; /* Index in large action table */
 | 
				
			||||||
 | 
						__le16 size;
 | 
				
			||||||
 | 
						__le32 act[1]; /* array of size for actions */
 | 
				
			||||||
 | 
						/* Max number of large actions */
 | 
				
			||||||
 | 
					#define ICE_MAX_LG_ACT	4
 | 
				
			||||||
 | 
						/* Bit 0:1 - Action type */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_TYPE_S	0
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_TYPE_M	(0x7 << ICE_LG_ACT_TYPE_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 0 - Forward to VSI or VSI list */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VSI_FORWARDING	0
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VSI_ID_S		3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VSI_ID_M		(0x3FF << ICE_LG_ACT_VSI_ID_S)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VSI_LIST_ID_S	3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VSI_LIST_ID_M	(0x3FF << ICE_LG_ACT_VSI_LIST_ID_S)
 | 
				
			||||||
 | 
						/* This bit needs to be set if action is forward to VSI list */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VSI_LIST		BIT(13)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_VALID_BIT		BIT(16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 1 - Forward to Queue of Queue group */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_TO_Q			0x1
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_Q_INDEX_S		3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_Q_INDEX_M		(0x7FF << ICE_LG_ACT_Q_INDEX_S)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_Q_REGION_S		14
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_Q_REGION_M		(0x7 << ICE_LG_ACT_Q_REGION_S)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_Q_PRIORITY_SET	BIT(17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 2 - Prune */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_PRUNE		0x2
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_EGRESS		BIT(14)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_INGRESS		BIT(15)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_PRUNET		BIT(16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 3 - Mirror VSI */
 | 
				
			||||||
 | 
					#define ICE_LG_OTHER_ACT_MIRROR		0x3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_MIRROR_VSI_ID_S	3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_MIRROR_VSI_ID_M	(0x3FF << ICE_LG_ACT_MIRROR_VSI_ID_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action type = 5 - Large Action */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC		0x5
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC_VALUE_S	3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC_VALUE_M	(0xFFFF << ICE_LG_ACT_GENERIC_VALUE_S)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC_OFFSET_S	19
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC_OFFSET_M	(0x7 << ICE_LG_ACT_GENERIC_OFFSET_S)
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC_PRIORITY_S	22
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_GENERIC_PRIORITY_M	(0x7 << ICE_LG_ACT_GENERIC_PRIORITY_S)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Action = 7 - Set Stat count */
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_STAT_COUNT		0x7
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_STAT_COUNT_S		3
 | 
				
			||||||
 | 
					#define ICE_LG_ACT_STAT_COUNT_M		(0x7F << ICE_LG_ACT_STAT_COUNT_S)
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add/Update/Remove VSI list command/response entry
 | 
				
			||||||
 | 
					 * "index" is returned as part of a response to a successful Add command, and
 | 
				
			||||||
 | 
					 * can be used to identify the VSI list for Update/Get/Remove commands.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_sw_rule_vsi_list {
 | 
				
			||||||
 | 
						__le16 index; /* Index of VSI/Prune list */
 | 
				
			||||||
 | 
						__le16 number_vsi;
 | 
				
			||||||
 | 
						__le16 vsi[1]; /* Array of number_vsi VSI numbers */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Query VSI list command/response entry */
 | 
				
			||||||
 | 
					struct ice_sw_rule_vsi_list_query {
 | 
				
			||||||
 | 
						__le16 index;
 | 
				
			||||||
 | 
						DECLARE_BITMAP(vsi_list, ICE_MAX_VSI);
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add switch rule response:
 | 
				
			||||||
 | 
					 * Content of return buffer is same as the input buffer. The status field and
 | 
				
			||||||
 | 
					 * LUT index are updated as part of the response
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_aqc_sw_rules_elem {
 | 
				
			||||||
 | 
						__le16 type; /* Switch rule type, one of T_... */
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_LKUP_RX		0x0
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_LKUP_TX		0x1
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_LG_ACT		0x2
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_VSI_LIST_SET		0x3
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR	0x4
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_PRUNE_LIST_SET	0x5
 | 
				
			||||||
 | 
					#define ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR	0x6
 | 
				
			||||||
 | 
						__le16 status;
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct ice_sw_rule_lkup_rx_tx lkup_tx_rx;
 | 
				
			||||||
 | 
							struct ice_sw_rule_lg_act lg_act;
 | 
				
			||||||
 | 
							struct ice_sw_rule_vsi_list vsi_list;
 | 
				
			||||||
 | 
							struct ice_sw_rule_vsi_list_query vsi_list_query;
 | 
				
			||||||
 | 
						} __packed pdata;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get Default Topology (indirect 0x0400) */
 | 
					/* Get Default Topology (indirect 0x0400) */
 | 
				
			||||||
struct ice_aqc_get_topo {
 | 
					struct ice_aqc_get_topo {
 | 
				
			||||||
	u8 port_num;
 | 
						u8 port_num;
 | 
				
			||||||
| 
						 | 
					@ -766,11 +1003,13 @@ struct ice_aq_desc {
 | 
				
			||||||
		struct ice_aqc_list_caps get_cap;
 | 
							struct ice_aqc_list_caps get_cap;
 | 
				
			||||||
		struct ice_aqc_get_phy_caps get_phy;
 | 
							struct ice_aqc_get_phy_caps get_phy;
 | 
				
			||||||
		struct ice_aqc_get_sw_cfg get_sw_conf;
 | 
							struct ice_aqc_get_sw_cfg get_sw_conf;
 | 
				
			||||||
 | 
							struct ice_aqc_sw_rules sw_rules;
 | 
				
			||||||
		struct ice_aqc_get_topo get_topo;
 | 
							struct ice_aqc_get_topo get_topo;
 | 
				
			||||||
		struct ice_aqc_query_txsched_res query_sched_res;
 | 
							struct ice_aqc_query_txsched_res query_sched_res;
 | 
				
			||||||
		struct ice_aqc_add_move_delete_elem add_move_delete_elem;
 | 
							struct ice_aqc_add_move_delete_elem add_move_delete_elem;
 | 
				
			||||||
		struct ice_aqc_nvm nvm;
 | 
							struct ice_aqc_nvm nvm;
 | 
				
			||||||
		struct ice_aqc_add_get_update_free_vsi vsi_cmd;
 | 
							struct ice_aqc_add_get_update_free_vsi vsi_cmd;
 | 
				
			||||||
 | 
							struct ice_aqc_alloc_free_res_cmd sw_res_ctrl;
 | 
				
			||||||
		struct ice_aqc_get_link_status get_link_status;
 | 
							struct ice_aqc_get_link_status get_link_status;
 | 
				
			||||||
	} params;
 | 
						} params;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -821,10 +1060,20 @@ enum ice_adminq_opc {
 | 
				
			||||||
	/* internal switch commands */
 | 
						/* internal switch commands */
 | 
				
			||||||
	ice_aqc_opc_get_sw_cfg				= 0x0200,
 | 
						ice_aqc_opc_get_sw_cfg				= 0x0200,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Alloc/Free/Get Resources */
 | 
				
			||||||
 | 
						ice_aqc_opc_alloc_res				= 0x0208,
 | 
				
			||||||
 | 
						ice_aqc_opc_free_res				= 0x0209,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* VSI commands */
 | 
						/* VSI commands */
 | 
				
			||||||
	ice_aqc_opc_add_vsi				= 0x0210,
 | 
						ice_aqc_opc_add_vsi				= 0x0210,
 | 
				
			||||||
	ice_aqc_opc_update_vsi				= 0x0211,
 | 
						ice_aqc_opc_update_vsi				= 0x0211,
 | 
				
			||||||
	ice_aqc_opc_free_vsi				= 0x0213,
 | 
						ice_aqc_opc_free_vsi				= 0x0213,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* switch rules population commands */
 | 
				
			||||||
 | 
						ice_aqc_opc_add_sw_rules			= 0x02A0,
 | 
				
			||||||
 | 
						ice_aqc_opc_update_sw_rules			= 0x02A1,
 | 
				
			||||||
 | 
						ice_aqc_opc_remove_sw_rules			= 0x02A2,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ice_aqc_opc_clear_pf_cfg			= 0x02A4,
 | 
						ice_aqc_opc_clear_pf_cfg			= 0x02A4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* transmit scheduler commands */
 | 
						/* transmit scheduler commands */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,6 +258,66 @@ ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
 | 
				
			||||||
	return status;
 | 
						return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ice_init_fltr_mgmt_struct - initializes filter management list and locks
 | 
				
			||||||
 | 
					 * @hw: pointer to the hw struct
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ice_switch_info *sw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hw->switch_info = devm_kzalloc(ice_hw_to_dev(hw),
 | 
				
			||||||
 | 
									       sizeof(*hw->switch_info), GFP_KERNEL);
 | 
				
			||||||
 | 
						sw = hw->switch_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!sw)
 | 
				
			||||||
 | 
							return ICE_ERR_NO_MEMORY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&sw->vsi_list_map_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_init(&sw->mac_list_lock);
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&sw->mac_list_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_init(&sw->vlan_list_lock);
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&sw->vlan_list_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_init(&sw->eth_m_list_lock);
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&sw->eth_m_list_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_init(&sw->promisc_list_lock);
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&sw->promisc_list_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_init(&sw->mac_vlan_list_lock);
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&sw->mac_vlan_list_head);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ice_cleanup_fltr_mgmt_struct - cleanup filter management list and locks
 | 
				
			||||||
 | 
					 * @hw: pointer to the hw struct
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ice_switch_info *sw = hw->switch_info;
 | 
				
			||||||
 | 
						struct ice_vsi_list_map_info *v_pos_map;
 | 
				
			||||||
 | 
						struct ice_vsi_list_map_info *v_tmp_map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry_safe(v_pos_map, v_tmp_map, &sw->vsi_list_map_head,
 | 
				
			||||||
 | 
									 list_entry) {
 | 
				
			||||||
 | 
							list_del(&v_pos_map->list_entry);
 | 
				
			||||||
 | 
							devm_kfree(ice_hw_to_dev(hw), v_pos_map);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mutex_destroy(&sw->mac_list_lock);
 | 
				
			||||||
 | 
						mutex_destroy(&sw->vlan_list_lock);
 | 
				
			||||||
 | 
						mutex_destroy(&sw->eth_m_list_lock);
 | 
				
			||||||
 | 
						mutex_destroy(&sw->promisc_list_lock);
 | 
				
			||||||
 | 
						mutex_destroy(&sw->mac_vlan_list_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						devm_kfree(ice_hw_to_dev(hw), sw);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ice_init_hw - main hardware initialization routine
 | 
					 * ice_init_hw - main hardware initialization routine
 | 
				
			||||||
 * @hw: pointer to the hardware structure
 | 
					 * @hw: pointer to the hardware structure
 | 
				
			||||||
| 
						 | 
					@ -321,6 +381,8 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto err_unroll_alloc;
 | 
							goto err_unroll_alloc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hw->evb_veb = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Query the allocated resources for tx scheduler */
 | 
						/* Query the allocated resources for tx scheduler */
 | 
				
			||||||
	status = ice_sched_query_res_alloc(hw);
 | 
						status = ice_sched_query_res_alloc(hw);
 | 
				
			||||||
	if (status) {
 | 
						if (status) {
 | 
				
			||||||
| 
						 | 
					@ -352,21 +414,27 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto err_unroll_sched;
 | 
							goto err_unroll_sched;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status = ice_init_fltr_mgmt_struct(hw);
 | 
				
			||||||
 | 
						if (status)
 | 
				
			||||||
 | 
							goto err_unroll_sched;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Get port MAC information */
 | 
						/* Get port MAC information */
 | 
				
			||||||
	mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp);
 | 
						mac_buf_len = sizeof(struct ice_aqc_manage_mac_read_resp);
 | 
				
			||||||
	mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL);
 | 
						mac_buf = devm_kzalloc(ice_hw_to_dev(hw), mac_buf_len, GFP_KERNEL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!mac_buf)
 | 
						if (!mac_buf)
 | 
				
			||||||
		goto err_unroll_sched;
 | 
							goto err_unroll_fltr_mgmt_struct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
 | 
						status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
 | 
				
			||||||
	devm_kfree(ice_hw_to_dev(hw), mac_buf);
 | 
						devm_kfree(ice_hw_to_dev(hw), mac_buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status)
 | 
						if (status)
 | 
				
			||||||
		goto err_unroll_sched;
 | 
							goto err_unroll_fltr_mgmt_struct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err_unroll_fltr_mgmt_struct:
 | 
				
			||||||
 | 
						ice_cleanup_fltr_mgmt_struct(hw);
 | 
				
			||||||
err_unroll_sched:
 | 
					err_unroll_sched:
 | 
				
			||||||
	ice_sched_cleanup_all(hw);
 | 
						ice_sched_cleanup_all(hw);
 | 
				
			||||||
err_unroll_alloc:
 | 
					err_unroll_alloc:
 | 
				
			||||||
| 
						 | 
					@ -389,6 +457,8 @@ void ice_deinit_hw(struct ice_hw *hw)
 | 
				
			||||||
		devm_kfree(ice_hw_to_dev(hw), hw->port_info);
 | 
							devm_kfree(ice_hw_to_dev(hw), hw->port_info);
 | 
				
			||||||
		hw->port_info = NULL;
 | 
							hw->port_info = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ice_cleanup_fltr_mgmt_struct(hw);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,6 +162,57 @@ static int ice_free_res(struct ice_res_tracker *res, u16 index, u16 id)
 | 
				
			||||||
	return count;
 | 
						return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ice_add_mac_to_list - Add a mac address filter entry to the list
 | 
				
			||||||
 | 
					 * @vsi: the VSI to be forwarded to
 | 
				
			||||||
 | 
					 * @add_list: pointer to the list which contains MAC filter entries
 | 
				
			||||||
 | 
					 * @macaddr: the MAC address to be added.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Adds mac address filter entry to the temp list
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns 0 on success or ENOMEM on failure.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,
 | 
				
			||||||
 | 
								       const u8 *macaddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ice_fltr_list_entry *tmp;
 | 
				
			||||||
 | 
						struct ice_pf *pf = vsi->back;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = devm_kzalloc(&pf->pdev->dev, sizeof(*tmp), GFP_ATOMIC);
 | 
				
			||||||
 | 
						if (!tmp)
 | 
				
			||||||
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp->fltr_info.flag = ICE_FLTR_TX;
 | 
				
			||||||
 | 
						tmp->fltr_info.src = vsi->vsi_num;
 | 
				
			||||||
 | 
						tmp->fltr_info.lkup_type = ICE_SW_LKUP_MAC;
 | 
				
			||||||
 | 
						tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
 | 
				
			||||||
 | 
						tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
 | 
				
			||||||
 | 
						ether_addr_copy(tmp->fltr_info.l_data.mac.mac_addr, macaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						INIT_LIST_HEAD(&tmp->list_entry);
 | 
				
			||||||
 | 
						list_add(&tmp->list_entry, add_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ice_free_fltr_list - free filter lists helper
 | 
				
			||||||
 | 
					 * @dev: pointer to the device struct
 | 
				
			||||||
 | 
					 * @h: pointer to the list head to be freed
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Helper function to free filter lists previously created using
 | 
				
			||||||
 | 
					 * ice_add_mac_to_list
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void ice_free_fltr_list(struct device *dev, struct list_head *h)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ice_fltr_list_entry *e, *tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						list_for_each_entry_safe(e, tmp, h, list_entry) {
 | 
				
			||||||
 | 
							list_del(&e->list_entry);
 | 
				
			||||||
 | 
							devm_kfree(dev, e);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * __ice_clean_ctrlq - helper function to clean controlq rings
 | 
					 * __ice_clean_ctrlq - helper function to clean controlq rings
 | 
				
			||||||
 * @pf: ptr to struct ice_pf
 | 
					 * @pf: ptr to struct ice_pf
 | 
				
			||||||
| 
						 | 
					@ -1519,6 +1570,8 @@ ice_vsi_setup(struct ice_pf *pf, enum ice_vsi_type type,
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int ice_setup_pf_sw(struct ice_pf *pf)
 | 
					static int ice_setup_pf_sw(struct ice_pf *pf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						LIST_HEAD(tmp_add_list);
 | 
				
			||||||
 | 
						u8 broadcast[ETH_ALEN];
 | 
				
			||||||
	struct ice_vsi *vsi;
 | 
						struct ice_vsi *vsi;
 | 
				
			||||||
	int status = 0;
 | 
						int status = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1528,7 +1581,37 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
 | 
				
			||||||
		goto error_exit;
 | 
							goto error_exit;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* tmp_add_list contains a list of MAC addresses for which MAC
 | 
				
			||||||
 | 
						 * filters need to be programmed. Add the VSI's unicast MAC to
 | 
				
			||||||
 | 
						 * this list
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						status = ice_add_mac_to_list(vsi, &tmp_add_list,
 | 
				
			||||||
 | 
									     vsi->port_info->mac.perm_addr);
 | 
				
			||||||
 | 
						if (status)
 | 
				
			||||||
 | 
							goto error_exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* VSI needs to receive broadcast traffic, so add the broadcast
 | 
				
			||||||
 | 
						 * MAC address to the list.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						eth_broadcast_addr(broadcast);
 | 
				
			||||||
 | 
						status = ice_add_mac_to_list(vsi, &tmp_add_list, broadcast);
 | 
				
			||||||
 | 
						if (status)
 | 
				
			||||||
 | 
							goto error_exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* program MAC filters for entries in tmp_add_list */
 | 
				
			||||||
 | 
						status = ice_add_mac(&pf->hw, &tmp_add_list);
 | 
				
			||||||
 | 
						if (status) {
 | 
				
			||||||
 | 
							dev_err(&pf->pdev->dev, "Could not add MAC filters\n");
 | 
				
			||||||
 | 
							status = -ENOMEM;
 | 
				
			||||||
 | 
							goto error_exit;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
 | 
				
			||||||
 | 
						return status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_exit:
 | 
					error_exit:
 | 
				
			||||||
 | 
						ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (vsi) {
 | 
						if (vsi) {
 | 
				
			||||||
		ice_vsi_free_q_vectors(vsi);
 | 
							ice_vsi_free_q_vectors(vsi);
 | 
				
			||||||
		if (vsi->netdev && vsi->netdev->reg_state == NETREG_REGISTERED)
 | 
							if (vsi->netdev && vsi->netdev->reg_state == NETREG_REGISTERED)
 | 
				
			||||||
| 
						 | 
					@ -1537,6 +1620,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
 | 
				
			||||||
			free_netdev(vsi->netdev);
 | 
								free_netdev(vsi->netdev);
 | 
				
			||||||
			vsi->netdev = NULL;
 | 
								vsi->netdev = NULL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ice_vsi_delete(vsi);
 | 
							ice_vsi_delete(vsi);
 | 
				
			||||||
		ice_vsi_put_qs(vsi);
 | 
							ice_vsi_put_qs(vsi);
 | 
				
			||||||
		pf->q_left_tx += vsi->alloc_txq;
 | 
							pf->q_left_tx += vsi->alloc_txq;
 | 
				
			||||||
| 
						 | 
					@ -1869,6 +1953,13 @@ static int ice_probe(struct pci_dev *pdev,
 | 
				
			||||||
			"probe failed due to setup pf switch:%d\n", err);
 | 
								"probe failed due to setup pf switch:%d\n", err);
 | 
				
			||||||
		goto err_alloc_sw_unroll;
 | 
							goto err_alloc_sw_unroll;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Driver is mostly up */
 | 
				
			||||||
 | 
						clear_bit(__ICE_DOWN, pf->state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* since everything is good, start the service timer */
 | 
				
			||||||
 | 
						mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_alloc_sw_unroll:
 | 
					err_alloc_sw_unroll:
 | 
				
			||||||
| 
						 | 
					@ -2012,6 +2103,7 @@ static int ice_vsi_release(struct ice_vsi *vsi)
 | 
				
			||||||
	ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx);
 | 
						ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx);
 | 
				
			||||||
	pf->num_avail_msix += vsi->num_q_vectors;
 | 
						pf->num_avail_msix += vsi->num_q_vectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ice_remove_vsi_fltr(&pf->hw, vsi->vsi_num);
 | 
				
			||||||
	ice_vsi_delete(vsi);
 | 
						ice_vsi_delete(vsi);
 | 
				
			||||||
	ice_vsi_free_q_vectors(vsi);
 | 
						ice_vsi_free_q_vectors(vsi);
 | 
				
			||||||
	ice_vsi_clear_rings(vsi);
 | 
						ice_vsi_clear_rings(vsi);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
/* Error Codes */
 | 
					/* Error Codes */
 | 
				
			||||||
enum ice_status {
 | 
					enum ice_status {
 | 
				
			||||||
	ICE_ERR_PARAM				= -1,
 | 
						ICE_ERR_PARAM				= -1,
 | 
				
			||||||
 | 
						ICE_ERR_NOT_IMPL			= -2,
 | 
				
			||||||
	ICE_ERR_NOT_READY			= -3,
 | 
						ICE_ERR_NOT_READY			= -3,
 | 
				
			||||||
	ICE_ERR_INVAL_SIZE			= -6,
 | 
						ICE_ERR_INVAL_SIZE			= -6,
 | 
				
			||||||
	ICE_ERR_DEVICE_NOT_SUPPORTED		= -8,
 | 
						ICE_ERR_DEVICE_NOT_SUPPORTED		= -8,
 | 
				
			||||||
| 
						 | 
					@ -15,6 +16,8 @@ enum ice_status {
 | 
				
			||||||
	ICE_ERR_NO_MEMORY			= -11,
 | 
						ICE_ERR_NO_MEMORY			= -11,
 | 
				
			||||||
	ICE_ERR_CFG				= -12,
 | 
						ICE_ERR_CFG				= -12,
 | 
				
			||||||
	ICE_ERR_OUT_OF_RANGE			= -13,
 | 
						ICE_ERR_OUT_OF_RANGE			= -13,
 | 
				
			||||||
 | 
						ICE_ERR_ALREADY_EXISTS			= -14,
 | 
				
			||||||
 | 
						ICE_ERR_DOES_NOT_EXIST			= -15,
 | 
				
			||||||
	ICE_ERR_BUF_TOO_SHORT			= -52,
 | 
						ICE_ERR_BUF_TOO_SHORT			= -52,
 | 
				
			||||||
	ICE_ERR_NVM_BLANK_MODE			= -53,
 | 
						ICE_ERR_NVM_BLANK_MODE			= -53,
 | 
				
			||||||
	ICE_ERR_AQ_ERROR			= -100,
 | 
						ICE_ERR_AQ_ERROR			= -100,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -19,6 +19,122 @@ struct ice_vsi_ctx {
 | 
				
			||||||
	bool alloc_from_pool;
 | 
						bool alloc_from_pool;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ice_sw_fwd_act_type {
 | 
				
			||||||
 | 
						ICE_FWD_TO_VSI = 0,
 | 
				
			||||||
 | 
						ICE_FWD_TO_VSI_LIST, /* Do not use this when adding filter */
 | 
				
			||||||
 | 
						ICE_FWD_TO_Q,
 | 
				
			||||||
 | 
						ICE_FWD_TO_QGRP,
 | 
				
			||||||
 | 
						ICE_DROP_PACKET,
 | 
				
			||||||
 | 
						ICE_INVAL_ACT
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Switch recipe ID enum values are specific to hardware */
 | 
				
			||||||
 | 
					enum ice_sw_lkup_type {
 | 
				
			||||||
 | 
						ICE_SW_LKUP_ETHERTYPE = 0,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_MAC = 1,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_MAC_VLAN = 2,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_PROMISC = 3,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_VLAN = 4,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_DFLT = 5,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_ETHERTYPE_MAC = 8,
 | 
				
			||||||
 | 
						ICE_SW_LKUP_PROMISC_VLAN = 9,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ice_fltr_info {
 | 
				
			||||||
 | 
						/* Look up information: how to look up packet */
 | 
				
			||||||
 | 
						enum ice_sw_lkup_type lkup_type;
 | 
				
			||||||
 | 
						/* Forward action: filter action to do after lookup */
 | 
				
			||||||
 | 
						enum ice_sw_fwd_act_type fltr_act;
 | 
				
			||||||
 | 
						/* rule ID returned by firmware once filter rule is created */
 | 
				
			||||||
 | 
						u16 fltr_rule_id;
 | 
				
			||||||
 | 
						u16 flag;
 | 
				
			||||||
 | 
					#define ICE_FLTR_RX		BIT(0)
 | 
				
			||||||
 | 
					#define ICE_FLTR_TX		BIT(1)
 | 
				
			||||||
 | 
					#define ICE_FLTR_TX_RX		(ICE_FLTR_RX | ICE_FLTR_TX)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Source VSI for LOOKUP_TX or source port for LOOKUP_RX */
 | 
				
			||||||
 | 
						u16 src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u8 mac_addr[ETH_ALEN];
 | 
				
			||||||
 | 
							} mac;
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u8 mac_addr[ETH_ALEN];
 | 
				
			||||||
 | 
								u16 vlan_id;
 | 
				
			||||||
 | 
							} mac_vlan;
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u16 vlan_id;
 | 
				
			||||||
 | 
							} vlan;
 | 
				
			||||||
 | 
							/* Set lkup_type as ICE_SW_LKUP_ETHERTYPE
 | 
				
			||||||
 | 
							 * if just using ethertype as filter. Set lkup_type as
 | 
				
			||||||
 | 
							 * ICE_SW_LKUP_ETHERTYPE_MAC if MAC also needs to be
 | 
				
			||||||
 | 
							 * passed in as filter.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							struct {
 | 
				
			||||||
 | 
								u16 ethertype;
 | 
				
			||||||
 | 
								u8 mac_addr[ETH_ALEN]; /* optional */
 | 
				
			||||||
 | 
							} ethertype_mac;
 | 
				
			||||||
 | 
						} l_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Depending on filter action */
 | 
				
			||||||
 | 
						union {
 | 
				
			||||||
 | 
							/* queue id in case of ICE_FWD_TO_Q and starting
 | 
				
			||||||
 | 
							 * queue id in case of ICE_FWD_TO_QGRP.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							u16 q_id:11;
 | 
				
			||||||
 | 
							u16 vsi_id:10;
 | 
				
			||||||
 | 
							u16 vsi_list_id:10;
 | 
				
			||||||
 | 
						} fwd_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Set to num_queues if action is ICE_FWD_TO_QGRP. This field
 | 
				
			||||||
 | 
						 * determines the range of queues the packet needs to be forwarded to
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						u8 qgrp_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Rule creations populate these indicators basing on the switch type */
 | 
				
			||||||
 | 
						bool lb_en;	/* Indicate if packet can be looped back */
 | 
				
			||||||
 | 
						bool lan_en;	/* Indicate if packet can be forwarded to the uplink */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Bookkeeping structure to hold bitmap of VSIs corresponding to VSI list id */
 | 
				
			||||||
 | 
					struct ice_vsi_list_map_info {
 | 
				
			||||||
 | 
						struct list_head list_entry;
 | 
				
			||||||
 | 
						DECLARE_BITMAP(vsi_map, ICE_MAX_VSI);
 | 
				
			||||||
 | 
						u16 vsi_list_id;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ice_sw_fltr_status {
 | 
				
			||||||
 | 
						ICE_FLTR_STATUS_NEW = 0,
 | 
				
			||||||
 | 
						ICE_FLTR_STATUS_FW_SUCCESS,
 | 
				
			||||||
 | 
						ICE_FLTR_STATUS_FW_FAIL,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ice_fltr_list_entry {
 | 
				
			||||||
 | 
						struct list_head list_entry;
 | 
				
			||||||
 | 
						enum ice_sw_fltr_status status;
 | 
				
			||||||
 | 
						struct ice_fltr_info fltr_info;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This defines an entry in the list that maintains MAC or VLAN membership
 | 
				
			||||||
 | 
					 * to HW list mapping, since multiple VSIs can subscribe to the same MAC or
 | 
				
			||||||
 | 
					 * VLAN. As an optimization the VSI list should be created only when a
 | 
				
			||||||
 | 
					 * second VSI becomes a subscriber to the VLAN address.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct ice_fltr_mgmt_list_entry {
 | 
				
			||||||
 | 
						/* back pointer to VSI list id to VSI list mapping */
 | 
				
			||||||
 | 
						struct ice_vsi_list_map_info *vsi_list_info;
 | 
				
			||||||
 | 
						u16 vsi_count;
 | 
				
			||||||
 | 
					#define ICE_INVAL_LG_ACT_INDEX 0xffff
 | 
				
			||||||
 | 
						u16 lg_act_idx;
 | 
				
			||||||
 | 
					#define ICE_INVAL_SW_MARKER_ID 0xffff
 | 
				
			||||||
 | 
						u16 sw_marker_id;
 | 
				
			||||||
 | 
						struct list_head list_entry;
 | 
				
			||||||
 | 
						struct ice_fltr_info fltr_info;
 | 
				
			||||||
 | 
					#define ICE_INVAL_COUNTER_ID 0xff
 | 
				
			||||||
 | 
						u8 counter_index;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* VSI related commands */
 | 
					/* VSI related commands */
 | 
				
			||||||
enum ice_status
 | 
					enum ice_status
 | 
				
			||||||
ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
 | 
					ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
 | 
				
			||||||
| 
						 | 
					@ -32,4 +148,8 @@ ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw);
 | 
					enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Switch/bridge related commands */
 | 
				
			||||||
 | 
					enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_lst);
 | 
				
			||||||
 | 
					enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst);
 | 
				
			||||||
 | 
					void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_id);
 | 
				
			||||||
#endif /* _ICE_SWITCH_H_ */
 | 
					#endif /* _ICE_SWITCH_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,6 +223,22 @@ struct ice_port_info {
 | 
				
			||||||
	bool is_vf;
 | 
						bool is_vf;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ice_switch_info {
 | 
				
			||||||
 | 
						/* Switch VSI lists to MAC/VLAN translation */
 | 
				
			||||||
 | 
						struct mutex mac_list_lock;		/* protect MAC list */
 | 
				
			||||||
 | 
						struct list_head mac_list_head;
 | 
				
			||||||
 | 
						struct mutex vlan_list_lock;		/* protect VLAN list */
 | 
				
			||||||
 | 
						struct list_head vlan_list_head;
 | 
				
			||||||
 | 
						struct mutex eth_m_list_lock;	/* protect ethtype list */
 | 
				
			||||||
 | 
						struct list_head eth_m_list_head;
 | 
				
			||||||
 | 
						struct mutex promisc_list_lock;	/* protect promisc mode list */
 | 
				
			||||||
 | 
						struct list_head promisc_list_head;
 | 
				
			||||||
 | 
						struct mutex mac_vlan_list_lock;	/* protect MAC-VLAN list */
 | 
				
			||||||
 | 
						struct list_head mac_vlan_list_head;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct list_head vsi_list_map_head;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Port hardware description */
 | 
					/* Port hardware description */
 | 
				
			||||||
struct ice_hw {
 | 
					struct ice_hw {
 | 
				
			||||||
	u8 __iomem *hw_addr;
 | 
						u8 __iomem *hw_addr;
 | 
				
			||||||
| 
						 | 
					@ -248,11 +264,14 @@ struct ice_hw {
 | 
				
			||||||
	u8 max_cgds;
 | 
						u8 max_cgds;
 | 
				
			||||||
	u8 sw_entry_point_layer;
 | 
						u8 sw_entry_point_layer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool evb_veb;		/* true for VEB, false for VEPA */
 | 
				
			||||||
	struct ice_bus_info bus;
 | 
						struct ice_bus_info bus;
 | 
				
			||||||
	struct ice_nvm_info nvm;
 | 
						struct ice_nvm_info nvm;
 | 
				
			||||||
	struct ice_hw_dev_caps dev_caps;	/* device capabilities */
 | 
						struct ice_hw_dev_caps dev_caps;	/* device capabilities */
 | 
				
			||||||
	struct ice_hw_func_caps func_caps;	/* function capabilities */
 | 
						struct ice_hw_func_caps func_caps;	/* function capabilities */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct ice_switch_info *switch_info;	/* switch filter lists */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Control Queue info */
 | 
						/* Control Queue info */
 | 
				
			||||||
	struct ice_ctl_q_info adminq;
 | 
						struct ice_ctl_q_info adminq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,6 +295,8 @@ struct ice_hw {
 | 
				
			||||||
	u8 itr_gran_100;
 | 
						u8 itr_gran_100;
 | 
				
			||||||
	u8 itr_gran_50;
 | 
						u8 itr_gran_50;
 | 
				
			||||||
	u8 itr_gran_25;
 | 
						u8 itr_gran_25;
 | 
				
			||||||
 | 
						bool ucast_shared;	/* true if VSIs can share unicast addr */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Checksum and Shadow RAM pointers */
 | 
					/* Checksum and Shadow RAM pointers */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue