drivers/net/ethernet/intel/ice/ice_lag.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_lag.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_lag.c
Extension
.c
Size
74246 bytes
Lines
2785
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tmp_lag && tmp_lag->primary) {
			primary_lag = tmp_lag;
			break;
		}
	}

	return primary_lag;
}

/**
 * ice_lag_cfg_fltr - Add/Remove rule for LAG
 * @lag: lag struct for local interface
 * @act: rule action
 * @recipe_id: recipe id for the new rule
 * @rule_idx: pointer to rule index
 * @direction: ICE_FLTR_RX or ICE_FLTR_TX
 * @add: boolean on whether we are adding filters
 */
static int
ice_lag_cfg_fltr(struct ice_lag *lag, u32 act, u16 recipe_id, u16 *rule_idx,
		 u8 direction, bool add)
{
	struct ice_sw_rule_lkup_rx_tx *s_rule;
	struct ice_hw *hw = &lag->pf->hw;
	u16 s_rule_sz, vsi_num;
	u8 *eth_hdr;
	u32 opc;
	int err;

	vsi_num = ice_get_hw_vsi_num(hw, 0);

	s_rule_sz = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule);
	s_rule = kzalloc(s_rule_sz, GFP_KERNEL);
	if (!s_rule) {
		dev_err(ice_pf_to_dev(lag->pf), "error allocating rule for LAG\n");
		return -ENOMEM;
	}

	if (add) {
		eth_hdr = s_rule->hdr_data;
		ice_fill_eth_hdr(eth_hdr);

		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, vsi_num);

		s_rule->recipe_id = cpu_to_le16(recipe_id);
		if (direction == ICE_FLTR_RX) {
			s_rule->hdr.type =
				cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
			s_rule->src = cpu_to_le16(hw->port_info->lport);
		} else {
			s_rule->hdr.type =
				cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
			s_rule->src = cpu_to_le16(vsi_num);
		}
		s_rule->act = cpu_to_le32(act);
		s_rule->hdr_len = cpu_to_le16(DUMMY_ETH_HDR_LEN);
		opc = ice_aqc_opc_add_sw_rules;
	} else {
		s_rule->index = cpu_to_le16(*rule_idx);
		opc = ice_aqc_opc_remove_sw_rules;
	}

	err = ice_aq_sw_rules(&lag->pf->hw, s_rule, s_rule_sz, 1, opc, NULL);
	if (err)
		goto dflt_fltr_free;

	if (add)
		*rule_idx = le16_to_cpu(s_rule->index);
	else
		*rule_idx = 0;

dflt_fltr_free:
	kfree(s_rule);
	return err;
}

/**
 * ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG
 * @lag: lag struct for local interface
 * @add: boolean on whether to add filter
 */
static int
ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
{
	u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
		ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE;
	int err;

	err = ice_lag_cfg_fltr(lag, act, lag->pf_recipe, &lag->pf_rx_rule_id,
			       ICE_FLTR_RX, add);

Annotation

Implementation Notes