mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
Merge branch 'net-enetc-cleanups-and-improvements'
Wei Fang says: ==================== net: enetc: cleanups and improvements The first group of patches (1, 2, 5-7) eliminates code duplication between the ENETC v1 and v4 drivers. Since both hardware generations share identical register layouts for MAC promiscuous mode, MAC hash filters, and VLAN promiscuous mode - differing only in register address offsets - common helper functions are extracted into enetc_pf_common.c and shared by both drivers. Patch 3 converts ndo_set_rx_mode() to ndo_set_rx_mode_async(), removing the dedicated workqueue that was previously needed to defer MAC address list updates to a sleepable context. Patch 4 replaces counter-based MAFT entry tracking with a bitmap, which keeps hardware and software state in sync and avoids partial failures during entry allocation. Patches 8 and 9 fix phylink-related issues: removing invalid code from enetc4_pl_mac_link_up() and properly differentiating phylink capabilities between pseudo-MAC and standalone MAC. The remaining patches (10-14) are minor cleanups: removing a redundant VLAN promiscuous mode initialization in probe, using the PCI device name for the debugfs directory, simplifying port speed configuration, removing a redundant num_vsi field, using alloc_etherdev_mqs() for the VF driver, and using kzalloc_flex() for a flexible array allocation. ==================== Link: https://patch.msgid.link/20260720014317.1059359-1-wei.fang@oss.nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
6a11e81062
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
|
||||
/* Copyright 2017-2019 NXP */
|
||||
/* Copyright 2017-2019, 2025-2026 NXP */
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/pci.h>
|
||||
|
|
@ -324,8 +324,6 @@ struct enetc_si {
|
|||
const struct enetc_drvdata *drvdata;
|
||||
const struct enetc_si_ops *ops;
|
||||
|
||||
struct workqueue_struct *workqueue;
|
||||
struct work_struct rx_mode_task;
|
||||
struct dentry *debugfs_root;
|
||||
struct enetc_msg_swbd msg; /* Only valid for VSI */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,15 +28,14 @@ static void enetc_show_si_mac_hash_filter(struct seq_file *s, int i)
|
|||
|
||||
static int enetc_mac_filter_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct enetc_si *si = s->private;
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
struct enetc_pf *pf = enetc_si_priv(s->private);
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
int num_si = pf->total_vfs + 1;
|
||||
struct maft_entry_data maft;
|
||||
struct enetc_pf *pf;
|
||||
int i, err, num_si;
|
||||
u32 val;
|
||||
|
||||
pf = enetc_si_priv(si);
|
||||
num_si = pf->caps.num_vsi + 1;
|
||||
struct ntmp_user *user;
|
||||
u32 val, entry_id;
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
val = enetc_port_rd(hw, ENETC4_PSIPMMR);
|
||||
for (i = 0; i < num_si; i++) {
|
||||
|
|
@ -50,31 +49,38 @@ static int enetc_mac_filter_show(struct seq_file *s, void *data)
|
|||
for (i = 0; i < num_si; i++)
|
||||
enetc_show_si_mac_hash_filter(s, i);
|
||||
|
||||
if (!pf->num_mfe)
|
||||
return 0;
|
||||
user = &pf->si->ntmp_user;
|
||||
rtnl_lock();
|
||||
|
||||
if (bitmap_empty(user->maft_eid_bitmap, user->maft_num_entries))
|
||||
goto unlock_rtnl;
|
||||
|
||||
/* MAC address filter table */
|
||||
seq_puts(s, "MAC address filter table\n");
|
||||
for (i = 0; i < pf->num_mfe; i++) {
|
||||
for_each_set_bit(entry_id, user->maft_eid_bitmap,
|
||||
user->maft_num_entries) {
|
||||
memset(&maft, 0, sizeof(maft));
|
||||
err = ntmp_maft_query_entry(&si->ntmp_user, i, &maft);
|
||||
err = ntmp_maft_query_entry(user, entry_id, &maft);
|
||||
if (err)
|
||||
return err;
|
||||
goto unlock_rtnl;
|
||||
|
||||
seq_printf(s, "Entry %d, MAC: %pM, SI bitmap: 0x%04x\n", i,
|
||||
maft.keye.mac_addr, le16_to_cpu(maft.cfge.si_bitmap));
|
||||
seq_printf(s, "Entry %d, MAC: %pM, SI bitmap: 0x%04x\n",
|
||||
entry_id, maft.keye.mac_addr,
|
||||
le16_to_cpu(maft.cfge.si_bitmap));
|
||||
}
|
||||
|
||||
return 0;
|
||||
unlock_rtnl:
|
||||
rtnl_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(enetc_mac_filter);
|
||||
|
||||
void enetc_create_debugfs(struct enetc_si *si)
|
||||
{
|
||||
struct net_device *ndev = si->ndev;
|
||||
struct dentry *root;
|
||||
|
||||
root = debugfs_create_dir(netdev_name(ndev), NULL);
|
||||
root = debugfs_create_dir(pci_name(si->pdev), NULL);
|
||||
if (IS_ERR(root))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,6 @@
|
|||
|
||||
/* Port Station interface promiscuous MAC mode register */
|
||||
#define ENETC4_PSIPMMR 0x200
|
||||
#define PSIPMMR_SI_MAC_UP(a) BIT(a) /* a = SI index */
|
||||
#define PSIPMMR_SI_MAC_MP(a) BIT((a) + 16)
|
||||
|
||||
/* Port Station interface promiscuous VLAN mode register */
|
||||
#define ENETC4_PSIPVMR 0x204
|
||||
|
|
@ -137,7 +135,6 @@
|
|||
#define ENETC4_PSIVHFR1(a) ((a) * 0x80 + 0x2064)
|
||||
|
||||
#define ENETC4_PMCAPR 0x4004
|
||||
#define PMCAPR_HD BIT(8)
|
||||
#define PMCAPR_FP GENMASK(10, 9)
|
||||
|
||||
/* Port capability register */
|
||||
|
|
@ -150,7 +147,7 @@
|
|||
#define PCR_L2DOSE BIT(4)
|
||||
#define PCR_TIMER_CS BIT(8)
|
||||
#define PCR_PSPEED GENMASK(29, 16)
|
||||
#define PCR_PSPEED_VAL(speed) (((speed) / 10 - 1) << 16)
|
||||
#define PCR_PSPEED_VAL(s) FIELD_PREP(PCR_PSPEED, ((s) / 10 - 1))
|
||||
|
||||
/* Port MAC address register 0/1 */
|
||||
#define ENETC4_PMAR0 0x4020
|
||||
|
|
@ -200,7 +197,6 @@
|
|||
#define PM_CMD_CFG_CNT_FRM_EN BIT(13)
|
||||
#define PM_CMD_CFG_TXP BIT(15)
|
||||
#define PM_CMD_CFG_SEND_IDLE BIT(16)
|
||||
#define PM_CMD_CFG_HD_FCEN BIT(18)
|
||||
#define PM_CMD_CFG_SFD BIT(21)
|
||||
#define PM_CMD_CFG_TX_FLUSH BIT(22)
|
||||
#define PM_CMD_CFG_TX_LOWP_EN BIT(23)
|
||||
|
|
|
|||
|
|
@ -23,18 +23,11 @@ static void enetc4_get_port_caps(struct enetc_pf *pf)
|
|||
u32 val;
|
||||
|
||||
val = enetc_port_rd(hw, ENETC4_ECAPR1);
|
||||
pf->caps.num_vsi = (val & ECAPR1_NUM_VSI) >> 24;
|
||||
pf->caps.num_msix = ((val & ECAPR1_NUM_MSIX) >> 12) + 1;
|
||||
|
||||
val = enetc_port_rd(hw, ENETC4_ECAPR2);
|
||||
pf->caps.num_rx_bdr = (val & ECAPR2_NUM_RX_BDR) >> 16;
|
||||
pf->caps.num_tx_bdr = val & ECAPR2_NUM_TX_BDR;
|
||||
|
||||
val = enetc_port_rd(hw, ENETC4_PMCAPR);
|
||||
pf->caps.half_duplex = (val & PMCAPR_HD) ? 1 : 0;
|
||||
|
||||
val = enetc_port_rd(hw, ENETC4_PSIMAFCAPR);
|
||||
pf->caps.mac_filter_num = val & PSIMAFCAPR_NUM_MAC_AFTE;
|
||||
}
|
||||
|
||||
static void enetc4_get_psi_hw_features(struct enetc_si *si)
|
||||
|
|
@ -75,38 +68,6 @@ static void enetc4_pf_get_si_primary_mac(struct enetc_hw *hw, int si,
|
|||
put_unaligned_le16(lower, addr + 4);
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_si_mac_promisc(struct enetc_hw *hw, int si,
|
||||
bool uc_promisc, bool mc_promisc)
|
||||
{
|
||||
u32 val = enetc_port_rd(hw, ENETC4_PSIPMMR);
|
||||
|
||||
if (uc_promisc)
|
||||
val |= PSIPMMR_SI_MAC_UP(si);
|
||||
else
|
||||
val &= ~PSIPMMR_SI_MAC_UP(si);
|
||||
|
||||
if (mc_promisc)
|
||||
val |= PSIPMMR_SI_MAC_MP(si);
|
||||
else
|
||||
val &= ~PSIPMMR_SI_MAC_MP(si);
|
||||
|
||||
enetc_port_wr(hw, ENETC4_PSIPMMR, val);
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_si_uc_hash_filter(struct enetc_hw *hw, int si,
|
||||
u64 hash)
|
||||
{
|
||||
enetc_port_wr(hw, ENETC4_PSIUMHFR0(si), lower_32_bits(hash));
|
||||
enetc_port_wr(hw, ENETC4_PSIUMHFR1(si), upper_32_bits(hash));
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_si_mc_hash_filter(struct enetc_hw *hw, int si,
|
||||
u64 hash)
|
||||
{
|
||||
enetc_port_wr(hw, ENETC4_PSIMMHFR0(si), lower_32_bits(hash));
|
||||
enetc_port_wr(hw, ENETC4_PSIMMHFR1(si), upper_32_bits(hash));
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_loopback(struct net_device *ndev, bool en)
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
|
|
@ -124,34 +85,47 @@ static void enetc4_pf_set_loopback(struct net_device *ndev, bool en)
|
|||
|
||||
static void enetc4_pf_clear_maft_entries(struct enetc_pf *pf)
|
||||
{
|
||||
int i;
|
||||
struct ntmp_user *user = &pf->si->ntmp_user;
|
||||
u32 entry_id;
|
||||
|
||||
for (i = 0; i < pf->num_mfe; i++)
|
||||
ntmp_maft_delete_entry(&pf->si->ntmp_user, i);
|
||||
|
||||
pf->num_mfe = 0;
|
||||
for_each_set_bit(entry_id, user->maft_eid_bitmap,
|
||||
user->maft_num_entries) {
|
||||
if (!ntmp_maft_delete_entry(user, entry_id))
|
||||
ntmp_clear_eid_bitmap(user->maft_eid_bitmap, entry_id);
|
||||
}
|
||||
}
|
||||
|
||||
static int enetc4_pf_add_maft_entries(struct enetc_pf *pf,
|
||||
struct enetc_mac_addr *mac,
|
||||
int mac_cnt)
|
||||
struct netdev_hw_addr_list *uc)
|
||||
{
|
||||
struct ntmp_user *user = &pf->si->ntmp_user;
|
||||
int mac_cnt = netdev_hw_addr_list_count(uc);
|
||||
struct maft_entry_data maft = {};
|
||||
struct netdev_hw_addr *ha;
|
||||
u32 available_entries;
|
||||
u16 si_bit = BIT(0);
|
||||
int i, err;
|
||||
u32 entry_id;
|
||||
int err;
|
||||
|
||||
available_entries = user->maft_num_entries -
|
||||
bitmap_weight(user->maft_eid_bitmap,
|
||||
user->maft_num_entries);
|
||||
|
||||
if (mac_cnt > available_entries)
|
||||
return -ENOSPC;
|
||||
|
||||
maft.cfge.si_bitmap = cpu_to_le16(si_bit);
|
||||
for (i = 0; i < mac_cnt; i++) {
|
||||
ether_addr_copy(maft.keye.mac_addr, mac[i].addr);
|
||||
err = ntmp_maft_add_entry(&pf->si->ntmp_user, i, &maft);
|
||||
netdev_hw_addr_list_for_each(ha, uc) {
|
||||
entry_id = ntmp_lookup_free_eid(user->maft_eid_bitmap,
|
||||
user->maft_num_entries);
|
||||
ether_addr_copy(maft.keye.mac_addr, ha->addr);
|
||||
err = ntmp_maft_add_entry(user, entry_id, &maft);
|
||||
if (unlikely(err)) {
|
||||
pf->num_mfe = i;
|
||||
ntmp_clear_eid_bitmap(user->maft_eid_bitmap, entry_id);
|
||||
goto clear_maft_entries;
|
||||
}
|
||||
}
|
||||
|
||||
pf->num_mfe = mac_cnt;
|
||||
|
||||
return 0;
|
||||
|
||||
clear_maft_entries:
|
||||
|
|
@ -160,97 +134,70 @@ static int enetc4_pf_add_maft_entries(struct enetc_pf *pf,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf)
|
||||
static void enetc4_pf_set_uc_hash_filter(struct enetc_pf *pf,
|
||||
struct netdev_hw_addr_list *uc)
|
||||
{
|
||||
int max_num_mfe = pf->caps.mac_filter_num;
|
||||
struct enetc_mac_filter mac_filter = {};
|
||||
struct net_device *ndev = pf->si->ndev;
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
struct enetc_mac_addr *mac_tbl;
|
||||
struct enetc_mac_filter *mac_filter = &pf->mac_filter[UC];
|
||||
struct netdev_hw_addr *ha;
|
||||
int i = 0, err;
|
||||
int mac_cnt;
|
||||
u64 hash;
|
||||
|
||||
netif_addr_lock_bh(ndev);
|
||||
enetc_reset_mac_addr_filter(mac_filter);
|
||||
netdev_hw_addr_list_for_each(ha, uc)
|
||||
enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
|
||||
|
||||
mac_cnt = netdev_uc_count(ndev);
|
||||
if (!mac_cnt) {
|
||||
netif_addr_unlock_bh(ndev);
|
||||
bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
|
||||
ENETC_MADDR_HASH_TBL_SZ);
|
||||
enetc_set_si_uc_hash_filter(pf->si, 0, hash);
|
||||
}
|
||||
|
||||
static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf,
|
||||
struct netdev_hw_addr_list *uc)
|
||||
{
|
||||
struct enetc_si *si = pf->si;
|
||||
int err;
|
||||
|
||||
if (netdev_hw_addr_list_empty(uc)) {
|
||||
/* clear both MAC hash and exact filters */
|
||||
enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
|
||||
enetc_set_si_uc_hash_filter(si, 0, 0);
|
||||
enetc4_pf_clear_maft_entries(pf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mac_cnt > max_num_mfe) {
|
||||
err = -ENOSPC;
|
||||
goto unlock_netif_addr;
|
||||
}
|
||||
|
||||
mac_tbl = kzalloc_objs(*mac_tbl, mac_cnt, GFP_ATOMIC);
|
||||
if (!mac_tbl) {
|
||||
err = -ENOMEM;
|
||||
goto unlock_netif_addr;
|
||||
}
|
||||
|
||||
netdev_for_each_uc_addr(ha, ndev) {
|
||||
enetc_add_mac_addr_ht_filter(&mac_filter, ha->addr);
|
||||
ether_addr_copy(mac_tbl[i++].addr, ha->addr);
|
||||
}
|
||||
|
||||
netif_addr_unlock_bh(ndev);
|
||||
|
||||
/* Set temporary unicast hash filters in case of Rx loss when
|
||||
/* Set temporary unicast hash filter in case of Rx loss when
|
||||
* updating MAC address filter table
|
||||
*/
|
||||
enetc4_pf_set_si_uc_hash_filter(hw, 0, *mac_filter.mac_hash_table);
|
||||
enetc4_pf_set_uc_hash_filter(pf, uc);
|
||||
enetc4_pf_clear_maft_entries(pf);
|
||||
|
||||
if (!enetc4_pf_add_maft_entries(pf, mac_tbl, i))
|
||||
enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
|
||||
|
||||
kfree(mac_tbl);
|
||||
|
||||
return 0;
|
||||
|
||||
unlock_netif_addr:
|
||||
netif_addr_unlock_bh(ndev);
|
||||
err = enetc4_pf_add_maft_entries(pf, uc);
|
||||
if (!err) {
|
||||
enetc_reset_mac_addr_filter(&pf->mac_filter[UC]);
|
||||
enetc_set_si_uc_hash_filter(si, 0, 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_mac_hash_filter(struct enetc_pf *pf, int type)
|
||||
static void enetc4_pf_set_mc_hash_filter(struct enetc_pf *pf,
|
||||
struct netdev_hw_addr_list *mc)
|
||||
{
|
||||
struct net_device *ndev = pf->si->ndev;
|
||||
struct enetc_mac_filter *mac_filter;
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
struct enetc_mac_filter *mac_filter = &pf->mac_filter[MC];
|
||||
struct netdev_hw_addr *ha;
|
||||
u64 hash;
|
||||
|
||||
netif_addr_lock_bh(ndev);
|
||||
if (type & ENETC_MAC_FILTER_TYPE_UC) {
|
||||
mac_filter = &pf->mac_filter[UC];
|
||||
enetc_reset_mac_addr_filter(mac_filter);
|
||||
netdev_for_each_uc_addr(ha, ndev)
|
||||
enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
|
||||
enetc_reset_mac_addr_filter(mac_filter);
|
||||
netdev_hw_addr_list_for_each(ha, mc)
|
||||
enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
|
||||
|
||||
enetc4_pf_set_si_uc_hash_filter(hw, 0,
|
||||
*mac_filter->mac_hash_table);
|
||||
}
|
||||
|
||||
if (type & ENETC_MAC_FILTER_TYPE_MC) {
|
||||
mac_filter = &pf->mac_filter[MC];
|
||||
enetc_reset_mac_addr_filter(mac_filter);
|
||||
netdev_for_each_mc_addr(ha, ndev)
|
||||
enetc_add_mac_addr_ht_filter(mac_filter, ha->addr);
|
||||
|
||||
enetc4_pf_set_si_mc_hash_filter(hw, 0,
|
||||
*mac_filter->mac_hash_table);
|
||||
}
|
||||
netif_addr_unlock_bh(ndev);
|
||||
bitmap_to_arr64(&hash, mac_filter->mac_hash_table,
|
||||
ENETC_MADDR_HASH_TBL_SZ);
|
||||
enetc_set_si_mc_hash_filter(pf->si, 0, hash);
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type)
|
||||
static void enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type,
|
||||
struct netdev_hw_addr_list *uc,
|
||||
struct netdev_hw_addr_list *mc)
|
||||
{
|
||||
/* Currently, the MAC address filter table (MAFT) only has 4 entries,
|
||||
* and multiple multicast addresses for filtering will be configured
|
||||
|
|
@ -258,15 +205,16 @@ static void enetc4_pf_set_mac_filter(struct enetc_pf *pf, int type)
|
|||
* unicast filtering. If the number of unicast addresses exceeds the
|
||||
* table capacity, the MAC hash filter will be used.
|
||||
*/
|
||||
if (type & ENETC_MAC_FILTER_TYPE_UC && enetc4_pf_set_uc_exact_filter(pf)) {
|
||||
if (type & ENETC_MAC_FILTER_TYPE_UC &&
|
||||
enetc4_pf_set_uc_exact_filter(pf, uc)) {
|
||||
/* Fall back to the MAC hash filter */
|
||||
enetc4_pf_set_mac_hash_filter(pf, ENETC_MAC_FILTER_TYPE_UC);
|
||||
enetc4_pf_set_uc_hash_filter(pf, uc);
|
||||
/* Clear the old MAC exact filter */
|
||||
enetc4_pf_clear_maft_entries(pf);
|
||||
}
|
||||
|
||||
if (type & ENETC_MAC_FILTER_TYPE_MC)
|
||||
enetc4_pf_set_mac_hash_filter(pf, ENETC_MAC_FILTER_TYPE_MC);
|
||||
enetc4_pf_set_mc_hash_filter(pf, mc);
|
||||
}
|
||||
|
||||
static const struct enetc_pf_ops enetc4_pf_ops = {
|
||||
|
|
@ -306,34 +254,35 @@ static void enetc4_default_rings_allocation(struct enetc_pf *pf)
|
|||
{
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
u32 num_rx_bdr, num_tx_bdr, val;
|
||||
int num_vfs = pf->total_vfs;
|
||||
u32 vf_tx_bdr, vf_rx_bdr;
|
||||
int i, rx_rem, tx_rem;
|
||||
|
||||
if (pf->caps.num_rx_bdr < ENETC_SI_MAX_RING_NUM + pf->caps.num_vsi)
|
||||
num_rx_bdr = pf->caps.num_rx_bdr - pf->caps.num_vsi;
|
||||
if (pf->caps.num_rx_bdr < ENETC_SI_MAX_RING_NUM + num_vfs)
|
||||
num_rx_bdr = pf->caps.num_rx_bdr - num_vfs;
|
||||
else
|
||||
num_rx_bdr = ENETC_SI_MAX_RING_NUM;
|
||||
|
||||
if (pf->caps.num_tx_bdr < ENETC_SI_MAX_RING_NUM + pf->caps.num_vsi)
|
||||
num_tx_bdr = pf->caps.num_tx_bdr - pf->caps.num_vsi;
|
||||
if (pf->caps.num_tx_bdr < ENETC_SI_MAX_RING_NUM + num_vfs)
|
||||
num_tx_bdr = pf->caps.num_tx_bdr - num_vfs;
|
||||
else
|
||||
num_tx_bdr = ENETC_SI_MAX_RING_NUM;
|
||||
|
||||
val = enetc4_psicfgr0_val_construct(false, num_tx_bdr, num_rx_bdr);
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR0(0), val);
|
||||
|
||||
if (!pf->caps.num_vsi)
|
||||
if (!num_vfs)
|
||||
return;
|
||||
|
||||
num_rx_bdr = pf->caps.num_rx_bdr - num_rx_bdr;
|
||||
rx_rem = num_rx_bdr % pf->caps.num_vsi;
|
||||
num_rx_bdr = num_rx_bdr / pf->caps.num_vsi;
|
||||
rx_rem = num_rx_bdr % num_vfs;
|
||||
num_rx_bdr = num_rx_bdr / num_vfs;
|
||||
|
||||
num_tx_bdr = pf->caps.num_tx_bdr - num_tx_bdr;
|
||||
tx_rem = num_tx_bdr % pf->caps.num_vsi;
|
||||
num_tx_bdr = num_tx_bdr / pf->caps.num_vsi;
|
||||
tx_rem = num_tx_bdr % num_vfs;
|
||||
num_tx_bdr = num_tx_bdr / num_vfs;
|
||||
|
||||
for (i = 0; i < pf->caps.num_vsi; i++) {
|
||||
for (i = 0; i < num_vfs; i++) {
|
||||
vf_tx_bdr = (i < tx_rem) ? num_tx_bdr + 1 : num_tx_bdr;
|
||||
vf_rx_bdr = (i < rx_rem) ? num_rx_bdr + 1 : num_rx_bdr;
|
||||
val = enetc4_psicfgr0_val_construct(true, vf_tx_bdr, vf_rx_bdr);
|
||||
|
|
@ -346,53 +295,70 @@ static void enetc4_allocate_si_rings(struct enetc_pf *pf)
|
|||
enetc4_default_rings_allocation(pf);
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_si_vlan_promisc(struct enetc_hw *hw, int si, bool en)
|
||||
{
|
||||
u32 val = enetc_port_rd(hw, ENETC4_PSIPVMR);
|
||||
|
||||
if (en)
|
||||
val |= BIT(si);
|
||||
else
|
||||
val &= ~BIT(si);
|
||||
|
||||
enetc_port_wr(hw, ENETC4_PSIPVMR, val);
|
||||
}
|
||||
|
||||
static void enetc4_set_default_si_vlan_promisc(struct enetc_pf *pf)
|
||||
{
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
int num_si = pf->caps.num_vsi + 1;
|
||||
int i;
|
||||
|
||||
/* enforce VLAN promiscuous mode for all SIs */
|
||||
for (i = 0; i < num_si; i++)
|
||||
enetc4_pf_set_si_vlan_promisc(hw, i, true);
|
||||
}
|
||||
|
||||
/* Allocate the number of MSI-X vectors for per SI. */
|
||||
static void enetc4_set_si_msix_num(struct enetc_pf *pf)
|
||||
{
|
||||
int valid_num_si = pf->total_vfs + 1;
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
int i, num_msix, total_si;
|
||||
int i, num_msix, num_vsi;
|
||||
u32 val;
|
||||
|
||||
total_si = pf->caps.num_vsi + 1;
|
||||
val = enetc_port_rd(hw, ENETC4_ECAPR1);
|
||||
num_vsi = FIELD_GET(ECAPR1_NUM_VSI, val);
|
||||
|
||||
num_msix = pf->caps.num_msix / total_si +
|
||||
pf->caps.num_msix % total_si - 1;
|
||||
val = num_msix & PSICFGR2_NUM_MSIX;
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR2(0), val);
|
||||
/* The PSIaCFGR2[NUM_MSIX] indicates the number of MSI-X allocated to
|
||||
* the SI is NUM_MSIX + 1, so the minimum number of MSI-X allocated to
|
||||
* each SI is 1. The total number of MSI-X allocated to PSI and VSIs
|
||||
* cannot exceed the total number of MSI-X owned by this ENETC, which
|
||||
* is ECAPR1[NUM_MSIX]. Otherwise, when multiple ENETC instances exist,
|
||||
* it will affect other ENETCs whose MSI-X interrupts cannot be
|
||||
* generated. This is similar to out-of-bounds array access: the array
|
||||
* itself is not affected, but adjacent arrays will be corrupted.
|
||||
*
|
||||
* pf->total_vfs is 0 if CONFIG_PCI_IOV is disabled. If the hardware
|
||||
* itself supports SR-IOV, then when allocating the number of MSIXs to
|
||||
* the SI, it must be taken into account that the VSI has at least 1
|
||||
* MSIX, and the total number of MSIXs of all SIs cannot exceed
|
||||
* ECAPR1[NUM_MSIX].
|
||||
*/
|
||||
if (!pf->total_vfs && num_vsi) {
|
||||
/* Because each SI has at least one MSIX, and from the hardware
|
||||
* perspective, pf->caps.num_msix will always be greater than
|
||||
* num_vsi. So num_msix is always greater than or equal to 0.
|
||||
*/
|
||||
num_msix = pf->caps.num_msix - num_vsi - 1;
|
||||
if (num_msix > PSICFGR2_NUM_MSIX)
|
||||
num_msix = PSICFGR2_NUM_MSIX;
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR2(0), num_msix);
|
||||
|
||||
num_msix = pf->caps.num_msix / total_si - 1;
|
||||
val = num_msix & PSICFGR2_NUM_MSIX;
|
||||
for (i = 0; i < pf->caps.num_vsi; i++)
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR2(i + 1), val);
|
||||
for (i = 0; i < num_vsi; i++)
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR2(i + 1), 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Likewise, from the hardware perspective pf->caps.num_msix is always
|
||||
* greater than valid_num_si. So num_msix is always greater than or
|
||||
* equal to 0.
|
||||
*/
|
||||
num_msix = pf->caps.num_msix / valid_num_si +
|
||||
pf->caps.num_msix % valid_num_si - 1;
|
||||
if (num_msix > PSICFGR2_NUM_MSIX)
|
||||
num_msix = PSICFGR2_NUM_MSIX;
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR2(0), num_msix);
|
||||
|
||||
num_msix = pf->caps.num_msix / valid_num_si - 1;
|
||||
if (num_msix > PSICFGR2_NUM_MSIX)
|
||||
num_msix = PSICFGR2_NUM_MSIX;
|
||||
|
||||
for (i = 0; i < pf->total_vfs; i++)
|
||||
enetc_port_wr(hw, ENETC4_PSICFGR2(i + 1), num_msix);
|
||||
}
|
||||
|
||||
static void enetc4_enable_all_si(struct enetc_pf *pf)
|
||||
{
|
||||
struct enetc_hw *hw = &pf->si->hw;
|
||||
int num_si = pf->caps.num_vsi + 1;
|
||||
int num_si = pf->total_vfs + 1;
|
||||
u32 si_bitmap = 0;
|
||||
int i;
|
||||
|
||||
|
|
@ -412,7 +378,9 @@ static void enetc4_configure_port_si(struct enetc_pf *pf)
|
|||
/* Outer VLAN tag will be used for VLAN filtering */
|
||||
enetc_port_wr(hw, ENETC4_PSIVLANFMR, PSIVLANFMR_VS);
|
||||
|
||||
enetc4_set_default_si_vlan_promisc(pf);
|
||||
/* Enforce VLAN promiscuous mode for all SIs */
|
||||
for (int i = 0; i < pf->total_vfs + 1; i++)
|
||||
enetc_set_si_vlan_promisc(pf->si, i, true);
|
||||
|
||||
/* Disable SI MAC multicast & unicast promiscuous */
|
||||
enetc_port_wr(hw, ENETC4_PSIPMMR, 0);
|
||||
|
|
@ -450,18 +418,60 @@ static void enetc4_configure_port(struct enetc_pf *pf)
|
|||
enetc_set_default_rss_key(pf);
|
||||
}
|
||||
|
||||
static void enetc4_get_ntmp_caps(struct enetc_si *si)
|
||||
{
|
||||
struct ntmp_user *user = &si->ntmp_user;
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
u32 val;
|
||||
|
||||
val = enetc_port_rd(hw, ENETC4_PSIMAFCAPR);
|
||||
user->maft_num_entries = FIELD_GET(PSIMAFCAPR_NUM_MAC_AFTE, val);
|
||||
}
|
||||
|
||||
static int enetc4_ntmp_bitmap_init(struct ntmp_user *user)
|
||||
{
|
||||
user->maft_eid_bitmap = bitmap_zalloc(user->maft_num_entries,
|
||||
GFP_KERNEL);
|
||||
if (!user->maft_eid_bitmap)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void enetc4_ntmp_bitmap_free(struct ntmp_user *user)
|
||||
{
|
||||
bitmap_free(user->maft_eid_bitmap);
|
||||
user->maft_eid_bitmap = NULL;
|
||||
}
|
||||
|
||||
static int enetc4_init_ntmp_user(struct enetc_si *si)
|
||||
{
|
||||
struct ntmp_user *user = &si->ntmp_user;
|
||||
int err;
|
||||
|
||||
/* For ENETC 4.1, all table versions are 0 */
|
||||
memset(&user->tbl, 0, sizeof(user->tbl));
|
||||
|
||||
return enetc4_setup_cbdr(si);
|
||||
err = enetc4_setup_cbdr(si);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
enetc4_get_ntmp_caps(si);
|
||||
err = enetc4_ntmp_bitmap_init(user);
|
||||
if (err)
|
||||
goto teardown_cbdr;
|
||||
|
||||
return 0;
|
||||
|
||||
teardown_cbdr:
|
||||
enetc4_teardown_cbdr(si);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void enetc4_free_ntmp_user(struct enetc_si *si)
|
||||
{
|
||||
enetc4_ntmp_bitmap_free(&si->ntmp_user);
|
||||
enetc4_teardown_cbdr(si);
|
||||
}
|
||||
|
||||
|
|
@ -479,7 +489,7 @@ static int enetc4_pf_init(struct enetc_pf *pf)
|
|||
|
||||
err = enetc4_init_ntmp_user(pf->si);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to init CBDR\n");
|
||||
dev_err(dev, "Failed to init NTMP user\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -493,18 +503,17 @@ static void enetc4_pf_free(struct enetc_pf *pf)
|
|||
enetc4_free_ntmp_user(pf->si);
|
||||
}
|
||||
|
||||
static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
|
||||
static int enetc4_pf_set_rx_mode(struct net_device *ndev,
|
||||
struct netdev_hw_addr_list *uc,
|
||||
struct netdev_hw_addr_list *mc)
|
||||
{
|
||||
struct enetc_si *si = container_of(work, struct enetc_si, rx_mode_task);
|
||||
struct enetc_pf *pf = enetc_si_priv(si);
|
||||
struct net_device *ndev = si->ndev;
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
||||
struct enetc_si *si = priv->si;
|
||||
bool uc_promisc = false;
|
||||
bool mc_promisc = false;
|
||||
int type = 0;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (ndev->flags & IFF_PROMISC) {
|
||||
uc_promisc = true;
|
||||
mc_promisc = true;
|
||||
|
|
@ -515,28 +524,21 @@ static void enetc4_psi_do_set_rx_mode(struct work_struct *work)
|
|||
type = ENETC_MAC_FILTER_TYPE_ALL;
|
||||
}
|
||||
|
||||
enetc4_pf_set_si_mac_promisc(hw, 0, uc_promisc, mc_promisc);
|
||||
enetc_set_si_uc_promisc(si, 0, uc_promisc);
|
||||
enetc_set_si_mc_promisc(si, 0, mc_promisc);
|
||||
|
||||
if (uc_promisc) {
|
||||
enetc4_pf_set_si_uc_hash_filter(hw, 0, 0);
|
||||
enetc_set_si_uc_hash_filter(si, 0, 0);
|
||||
enetc4_pf_clear_maft_entries(pf);
|
||||
}
|
||||
|
||||
if (mc_promisc)
|
||||
enetc4_pf_set_si_mc_hash_filter(hw, 0, 0);
|
||||
enetc_set_si_mc_hash_filter(si, 0, 0);
|
||||
|
||||
/* Set new MAC filter */
|
||||
enetc4_pf_set_mac_filter(pf, type);
|
||||
enetc4_pf_set_mac_filter(pf, type, uc, mc);
|
||||
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static void enetc4_pf_set_rx_mode(struct net_device *ndev)
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct enetc_si *si = priv->si;
|
||||
|
||||
queue_work(si->workqueue, &si->rx_mode_task);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enetc4_pf_set_features(struct net_device *ndev,
|
||||
|
|
@ -544,12 +546,11 @@ static int enetc4_pf_set_features(struct net_device *ndev,
|
|||
{
|
||||
netdev_features_t changed = ndev->features ^ features;
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct enetc_hw *hw = &priv->si->hw;
|
||||
|
||||
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
|
||||
bool promisc_en = !(features & NETIF_F_HW_VLAN_CTAG_FILTER);
|
||||
|
||||
enetc4_pf_set_si_vlan_promisc(hw, 0, promisc_en);
|
||||
enetc_set_si_vlan_promisc(priv->si, 0, promisc_en);
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_LOOPBACK)
|
||||
|
|
@ -566,7 +567,7 @@ static const struct net_device_ops enetc4_ndev_ops = {
|
|||
.ndo_start_xmit = enetc_xmit,
|
||||
.ndo_get_stats = enetc_get_stats,
|
||||
.ndo_set_mac_address = enetc_pf_set_mac_addr,
|
||||
.ndo_set_rx_mode = enetc4_pf_set_rx_mode,
|
||||
.ndo_set_rx_mode_async = enetc4_pf_set_rx_mode,
|
||||
.ndo_set_features = enetc4_pf_set_features,
|
||||
.ndo_vlan_rx_add_vid = enetc_vlan_rx_add_vid,
|
||||
.ndo_vlan_rx_kill_vid = enetc_vlan_rx_del_vid,
|
||||
|
|
@ -602,11 +603,6 @@ static void enetc4_mac_config(struct enetc_pf *pf, unsigned int mode,
|
|||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
val |= IFMODE_RGMII;
|
||||
/* We need to enable auto-negotiation for the MAC
|
||||
* if its RGMII interface support In-Band status.
|
||||
*/
|
||||
if (phylink_autoneg_inband(mode))
|
||||
val |= PM_IF_MODE_ENA;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RMII:
|
||||
val |= IFMODE_RMII;
|
||||
|
|
@ -616,7 +612,6 @@ static void enetc4_mac_config(struct enetc_pf *pf, unsigned int mode,
|
|||
val |= IFMODE_SGMII;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_10GBASER:
|
||||
case PHY_INTERFACE_MODE_XGMII:
|
||||
case PHY_INTERFACE_MODE_USXGMII:
|
||||
val |= IFMODE_XGMII;
|
||||
break;
|
||||
|
|
@ -642,26 +637,19 @@ static void enetc4_set_port_speed(struct enetc_ndev_priv *priv, int speed)
|
|||
u32 old_speed = priv->speed;
|
||||
u32 val;
|
||||
|
||||
/* If the speed is unknown, use the minimum value */
|
||||
if (speed == SPEED_UNKNOWN) {
|
||||
speed = SPEED_10;
|
||||
dev_warn(priv->dev, "Speed unknown, default is 10Mbps\n");
|
||||
}
|
||||
|
||||
if (speed == old_speed)
|
||||
return;
|
||||
|
||||
val = enetc_port_rd(&priv->si->hw, ENETC4_PCR);
|
||||
val &= ~PCR_PSPEED;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_100:
|
||||
case SPEED_1000:
|
||||
case SPEED_2500:
|
||||
case SPEED_10000:
|
||||
val |= (PCR_PSPEED & PCR_PSPEED_VAL(speed));
|
||||
break;
|
||||
case SPEED_10:
|
||||
default:
|
||||
val |= (PCR_PSPEED & PCR_PSPEED_VAL(SPEED_10));
|
||||
}
|
||||
|
||||
priv->speed = speed;
|
||||
val = enetc_port_rd(&priv->si->hw, ENETC4_PCR) & (~PCR_PSPEED);
|
||||
val |= PCR_PSPEED_VAL(speed);
|
||||
enetc_port_wr(&priv->si->hw, ENETC4_PCR, val);
|
||||
priv->speed = speed;
|
||||
}
|
||||
|
||||
static void enetc4_set_rgmii_mac(struct enetc_pf *pf, int speed, int duplex)
|
||||
|
|
@ -717,22 +705,6 @@ static void enetc4_set_rmii_mac(struct enetc_pf *pf, int speed, int duplex)
|
|||
enetc_port_mac_wr(si, ENETC4_PM_IF_MODE(0), val);
|
||||
}
|
||||
|
||||
static void enetc4_set_hd_flow_control(struct enetc_pf *pf, bool enable)
|
||||
{
|
||||
struct enetc_si *si = pf->si;
|
||||
u32 old_val, val;
|
||||
|
||||
if (!pf->caps.half_duplex)
|
||||
return;
|
||||
|
||||
old_val = enetc_port_mac_rd(si, ENETC4_PM_CMD_CFG(0));
|
||||
val = u32_replace_bits(old_val, enable ? 1 : 0, PM_CMD_CFG_HD_FCEN);
|
||||
if (val == old_val)
|
||||
return;
|
||||
|
||||
enetc_port_mac_wr(si, ENETC4_PM_CMD_CFG(0), val);
|
||||
}
|
||||
|
||||
static void enetc4_set_rx_pause(struct enetc_pf *pf, bool rx_pause)
|
||||
{
|
||||
struct enetc_si *si = pf->si;
|
||||
|
|
@ -908,13 +880,11 @@ static void enetc4_pl_mac_link_up(struct phylink_config *config,
|
|||
struct enetc_pf *pf = phylink_to_enetc_pf(config);
|
||||
struct enetc_si *si = pf->si;
|
||||
struct enetc_ndev_priv *priv;
|
||||
bool hd_fc = false;
|
||||
|
||||
priv = netdev_priv(si->ndev);
|
||||
enetc4_set_port_speed(priv, speed);
|
||||
|
||||
if (!phylink_autoneg_inband(mode) &&
|
||||
phy_interface_mode_is_rgmii(interface))
|
||||
if (phy_interface_mode_is_rgmii(interface))
|
||||
enetc4_set_rgmii_mac(pf, speed, duplex);
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_RMII)
|
||||
|
|
@ -926,18 +896,8 @@ static void enetc4_pl_mac_link_up(struct phylink_config *config,
|
|||
*/
|
||||
if (priv->active_offloads & ENETC_F_QBU)
|
||||
tx_pause = false;
|
||||
} else { /* DUPLEX_HALF */
|
||||
if (tx_pause || rx_pause)
|
||||
hd_fc = true;
|
||||
|
||||
/* As per 802.3 annex 31B, PAUSE frames are only supported
|
||||
* when the link is configured for full duplex operation.
|
||||
*/
|
||||
tx_pause = false;
|
||||
rx_pause = false;
|
||||
}
|
||||
|
||||
enetc4_set_hd_flow_control(pf, hd_fc);
|
||||
enetc4_set_tx_pause(pf, priv->num_rx_rings, tx_pause);
|
||||
enetc4_set_rx_pause(pf, rx_pause);
|
||||
enetc4_mac_tx_enable(pf);
|
||||
|
|
@ -1009,19 +969,6 @@ static void enetc4_link_deinit(struct enetc_ndev_priv *priv)
|
|||
enetc_mdiobus_destroy(pf);
|
||||
}
|
||||
|
||||
static int enetc4_psi_wq_task_init(struct enetc_si *si)
|
||||
{
|
||||
char wq_name[24];
|
||||
|
||||
INIT_WORK(&si->rx_mode_task, enetc4_psi_do_set_rx_mode);
|
||||
snprintf(wq_name, sizeof(wq_name), "enetc-%s", pci_name(si->pdev));
|
||||
si->workqueue = create_singlethread_workqueue(wq_name);
|
||||
if (!si->workqueue)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enetc4_pf_netdev_create(struct enetc_si *si)
|
||||
{
|
||||
struct device *dev = &si->pdev->dev;
|
||||
|
|
@ -1062,12 +1009,6 @@ static int enetc4_pf_netdev_create(struct enetc_si *si)
|
|||
if (err)
|
||||
goto err_link_init;
|
||||
|
||||
err = enetc4_psi_wq_task_init(si);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to init workqueue\n");
|
||||
goto err_wq_init;
|
||||
}
|
||||
|
||||
err = register_netdev(ndev);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to register netdev\n");
|
||||
|
|
@ -1077,8 +1018,6 @@ static int enetc4_pf_netdev_create(struct enetc_si *si)
|
|||
return 0;
|
||||
|
||||
err_reg_netdev:
|
||||
destroy_workqueue(si->workqueue);
|
||||
err_wq_init:
|
||||
enetc4_link_deinit(priv);
|
||||
err_link_init:
|
||||
enetc_free_msix(priv);
|
||||
|
|
@ -1096,8 +1035,6 @@ static void enetc4_pf_netdev_destroy(struct enetc_si *si)
|
|||
struct net_device *ndev = si->ndev;
|
||||
|
||||
unregister_netdev(ndev);
|
||||
cancel_work(&si->rx_mode_task);
|
||||
destroy_workqueue(si->workqueue);
|
||||
enetc4_link_deinit(priv);
|
||||
enetc_free_msix(priv);
|
||||
free_netdev(ndev);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static const u32 enetc_rxbdr_regs[] = {
|
|||
};
|
||||
|
||||
static const u32 enetc_port_regs[] = {
|
||||
ENETC_PMR, ENETC_PSR, ENETC_PSIPMR, ENETC_PSIPMAR0(0),
|
||||
ENETC_PMR, ENETC_PSR, ENETC_PSIPMMR, ENETC_PSIPMAR0(0),
|
||||
ENETC_PSIPMAR1(0), ENETC_PTXMBAR, ENETC_PCAPR0, ENETC_PCAPR1,
|
||||
ENETC_PSICFGR0(0), ENETC_PRFSCAPR, ENETC_PTCMSDUR(0),
|
||||
ENETC_PM0_CMD_CFG, ENETC_PM0_MAXFRM, ENETC_PM0_IF_MODE
|
||||
|
|
|
|||
|
|
@ -180,13 +180,13 @@ enum enetc_bdr_type {TX, RX};
|
|||
#define ENETC_PMR_PSPEED_1000M BIT(9)
|
||||
#define ENETC_PMR_PSPEED_2500M BIT(10)
|
||||
#define ENETC_PSR 0x0004 /* RO */
|
||||
#define ENETC_PSIPMR 0x0018
|
||||
#define ENETC_PSIPMR_SET_UP(n) BIT(n) /* n = SI index */
|
||||
#define ENETC_PSIPMR_SET_MP(n) BIT((n) + 16)
|
||||
#define ENETC_PSIPMMR 0x0018
|
||||
#define PSIPMMR_SI_MAC_UP(n) BIT(n) /* n = SI index */
|
||||
#define PSIPMMR_SI_MAC_MP(n) BIT((n) + 16)
|
||||
|
||||
#define ENETC_PSIPVMR 0x001c
|
||||
#define ENETC_VLAN_PROMISC_MAP_ALL 0x7
|
||||
#define ENETC_PSIPVMR_SET_VP(simap) ((simap) & 0x7)
|
||||
#define ENETC_PSIPVMR_SET_VUTA(simap) (((simap) & 0x7) << 16)
|
||||
#define PSIPVMR_SI_VLAN_P(n) BIT(n) /* n = SI index */
|
||||
|
||||
#define ENETC_PSIPMAR0(n) (0x0100 + (n) * 0x8) /* n = SI index */
|
||||
#define ENETC_PSIPMAR1(n) (0x0104 + (n) * 0x8)
|
||||
#define ENETC_PVCLCTR 0x0208
|
||||
|
|
|
|||
|
|
@ -42,26 +42,6 @@ static void enetc_pf_destroy_pcs(struct phylink_pcs *pcs)
|
|||
lynx_pcs_destroy(pcs);
|
||||
}
|
||||
|
||||
static void enetc_set_vlan_promisc(struct enetc_hw *hw, char si_map)
|
||||
{
|
||||
u32 val = enetc_port_rd(hw, ENETC_PSIPVMR);
|
||||
|
||||
val &= ~ENETC_PSIPVMR_SET_VP(ENETC_VLAN_PROMISC_MAP_ALL);
|
||||
enetc_port_wr(hw, ENETC_PSIPVMR, ENETC_PSIPVMR_SET_VP(si_map) | val);
|
||||
}
|
||||
|
||||
static void enetc_enable_si_vlan_promisc(struct enetc_pf *pf, int si_idx)
|
||||
{
|
||||
pf->vlan_promisc_simap |= BIT(si_idx);
|
||||
enetc_set_vlan_promisc(&pf->si->hw, pf->vlan_promisc_simap);
|
||||
}
|
||||
|
||||
static void enetc_disable_si_vlan_promisc(struct enetc_pf *pf, int si_idx)
|
||||
{
|
||||
pf->vlan_promisc_simap &= ~BIT(si_idx);
|
||||
enetc_set_vlan_promisc(&pf->si->hw, pf->vlan_promisc_simap);
|
||||
}
|
||||
|
||||
static void enetc_set_isol_vlan(struct enetc_hw *hw, int si, u16 vlan, u8 qos)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
|
@ -80,37 +60,6 @@ static void enetc_add_mac_addr_em_filter(struct enetc_mac_filter *filter,
|
|||
filter->mac_addr_cnt++;
|
||||
}
|
||||
|
||||
static void enetc_clear_mac_ht_flt(struct enetc_si *si, int si_idx, int type)
|
||||
{
|
||||
bool err = si->errata & ENETC_ERR_UCMCSWP;
|
||||
|
||||
if (type == UC) {
|
||||
enetc_port_wr(&si->hw, ENETC_PSIUMHFR0(si_idx, err), 0);
|
||||
enetc_port_wr(&si->hw, ENETC_PSIUMHFR1(si_idx), 0);
|
||||
} else { /* MC */
|
||||
enetc_port_wr(&si->hw, ENETC_PSIMMHFR0(si_idx, err), 0);
|
||||
enetc_port_wr(&si->hw, ENETC_PSIMMHFR1(si_idx), 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void enetc_set_mac_ht_flt(struct enetc_si *si, int si_idx, int type,
|
||||
unsigned long hash)
|
||||
{
|
||||
bool err = si->errata & ENETC_ERR_UCMCSWP;
|
||||
|
||||
if (type == UC) {
|
||||
enetc_port_wr(&si->hw, ENETC_PSIUMHFR0(si_idx, err),
|
||||
lower_32_bits(hash));
|
||||
enetc_port_wr(&si->hw, ENETC_PSIUMHFR1(si_idx),
|
||||
upper_32_bits(hash));
|
||||
} else { /* MC */
|
||||
enetc_port_wr(&si->hw, ENETC_PSIMMHFR0(si_idx, err),
|
||||
lower_32_bits(hash));
|
||||
enetc_port_wr(&si->hw, ENETC_PSIMMHFR1(si_idx),
|
||||
upper_32_bits(hash));
|
||||
}
|
||||
}
|
||||
|
||||
static void enetc_sync_mac_filters(struct enetc_pf *pf)
|
||||
{
|
||||
struct enetc_mac_filter *f = pf->mac_filter;
|
||||
|
|
@ -122,12 +71,16 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
|
|||
for (i = 0; i < MADDR_TYPE; i++, f++) {
|
||||
bool em = (f->mac_addr_cnt == 1) && (i == UC);
|
||||
bool clear = !f->mac_addr_cnt;
|
||||
u64 hash;
|
||||
|
||||
if (clear) {
|
||||
if (i == UC)
|
||||
if (i == UC) {
|
||||
enetc_clear_mac_flt_entry(si, pos);
|
||||
enetc_set_si_uc_hash_filter(si, 0, 0);
|
||||
} else {
|
||||
enetc_set_si_mc_hash_filter(si, 0, 0);
|
||||
}
|
||||
|
||||
enetc_clear_mac_ht_flt(si, 0, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +88,7 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
|
|||
if (em) {
|
||||
int err;
|
||||
|
||||
enetc_clear_mac_ht_flt(si, 0, UC);
|
||||
enetc_set_si_uc_hash_filter(si, 0, 0);
|
||||
|
||||
err = enetc_set_mac_flt_entry(si, pos, f->mac_addr,
|
||||
BIT(0));
|
||||
|
|
@ -147,11 +100,15 @@ static void enetc_sync_mac_filters(struct enetc_pf *pf)
|
|||
err);
|
||||
}
|
||||
|
||||
bitmap_to_arr64(&hash, f->mac_hash_table,
|
||||
ENETC_MADDR_HASH_TBL_SZ);
|
||||
/* hash table filter, clear EM filter for UC entries */
|
||||
if (i == UC)
|
||||
if (i == UC) {
|
||||
enetc_clear_mac_flt_entry(si, pos);
|
||||
|
||||
enetc_set_mac_ht_flt(si, 0, i, *f->mac_hash_table);
|
||||
enetc_set_si_uc_hash_filter(si, 0, hash);
|
||||
} else {
|
||||
enetc_set_si_mc_hash_filter(si, 0, hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,21 +116,17 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
|
|||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
||||
struct enetc_hw *hw = &priv->si->hw;
|
||||
bool uprom = false, mprom = false;
|
||||
struct enetc_mac_filter *filter;
|
||||
struct netdev_hw_addr *ha;
|
||||
u32 psipmr = 0;
|
||||
bool em;
|
||||
|
||||
if (ndev->flags & IFF_PROMISC) {
|
||||
/* enable promisc mode for SI0 (PF) */
|
||||
psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0);
|
||||
uprom = true;
|
||||
mprom = true;
|
||||
} else if (ndev->flags & IFF_ALLMULTI) {
|
||||
/* enable multi cast promisc mode for SI0 (PF) */
|
||||
psipmr = ENETC_PSIPMR_SET_MP(0);
|
||||
mprom = true;
|
||||
}
|
||||
|
||||
|
|
@ -211,9 +164,8 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
|
|||
/* update PF entries */
|
||||
enetc_sync_mac_filters(pf);
|
||||
|
||||
psipmr |= enetc_port_rd(hw, ENETC_PSIPMR) &
|
||||
~(ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0));
|
||||
enetc_port_wr(hw, ENETC_PSIPMR, psipmr);
|
||||
enetc_set_si_uc_promisc(priv->si, 0, uprom);
|
||||
enetc_set_si_mc_promisc(priv->si, 0, mprom);
|
||||
}
|
||||
|
||||
static void enetc_set_loopback(struct net_device *ndev, bool en)
|
||||
|
|
@ -469,12 +421,11 @@ static void enetc_configure_port(struct enetc_pf *pf)
|
|||
|
||||
/* split up RFS entries */
|
||||
enetc_port_assign_rfs_entries(pf->si);
|
||||
|
||||
/* enforce VLAN promisc mode for all SIs */
|
||||
pf->vlan_promisc_simap = ENETC_VLAN_PROMISC_MAP_ALL;
|
||||
enetc_set_vlan_promisc(hw, pf->vlan_promisc_simap);
|
||||
for (int i = 0; i < pf->total_vfs + 1; i++)
|
||||
enetc_set_si_vlan_promisc(pf->si, i, true);
|
||||
|
||||
enetc_port_wr(hw, ENETC_PSIPMR, 0);
|
||||
enetc_port_wr(hw, ENETC_PSIPMMR, 0);
|
||||
|
||||
/* enable port */
|
||||
enetc_port_wr(hw, ENETC_PMR, ENETC_PMR_EN);
|
||||
|
|
@ -494,12 +445,9 @@ static int enetc_pf_set_features(struct net_device *ndev,
|
|||
}
|
||||
|
||||
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
|
||||
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
||||
bool promisc = !(features & NETIF_F_HW_VLAN_CTAG_FILTER);
|
||||
|
||||
if (!!(features & NETIF_F_HW_VLAN_CTAG_FILTER))
|
||||
enetc_disable_si_vlan_promisc(pf, 0);
|
||||
else
|
||||
enetc_enable_si_vlan_promisc(pf, 0);
|
||||
enetc_set_si_vlan_promisc(priv->si, 0, promisc);
|
||||
}
|
||||
|
||||
if (changed & NETIF_F_LOOPBACK)
|
||||
|
|
|
|||
|
|
@ -17,12 +17,9 @@ struct enetc_vf_state {
|
|||
};
|
||||
|
||||
struct enetc_port_caps {
|
||||
u32 half_duplex:1;
|
||||
int num_vsi;
|
||||
int num_msix;
|
||||
int num_rx_bdr;
|
||||
int num_tx_bdr;
|
||||
int mac_filter_num;
|
||||
};
|
||||
|
||||
struct enetc_pf;
|
||||
|
|
@ -47,7 +44,6 @@ struct enetc_pf {
|
|||
struct work_struct msg_task;
|
||||
char msg_int_name[ENETC_INT_NAME_MAX];
|
||||
|
||||
char vlan_promisc_simap; /* bitmap of SIs in VLAN promisc mode */
|
||||
DECLARE_BITMAP(vlan_ht_filter, ENETC_VLAN_HT_SIZE);
|
||||
DECLARE_BITMAP(active_vlans, VLAN_N_VID);
|
||||
|
||||
|
|
@ -60,8 +56,6 @@ struct enetc_pf {
|
|||
|
||||
struct enetc_port_caps caps;
|
||||
const struct enetc_pf_ops *ops;
|
||||
|
||||
int num_mfe; /* number of mac address filter table entries */
|
||||
};
|
||||
|
||||
#define phylink_to_enetc_pf(config) \
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
|
||||
/* Copyright 2024 NXP */
|
||||
/* Copyright 2024-2026 NXP */
|
||||
|
||||
#include <linux/fsl/enetc_mdio.h>
|
||||
#include <linux/of_mdio.h>
|
||||
|
|
@ -87,6 +87,112 @@ int enetc_setup_mac_addresses(struct device_node *np, struct enetc_pf *pf)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_setup_mac_addresses);
|
||||
|
||||
void enetc_set_si_uc_promisc(struct enetc_si *si, int si_id, bool promisc)
|
||||
{
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
int psipmmr_off;
|
||||
u32 val;
|
||||
|
||||
if (is_enetc_rev1(si))
|
||||
psipmmr_off = ENETC_PSIPMMR;
|
||||
else
|
||||
psipmmr_off = ENETC4_PSIPMMR;
|
||||
|
||||
val = enetc_port_rd(hw, psipmmr_off);
|
||||
|
||||
if (promisc)
|
||||
val |= PSIPMMR_SI_MAC_UP(si_id);
|
||||
else
|
||||
val &= ~PSIPMMR_SI_MAC_UP(si_id);
|
||||
|
||||
enetc_port_wr(hw, psipmmr_off, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_set_si_uc_promisc);
|
||||
|
||||
void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc)
|
||||
{
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
int psipmmr_off;
|
||||
u32 val;
|
||||
|
||||
if (is_enetc_rev1(si))
|
||||
psipmmr_off = ENETC_PSIPMMR;
|
||||
else
|
||||
psipmmr_off = ENETC4_PSIPMMR;
|
||||
|
||||
val = enetc_port_rd(hw, psipmmr_off);
|
||||
|
||||
if (promisc)
|
||||
val |= PSIPMMR_SI_MAC_MP(si_id);
|
||||
else
|
||||
val &= ~PSIPMMR_SI_MAC_MP(si_id);
|
||||
|
||||
enetc_port_wr(hw, psipmmr_off, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_set_si_mc_promisc);
|
||||
|
||||
void enetc_set_si_uc_hash_filter(struct enetc_si *si, int si_id, u64 hash)
|
||||
{
|
||||
int psiumhfr0_off, psiumhfr1_off;
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
|
||||
if (is_enetc_rev1(si)) {
|
||||
bool err = si->errata & ENETC_ERR_UCMCSWP;
|
||||
|
||||
psiumhfr0_off = ENETC_PSIUMHFR0(si_id, err);
|
||||
psiumhfr1_off = ENETC_PSIUMHFR1(si_id);
|
||||
} else {
|
||||
psiumhfr0_off = ENETC4_PSIUMHFR0(si_id);
|
||||
psiumhfr1_off = ENETC4_PSIUMHFR1(si_id);
|
||||
}
|
||||
|
||||
enetc_port_wr(hw, psiumhfr0_off, lower_32_bits(hash));
|
||||
enetc_port_wr(hw, psiumhfr1_off, upper_32_bits(hash));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_set_si_uc_hash_filter);
|
||||
|
||||
void enetc_set_si_mc_hash_filter(struct enetc_si *si, int si_id, u64 hash)
|
||||
{
|
||||
int psimmhfr0_off, psimmhfr1_off;
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
|
||||
if (is_enetc_rev1(si)) {
|
||||
bool err = si->errata & ENETC_ERR_UCMCSWP;
|
||||
|
||||
psimmhfr0_off = ENETC_PSIMMHFR0(si_id, err);
|
||||
psimmhfr1_off = ENETC_PSIMMHFR1(si_id);
|
||||
} else {
|
||||
psimmhfr0_off = ENETC4_PSIMMHFR0(si_id);
|
||||
psimmhfr1_off = ENETC4_PSIMMHFR1(si_id);
|
||||
}
|
||||
|
||||
enetc_port_wr(hw, psimmhfr0_off, lower_32_bits(hash));
|
||||
enetc_port_wr(hw, psimmhfr1_off, upper_32_bits(hash));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_set_si_mc_hash_filter);
|
||||
|
||||
void enetc_set_si_vlan_promisc(struct enetc_si *si, int si_id, bool promisc)
|
||||
{
|
||||
struct enetc_hw *hw = &si->hw;
|
||||
int psipvmr_off;
|
||||
u32 val;
|
||||
|
||||
if (is_enetc_rev1(si))
|
||||
psipvmr_off = ENETC_PSIPVMR;
|
||||
else
|
||||
psipvmr_off = ENETC4_PSIPVMR;
|
||||
|
||||
val = enetc_port_rd(hw, psipvmr_off);
|
||||
|
||||
if (promisc)
|
||||
val |= PSIPVMR_SI_VLAN_P(si_id);
|
||||
else
|
||||
val &= ~PSIPVMR_SI_VLAN_P(si_id);
|
||||
|
||||
enetc_port_wr(hw, psipvmr_off, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enetc_set_si_vlan_promisc);
|
||||
|
||||
void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
|
||||
const struct net_device_ops *ndev_ops)
|
||||
{
|
||||
|
|
@ -275,7 +381,8 @@ static bool enetc_port_has_pcs(struct enetc_pf *pf)
|
|||
return (pf->if_mode == PHY_INTERFACE_MODE_SGMII ||
|
||||
pf->if_mode == PHY_INTERFACE_MODE_1000BASEX ||
|
||||
pf->if_mode == PHY_INTERFACE_MODE_2500BASEX ||
|
||||
pf->if_mode == PHY_INTERFACE_MODE_USXGMII);
|
||||
pf->if_mode == PHY_INTERFACE_MODE_USXGMII ||
|
||||
pf->if_mode == PHY_INTERFACE_MODE_10GBASER);
|
||||
}
|
||||
|
||||
int enetc_mdiobus_create(struct enetc_pf *pf, struct device_node *node)
|
||||
|
|
@ -316,25 +423,42 @@ int enetc_phylink_create(struct enetc_ndev_priv *priv, struct device_node *node,
|
|||
{
|
||||
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
||||
struct phylink *phylink;
|
||||
unsigned long mac_caps;
|
||||
int err;
|
||||
|
||||
pf->phylink_config.dev = &priv->ndev->dev;
|
||||
pf->phylink_config.type = PHYLINK_NETDEV;
|
||||
pf->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
|
||||
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_USXGMII,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
phy_interface_set_rgmii(pf->phylink_config.supported_interfaces);
|
||||
|
||||
mac_caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
|
||||
if (!enetc_is_pseudo_mac(priv->si)) {
|
||||
mac_caps |= MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
|
||||
|
||||
__set_bit(PHY_INTERFACE_MODE_SGMII,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_1000BASEX,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_2500BASEX,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
__set_bit(PHY_INTERFACE_MODE_USXGMII,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
|
||||
if (!is_enetc_rev1(priv->si)) {
|
||||
mac_caps |= MAC_5000FD | MAC_10000FD;
|
||||
__set_bit(PHY_INTERFACE_MODE_10GBASER,
|
||||
pf->phylink_config.supported_interfaces);
|
||||
}
|
||||
|
||||
phy_interface_set_rgmii(pf->phylink_config.supported_interfaces);
|
||||
} else {
|
||||
mac_caps |= MAC_10FD | MAC_100FD | MAC_1000FD | MAC_2500FD |
|
||||
MAC_5000FD | MAC_10000FD | MAC_20000FD |
|
||||
MAC_25000FD;
|
||||
}
|
||||
|
||||
pf->phylink_config.mac_capabilities = mac_caps;
|
||||
phylink = phylink_create(&pf->phylink_config, of_fwnode_handle(node),
|
||||
pf->if_mode, ops);
|
||||
if (IS_ERR(phylink)) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ void enetc_set_default_rss_key(struct enetc_pf *pf);
|
|||
int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid);
|
||||
int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid);
|
||||
int enetc_init_sriov_resources(struct enetc_pf *pf);
|
||||
void enetc_set_si_uc_promisc(struct enetc_si *si, int si_id, bool promisc);
|
||||
void enetc_set_si_mc_promisc(struct enetc_si *si, int si_id, bool promisc);
|
||||
void enetc_set_si_uc_hash_filter(struct enetc_si *si, int si_id, u64 hash);
|
||||
void enetc_set_si_mc_hash_filter(struct enetc_si *si, int si_id, u64 hash);
|
||||
void enetc_set_si_vlan_promisc(struct enetc_si *si, int si_id, bool promisc);
|
||||
|
||||
static inline u16 enetc_get_ip_revision(struct enetc_hw *hw)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1135,7 +1135,6 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
|
|||
struct flow_action_entry *entry;
|
||||
struct action_gate_entry *e;
|
||||
u8 sfi_overwrite = 0;
|
||||
int entries_size;
|
||||
int i, err;
|
||||
|
||||
if (f->common.chain_index >= priv->psfp_cap.max_streamid) {
|
||||
|
|
@ -1242,8 +1241,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
|
|||
goto free_filter;
|
||||
}
|
||||
|
||||
entries_size = struct_size(sgi, entries, entryg->gate.num_entries);
|
||||
sgi = kzalloc(entries_size, GFP_KERNEL);
|
||||
sgi = kzalloc_flex(*sgi, entries, entryg->gate.num_entries);
|
||||
if (!sgi) {
|
||||
err = -ENOMEM;
|
||||
goto free_filter;
|
||||
|
|
|
|||
|
|
@ -317,7 +317,14 @@ static int enetc_vf_probe(struct pci_dev *pdev,
|
|||
|
||||
enetc_get_si_caps(si);
|
||||
|
||||
ndev = alloc_etherdev_mq(sizeof(*priv), ENETC_MAX_NUM_TXQS);
|
||||
/* Currently, the supported SoCs have a max of 6 CPUs and the VFs
|
||||
* have less than 6 RX/TX rings. So no issues for these supported
|
||||
* SoCs, but for future SoCs which have more CPUs or more TX/RX
|
||||
* rings, all the related logic needs to be improved.
|
||||
*/
|
||||
ndev = alloc_etherdev_mqs(sizeof(*priv),
|
||||
min(si->num_tx_rings, ENETC_MAX_NUM_TXQS),
|
||||
min(si->num_rx_rings, ENETC_MAX_NUM_TXQS));
|
||||
if (!ndev) {
|
||||
err = -ENOMEM;
|
||||
dev_err(&pdev->dev, "netdev creation failed\n");
|
||||
|
|
|
|||
|
|
@ -75,8 +75,10 @@ struct ntmp_user {
|
|||
/* NTMP table bitmaps for resource management */
|
||||
u32 ett_bitmap_size;
|
||||
u32 ect_bitmap_size;
|
||||
u16 maft_num_entries;
|
||||
unsigned long *ett_gid_bitmap; /* only valid for switch */
|
||||
unsigned long *ect_gid_bitmap; /* only valid for switch */
|
||||
unsigned long *maft_eid_bitmap; /* only valid for ENETC */
|
||||
};
|
||||
|
||||
struct maft_entry_data {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user