cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ice_fltr.c (12696B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (C) 2018-2020, Intel Corporation. */
      3
      4#include "ice.h"
      5#include "ice_fltr.h"
      6
      7/**
      8 * ice_fltr_free_list - free filter lists helper
      9 * @dev: pointer to the device struct
     10 * @h: pointer to the list head to be freed
     11 *
     12 * Helper function to free filter lists previously created using
     13 * ice_fltr_add_mac_to_list
     14 */
     15void ice_fltr_free_list(struct device *dev, struct list_head *h)
     16{
     17	struct ice_fltr_list_entry *e, *tmp;
     18
     19	list_for_each_entry_safe(e, tmp, h, list_entry) {
     20		list_del(&e->list_entry);
     21		devm_kfree(dev, e);
     22	}
     23}
     24
     25/**
     26 * ice_fltr_add_entry_to_list - allocate and add filter entry to list
     27 * @dev: pointer to device needed by alloc function
     28 * @info: filter info struct that gets added to the passed in list
     29 * @list: pointer to the list which contains MAC filters entry
     30 */
     31static int
     32ice_fltr_add_entry_to_list(struct device *dev, struct ice_fltr_info *info,
     33			   struct list_head *list)
     34{
     35	struct ice_fltr_list_entry *entry;
     36
     37	entry = devm_kzalloc(dev, sizeof(*entry), GFP_ATOMIC);
     38	if (!entry)
     39		return -ENOMEM;
     40
     41	entry->fltr_info = *info;
     42
     43	INIT_LIST_HEAD(&entry->list_entry);
     44	list_add(&entry->list_entry, list);
     45
     46	return 0;
     47}
     48
     49/**
     50 * ice_fltr_set_vlan_vsi_promisc
     51 * @hw: pointer to the hardware structure
     52 * @vsi: the VSI being configured
     53 * @promisc_mask: mask of promiscuous config bits
     54 *
     55 * Set VSI with all associated VLANs to given promiscuous mode(s)
     56 */
     57int
     58ice_fltr_set_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
     59			      u8 promisc_mask)
     60{
     61	struct ice_pf *pf = hw->back;
     62	int result;
     63
     64	result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, false);
     65	if (result)
     66		dev_err(ice_pf_to_dev(pf),
     67			"Error setting promisc mode on VSI %i (rc=%d)\n",
     68			vsi->vsi_num, result);
     69
     70	return result;
     71}
     72
     73/**
     74 * ice_fltr_clear_vlan_vsi_promisc
     75 * @hw: pointer to the hardware structure
     76 * @vsi: the VSI being configured
     77 * @promisc_mask: mask of promiscuous config bits
     78 *
     79 * Clear VSI with all associated VLANs to given promiscuous mode(s)
     80 */
     81int
     82ice_fltr_clear_vlan_vsi_promisc(struct ice_hw *hw, struct ice_vsi *vsi,
     83				u8 promisc_mask)
     84{
     85	struct ice_pf *pf = hw->back;
     86	int result;
     87
     88	result = ice_set_vlan_vsi_promisc(hw, vsi->idx, promisc_mask, true);
     89	if (result)
     90		dev_err(ice_pf_to_dev(pf),
     91			"Error clearing promisc mode on VSI %i (rc=%d)\n",
     92			vsi->vsi_num, result);
     93
     94	return result;
     95}
     96
     97/**
     98 * ice_fltr_clear_vsi_promisc - clear specified promiscuous mode(s)
     99 * @hw: pointer to the hardware structure
    100 * @vsi_handle: VSI handle to clear mode
    101 * @promisc_mask: mask of promiscuous config bits to clear
    102 * @vid: VLAN ID to clear VLAN promiscuous
    103 */
    104int
    105ice_fltr_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
    106			   u16 vid)
    107{
    108	struct ice_pf *pf = hw->back;
    109	int result;
    110
    111	result = ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
    112	if (result)
    113		dev_err(ice_pf_to_dev(pf),
    114			"Error clearing promisc mode on VSI %i for VID %u (rc=%d)\n",
    115			ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
    116
    117	return result;
    118}
    119
    120/**
    121 * ice_fltr_set_vsi_promisc - set given VSI to given promiscuous mode(s)
    122 * @hw: pointer to the hardware structure
    123 * @vsi_handle: VSI handle to configure
    124 * @promisc_mask: mask of promiscuous config bits
    125 * @vid: VLAN ID to set VLAN promiscuous
    126 */
    127int
    128ice_fltr_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
    129			 u16 vid)
    130{
    131	struct ice_pf *pf = hw->back;
    132	int result;
    133
    134	result = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid);
    135	if (result)
    136		dev_err(ice_pf_to_dev(pf),
    137			"Error setting promisc mode on VSI %i for VID %u (rc=%d)\n",
    138			ice_get_hw_vsi_num(hw, vsi_handle), vid, result);
    139
    140	return result;
    141}
    142
    143/**
    144 * ice_fltr_add_mac_list - add list of MAC filters
    145 * @vsi: pointer to VSI struct
    146 * @list: list of filters
    147 */
    148int ice_fltr_add_mac_list(struct ice_vsi *vsi, struct list_head *list)
    149{
    150	return ice_add_mac(&vsi->back->hw, list);
    151}
    152
    153/**
    154 * ice_fltr_remove_mac_list - remove list of MAC filters
    155 * @vsi: pointer to VSI struct
    156 * @list: list of filters
    157 */
    158int ice_fltr_remove_mac_list(struct ice_vsi *vsi, struct list_head *list)
    159{
    160	return ice_remove_mac(&vsi->back->hw, list);
    161}
    162
    163/**
    164 * ice_fltr_add_vlan_list - add list of VLAN filters
    165 * @vsi: pointer to VSI struct
    166 * @list: list of filters
    167 */
    168static int ice_fltr_add_vlan_list(struct ice_vsi *vsi, struct list_head *list)
    169{
    170	return ice_add_vlan(&vsi->back->hw, list);
    171}
    172
    173/**
    174 * ice_fltr_remove_vlan_list - remove list of VLAN filters
    175 * @vsi: pointer to VSI struct
    176 * @list: list of filters
    177 */
    178static int
    179ice_fltr_remove_vlan_list(struct ice_vsi *vsi, struct list_head *list)
    180{
    181	return ice_remove_vlan(&vsi->back->hw, list);
    182}
    183
    184/**
    185 * ice_fltr_add_eth_list - add list of ethertype filters
    186 * @vsi: pointer to VSI struct
    187 * @list: list of filters
    188 */
    189static int ice_fltr_add_eth_list(struct ice_vsi *vsi, struct list_head *list)
    190{
    191	return ice_add_eth_mac(&vsi->back->hw, list);
    192}
    193
    194/**
    195 * ice_fltr_remove_eth_list - remove list of ethertype filters
    196 * @vsi: pointer to VSI struct
    197 * @list: list of filters
    198 */
    199static int ice_fltr_remove_eth_list(struct ice_vsi *vsi, struct list_head *list)
    200{
    201	return ice_remove_eth_mac(&vsi->back->hw, list);
    202}
    203
    204/**
    205 * ice_fltr_remove_all - remove all filters associated with VSI
    206 * @vsi: pointer to VSI struct
    207 */
    208void ice_fltr_remove_all(struct ice_vsi *vsi)
    209{
    210	ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);
    211}
    212
    213/**
    214 * ice_fltr_add_mac_to_list - add MAC filter info to exsisting list
    215 * @vsi: pointer to VSI struct
    216 * @list: list to add filter info to
    217 * @mac: MAC address to add
    218 * @action: filter action
    219 */
    220int
    221ice_fltr_add_mac_to_list(struct ice_vsi *vsi, struct list_head *list,
    222			 const u8 *mac, enum ice_sw_fwd_act_type action)
    223{
    224	struct ice_fltr_info info = { 0 };
    225
    226	info.flag = ICE_FLTR_TX;
    227	info.src_id = ICE_SRC_ID_VSI;
    228	info.lkup_type = ICE_SW_LKUP_MAC;
    229	info.fltr_act = action;
    230	info.vsi_handle = vsi->idx;
    231
    232	ether_addr_copy(info.l_data.mac.mac_addr, mac);
    233
    234	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
    235					  list);
    236}
    237
    238/**
    239 * ice_fltr_add_vlan_to_list - add VLAN filter info to exsisting list
    240 * @vsi: pointer to VSI struct
    241 * @list: list to add filter info to
    242 * @vlan: VLAN filter details
    243 */
    244static int
    245ice_fltr_add_vlan_to_list(struct ice_vsi *vsi, struct list_head *list,
    246			  struct ice_vlan *vlan)
    247{
    248	struct ice_fltr_info info = { 0 };
    249
    250	info.flag = ICE_FLTR_TX;
    251	info.src_id = ICE_SRC_ID_VSI;
    252	info.lkup_type = ICE_SW_LKUP_VLAN;
    253	info.fltr_act = ICE_FWD_TO_VSI;
    254	info.vsi_handle = vsi->idx;
    255	info.l_data.vlan.vlan_id = vlan->vid;
    256	info.l_data.vlan.tpid = vlan->tpid;
    257	info.l_data.vlan.tpid_valid = true;
    258
    259	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
    260					  list);
    261}
    262
    263/**
    264 * ice_fltr_add_eth_to_list - add ethertype filter info to exsisting list
    265 * @vsi: pointer to VSI struct
    266 * @list: list to add filter info to
    267 * @ethertype: ethertype of packet that matches filter
    268 * @flag: filter direction, Tx or Rx
    269 * @action: filter action
    270 */
    271static int
    272ice_fltr_add_eth_to_list(struct ice_vsi *vsi, struct list_head *list,
    273			 u16 ethertype, u16 flag,
    274			 enum ice_sw_fwd_act_type action)
    275{
    276	struct ice_fltr_info info = { 0 };
    277
    278	info.flag = flag;
    279	info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
    280	info.fltr_act = action;
    281	info.vsi_handle = vsi->idx;
    282	info.l_data.ethertype_mac.ethertype = ethertype;
    283
    284	if (flag == ICE_FLTR_TX)
    285		info.src_id = ICE_SRC_ID_VSI;
    286	else
    287		info.src_id = ICE_SRC_ID_LPORT;
    288
    289	return ice_fltr_add_entry_to_list(ice_pf_to_dev(vsi->back), &info,
    290					  list);
    291}
    292
    293/**
    294 * ice_fltr_prepare_mac - add or remove MAC rule
    295 * @vsi: pointer to VSI struct
    296 * @mac: MAC address to add
    297 * @action: action to be performed on filter match
    298 * @mac_action: pointer to add or remove MAC function
    299 */
    300static int
    301ice_fltr_prepare_mac(struct ice_vsi *vsi, const u8 *mac,
    302		     enum ice_sw_fwd_act_type action,
    303		     int (*mac_action)(struct ice_vsi *, struct list_head *))
    304{
    305	LIST_HEAD(tmp_list);
    306	int result;
    307
    308	if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action)) {
    309		ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
    310		return -ENOMEM;
    311	}
    312
    313	result = mac_action(vsi, &tmp_list);
    314	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
    315	return result;
    316}
    317
    318/**
    319 * ice_fltr_prepare_mac_and_broadcast - add or remove MAC and broadcast filter
    320 * @vsi: pointer to VSI struct
    321 * @mac: MAC address to add
    322 * @action: action to be performed on filter match
    323 * @mac_action: pointer to add or remove MAC function
    324 */
    325static int
    326ice_fltr_prepare_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
    327				   enum ice_sw_fwd_act_type action,
    328				   int(*mac_action)
    329				   (struct ice_vsi *, struct list_head *))
    330{
    331	u8 broadcast[ETH_ALEN];
    332	LIST_HEAD(tmp_list);
    333	int result;
    334
    335	eth_broadcast_addr(broadcast);
    336	if (ice_fltr_add_mac_to_list(vsi, &tmp_list, mac, action) ||
    337	    ice_fltr_add_mac_to_list(vsi, &tmp_list, broadcast, action)) {
    338		ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
    339		return -ENOMEM;
    340	}
    341
    342	result = mac_action(vsi, &tmp_list);
    343	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
    344	return result;
    345}
    346
    347/**
    348 * ice_fltr_prepare_vlan - add or remove VLAN filter
    349 * @vsi: pointer to VSI struct
    350 * @vlan: VLAN filter details
    351 * @vlan_action: pointer to add or remove VLAN function
    352 */
    353static int
    354ice_fltr_prepare_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan,
    355		      int (*vlan_action)(struct ice_vsi *, struct list_head *))
    356{
    357	LIST_HEAD(tmp_list);
    358	int result;
    359
    360	if (ice_fltr_add_vlan_to_list(vsi, &tmp_list, vlan))
    361		return -ENOMEM;
    362
    363	result = vlan_action(vsi, &tmp_list);
    364	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
    365	return result;
    366}
    367
    368/**
    369 * ice_fltr_prepare_eth - add or remove ethertype filter
    370 * @vsi: pointer to VSI struct
    371 * @ethertype: ethertype of packet to be filtered
    372 * @flag: direction of packet, Tx or Rx
    373 * @action: action to be performed on filter match
    374 * @eth_action: pointer to add or remove ethertype function
    375 */
    376static int
    377ice_fltr_prepare_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
    378		     enum ice_sw_fwd_act_type action,
    379		     int (*eth_action)(struct ice_vsi *, struct list_head *))
    380{
    381	LIST_HEAD(tmp_list);
    382	int result;
    383
    384	if (ice_fltr_add_eth_to_list(vsi, &tmp_list, ethertype, flag, action))
    385		return -ENOMEM;
    386
    387	result = eth_action(vsi, &tmp_list);
    388	ice_fltr_free_list(ice_pf_to_dev(vsi->back), &tmp_list);
    389	return result;
    390}
    391
    392/**
    393 * ice_fltr_add_mac - add single MAC filter
    394 * @vsi: pointer to VSI struct
    395 * @mac: MAC to add
    396 * @action: action to be performed on filter match
    397 */
    398int ice_fltr_add_mac(struct ice_vsi *vsi, const u8 *mac,
    399		     enum ice_sw_fwd_act_type action)
    400{
    401	return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_add_mac_list);
    402}
    403
    404/**
    405 * ice_fltr_add_mac_and_broadcast - add single MAC and broadcast
    406 * @vsi: pointer to VSI struct
    407 * @mac: MAC to add
    408 * @action: action to be performed on filter match
    409 */
    410int
    411ice_fltr_add_mac_and_broadcast(struct ice_vsi *vsi, const u8 *mac,
    412			       enum ice_sw_fwd_act_type action)
    413{
    414	return ice_fltr_prepare_mac_and_broadcast(vsi, mac, action,
    415						  ice_fltr_add_mac_list);
    416}
    417
    418/**
    419 * ice_fltr_remove_mac - remove MAC filter
    420 * @vsi: pointer to VSI struct
    421 * @mac: filter MAC to remove
    422 * @action: action to remove
    423 */
    424int ice_fltr_remove_mac(struct ice_vsi *vsi, const u8 *mac,
    425			enum ice_sw_fwd_act_type action)
    426{
    427	return ice_fltr_prepare_mac(vsi, mac, action, ice_fltr_remove_mac_list);
    428}
    429
    430/**
    431 * ice_fltr_add_vlan - add single VLAN filter
    432 * @vsi: pointer to VSI struct
    433 * @vlan: VLAN filter details
    434 */
    435int ice_fltr_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
    436{
    437	return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_add_vlan_list);
    438}
    439
    440/**
    441 * ice_fltr_remove_vlan - remove VLAN filter
    442 * @vsi: pointer to VSI struct
    443 * @vlan: VLAN filter details
    444 */
    445int ice_fltr_remove_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
    446{
    447	return ice_fltr_prepare_vlan(vsi, vlan, ice_fltr_remove_vlan_list);
    448}
    449
    450/**
    451 * ice_fltr_add_eth - add specyfic ethertype filter
    452 * @vsi: pointer to VSI struct
    453 * @ethertype: ethertype of filter
    454 * @flag: direction of packet to be filtered, Tx or Rx
    455 * @action: action to be performed on filter match
    456 */
    457int ice_fltr_add_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
    458		     enum ice_sw_fwd_act_type action)
    459{
    460	return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
    461				    ice_fltr_add_eth_list);
    462}
    463
    464/**
    465 * ice_fltr_remove_eth - remove ethertype filter
    466 * @vsi: pointer to VSI struct
    467 * @ethertype: ethertype of filter
    468 * @flag: direction of filter
    469 * @action: action to remove
    470 */
    471int ice_fltr_remove_eth(struct ice_vsi *vsi, u16 ethertype, u16 flag,
    472			enum ice_sw_fwd_act_type action)
    473{
    474	return ice_fltr_prepare_eth(vsi, ethertype, flag, action,
    475				    ice_fltr_remove_eth_list);
    476}