ice: Move common functions out of ice_main.c part 1/7
The functions that are used for PF VSI/netdev setup will also be used for SR-IOV support. To allow reuse of these functions, move these functions out of ice_main.c to ice_common.c/ice_lib.c This move is done across multiple patches. Each patch moves a few functions and may have minor adjustments. For example, a function that was previously static in ice_main.c will be made non-static temporarily in its new location to allow the driver to build cleanly. These adjustments will be removed in subsequent patches where more code is moved out of ice_main.c In this particular patch, the following functions were moved out of ice_main.c: int ice_add_mac_to_list ice_free_fltr_list ice_stat_update40 ice_stat_update32 ice_update_eth_stats ice_vsi_add_vlan ice_vsi_kill_vlan ice_vsi_manage_vlan_insertion ice_vsi_manage_vlan_stripping Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
3b6bf296c4
commit
45d3d428ea
@ -13,5 +13,6 @@ ice-y := ice_main.o \
|
||||
ice_nvm.o \
|
||||
ice_switch.o \
|
||||
ice_sched.o \
|
||||
ice_lib.o \
|
||||
ice_txrx.o \
|
||||
ice_ethtool.o
|
||||
|
@ -2652,3 +2652,64 @@ ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_id, u8 tc_bitmap,
|
||||
return ice_cfg_vsi_qs(pi, vsi_id, tc_bitmap, max_lanqs,
|
||||
ICE_SCHED_NODE_OWNER_LAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_stat_update40 - read 40 bit stat from the chip and update stat values
|
||||
* @hw: ptr to the hardware info
|
||||
* @hireg: high 32 bit HW register to read from
|
||||
* @loreg: low 32 bit HW register to read from
|
||||
* @prev_stat_loaded: bool to specify if previous stats are loaded
|
||||
* @prev_stat: ptr to previous loaded stat value
|
||||
* @cur_stat: ptr to current stat value
|
||||
*/
|
||||
void ice_stat_update40(struct ice_hw *hw, u32 hireg, u32 loreg,
|
||||
bool prev_stat_loaded, u64 *prev_stat, u64 *cur_stat)
|
||||
{
|
||||
u64 new_data;
|
||||
|
||||
new_data = rd32(hw, loreg);
|
||||
new_data |= ((u64)(rd32(hw, hireg) & 0xFFFF)) << 32;
|
||||
|
||||
/* device stats are not reset at PFR, they likely will not be zeroed
|
||||
* when the driver starts. So save the first values read and use them as
|
||||
* offsets to be subtracted from the raw values in order to report stats
|
||||
* that count from zero.
|
||||
*/
|
||||
if (!prev_stat_loaded)
|
||||
*prev_stat = new_data;
|
||||
if (new_data >= *prev_stat)
|
||||
*cur_stat = new_data - *prev_stat;
|
||||
else
|
||||
/* to manage the potential roll-over */
|
||||
*cur_stat = (new_data + BIT_ULL(40)) - *prev_stat;
|
||||
*cur_stat &= 0xFFFFFFFFFFULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_stat_update32 - read 32 bit stat from the chip and update stat values
|
||||
* @hw: ptr to the hardware info
|
||||
* @reg: HW register to read from
|
||||
* @prev_stat_loaded: bool to specify if previous stats are loaded
|
||||
* @prev_stat: ptr to previous loaded stat value
|
||||
* @cur_stat: ptr to current stat value
|
||||
*/
|
||||
void ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
|
||||
u64 *prev_stat, u64 *cur_stat)
|
||||
{
|
||||
u32 new_data;
|
||||
|
||||
new_data = rd32(hw, reg);
|
||||
|
||||
/* device stats are not reset at PFR, they likely will not be zeroed
|
||||
* when the driver starts. So save the first values read and use them as
|
||||
* offsets to be subtracted from the raw values in order to report stats
|
||||
* that count from zero.
|
||||
*/
|
||||
if (!prev_stat_loaded)
|
||||
*prev_stat = new_data;
|
||||
if (new_data >= *prev_stat)
|
||||
*cur_stat = new_data - *prev_stat;
|
||||
else
|
||||
/* to manage the potential roll-over */
|
||||
*cur_stat = (new_data + BIT_ULL(32)) - *prev_stat;
|
||||
}
|
||||
|
@ -96,4 +96,8 @@ ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_id, u8 tc, u8 num_qgrps,
|
||||
struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
|
||||
struct ice_sq_cd *cd);
|
||||
void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf);
|
||||
void ice_stat_update40(struct ice_hw *hw, u32 hireg, u32 loreg,
|
||||
bool prev_stat_loaded, u64 *prev_stat, u64 *cur_stat);
|
||||
void ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
|
||||
u64 *prev_stat, u64 *cur_stat);
|
||||
#endif /* _ICE_COMMON_H_ */
|
||||
|
258
drivers/net/ethernet/intel/ice/ice_lib.c
Normal file
258
drivers/net/ethernet/intel/ice/ice_lib.c
Normal file
@ -0,0 +1,258 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2018, Intel Corporation. */
|
||||
|
||||
#include "ice.h"
|
||||
#include "ice_lib.h"
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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_update_eth_stats - Update VSI-specific ethernet statistics counters
|
||||
* @vsi: the VSI to be updated
|
||||
*/
|
||||
void ice_update_eth_stats(struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_eth_stats *prev_es, *cur_es;
|
||||
struct ice_hw *hw = &vsi->back->hw;
|
||||
u16 vsi_num = vsi->vsi_num; /* HW absolute index of a VSI */
|
||||
|
||||
prev_es = &vsi->eth_stats_prev;
|
||||
cur_es = &vsi->eth_stats;
|
||||
|
||||
ice_stat_update40(hw, GLV_GORCH(vsi_num), GLV_GORCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_bytes,
|
||||
&cur_es->rx_bytes);
|
||||
|
||||
ice_stat_update40(hw, GLV_UPRCH(vsi_num), GLV_UPRCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_unicast,
|
||||
&cur_es->rx_unicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_MPRCH(vsi_num), GLV_MPRCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_multicast,
|
||||
&cur_es->rx_multicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_BPRCH(vsi_num), GLV_BPRCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_broadcast,
|
||||
&cur_es->rx_broadcast);
|
||||
|
||||
ice_stat_update32(hw, GLV_RDPC(vsi_num), vsi->stat_offsets_loaded,
|
||||
&prev_es->rx_discards, &cur_es->rx_discards);
|
||||
|
||||
ice_stat_update40(hw, GLV_GOTCH(vsi_num), GLV_GOTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_bytes,
|
||||
&cur_es->tx_bytes);
|
||||
|
||||
ice_stat_update40(hw, GLV_UPTCH(vsi_num), GLV_UPTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_unicast,
|
||||
&cur_es->tx_unicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_MPTCH(vsi_num), GLV_MPTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_multicast,
|
||||
&cur_es->tx_multicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_BPTCH(vsi_num), GLV_BPTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_broadcast,
|
||||
&cur_es->tx_broadcast);
|
||||
|
||||
ice_stat_update32(hw, GLV_TEPC(vsi_num), vsi->stat_offsets_loaded,
|
||||
&prev_es->tx_errors, &cur_es->tx_errors);
|
||||
|
||||
vsi->stat_offsets_loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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_vsi_add_vlan - Add VSI membership for given VLAN
|
||||
* @vsi: the VSI being configured
|
||||
* @vid: VLAN id to be added
|
||||
*/
|
||||
int ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid)
|
||||
{
|
||||
struct ice_fltr_list_entry *tmp;
|
||||
struct ice_pf *pf = vsi->back;
|
||||
LIST_HEAD(tmp_add_list);
|
||||
enum ice_status status;
|
||||
int err = 0;
|
||||
|
||||
tmp = devm_kzalloc(&pf->pdev->dev, sizeof(*tmp), GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
tmp->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
|
||||
tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
|
||||
tmp->fltr_info.flag = ICE_FLTR_TX;
|
||||
tmp->fltr_info.src = vsi->vsi_num;
|
||||
tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
|
||||
tmp->fltr_info.l_data.vlan.vlan_id = vid;
|
||||
|
||||
INIT_LIST_HEAD(&tmp->list_entry);
|
||||
list_add(&tmp->list_entry, &tmp_add_list);
|
||||
|
||||
status = ice_add_vlan(&pf->hw, &tmp_add_list);
|
||||
if (status) {
|
||||
err = -ENODEV;
|
||||
dev_err(&pf->pdev->dev, "Failure Adding VLAN %d on VSI %i\n",
|
||||
vid, vsi->vsi_num);
|
||||
}
|
||||
|
||||
ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_kill_vlan - Remove VSI membership for a given VLAN
|
||||
* @vsi: the VSI being configured
|
||||
* @vid: VLAN id to be removed
|
||||
*
|
||||
* Returns 0 on success and negative on failure
|
||||
*/
|
||||
int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
|
||||
{
|
||||
struct ice_fltr_list_entry *list;
|
||||
struct ice_pf *pf = vsi->back;
|
||||
LIST_HEAD(tmp_add_list);
|
||||
int status = 0;
|
||||
|
||||
list = devm_kzalloc(&pf->pdev->dev, sizeof(*list), GFP_KERNEL);
|
||||
if (!list)
|
||||
return -ENOMEM;
|
||||
|
||||
list->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
|
||||
list->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
|
||||
list->fltr_info.fltr_act = ICE_FWD_TO_VSI;
|
||||
list->fltr_info.l_data.vlan.vlan_id = vid;
|
||||
list->fltr_info.flag = ICE_FLTR_TX;
|
||||
list->fltr_info.src = vsi->vsi_num;
|
||||
|
||||
INIT_LIST_HEAD(&list->list_entry);
|
||||
list_add(&list->list_entry, &tmp_add_list);
|
||||
|
||||
if (ice_remove_vlan(&pf->hw, &tmp_add_list)) {
|
||||
dev_err(&pf->pdev->dev, "Error removing VLAN %d on vsi %i\n",
|
||||
vid, vsi->vsi_num);
|
||||
status = -EIO;
|
||||
}
|
||||
|
||||
ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx
|
||||
* @vsi: the VSI being changed
|
||||
*/
|
||||
int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
|
||||
{
|
||||
struct device *dev = &vsi->back->pdev->dev;
|
||||
struct ice_hw *hw = &vsi->back->hw;
|
||||
struct ice_vsi_ctx ctxt = { 0 };
|
||||
enum ice_status status;
|
||||
|
||||
/* Here we are configuring the VSI to let the driver add VLAN tags by
|
||||
* setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
|
||||
* insertion happens in the Tx hot path, in ice_tx_map.
|
||||
*/
|
||||
ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
|
||||
|
||||
ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
|
||||
ctxt.vsi_num = vsi->vsi_num;
|
||||
|
||||
status = ice_aq_update_vsi(hw, &ctxt, NULL);
|
||||
if (status) {
|
||||
dev_err(dev, "update VSI for VLAN insert failed, err %d aq_err %d\n",
|
||||
status, hw->adminq.sq_last_status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
vsi->info.vlan_flags = ctxt.info.vlan_flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_manage_vlan_stripping - Manage VLAN stripping for the VSI for Rx
|
||||
* @vsi: the VSI being changed
|
||||
* @ena: boolean value indicating if this is a enable or disable request
|
||||
*/
|
||||
int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
|
||||
{
|
||||
struct device *dev = &vsi->back->pdev->dev;
|
||||
struct ice_hw *hw = &vsi->back->hw;
|
||||
struct ice_vsi_ctx ctxt = { 0 };
|
||||
enum ice_status status;
|
||||
|
||||
/* Here we are configuring what the VSI should do with the VLAN tag in
|
||||
* the Rx packet. We can either leave the tag in the packet or put it in
|
||||
* the Rx descriptor.
|
||||
*/
|
||||
if (ena) {
|
||||
/* Strip VLAN tag from Rx packet and put it in the desc */
|
||||
ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
|
||||
} else {
|
||||
/* Disable stripping. Leave tag in packet */
|
||||
ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
|
||||
}
|
||||
|
||||
/* Allow all packets untagged/tagged */
|
||||
ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
|
||||
|
||||
ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
|
||||
ctxt.vsi_num = vsi->vsi_num;
|
||||
|
||||
status = ice_aq_update_vsi(hw, &ctxt, NULL);
|
||||
if (status) {
|
||||
dev_err(dev, "update VSI for VLAN strip failed, ena = %d err %d aq_err %d\n",
|
||||
ena, status, hw->adminq.sq_last_status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
vsi->info.vlan_flags = ctxt.info.vlan_flags;
|
||||
return 0;
|
||||
}
|
23
drivers/net/ethernet/intel/ice/ice_lib.h
Normal file
23
drivers/net/ethernet/intel/ice/ice_lib.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2018, Intel Corporation. */
|
||||
|
||||
#ifndef _ICE_LIB_H_
|
||||
#define _ICE_LIB_H_
|
||||
|
||||
#include "ice.h"
|
||||
|
||||
int ice_add_mac_to_list(struct ice_vsi *vsi, struct list_head *add_list,
|
||||
const u8 *macaddr);
|
||||
|
||||
void ice_free_fltr_list(struct device *dev, struct list_head *h);
|
||||
|
||||
void ice_update_eth_stats(struct ice_vsi *vsi);
|
||||
|
||||
int ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid);
|
||||
|
||||
int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid);
|
||||
|
||||
int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi);
|
||||
|
||||
int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena);
|
||||
#endif /* !_ICE_LIB_H_ */
|
@ -6,6 +6,7 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include "ice.h"
|
||||
#include "ice_lib.h"
|
||||
|
||||
#define DRV_VERSION "0.7.1-k"
|
||||
#define DRV_SUMMARY "Intel(R) Ethernet Connection E800 Series Linux Driver"
|
||||
@ -243,39 +244,6 @@ static int ice_free_res(struct ice_res_tracker *res, u16 index, u16 id)
|
||||
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_add_mac_to_sync_list - creates list of mac addresses to be synced
|
||||
* @netdev: the net device on which the sync is happening
|
||||
@ -318,24 +286,6 @@ static int ice_add_mac_to_unsync_list(struct net_device *netdev, const u8 *addr)
|
||||
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_vsi_fltr_changed - check if filter state changed
|
||||
* @vsi: VSI to be checked
|
||||
@ -3148,44 +3098,6 @@ ice_pf_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi)
|
||||
return ice_vsi_setup(pf, pi, ICE_VSI_PF, ICE_INVAL_VFID);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_add_vlan - Add vsi membership for given vlan
|
||||
* @vsi: the vsi being configured
|
||||
* @vid: vlan id to be added
|
||||
*/
|
||||
static int ice_vsi_add_vlan(struct ice_vsi *vsi, u16 vid)
|
||||
{
|
||||
struct ice_fltr_list_entry *tmp;
|
||||
struct ice_pf *pf = vsi->back;
|
||||
LIST_HEAD(tmp_add_list);
|
||||
enum ice_status status;
|
||||
int err = 0;
|
||||
|
||||
tmp = devm_kzalloc(&pf->pdev->dev, sizeof(*tmp), GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
tmp->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
|
||||
tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
|
||||
tmp->fltr_info.flag = ICE_FLTR_TX;
|
||||
tmp->fltr_info.src = vsi->vsi_num;
|
||||
tmp->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
|
||||
tmp->fltr_info.l_data.vlan.vlan_id = vid;
|
||||
|
||||
INIT_LIST_HEAD(&tmp->list_entry);
|
||||
list_add(&tmp->list_entry, &tmp_add_list);
|
||||
|
||||
status = ice_add_vlan(&pf->hw, &tmp_add_list);
|
||||
if (status) {
|
||||
err = -ENODEV;
|
||||
dev_err(&pf->pdev->dev, "Failure Adding VLAN %d on VSI %i\n",
|
||||
vid, vsi->vsi_num);
|
||||
}
|
||||
|
||||
ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vlan_rx_add_vid - Add a vlan id filter to HW offload
|
||||
* @netdev: network interface to be adjusted
|
||||
@ -3229,44 +3141,6 @@ static int ice_vlan_rx_add_vid(struct net_device *netdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_kill_vlan - Remove VSI membership for a given VLAN
|
||||
* @vsi: the VSI being configured
|
||||
* @vid: VLAN id to be removed
|
||||
*
|
||||
* Returns 0 on success and negative on failure
|
||||
*/
|
||||
static int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
|
||||
{
|
||||
struct ice_fltr_list_entry *list;
|
||||
struct ice_pf *pf = vsi->back;
|
||||
LIST_HEAD(tmp_add_list);
|
||||
int status = 0;
|
||||
|
||||
list = devm_kzalloc(&pf->pdev->dev, sizeof(*list), GFP_KERNEL);
|
||||
if (!list)
|
||||
return -ENOMEM;
|
||||
|
||||
list->fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
|
||||
list->fltr_info.fwd_id.vsi_id = vsi->vsi_num;
|
||||
list->fltr_info.fltr_act = ICE_FWD_TO_VSI;
|
||||
list->fltr_info.l_data.vlan.vlan_id = vid;
|
||||
list->fltr_info.flag = ICE_FLTR_TX;
|
||||
list->fltr_info.src = vsi->vsi_num;
|
||||
|
||||
INIT_LIST_HEAD(&list->list_entry);
|
||||
list_add(&list->list_entry, &tmp_add_list);
|
||||
|
||||
if (ice_remove_vlan(&pf->hw, &tmp_add_list)) {
|
||||
dev_err(&pf->pdev->dev, "Error removing VLAN %d on vsi %i\n",
|
||||
vid, vsi->vsi_num);
|
||||
status = -EIO;
|
||||
}
|
||||
|
||||
ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vlan_rx_kill_vid - Remove a vlan id filter from HW offload
|
||||
* @netdev: network interface to be adjusted
|
||||
@ -4023,78 +3897,6 @@ static int ice_fdb_del(struct ndmsg *ndm, __always_unused struct nlattr *tb[],
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_manage_vlan_insertion - Manage VLAN insertion for the VSI for Tx
|
||||
* @vsi: the vsi being changed
|
||||
*/
|
||||
static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi)
|
||||
{
|
||||
struct device *dev = &vsi->back->pdev->dev;
|
||||
struct ice_hw *hw = &vsi->back->hw;
|
||||
struct ice_vsi_ctx ctxt = { 0 };
|
||||
enum ice_status status;
|
||||
|
||||
/* Here we are configuring the VSI to let the driver add VLAN tags by
|
||||
* setting vlan_flags to ICE_AQ_VSI_VLAN_MODE_ALL. The actual VLAN tag
|
||||
* insertion happens in the Tx hot path, in ice_tx_map.
|
||||
*/
|
||||
ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_MODE_ALL;
|
||||
|
||||
ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
|
||||
ctxt.vsi_num = vsi->vsi_num;
|
||||
|
||||
status = ice_aq_update_vsi(hw, &ctxt, NULL);
|
||||
if (status) {
|
||||
dev_err(dev, "update VSI for VLAN insert failed, err %d aq_err %d\n",
|
||||
status, hw->adminq.sq_last_status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
vsi->info.vlan_flags = ctxt.info.vlan_flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_vsi_manage_vlan_stripping - Manage VLAN stripping for the VSI for Rx
|
||||
* @vsi: the vsi being changed
|
||||
* @ena: boolean value indicating if this is a enable or disable request
|
||||
*/
|
||||
static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena)
|
||||
{
|
||||
struct device *dev = &vsi->back->pdev->dev;
|
||||
struct ice_hw *hw = &vsi->back->hw;
|
||||
struct ice_vsi_ctx ctxt = { 0 };
|
||||
enum ice_status status;
|
||||
|
||||
/* Here we are configuring what the VSI should do with the VLAN tag in
|
||||
* the Rx packet. We can either leave the tag in the packet or put it in
|
||||
* the Rx descriptor.
|
||||
*/
|
||||
if (ena) {
|
||||
/* Strip VLAN tag from Rx packet and put it in the desc */
|
||||
ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_STR_BOTH;
|
||||
} else {
|
||||
/* Disable stripping. Leave tag in packet */
|
||||
ctxt.info.vlan_flags = ICE_AQ_VSI_VLAN_EMOD_NOTHING;
|
||||
}
|
||||
|
||||
/* Allow all packets untagged/tagged */
|
||||
ctxt.info.vlan_flags |= ICE_AQ_VSI_VLAN_MODE_ALL;
|
||||
|
||||
ctxt.info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID);
|
||||
ctxt.vsi_num = vsi->vsi_num;
|
||||
|
||||
status = ice_aq_update_vsi(hw, &ctxt, NULL);
|
||||
if (status) {
|
||||
dev_err(dev, "update VSI for VALN strip failed, ena = %d err %d aq_err %d\n",
|
||||
ena, status, hw->adminq.sq_last_status);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
vsi->info.vlan_flags = ctxt.info.vlan_flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_set_features - set the netdev feature flags
|
||||
* @netdev: ptr to the netdev being adjusted
|
||||
@ -4727,122 +4529,6 @@ static void ice_fetch_u64_stats_per_ring(struct ice_ring *ring, u64 *pkts,
|
||||
} while (u64_stats_fetch_retry_irq(&ring->syncp, start));
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_stat_update40 - read 40 bit stat from the chip and update stat values
|
||||
* @hw: ptr to the hardware info
|
||||
* @hireg: high 32 bit HW register to read from
|
||||
* @loreg: low 32 bit HW register to read from
|
||||
* @prev_stat_loaded: bool to specify if previous stats are loaded
|
||||
* @prev_stat: ptr to previous loaded stat value
|
||||
* @cur_stat: ptr to current stat value
|
||||
*/
|
||||
static void ice_stat_update40(struct ice_hw *hw, u32 hireg, u32 loreg,
|
||||
bool prev_stat_loaded, u64 *prev_stat,
|
||||
u64 *cur_stat)
|
||||
{
|
||||
u64 new_data;
|
||||
|
||||
new_data = rd32(hw, loreg);
|
||||
new_data |= ((u64)(rd32(hw, hireg) & 0xFFFF)) << 32;
|
||||
|
||||
/* device stats are not reset at PFR, they likely will not be zeroed
|
||||
* when the driver starts. So save the first values read and use them as
|
||||
* offsets to be subtracted from the raw values in order to report stats
|
||||
* that count from zero.
|
||||
*/
|
||||
if (!prev_stat_loaded)
|
||||
*prev_stat = new_data;
|
||||
if (likely(new_data >= *prev_stat))
|
||||
*cur_stat = new_data - *prev_stat;
|
||||
else
|
||||
/* to manage the potential roll-over */
|
||||
*cur_stat = (new_data + BIT_ULL(40)) - *prev_stat;
|
||||
*cur_stat &= 0xFFFFFFFFFFULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_stat_update32 - read 32 bit stat from the chip and update stat values
|
||||
* @hw: ptr to the hardware info
|
||||
* @reg: HW register to read from
|
||||
* @prev_stat_loaded: bool to specify if previous stats are loaded
|
||||
* @prev_stat: ptr to previous loaded stat value
|
||||
* @cur_stat: ptr to current stat value
|
||||
*/
|
||||
static void ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
|
||||
u64 *prev_stat, u64 *cur_stat)
|
||||
{
|
||||
u32 new_data;
|
||||
|
||||
new_data = rd32(hw, reg);
|
||||
|
||||
/* device stats are not reset at PFR, they likely will not be zeroed
|
||||
* when the driver starts. So save the first values read and use them as
|
||||
* offsets to be subtracted from the raw values in order to report stats
|
||||
* that count from zero.
|
||||
*/
|
||||
if (!prev_stat_loaded)
|
||||
*prev_stat = new_data;
|
||||
if (likely(new_data >= *prev_stat))
|
||||
*cur_stat = new_data - *prev_stat;
|
||||
else
|
||||
/* to manage the potential roll-over */
|
||||
*cur_stat = (new_data + BIT_ULL(32)) - *prev_stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_update_eth_stats - Update VSI-specific ethernet statistics counters
|
||||
* @vsi: the VSI to be updated
|
||||
*/
|
||||
static void ice_update_eth_stats(struct ice_vsi *vsi)
|
||||
{
|
||||
struct ice_eth_stats *prev_es, *cur_es;
|
||||
struct ice_hw *hw = &vsi->back->hw;
|
||||
u16 vsi_num = vsi->vsi_num; /* HW absolute index of a VSI */
|
||||
|
||||
prev_es = &vsi->eth_stats_prev;
|
||||
cur_es = &vsi->eth_stats;
|
||||
|
||||
ice_stat_update40(hw, GLV_GORCH(vsi_num), GLV_GORCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_bytes,
|
||||
&cur_es->rx_bytes);
|
||||
|
||||
ice_stat_update40(hw, GLV_UPRCH(vsi_num), GLV_UPRCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_unicast,
|
||||
&cur_es->rx_unicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_MPRCH(vsi_num), GLV_MPRCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_multicast,
|
||||
&cur_es->rx_multicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_BPRCH(vsi_num), GLV_BPRCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->rx_broadcast,
|
||||
&cur_es->rx_broadcast);
|
||||
|
||||
ice_stat_update32(hw, GLV_RDPC(vsi_num), vsi->stat_offsets_loaded,
|
||||
&prev_es->rx_discards, &cur_es->rx_discards);
|
||||
|
||||
ice_stat_update40(hw, GLV_GOTCH(vsi_num), GLV_GOTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_bytes,
|
||||
&cur_es->tx_bytes);
|
||||
|
||||
ice_stat_update40(hw, GLV_UPTCH(vsi_num), GLV_UPTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_unicast,
|
||||
&cur_es->tx_unicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_MPTCH(vsi_num), GLV_MPTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_multicast,
|
||||
&cur_es->tx_multicast);
|
||||
|
||||
ice_stat_update40(hw, GLV_BPTCH(vsi_num), GLV_BPTCL(vsi_num),
|
||||
vsi->stat_offsets_loaded, &prev_es->tx_broadcast,
|
||||
&cur_es->tx_broadcast);
|
||||
|
||||
ice_stat_update32(hw, GLV_TEPC(vsi_num), vsi->stat_offsets_loaded,
|
||||
&prev_es->tx_errors, &cur_es->tx_errors);
|
||||
|
||||
vsi->stat_offsets_loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_update_vsi_ring_stats - Update VSI stats counters
|
||||
* @vsi: the VSI to be updated
|
||||
|
Loading…
Reference in New Issue
Block a user