Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Several cases of bug fixes in 'net' overlapping other changes in 'net-next-. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -204,17 +204,6 @@ static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring)
|
||||
return num_msgs;
|
||||
}
|
||||
|
||||
static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring)
|
||||
{
|
||||
u32 data = 0x7777;
|
||||
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16);
|
||||
xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40);
|
||||
xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80);
|
||||
}
|
||||
|
||||
void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring,
|
||||
struct xgene_enet_pdata *pdata,
|
||||
enum xgene_enet_err_code status)
|
||||
@@ -929,5 +918,4 @@ struct xgene_ring_ops xgene_ring1_ops = {
|
||||
.clear = xgene_enet_clear_ring,
|
||||
.wr_cmd = xgene_enet_wr_cmd,
|
||||
.len = xgene_enet_ring_len,
|
||||
.coalesce = xgene_enet_setup_coalescing,
|
||||
};
|
||||
|
||||
@@ -55,8 +55,10 @@ enum xgene_enet_rm {
|
||||
#define PREFETCH_BUF_EN BIT(21)
|
||||
#define CSR_RING_ID_BUF 0x000c
|
||||
#define CSR_PBM_COAL 0x0014
|
||||
#define CSR_PBM_CTICK0 0x0018
|
||||
#define CSR_PBM_CTICK1 0x001c
|
||||
#define CSR_PBM_CTICK2 0x0020
|
||||
#define CSR_PBM_CTICK3 0x0024
|
||||
#define CSR_THRESHOLD0_SET1 0x0030
|
||||
#define CSR_THRESHOLD1_SET1 0x0034
|
||||
#define CSR_RING_NE_INT_MODE 0x017c
|
||||
|
||||
@@ -1188,7 +1188,8 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
|
||||
tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
|
||||
}
|
||||
|
||||
pdata->ring_ops->coalesce(pdata->tx_ring[0]);
|
||||
if (pdata->ring_ops->coalesce)
|
||||
pdata->ring_ops->coalesce(pdata->tx_ring[0]);
|
||||
pdata->tx_qcnt_hi = pdata->tx_ring[0]->slots - 128;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -30,7 +30,7 @@ static void xgene_enet_ring_init(struct xgene_enet_desc_ring *ring)
|
||||
ring_cfg[0] |= SET_VAL(X2_INTLINE, ring->id & RING_BUFNUM_MASK);
|
||||
ring_cfg[3] |= SET_BIT(X2_DEQINTEN);
|
||||
}
|
||||
ring_cfg[0] |= SET_VAL(X2_CFGCRID, 1);
|
||||
ring_cfg[0] |= SET_VAL(X2_CFGCRID, 2);
|
||||
|
||||
addr >>= 8;
|
||||
ring_cfg[2] |= QCOHERENT | SET_VAL(RINGADDRL, addr);
|
||||
@@ -192,13 +192,15 @@ static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring)
|
||||
|
||||
static void xgene_enet_setup_coalescing(struct xgene_enet_desc_ring *ring)
|
||||
{
|
||||
u32 data = 0x7777;
|
||||
u32 data = 0x77777777;
|
||||
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_COAL, 0x8e);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK0, data);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK1, data);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data << 16);
|
||||
xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x40);
|
||||
xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x80);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK2, data);
|
||||
xgene_enet_ring_wr32(ring, CSR_PBM_CTICK3, data);
|
||||
xgene_enet_ring_wr32(ring, CSR_THRESHOLD0_SET1, 0x08);
|
||||
xgene_enet_ring_wr32(ring, CSR_THRESHOLD1_SET1, 0x10);
|
||||
}
|
||||
|
||||
struct xgene_ring_ops xgene_ring2_ops = {
|
||||
|
||||
@@ -307,6 +307,10 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac,
|
||||
u32 ctl;
|
||||
|
||||
ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL);
|
||||
|
||||
/* preserve ONLY bits 16-17 from current hardware value */
|
||||
ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
|
||||
|
||||
if (bgmac->feature_flags & BGMAC_FEAT_RX_MASK_SETUP) {
|
||||
ctl &= ~BGMAC_DMA_RX_BL_MASK;
|
||||
ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT;
|
||||
@@ -317,7 +321,6 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac,
|
||||
ctl &= ~BGMAC_DMA_RX_PT_MASK;
|
||||
ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT;
|
||||
}
|
||||
ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
|
||||
ctl |= BGMAC_DMA_RX_ENABLE;
|
||||
ctl |= BGMAC_DMA_RX_PARITY_DISABLE;
|
||||
ctl |= BGMAC_DMA_RX_OVERFLOW_CONT;
|
||||
@@ -1046,9 +1049,9 @@ static void bgmac_enable(struct bgmac *bgmac)
|
||||
|
||||
mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>
|
||||
BGMAC_DS_MM_SHIFT;
|
||||
if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) || mode != 0)
|
||||
if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST || mode != 0)
|
||||
bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
|
||||
if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST && mode == 2)
|
||||
if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) && mode == 2)
|
||||
bgmac_cco_ctl_maskset(bgmac, 1, ~0,
|
||||
BGMAC_CHIPCTL_1_RXC_DLL_BYPASS);
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/aer.h>
|
||||
#include <linux/crash_dump.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_CNIC)
|
||||
#define BCM_CNIC 1
|
||||
@@ -4764,15 +4765,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp)
|
||||
BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
|
||||
}
|
||||
|
||||
static int
|
||||
bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
|
||||
static void
|
||||
bnx2_wait_dma_complete(struct bnx2 *bp)
|
||||
{
|
||||
u32 val;
|
||||
int i, rc = 0;
|
||||
u8 old_port;
|
||||
int i;
|
||||
|
||||
/* Wait for the current PCI transaction to complete before
|
||||
* issuing a reset. */
|
||||
/*
|
||||
* Wait for the current PCI transaction to complete before
|
||||
* issuing a reset.
|
||||
*/
|
||||
if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||
|
||||
(BNX2_CHIP(bp) == BNX2_CHIP_5708)) {
|
||||
BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
|
||||
@@ -4796,6 +4798,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
|
||||
{
|
||||
u32 val;
|
||||
int i, rc = 0;
|
||||
u8 old_port;
|
||||
|
||||
/* Wait for the current PCI transaction to complete before
|
||||
* issuing a reset. */
|
||||
bnx2_wait_dma_complete(bp);
|
||||
|
||||
/* Wait for the firmware to tell us it is ok to issue a reset. */
|
||||
bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
|
||||
|
||||
@@ -6361,6 +6378,10 @@ bnx2_open(struct net_device *dev)
|
||||
struct bnx2 *bp = netdev_priv(dev);
|
||||
int rc;
|
||||
|
||||
rc = bnx2_request_firmware(bp);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
netif_carrier_off(dev);
|
||||
|
||||
bnx2_disable_int(bp);
|
||||
@@ -6429,6 +6450,7 @@ open_err:
|
||||
bnx2_free_irq(bp);
|
||||
bnx2_free_mem(bp);
|
||||
bnx2_del_napi(bp);
|
||||
bnx2_release_firmware(bp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -8571,12 +8593,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
rc = bnx2_request_firmware(bp);
|
||||
if (rc < 0)
|
||||
goto error;
|
||||
/*
|
||||
* In-flight DMA from 1st kernel could continue going in kdump kernel.
|
||||
* New io-page table has been created before bnx2 does reset at open stage.
|
||||
* We have to wait for the in-flight DMA to complete to avoid it look up
|
||||
* into the newly created io-page table.
|
||||
*/
|
||||
if (is_kdump_kernel())
|
||||
bnx2_wait_dma_complete(bp);
|
||||
|
||||
|
||||
bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
|
||||
memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
|
||||
|
||||
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
|
||||
@@ -8611,7 +8636,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
bnx2_release_firmware(bp);
|
||||
pci_iounmap(pdev, bp->regview);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
|
||||
@@ -6305,6 +6305,7 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
||||
struct tc_to_netdev *ntc)
|
||||
{
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
bool sh = false;
|
||||
u8 tc;
|
||||
|
||||
if (ntc->type != TC_SETUP_MQPRIO)
|
||||
@@ -6321,12 +6322,11 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
||||
if (netdev_get_num_tc(dev) == tc)
|
||||
return 0;
|
||||
|
||||
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
|
||||
sh = true;
|
||||
|
||||
if (tc) {
|
||||
int max_rx_rings, max_tx_rings, rc;
|
||||
bool sh = false;
|
||||
|
||||
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
|
||||
sh = true;
|
||||
|
||||
rc = bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh);
|
||||
if (rc || bp->tx_nr_rings_per_tc * tc > max_tx_rings)
|
||||
@@ -6344,7 +6344,8 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
|
||||
bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
|
||||
netdev_reset_tc(dev);
|
||||
}
|
||||
bp->cp_nr_rings = max_t(int, bp->tx_nr_rings, bp->rx_nr_rings);
|
||||
bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
|
||||
bp->tx_nr_rings + bp->rx_nr_rings;
|
||||
bp->num_stat_ctxs = bp->cp_nr_rings;
|
||||
|
||||
if (netif_running(bp->dev))
|
||||
|
||||
@@ -774,8 +774,8 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
|
||||
|
||||
if (vf->flags & BNXT_VF_LINK_UP) {
|
||||
/* if physical link is down, force link up on VF */
|
||||
if (phy_qcfg_resp.link ==
|
||||
PORT_PHY_QCFG_RESP_LINK_NO_LINK) {
|
||||
if (phy_qcfg_resp.link !=
|
||||
PORT_PHY_QCFG_RESP_LINK_LINK) {
|
||||
phy_qcfg_resp.link =
|
||||
PORT_PHY_QCFG_RESP_LINK_LINK;
|
||||
phy_qcfg_resp.link_speed = cpu_to_le16(
|
||||
|
||||
@@ -177,6 +177,7 @@ bnad_txcmpl_process(struct bnad *bnad, struct bna_tcb *tcb)
|
||||
return 0;
|
||||
|
||||
hw_cons = *(tcb->hw_consumer_index);
|
||||
rmb();
|
||||
cons = tcb->consumer_index;
|
||||
q_depth = tcb->q_depth;
|
||||
|
||||
@@ -3094,7 +3095,7 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
BNA_QE_INDX_INC(prod, q_depth);
|
||||
tcb->producer_index = prod;
|
||||
|
||||
smp_mb();
|
||||
wmb();
|
||||
|
||||
if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
|
||||
return NETDEV_TX_OK;
|
||||
@@ -3102,7 +3103,6 @@ bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
skb_tx_timestamp(skb);
|
||||
|
||||
bna_txq_prod_indx_doorbell(tcb);
|
||||
smp_mb();
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@@ -178,9 +178,9 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6005),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6006),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6007),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6008),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6009),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x600d),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6010),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6011),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6014),
|
||||
CH_PCI_ID_TABLE_FENTRY(0x6015),
|
||||
|
||||
@@ -332,8 +332,10 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev,
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
handle = dev->ops->get_handle(dev, port_id);
|
||||
if (IS_ERR(handle))
|
||||
if (IS_ERR(handle)) {
|
||||
put_device(&dev->cls_dev);
|
||||
return handle;
|
||||
}
|
||||
|
||||
handle->dev = dev;
|
||||
handle->owner_dev = owner_dev;
|
||||
@@ -356,6 +358,8 @@ out_when_init_queue:
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
hnae_fini_queue(handle->qs[j]);
|
||||
|
||||
put_device(&dev->cls_dev);
|
||||
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
EXPORT_SYMBOL(hnae_get_handle);
|
||||
@@ -377,6 +381,8 @@ void hnae_put_handle(struct hnae_handle *h)
|
||||
dev->ops->put_handle(h);
|
||||
|
||||
module_put(dev->owner);
|
||||
|
||||
put_device(&dev->cls_dev);
|
||||
}
|
||||
EXPORT_SYMBOL(hnae_put_handle);
|
||||
|
||||
|
||||
@@ -2438,6 +2438,8 @@ static int ehea_open(struct net_device *dev)
|
||||
|
||||
netif_info(port, ifup, dev, "enabling port\n");
|
||||
|
||||
netif_carrier_off(dev);
|
||||
|
||||
ret = ehea_up(dev);
|
||||
if (!ret) {
|
||||
port_napi_enable(port);
|
||||
|
||||
@@ -1493,9 +1493,8 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
|
||||
adapter->max_rx_add_entries_per_subcrq > entries_page ?
|
||||
entries_page : adapter->max_rx_add_entries_per_subcrq;
|
||||
|
||||
/* Choosing the maximum number of queues supported by firmware*/
|
||||
adapter->req_tx_queues = adapter->max_tx_queues;
|
||||
adapter->req_rx_queues = adapter->max_rx_queues;
|
||||
adapter->req_tx_queues = adapter->opt_tx_comp_sub_queues;
|
||||
adapter->req_rx_queues = adapter->opt_rx_comp_queues;
|
||||
adapter->req_rx_add_queues = adapter->max_rx_add_queues;
|
||||
|
||||
adapter->req_mtu = adapter->max_mtu;
|
||||
@@ -3698,7 +3697,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
|
||||
struct net_device *netdev;
|
||||
unsigned char *mac_addr_p;
|
||||
struct dentry *ent;
|
||||
char buf[16]; /* debugfs name buf */
|
||||
char buf[17]; /* debugfs name buf */
|
||||
int rc;
|
||||
|
||||
dev_dbg(&dev->dev, "entering ibmvnic_probe for UA 0x%x\n",
|
||||
@@ -3837,6 +3836,9 @@ static int ibmvnic_remove(struct vio_dev *dev)
|
||||
if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir))
|
||||
debugfs_remove_recursive(adapter->debugfs_dir);
|
||||
|
||||
dma_unmap_single(&dev->dev, adapter->stats_token,
|
||||
sizeof(struct ibmvnic_statistics), DMA_FROM_DEVICE);
|
||||
|
||||
if (adapter->ras_comps)
|
||||
dma_free_coherent(&dev->dev,
|
||||
adapter->ras_comp_num *
|
||||
|
||||
@@ -1379,6 +1379,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
|
||||
temp = (val & 0x003fff00) >> 8;
|
||||
|
||||
temp *= 64000000;
|
||||
temp += mp->t_clk / 2;
|
||||
do_div(temp, mp->t_clk);
|
||||
|
||||
return (unsigned int)temp;
|
||||
@@ -1415,6 +1416,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
|
||||
|
||||
temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4;
|
||||
temp *= 64000000;
|
||||
temp += mp->t_clk / 2;
|
||||
do_div(temp, mp->t_clk);
|
||||
|
||||
return (unsigned int)temp;
|
||||
|
||||
@@ -2254,7 +2254,6 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
|
||||
|
||||
if (!shutdown)
|
||||
free_netdev(dev);
|
||||
dev->ethtool_ops = NULL;
|
||||
}
|
||||
|
||||
static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
||||
@@ -1445,6 +1445,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
|
||||
c->netdev = priv->netdev;
|
||||
c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
|
||||
c->num_tc = priv->params.num_tc;
|
||||
c->xdp = !!priv->xdp_prog;
|
||||
|
||||
if (priv->params.rx_am_enabled)
|
||||
rx_cq_profile = mlx5e_am_get_def_profile(priv->params.rx_cq_period_mode);
|
||||
@@ -1468,6 +1469,12 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
|
||||
if (err)
|
||||
goto err_close_tx_cqs;
|
||||
|
||||
/* XDP SQ CQ params are same as normal TXQ sq CQ params */
|
||||
err = c->xdp ? mlx5e_open_cq(c, &cparam->tx_cq, &c->xdp_sq.cq,
|
||||
priv->params.tx_cq_moderation) : 0;
|
||||
if (err)
|
||||
goto err_close_rx_cq;
|
||||
|
||||
napi_enable(&c->napi);
|
||||
|
||||
err = mlx5e_open_sq(c, 0, &cparam->icosq, &c->icosq);
|
||||
@@ -1488,21 +1495,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->xdp_prog) {
|
||||
/* XDP SQ CQ params are same as normal TXQ sq CQ params */
|
||||
err = mlx5e_open_cq(c, &cparam->tx_cq, &c->xdp_sq.cq,
|
||||
priv->params.tx_cq_moderation);
|
||||
if (err)
|
||||
goto err_close_sqs;
|
||||
err = c->xdp ? mlx5e_open_sq(c, 0, &cparam->xdp_sq, &c->xdp_sq) : 0;
|
||||
if (err)
|
||||
goto err_close_sqs;
|
||||
|
||||
err = mlx5e_open_sq(c, 0, &cparam->xdp_sq, &c->xdp_sq);
|
||||
if (err) {
|
||||
mlx5e_close_cq(&c->xdp_sq.cq);
|
||||
goto err_close_sqs;
|
||||
}
|
||||
}
|
||||
|
||||
c->xdp = !!priv->xdp_prog;
|
||||
err = mlx5e_open_rq(c, &cparam->rq, &c->rq);
|
||||
if (err)
|
||||
goto err_close_xdp_sq;
|
||||
@@ -1512,7 +1508,8 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
|
||||
|
||||
return 0;
|
||||
err_close_xdp_sq:
|
||||
mlx5e_close_sq(&c->xdp_sq);
|
||||
if (c->xdp)
|
||||
mlx5e_close_sq(&c->xdp_sq);
|
||||
|
||||
err_close_sqs:
|
||||
mlx5e_close_sqs(c);
|
||||
@@ -1522,6 +1519,10 @@ err_close_icosq:
|
||||
|
||||
err_disable_napi:
|
||||
napi_disable(&c->napi);
|
||||
if (c->xdp)
|
||||
mlx5e_close_cq(&c->xdp_sq.cq);
|
||||
|
||||
err_close_rx_cq:
|
||||
mlx5e_close_cq(&c->rq.cq);
|
||||
|
||||
err_close_tx_cqs:
|
||||
|
||||
@@ -310,7 +310,7 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
|
||||
netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
|
||||
#endif
|
||||
|
||||
netdev->features |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC;
|
||||
netdev->features |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
|
||||
netdev->hw_features |= NETIF_F_HW_TC;
|
||||
|
||||
eth_hw_addr_random(netdev);
|
||||
|
||||
@@ -398,12 +398,15 @@ static int parse_cls_flower(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec
|
||||
skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_VLAN,
|
||||
f->mask);
|
||||
if (mask->vlan_id) {
|
||||
if (mask->vlan_id || mask->vlan_priority) {
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_c, vlan_tag, 1);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, vlan_tag, 1);
|
||||
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, mask->vlan_id);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, key->vlan_id);
|
||||
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, mask->vlan_priority);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, key->vlan_priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,8 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
|
||||
if (esw->mode != SRIOV_OFFLOADS)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
flow_act.action = attr->action;
|
||||
/* per flow vlan pop/push is emulated, don't set that into the firmware */
|
||||
flow_act.action = attr->action & ~(MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH | MLX5_FLOW_CONTEXT_ACTION_VLAN_POP);
|
||||
|
||||
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
|
||||
dest[i].type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
|
||||
|
||||
@@ -1836,7 +1836,7 @@ static int init_root_ns(struct mlx5_flow_steering *steering)
|
||||
{
|
||||
|
||||
steering->root_ns = create_root_ns(steering, FS_FT_NIC_RX);
|
||||
if (IS_ERR_OR_NULL(steering->root_ns))
|
||||
if (!steering->root_ns)
|
||||
goto cleanup;
|
||||
|
||||
if (init_root_tree(steering, &root_fs, &steering->root_ns->ns.node))
|
||||
|
||||
@@ -1226,6 +1226,9 @@ static int init_one(struct pci_dev *pdev,
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
dev->pdev = pdev;
|
||||
dev->event = mlx5_core_event;
|
||||
|
||||
if (prof_sel < 0 || prof_sel >= ARRAY_SIZE(profile)) {
|
||||
mlx5_core_warn(dev,
|
||||
"selected profile out of range, selecting default (%d)\n",
|
||||
@@ -1233,8 +1236,6 @@ static int init_one(struct pci_dev *pdev,
|
||||
prof_sel = MLX5_DEFAULT_PROF;
|
||||
}
|
||||
dev->profile = &profile[prof_sel];
|
||||
dev->pdev = pdev;
|
||||
dev->event = mlx5_core_event;
|
||||
|
||||
INIT_LIST_HEAD(&priv->ctx_list);
|
||||
spin_lock_init(&priv->ctx_lock);
|
||||
|
||||
@@ -231,7 +231,7 @@ mlxsw_sp_span_entry_create(struct mlxsw_sp_port *port)
|
||||
|
||||
span_entry->used = true;
|
||||
span_entry->id = index;
|
||||
span_entry->ref_count = 0;
|
||||
span_entry->ref_count = 1;
|
||||
span_entry->local_port = local_port;
|
||||
return span_entry;
|
||||
}
|
||||
@@ -270,6 +270,7 @@ static struct mlxsw_sp_span_entry
|
||||
|
||||
span_entry = mlxsw_sp_span_entry_find(port);
|
||||
if (span_entry) {
|
||||
/* Already exists, just take a reference */
|
||||
span_entry->ref_count++;
|
||||
return span_entry;
|
||||
}
|
||||
@@ -280,6 +281,7 @@ static struct mlxsw_sp_span_entry
|
||||
static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_span_entry *span_entry)
|
||||
{
|
||||
WARN_ON(!span_entry->ref_count);
|
||||
if (--span_entry->ref_count == 0)
|
||||
mlxsw_sp_span_entry_destroy(mlxsw_sp, span_entry);
|
||||
return 0;
|
||||
|
||||
@@ -115,7 +115,7 @@ struct mlxsw_sp_rif {
|
||||
struct mlxsw_sp_mid {
|
||||
struct list_head list;
|
||||
unsigned char addr[ETH_ALEN];
|
||||
u16 vid;
|
||||
u16 fid;
|
||||
u16 mid;
|
||||
unsigned int ref_count;
|
||||
};
|
||||
|
||||
@@ -589,21 +589,22 @@ static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp);
|
||||
|
||||
static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
mlxsw_sp_router_fib_flush(mlxsw_sp);
|
||||
kfree(mlxsw_sp->router.vrs);
|
||||
}
|
||||
|
||||
struct mlxsw_sp_neigh_key {
|
||||
unsigned char addr[sizeof(struct in6_addr)];
|
||||
struct net_device *dev;
|
||||
struct neighbour *n;
|
||||
};
|
||||
|
||||
struct mlxsw_sp_neigh_entry {
|
||||
struct rhash_head ht_node;
|
||||
struct mlxsw_sp_neigh_key key;
|
||||
u16 rif;
|
||||
struct neighbour *n;
|
||||
bool offloaded;
|
||||
struct delayed_work dw;
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
@@ -641,19 +642,15 @@ mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
|
||||
static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work);
|
||||
|
||||
static struct mlxsw_sp_neigh_entry *
|
||||
mlxsw_sp_neigh_entry_create(const void *addr, size_t addr_len,
|
||||
struct net_device *dev, u16 rif,
|
||||
struct neighbour *n)
|
||||
mlxsw_sp_neigh_entry_create(struct neighbour *n, u16 rif)
|
||||
{
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry;
|
||||
|
||||
neigh_entry = kzalloc(sizeof(*neigh_entry), GFP_ATOMIC);
|
||||
if (!neigh_entry)
|
||||
return NULL;
|
||||
memcpy(neigh_entry->key.addr, addr, addr_len);
|
||||
neigh_entry->key.dev = dev;
|
||||
neigh_entry->key.n = n;
|
||||
neigh_entry->rif = rif;
|
||||
neigh_entry->n = n;
|
||||
INIT_DELAYED_WORK(&neigh_entry->dw, mlxsw_sp_router_neigh_update_hw);
|
||||
INIT_LIST_HEAD(&neigh_entry->nexthop_list);
|
||||
return neigh_entry;
|
||||
@@ -666,13 +663,11 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp_neigh_entry *neigh_entry)
|
||||
}
|
||||
|
||||
static struct mlxsw_sp_neigh_entry *
|
||||
mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, const void *addr,
|
||||
size_t addr_len, struct net_device *dev)
|
||||
mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
|
||||
{
|
||||
struct mlxsw_sp_neigh_key key = {{ 0 } };
|
||||
struct mlxsw_sp_neigh_key key;
|
||||
|
||||
memcpy(key.addr, addr, addr_len);
|
||||
key.dev = dev;
|
||||
key.n = n;
|
||||
return rhashtable_lookup_fast(&mlxsw_sp->router.neigh_ht,
|
||||
&key, mlxsw_sp_neigh_ht_params);
|
||||
}
|
||||
@@ -684,26 +679,20 @@ int mlxsw_sp_router_neigh_construct(struct net_device *dev,
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry;
|
||||
struct mlxsw_sp_rif *r;
|
||||
u32 dip;
|
||||
int err;
|
||||
|
||||
if (n->tbl != &arp_tbl)
|
||||
return 0;
|
||||
|
||||
dip = ntohl(*((__be32 *) n->primary_key));
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &dip, sizeof(dip),
|
||||
n->dev);
|
||||
if (neigh_entry) {
|
||||
WARN_ON(neigh_entry->n != n);
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
|
||||
if (neigh_entry)
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, n->dev);
|
||||
if (WARN_ON(!r))
|
||||
return -EINVAL;
|
||||
|
||||
neigh_entry = mlxsw_sp_neigh_entry_create(&dip, sizeof(dip), n->dev,
|
||||
r->rif, n);
|
||||
neigh_entry = mlxsw_sp_neigh_entry_create(n, r->rif);
|
||||
if (!neigh_entry)
|
||||
return -ENOMEM;
|
||||
err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
|
||||
@@ -722,14 +711,11 @@ void mlxsw_sp_router_neigh_destroy(struct net_device *dev,
|
||||
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry;
|
||||
u32 dip;
|
||||
|
||||
if (n->tbl != &arp_tbl)
|
||||
return;
|
||||
|
||||
dip = ntohl(*((__be32 *) n->primary_key));
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &dip, sizeof(dip),
|
||||
n->dev);
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
|
||||
if (!neigh_entry)
|
||||
return;
|
||||
mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
|
||||
@@ -812,6 +798,26 @@ static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
|
||||
}
|
||||
}
|
||||
|
||||
static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl)
|
||||
{
|
||||
u8 num_rec, last_rec_index, num_entries;
|
||||
|
||||
num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl);
|
||||
last_rec_index = num_rec - 1;
|
||||
|
||||
if (num_rec < MLXSW_REG_RAUHTD_REC_MAX_NUM)
|
||||
return false;
|
||||
if (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, last_rec_index) ==
|
||||
MLXSW_REG_RAUHTD_TYPE_IPV6)
|
||||
return true;
|
||||
|
||||
num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl,
|
||||
last_rec_index);
|
||||
if (++num_entries == MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
char *rauhtd_pl;
|
||||
@@ -838,7 +844,7 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
|
||||
for (i = 0; i < num_rec; i++)
|
||||
mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl,
|
||||
i);
|
||||
} while (num_rec);
|
||||
} while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl));
|
||||
rtnl_unlock();
|
||||
|
||||
kfree(rauhtd_pl);
|
||||
@@ -857,7 +863,7 @@ static void mlxsw_sp_router_neighs_update_nh(struct mlxsw_sp *mlxsw_sp)
|
||||
* is active regardless of the traffic.
|
||||
*/
|
||||
if (!list_empty(&neigh_entry->nexthop_list))
|
||||
neigh_event_send(neigh_entry->n, NULL);
|
||||
neigh_event_send(neigh_entry->key.n, NULL);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
@@ -903,9 +909,9 @@ static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
|
||||
rtnl_lock();
|
||||
list_for_each_entry(neigh_entry, &mlxsw_sp->router.nexthop_neighs_list,
|
||||
nexthop_neighs_list_node) {
|
||||
if (!(neigh_entry->n->nud_state & NUD_VALID) &&
|
||||
if (!(neigh_entry->key.n->nud_state & NUD_VALID) &&
|
||||
!list_empty(&neigh_entry->nexthop_list))
|
||||
neigh_event_send(neigh_entry->n, NULL);
|
||||
neigh_event_send(neigh_entry->key.n, NULL);
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
@@ -922,7 +928,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
|
||||
{
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry =
|
||||
container_of(work, struct mlxsw_sp_neigh_entry, dw.work);
|
||||
struct neighbour *n = neigh_entry->n;
|
||||
struct neighbour *n = neigh_entry->key.n;
|
||||
struct mlxsw_sp_port *mlxsw_sp_port = neigh_entry->mlxsw_sp_port;
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
char rauht_pl[MLXSW_REG_RAUHT_LEN];
|
||||
@@ -1025,11 +1031,8 @@ int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
|
||||
|
||||
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
dip = ntohl(*((__be32 *) n->primary_key));
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp,
|
||||
&dip,
|
||||
sizeof(__be32),
|
||||
dev);
|
||||
if (WARN_ON(!neigh_entry) || WARN_ON(neigh_entry->n != n)) {
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
|
||||
if (WARN_ON(!neigh_entry)) {
|
||||
mlxsw_sp_port_dev_put(mlxsw_sp_port);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
@@ -1338,33 +1341,26 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp,
|
||||
struct fib_nh *fib_nh)
|
||||
{
|
||||
struct mlxsw_sp_neigh_entry *neigh_entry;
|
||||
u32 gwip = ntohl(fib_nh->nh_gw);
|
||||
struct net_device *dev = fib_nh->nh_dev;
|
||||
struct neighbour *n;
|
||||
u8 nud_state;
|
||||
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &gwip,
|
||||
sizeof(gwip), dev);
|
||||
if (!neigh_entry) {
|
||||
__be32 gwipn = htonl(gwip);
|
||||
|
||||
n = neigh_create(&arp_tbl, &gwipn, dev);
|
||||
/* Take a reference of neigh here ensuring that neigh would
|
||||
* not be detructed before the nexthop entry is finished.
|
||||
* The reference is taken either in neigh_lookup() or
|
||||
* in neith_create() in case n is not found.
|
||||
*/
|
||||
n = neigh_lookup(&arp_tbl, &fib_nh->nh_gw, dev);
|
||||
if (!n) {
|
||||
n = neigh_create(&arp_tbl, &fib_nh->nh_gw, dev);
|
||||
if (IS_ERR(n))
|
||||
return PTR_ERR(n);
|
||||
neigh_event_send(n, NULL);
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, &gwip,
|
||||
sizeof(gwip), dev);
|
||||
if (!neigh_entry) {
|
||||
neigh_release(n);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/* Take a reference of neigh here ensuring that neigh would
|
||||
* not be detructed before the nexthop entry is finished.
|
||||
* The second branch takes the reference in neith_create()
|
||||
*/
|
||||
n = neigh_entry->n;
|
||||
neigh_clone(n);
|
||||
}
|
||||
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
|
||||
if (!neigh_entry) {
|
||||
neigh_release(n);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If that is the first nexthop connected to that neigh, add to
|
||||
@@ -1398,7 +1394,7 @@ static void mlxsw_sp_nexthop_fini(struct mlxsw_sp *mlxsw_sp,
|
||||
if (list_empty(&nh->neigh_entry->nexthop_list))
|
||||
list_del(&nh->neigh_entry->nexthop_neighs_list_node);
|
||||
|
||||
neigh_release(neigh_entry->n);
|
||||
neigh_release(neigh_entry->key.n);
|
||||
}
|
||||
|
||||
static struct mlxsw_sp_nexthop_group *
|
||||
@@ -1458,11 +1454,11 @@ static bool mlxsw_sp_nexthop_match(struct mlxsw_sp_nexthop *nh,
|
||||
|
||||
for (i = 0; i < fi->fib_nhs; i++) {
|
||||
struct fib_nh *fib_nh = &fi->fib_nh[i];
|
||||
u32 gwip = ntohl(fib_nh->nh_gw);
|
||||
struct neighbour *n = nh->neigh_entry->key.n;
|
||||
|
||||
if (memcmp(nh->neigh_entry->key.addr,
|
||||
&gwip, sizeof(u32)) == 0 &&
|
||||
nh->neigh_entry->key.dev == fib_nh->nh_dev)
|
||||
if (memcmp(n->primary_key, &fib_nh->nh_gw,
|
||||
sizeof(fib_nh->nh_gw)) == 0 &&
|
||||
n->dev == fib_nh->nh_dev)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -1869,19 +1865,19 @@ static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp)
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
|
||||
}
|
||||
|
||||
static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
|
||||
static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
struct mlxsw_sp_fib_entry *fib_entry;
|
||||
struct mlxsw_sp_fib_entry *tmp;
|
||||
struct mlxsw_sp_vr *vr;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
if (mlxsw_sp->router.aborted)
|
||||
return;
|
||||
dev_warn(mlxsw_sp->bus_info->dev, "FIB abort triggered. Note that FIB entries are no longer being offloaded to this device.\n");
|
||||
for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
|
||||
vr = &mlxsw_sp->router.vrs[i];
|
||||
|
||||
if (!vr->used)
|
||||
continue;
|
||||
|
||||
@@ -1897,6 +1893,13 @@ static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
int err;
|
||||
|
||||
mlxsw_sp_router_fib_flush(mlxsw_sp);
|
||||
mlxsw_sp->router.aborted = true;
|
||||
err = mlxsw_sp_router_set_abort_trap(mlxsw_sp);
|
||||
if (err)
|
||||
@@ -1952,6 +1955,9 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
|
||||
struct fib_entry_notifier_info *fen_info = ptr;
|
||||
int err;
|
||||
|
||||
if (!net_eq(fen_info->info.net, &init_net))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
switch (event) {
|
||||
case FIB_EVENT_ENTRY_ADD:
|
||||
err = mlxsw_sp_router_fib4_add(mlxsw_sp, fen_info);
|
||||
|
||||
@@ -929,12 +929,12 @@ static int mlxsw_sp_port_smid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mid,
|
||||
|
||||
static struct mlxsw_sp_mid *__mlxsw_sp_mc_get(struct mlxsw_sp *mlxsw_sp,
|
||||
const unsigned char *addr,
|
||||
u16 vid)
|
||||
u16 fid)
|
||||
{
|
||||
struct mlxsw_sp_mid *mid;
|
||||
|
||||
list_for_each_entry(mid, &mlxsw_sp->br_mids.list, list) {
|
||||
if (ether_addr_equal(mid->addr, addr) && mid->vid == vid)
|
||||
if (ether_addr_equal(mid->addr, addr) && mid->fid == fid)
|
||||
return mid;
|
||||
}
|
||||
return NULL;
|
||||
@@ -942,7 +942,7 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_get(struct mlxsw_sp *mlxsw_sp,
|
||||
|
||||
static struct mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
|
||||
const unsigned char *addr,
|
||||
u16 vid)
|
||||
u16 fid)
|
||||
{
|
||||
struct mlxsw_sp_mid *mid;
|
||||
u16 mid_idx;
|
||||
@@ -958,7 +958,7 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
|
||||
|
||||
set_bit(mid_idx, mlxsw_sp->br_mids.mapped);
|
||||
ether_addr_copy(mid->addr, addr);
|
||||
mid->vid = vid;
|
||||
mid->fid = fid;
|
||||
mid->mid = mid_idx;
|
||||
mid->ref_count = 0;
|
||||
list_add_tail(&mid->list, &mlxsw_sp->br_mids.list);
|
||||
@@ -991,9 +991,9 @@ static int mlxsw_sp_port_mdb_add(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
if (switchdev_trans_ph_prepare(trans))
|
||||
return 0;
|
||||
|
||||
mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, mdb->vid);
|
||||
mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, fid);
|
||||
if (!mid) {
|
||||
mid = __mlxsw_sp_mc_alloc(mlxsw_sp, mdb->addr, mdb->vid);
|
||||
mid = __mlxsw_sp_mc_alloc(mlxsw_sp, mdb->addr, fid);
|
||||
if (!mid) {
|
||||
netdev_err(dev, "Unable to allocate MC group\n");
|
||||
return -ENOMEM;
|
||||
@@ -1137,7 +1137,7 @@ static int mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
u16 mid_idx;
|
||||
int err = 0;
|
||||
|
||||
mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, mdb->vid);
|
||||
mid = __mlxsw_sp_mc_get(mlxsw_sp, mdb->addr, fid);
|
||||
if (!mid) {
|
||||
netdev_err(dev, "Unable to remove port from MC DB\n");
|
||||
return -EINVAL;
|
||||
|
||||
@@ -727,9 +727,6 @@ struct core_tx_bd_flags {
|
||||
#define CORE_TX_BD_FLAGS_L4_PROTOCOL_SHIFT 6
|
||||
#define CORE_TX_BD_FLAGS_L4_PSEUDO_CSUM_MODE_MASK 0x1
|
||||
#define CORE_TX_BD_FLAGS_L4_PSEUDO_CSUM_MODE_SHIFT 7
|
||||
#define CORE_TX_BD_FLAGS_ROCE_FLAV_MASK 0x1
|
||||
#define CORE_TX_BD_FLAGS_ROCE_FLAV_SHIFT 12
|
||||
|
||||
};
|
||||
|
||||
struct core_tx_bd {
|
||||
|
||||
@@ -1119,6 +1119,7 @@ static void qed_ll2_prepare_tx_packet_set_bd(struct qed_hwfn *p_hwfn,
|
||||
start_bd->bd_flags.as_bitfield |= CORE_TX_BD_FLAGS_START_BD_MASK <<
|
||||
CORE_TX_BD_FLAGS_START_BD_SHIFT;
|
||||
SET_FIELD(start_bd->bitfield0, CORE_TX_BD_NBDS, num_of_bds);
|
||||
SET_FIELD(start_bd->bitfield0, CORE_TX_BD_ROCE_FLAV, type);
|
||||
DMA_REGPAIR_LE(start_bd->addr, first_frag);
|
||||
start_bd->nbytes = cpu_to_le16(first_frag_len);
|
||||
|
||||
|
||||
@@ -845,20 +845,19 @@ static void qed_update_pf_params(struct qed_dev *cdev,
|
||||
{
|
||||
int i;
|
||||
|
||||
if (IS_ENABLED(CONFIG_QED_RDMA)) {
|
||||
params->rdma_pf_params.num_qps = QED_ROCE_QPS;
|
||||
params->rdma_pf_params.min_dpis = QED_ROCE_DPIS;
|
||||
/* divide by 3 the MRs to avoid MF ILT overflow */
|
||||
params->rdma_pf_params.num_mrs = RDMA_MAX_TIDS;
|
||||
params->rdma_pf_params.gl_pi = QED_ROCE_PROTOCOL_INDEX;
|
||||
}
|
||||
|
||||
for (i = 0; i < cdev->num_hwfns; i++) {
|
||||
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
|
||||
|
||||
p_hwfn->pf_params = *params;
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_QED_RDMA))
|
||||
return;
|
||||
|
||||
params->rdma_pf_params.num_qps = QED_ROCE_QPS;
|
||||
params->rdma_pf_params.min_dpis = QED_ROCE_DPIS;
|
||||
/* divide by 3 the MRs to avoid MF ILT overflow */
|
||||
params->rdma_pf_params.num_mrs = RDMA_MAX_TIDS;
|
||||
params->rdma_pf_params.gl_pi = QED_ROCE_PROTOCOL_INDEX;
|
||||
}
|
||||
|
||||
static int qed_slowpath_start(struct qed_dev *cdev,
|
||||
|
||||
@@ -177,16 +177,23 @@ static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf)
|
||||
for (i = 0, k = 0; i < QEDE_QUEUE_CNT(edev); i++) {
|
||||
int tc;
|
||||
|
||||
for (j = 0; j < QEDE_NUM_RQSTATS; j++)
|
||||
sprintf(buf + (k + j) * ETH_GSTRING_LEN,
|
||||
"%d: %s", i, qede_rqstats_arr[j].string);
|
||||
k += QEDE_NUM_RQSTATS;
|
||||
for (tc = 0; tc < edev->num_tc; tc++) {
|
||||
for (j = 0; j < QEDE_NUM_TQSTATS; j++)
|
||||
if (edev->fp_array[i].type & QEDE_FASTPATH_RX) {
|
||||
for (j = 0; j < QEDE_NUM_RQSTATS; j++)
|
||||
sprintf(buf + (k + j) * ETH_GSTRING_LEN,
|
||||
"%d.%d: %s", i, tc,
|
||||
qede_tqstats_arr[j].string);
|
||||
k += QEDE_NUM_TQSTATS;
|
||||
"%d: %s", i,
|
||||
qede_rqstats_arr[j].string);
|
||||
k += QEDE_NUM_RQSTATS;
|
||||
}
|
||||
|
||||
if (edev->fp_array[i].type & QEDE_FASTPATH_TX) {
|
||||
for (tc = 0; tc < edev->num_tc; tc++) {
|
||||
for (j = 0; j < QEDE_NUM_TQSTATS; j++)
|
||||
sprintf(buf + (k + j) *
|
||||
ETH_GSTRING_LEN,
|
||||
"%d.%d: %s", i, tc,
|
||||
qede_tqstats_arr[j].string);
|
||||
k += QEDE_NUM_TQSTATS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2915,7 +2915,7 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq)
|
||||
}
|
||||
|
||||
mapping = dma_map_page(&edev->pdev->dev, replace_buf->data, 0,
|
||||
rxq->rx_buf_size, DMA_FROM_DEVICE);
|
||||
PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) {
|
||||
DP_NOTICE(edev,
|
||||
"Failed to map TPA replacement buffer\n");
|
||||
|
||||
@@ -575,10 +575,11 @@ void emac_mac_start(struct emac_adapter *adpt)
|
||||
|
||||
mac |= TXEN | RXEN; /* enable RX/TX */
|
||||
|
||||
/* We don't have ethtool support yet, so force flow-control mode
|
||||
* to 'full' always.
|
||||
*/
|
||||
mac |= TXFC | RXFC;
|
||||
/* Configure MAC flow control to match the PHY's settings. */
|
||||
if (phydev->pause)
|
||||
mac |= RXFC;
|
||||
if (phydev->pause != phydev->asym_pause)
|
||||
mac |= TXFC;
|
||||
|
||||
/* setup link speed */
|
||||
mac &= ~SPEED_MASK;
|
||||
@@ -1003,6 +1004,12 @@ int emac_mac_up(struct emac_adapter *adpt)
|
||||
writel((u32)~DIS_INT, adpt->base + EMAC_INT_STATUS);
|
||||
writel(adpt->irq.mask, adpt->base + EMAC_INT_MASK);
|
||||
|
||||
/* Enable pause frames. Without this feature, the EMAC has been shown
|
||||
* to receive (and drop) frames with FCS errors at gigabit connections.
|
||||
*/
|
||||
adpt->phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
|
||||
adpt->phydev->advertising |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
|
||||
|
||||
adpt->phydev->irq = PHY_IGNORE_INTERRUPT;
|
||||
phy_start(adpt->phydev);
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ static const struct emac_reg_write sgmii_v2_laned[] = {
|
||||
/* CDR Settings */
|
||||
{EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0,
|
||||
UCDR_STEP_BY_TWO_MODE0 | UCDR_xO_GAIN_MODE(10)},
|
||||
{EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(6)},
|
||||
{EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(0)},
|
||||
{EMAC_SGMII_LN_UCDR_SO_CONFIG, UCDR_ENABLE | UCDR_SO_SATURATION(12)},
|
||||
|
||||
/* TX/RX Settings */
|
||||
|
||||
@@ -485,6 +485,9 @@ efx_copy_channel(const struct efx_channel *old_channel)
|
||||
*channel = *old_channel;
|
||||
|
||||
channel->napi_dev = NULL;
|
||||
INIT_HLIST_NODE(&channel->napi_str.napi_hash_node);
|
||||
channel->napi_str.napi_id = 0;
|
||||
channel->napi_str.state = 0;
|
||||
memset(&channel->eventq, 0, sizeof(channel->eventq));
|
||||
|
||||
for (j = 0; j < EFX_TXQ_TYPES; j++) {
|
||||
|
||||
@@ -882,6 +882,13 @@ static int stmmac_init_phy(struct net_device *dev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* stmmac_adjust_link will change this to PHY_IGNORE_INTERRUPT to avoid
|
||||
* subsequent PHY polling, make sure we force a link transition if
|
||||
* we have a UP/DOWN/UP transition
|
||||
*/
|
||||
if (phydev->is_pseudo_fixed_link)
|
||||
phydev->irq = PHY_POLL;
|
||||
|
||||
pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)"
|
||||
" Link = %d\n", dev->name, phydev->phy_id, phydev->link);
|
||||
|
||||
|
||||
@@ -176,9 +176,12 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave)
|
||||
}
|
||||
|
||||
dev = bus_find_device(&platform_bus_type, NULL, node, match);
|
||||
of_node_put(node);
|
||||
priv = dev_get_drvdata(dev);
|
||||
|
||||
priv->cpsw_phy_sel(priv, phy_mode, slave);
|
||||
|
||||
put_device(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpsw_phy_sel);
|
||||
|
||||
|
||||
@@ -1410,6 +1410,7 @@ static int emac_dev_open(struct net_device *ndev)
|
||||
int i = 0;
|
||||
struct emac_priv *priv = netdev_priv(ndev);
|
||||
struct phy_device *phydev = NULL;
|
||||
struct device *phy = NULL;
|
||||
|
||||
ret = pm_runtime_get_sync(&priv->pdev->dev);
|
||||
if (ret < 0) {
|
||||
@@ -1488,19 +1489,20 @@ static int emac_dev_open(struct net_device *ndev)
|
||||
|
||||
/* use the first phy on the bus if pdata did not give us a phy id */
|
||||
if (!phydev && !priv->phy_id) {
|
||||
struct device *phy;
|
||||
|
||||
phy = bus_find_device(&mdio_bus_type, NULL, NULL,
|
||||
match_first_device);
|
||||
if (phy)
|
||||
if (phy) {
|
||||
priv->phy_id = dev_name(phy);
|
||||
if (!priv->phy_id || !*priv->phy_id)
|
||||
put_device(phy);
|
||||
}
|
||||
}
|
||||
|
||||
if (!phydev && priv->phy_id && *priv->phy_id) {
|
||||
phydev = phy_connect(ndev, priv->phy_id,
|
||||
&emac_adjust_link,
|
||||
PHY_INTERFACE_MODE_MII);
|
||||
|
||||
put_device(phy); /* reference taken by bus_find_device */
|
||||
if (IS_ERR(phydev)) {
|
||||
dev_err(emac_dev, "could not connect to phy %s\n",
|
||||
priv->phy_id);
|
||||
|
||||
@@ -1694,7 +1694,7 @@ struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl)
|
||||
pr_debug("%s: bssid matched\n", __func__);
|
||||
break;
|
||||
} else {
|
||||
pr_debug("%s: bssid unmached\n", __func__);
|
||||
pr_debug("%s: bssid unmatched\n", __func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,8 +708,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
|
||||
if (!qmgr_stat_below_low_watermark(rxq) &&
|
||||
napi_reschedule(napi)) { /* not empty again */
|
||||
#if DEBUG_RX
|
||||
printk(KERN_DEBUG "%s: eth_poll"
|
||||
" napi_reschedule successed\n",
|
||||
printk(KERN_DEBUG "%s: eth_poll napi_reschedule succeeded\n",
|
||||
dev->name);
|
||||
#endif
|
||||
qmgr_disable_irq(rxq);
|
||||
|
||||
Reference in New Issue
Block a user