summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-12-08 13:28:11 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-12-08 13:28:11 -0800
commit95e6ba5133163f8241c9ea2439369cec0452fec6 (patch)
tree3b84a8150537c03573ea8bfbd123e9cd52e19f3d /drivers
parent138f371ddf4ff50207dbe33ebfc237e756cd6222 (diff)
parent0fc75219fe9a3c90631453e9870e4f6d956f0ebc (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from David Miller: 1) More jumbo frame fixes in r8169, from Heiner Kallweit. 2) Fix bpf build in minimal configuration, from Alexei Starovoitov. 3) Use after free in slcan driver, from Jouni Hogander. 4) Flower classifier port ranges don't work properly in the HW offload case, from Yoshiki Komachi. 5) Use after free in hns3_nic_maybe_stop_tx(), from Yunsheng Lin. 6) Out of bounds access in mqprio_dump(), from Vladyslav Tarasiuk. 7) Fix flow dissection in dsa TX path, from Alexander Lobakin. 8) Stale syncookie timestampe fixes from Guillaume Nault. [ Did an evil merge to silence a warning introduced by this pull - Linus ] * git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (84 commits) r8169: fix rtl_hw_jumbo_disable for RTL8168evl net_sched: validate TCA_KIND attribute in tc_chain_tmplt_add() r8169: add missing RX enabling for WoL on RTL8125 vhost/vsock: accept only packets with the right dst_cid net: phy: dp83867: fix hfs boot in rgmii mode net: ethernet: ti: cpsw: fix extra rx interrupt inet: protect against too small mtu values. gre: refetch erspan header from skb->data after pskb_may_pull() pppoe: remove redundant BUG_ON() check in pppoe_pernet tcp: Protect accesses to .ts_recent_stamp with {READ,WRITE}_ONCE() tcp: tighten acceptance of ACKs not matching a child socket tcp: fix rejected syncookies due to stale timestamps lpc_eth: kernel BUG on remove tcp: md5: fix potential overestimation of TCP option space net: sched: allow indirect blocks to bind to clsact in TC net: core: rename indirect block ingress cb function net-sysfs: Call dev_hold always in netdev_queue_add_kobject net: dsa: fix flow dissection on Tx path net/tls: Fix return values to avoid ENOTSUPP net: avoid an indirect call in ____sys_recvmsg() ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/core/addr.c7
-rw-r--r--drivers/infiniband/sw/rxe/rxe_net.c8
-rw-r--r--drivers/net/can/slcan.c1
-rw-r--r--drivers/net/can/usb/ucan.c2
-rw-r--r--drivers/net/can/xilinx_can.c28
-rw-r--r--drivers/net/ethernet/cavium/thunder/thunder_bgx.c2
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc.c5
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3_enet.c50
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/port.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c27
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c31
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tx.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h9
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c122
-rw-r--r--drivers/net/ethernet/mscc/ocelot.c14
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c2
-rw-r--r--drivers/net/ethernet/pensando/ionic/ionic_lif.c16
-rw-r--r--drivers/net/ethernet/realtek/r8169_main.c4
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c2
-rw-r--r--drivers/net/ethernet/ti/Kconfig2
-rw-r--r--drivers/net/ethernet/ti/cpsw_priv.c2
-rw-r--r--drivers/net/geneve.c4
-rw-r--r--drivers/net/phy/dp83867.c119
-rw-r--r--drivers/net/phy/mdio-thunder.c1
-rw-r--r--drivers/net/phy/sfp.c17
-rw-r--r--drivers/net/ppp/ppp_generic.c5
-rw-r--r--drivers/net/ppp/pppoe.c2
-rw-r--r--drivers/net/vxlan.c8
-rw-r--r--drivers/s390/net/qeth_core.h4
-rw-r--r--drivers/s390/net/qeth_core_main.c158
-rw-r--r--drivers/s390/net/qeth_core_mpc.h14
-rw-r--r--drivers/s390/net/qeth_ethtool.c1
-rw-r--r--drivers/s390/net/qeth_l2_main.c12
-rw-r--r--drivers/s390/net/qeth_l3_main.c13
-rw-r--r--drivers/vhost/vsock.c4
41 files changed, 448 insertions, 305 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 6d7ec371e7b2..606fa6d86685 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -421,16 +421,15 @@ static int addr6_resolve(struct sockaddr *src_sock,
(const struct sockaddr_in6 *)dst_sock;
struct flowi6 fl6;
struct dst_entry *dst;
- int ret;
memset(&fl6, 0, sizeof fl6);
fl6.daddr = dst_in->sin6_addr;
fl6.saddr = src_in->sin6_addr;
fl6.flowi6_oif = addr->bound_dev_if;
- ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6);
- if (ret < 0)
- return ret;
+ dst = ipv6_stub->ipv6_dst_lookup_flow(addr->net, NULL, &fl6, NULL);
+ if (IS_ERR(dst))
+ return PTR_ERR(dst);
if (ipv6_addr_any(&src_in->sin6_addr))
src_in->sin6_addr = fl6.saddr;
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index 5a3474f9351b..312c2fc961c0 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -117,10 +117,12 @@ static struct dst_entry *rxe_find_route6(struct net_device *ndev,
memcpy(&fl6.daddr, daddr, sizeof(*daddr));
fl6.flowi6_proto = IPPROTO_UDP;
- if (unlikely(ipv6_stub->ipv6_dst_lookup(sock_net(recv_sockets.sk6->sk),
- recv_sockets.sk6->sk, &ndst, &fl6))) {
+ ndst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk),
+ recv_sockets.sk6->sk, &fl6,
+ NULL);
+ if (unlikely(IS_ERR(ndst))) {
pr_err_ratelimited("no route to %pI6\n", daddr);
- goto put;
+ return NULL;
}
if (unlikely(ndst->error)) {
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 0a9f42e5fedf..2e57122f02fb 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -617,6 +617,7 @@ err_free_chan:
sl->tty = NULL;
tty->disc_data = NULL;
clear_bit(SLF_INUSE, &sl->flags);
+ slc_free_netdev(sl->dev);
free_netdev(sl->dev);
err_exit:
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 04aac3bb54ef..81e942f713e6 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -792,7 +792,7 @@ resubmit:
up);
usb_anchor_urb(urb, &up->rx_urbs);
- ret = usb_submit_urb(urb, GFP_KERNEL);
+ ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret < 0) {
netdev_err(up->netdev,
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 4a96e2dd7d77..464af939cd8a 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -542,16 +542,17 @@ static int xcan_do_set_mode(struct net_device *ndev, enum can_mode mode)
/**
* xcan_write_frame - Write a frame to HW
- * @priv: Driver private data structure
+ * @ndev: Pointer to net_device structure
* @skb: sk_buff pointer that contains data to be Txed
* @frame_offset: Register offset to write the frame to
*/
-static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb,
+static void xcan_write_frame(struct net_device *ndev, struct sk_buff *skb,
int frame_offset)
{
u32 id, dlc, data[2] = {0, 0};
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
u32 ramoff, dwindex = 0, i;
+ struct xcan_priv *priv = netdev_priv(ndev);
/* Watch carefully on the bit sequence */
if (cf->can_id & CAN_EFF_FLAG) {
@@ -587,6 +588,14 @@ static void xcan_write_frame(struct xcan_priv *priv, struct sk_buff *skb,
dlc |= XCAN_DLCR_EDL_MASK;
}
+ if (!(priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES) &&
+ (priv->devtype.flags & XCAN_FLAG_TXFEMP))
+ can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
+ else
+ can_put_echo_skb(skb, ndev, 0);
+
+ priv->tx_head++;
+
priv->write_reg(priv, XCAN_FRAME_ID_OFFSET(frame_offset), id);
/* If the CAN frame is RTR frame this write triggers transmission
* (not on CAN FD)
@@ -638,13 +647,9 @@ static int xcan_start_xmit_fifo(struct sk_buff *skb, struct net_device *ndev)
XCAN_SR_TXFLL_MASK))
return -ENOSPC;
- can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
-
spin_lock_irqsave(&priv->tx_lock, flags);
- priv->tx_head++;
-
- xcan_write_frame(priv, skb, XCAN_TXFIFO_OFFSET);
+ xcan_write_frame(ndev, skb, XCAN_TXFIFO_OFFSET);
/* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */
if (priv->tx_max > 1)
@@ -675,13 +680,9 @@ static int xcan_start_xmit_mailbox(struct sk_buff *skb, struct net_device *ndev)
BIT(XCAN_TX_MAILBOX_IDX)))
return -ENOSPC;
- can_put_echo_skb(skb, ndev, 0);
-
spin_lock_irqsave(&priv->tx_lock, flags);
- priv->tx_head++;
-
- xcan_write_frame(priv, skb,
+ xcan_write_frame(ndev, skb,
XCAN_TXMSG_FRAME_OFFSET(XCAN_TX_MAILBOX_IDX));
/* Mark buffer as ready for transmit */
@@ -1772,7 +1773,8 @@ static int xcan_probe(struct platform_device *pdev)
priv->bus_clk = devm_clk_get(&pdev->dev, devtype->bus_clk_name);
if (IS_ERR(priv->bus_clk)) {
- dev_err(&pdev->dev, "bus clock not found\n");
+ if (PTR_ERR(priv->bus_clk) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "bus clock not found\n");
ret = PTR_ERR(priv->bus_clk);
goto err_free;
}
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 1e09fdb63c4f..c4f6ec0cd183 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -1115,7 +1115,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
phy_interface_mode(lmac->lmac_type)))
return -ENODEV;
- phy_start_aneg(lmac->phydev);
+ phy_start(lmac->phydev);
return 0;
}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 9db1b96ed9b9..17739906c966 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -1332,6 +1332,7 @@ static int enetc_phy_connect(struct net_device *ndev)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct phy_device *phydev;
+ struct ethtool_eee edata;
if (!priv->phy_node)
return 0; /* phy-less mode */
@@ -1345,6 +1346,10 @@ static int enetc_phy_connect(struct net_device *ndev)
phy_attached_info(phydev);
+ /* disable EEE autoneg, until ENETC driver supports it */
+ memset(&edata, 0, sizeof(struct ethtool_eee));
+ phy_ethtool_set_eee(phydev, &edata);
+
return 0;
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index ba0536802b13..69545dd6c938 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1287,30 +1287,25 @@ static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size,
}
static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
- struct sk_buff **out_skb)
+ struct net_device *netdev,
+ struct sk_buff *skb)
{
+ struct hns3_nic_priv *priv = netdev_priv(netdev);
unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U];
- struct sk_buff *skb = *out_skb;
unsigned int bd_num;
bd_num = hns3_tx_bd_num(skb, bd_size);
if (unlikely(bd_num > HNS3_MAX_NON_TSO_BD_NUM)) {
- struct sk_buff *new_skb;
-
if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) &&
!hns3_skb_need_linearized(skb, bd_size, bd_num))
goto out;
- /* manual split the send packet */
- new_skb = skb_copy(skb, GFP_ATOMIC);
- if (!new_skb)
+ if (__skb_linearize(skb))
return -ENOMEM;
- dev_kfree_skb_any(skb);
- *out_skb = new_skb;
- bd_num = hns3_tx_bd_count(new_skb->len);
- if ((skb_is_gso(new_skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
- (!skb_is_gso(new_skb) &&
+ bd_num = hns3_tx_bd_count(skb->len);
+ if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) ||
+ (!skb_is_gso(skb) &&
bd_num > HNS3_MAX_NON_TSO_BD_NUM))
return -ENOMEM;
@@ -1320,10 +1315,23 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
}
out:
- if (unlikely(ring_space(ring) < bd_num))
- return -EBUSY;
+ if (likely(ring_space(ring) >= bd_num))
+ return bd_num;
- return bd_num;
+ netif_stop_subqueue(netdev, ring->queue_index);
+ smp_mb(); /* Memory barrier before checking ring_space */
+
+ /* Start queue in case hns3_clean_tx_ring has just made room
+ * available and has not seen the queue stopped state performed
+ * by netif_stop_subqueue above.
+ */
+ if (ring_space(ring) >= bd_num && netif_carrier_ok(netdev) &&
+ !test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) {
+ netif_start_subqueue(netdev, ring->queue_index);
+ return bd_num;
+ }
+
+ return -EBUSY;
}
static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
@@ -1400,13 +1408,13 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
/* Prefetch the data used later */
prefetch(skb->data);
- ret = hns3_nic_maybe_stop_tx(ring, &skb);
+ ret = hns3_nic_maybe_stop_tx(ring, netdev, skb);
if (unlikely(ret <= 0)) {
if (ret == -EBUSY) {
u64_stats_update_begin(&ring->syncp);
ring->stats.tx_busy++;
u64_stats_update_end(&ring->syncp);
- goto out_net_tx_busy;
+ return NETDEV_TX_BUSY;
} else if (ret == -ENOMEM) {
u64_stats_update_begin(&ring->syncp);
ring->stats.sw_err_cnt++;
@@ -1457,12 +1465,6 @@ fill_err:
out_err_tx_ok:
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
-
-out_net_tx_busy:
- netif_stop_subqueue(netdev, ring->queue_index);
- smp_mb(); /* Commit all data before submit */
-
- return NETDEV_TX_BUSY;
}
static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p)
@@ -2519,7 +2521,7 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring)
dev_queue = netdev_get_tx_queue(netdev, ring->tqp->tqp_index);
netdev_tx_completed_queue(dev_queue, pkts, bytes);
- if (unlikely(pkts && netif_carrier_ok(netdev) &&
+ if (unlikely(netif_carrier_ok(netdev) &&
ring_space(ring) > HNS3_MAX_TSO_BD_NUM)) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 7c7038676d6d..d862e9ba27e1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -8438,13 +8438,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
if (hdev->pdev->revision == 0x20)
return -EOPNOTSUPP;
+ vport = hclge_get_vf_vport(hdev, vfid);
+ if (!vport)
+ return -EINVAL;
+
/* qos is a 3 bits value, so can not be bigger than 7 */
- if (vfid >= hdev->num_alloc_vfs || vlan > VLAN_N_VID - 1 || qos > 7)
+ if (vlan > VLAN_N_VID - 1 || qos > 7)
return -EINVAL;
if (proto != htons(ETH_P_8021Q))
return -EPROTONOSUPPORT;
- vport = &hdev->vport[vfid];
state = hclge_get_port_base_vlan_state(vport,
vport->port_base_vlan_cfg.state,
vlan);
@@ -8455,21 +8458,12 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
vlan_info.qos = qos;
vlan_info.vlan_proto = ntohs(proto);
- /* update port based VLAN for PF */
- if (!vfid) {
- hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
- ret = hclge_update_port_base_vlan_cfg(vport, state, &vlan_info);
- hclge_notify_client(hdev, HNAE3_UP_CLIENT);
-
- return ret;
- }
-
if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
return hclge_update_port_base_vlan_cfg(vport, state,
&vlan_info);
} else {
ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
- (u8)vfid, state,
+ vport->vport_id, state,
vlan, qos,
ntohs(proto));
return ret;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index f1a7bc46f1c0..2c16add0b642 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -816,7 +816,7 @@ struct mlx5e_xsk {
struct mlx5e_priv {
/* priv data path fields - start */
struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC];
- int channel_tc2txq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
+ int channel_tc2realtxq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
#ifdef CONFIG_MLX5_CORE_EN_DCB
struct mlx5e_dcbx_dp dcbx_dp;
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
index f777994f3005..fce6eccdcf8b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
@@ -73,6 +73,7 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = {
[MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000,
[MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = 50000,
[MLX5E_CAUI_4_100GBASE_CR4_KR4] = 100000,
+ [MLX5E_100GAUI_2_100GBASE_CR2_KR2] = 100000,
[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000,
[MLX5E_400GAUI_8] = 400000,
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
index 7b672ada63a3..ae99fac08b53 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
@@ -155,8 +155,11 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
}
if (port_buffer->buffer[i].size <
- (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
+ (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) {
+ pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
+ i, port_buffer->buffer[i].size);
return -ENOMEM;
+ }
port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff;
port_buffer->buffer[i].xon =
@@ -232,6 +235,26 @@ static int update_buffer_lossy(unsigned int max_mtu,
return 0;
}
+static int fill_pfc_en(struct mlx5_core_dev *mdev, u8 *pfc_en)
+{
+ u32 g_rx_pause, g_tx_pause;
+ int err;
+
+ err = mlx5_query_port_pause(mdev, &g_rx_pause, &g_tx_pause);
+ if (err)
+ return err;
+
+ /* If global pause enabled, set all active buffers to lossless.
+ * Otherwise, check PFC setting.
+ */
+ if (g_rx_pause || g_tx_pause)
+ *pfc_en = 0xff;
+ else
+ err = mlx5_query_port_pfc(mdev, pfc_en, NULL);
+
+ return err;
+}
+
#define MINIMUM_MAX_MTU 9216
int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
u32 change, unsigned int mtu,
@@ -277,7 +300,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) {
update_prio2buffer = true;
- err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL);
+ err = fill_pfc_en(priv->mdev, &curr_pfc_en);
if (err)
return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
index 6ed87534d314..af4ebd2951b5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
@@ -297,10 +297,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
int ret;
- ret = ipv6_stub->ipv6_dst_lookup(dev_net(mirred_dev), NULL, &dst,
- fl6);
- if (ret < 0)
- return ret;
+ dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(mirred_dev), NULL, fl6,
+ NULL);
+ if (IS_ERR(dst))
+ return PTR_ERR(dst);
if (!(*out_ttl))
*out_ttl = ip6_dst_hoplimit(dst);
@@ -329,7 +329,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
struct net_device *out_dev, *route_dev;
struct flowi6 fl6 = {};
struct ipv6hdr *ip6h;
- struct neighbour *n;
+ struct neighbour *n = NULL;
int ipv6_encap_size;
char *encap_header;
u8 nud_state, ttl;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 95601269fa2e..c6776f308d5e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1027,18 +1027,11 @@ static bool ext_link_mode_requested(const unsigned long *adver)
return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS);
}
-static bool ext_speed_requested(u32 speed)
-{
-#define MLX5E_MAX_PTYS_LEGACY_SPEED 100000
- return !!(speed > MLX5E_MAX_PTYS_LEGACY_SPEED);
-}
-
-static bool ext_requested(u8 autoneg, const unsigned long *adver, u32 speed)
+static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported)
{
bool ext_link_mode = ext_link_mode_requested(adver);
- bool ext_speed = ext_speed_requested(speed);
- return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_speed;
+ return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported;
}
int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
@@ -1065,8 +1058,8 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
autoneg = link_ksettings->base.autoneg;
speed = link_ksettings->base.speed;
- ext = ext_requested(autoneg, adver, speed),
ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
+ ext = ext_requested(autoneg, adver, ext_supported);
if (!ext_supported && ext)
return -EOPNOTSUPP;
@@ -1643,7 +1636,7 @@ static int mlx5e_get_module_info(struct net_device *netdev,
break;
case MLX5_MODULE_ID_SFP:
modinfo->type = ETH_MODULE_SFF_8472;
- modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
break;
default:
netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n",
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 09ed7f5f688b..4980e80a5e85 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1691,11 +1691,10 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
struct mlx5e_params *params,
struct mlx5e_channel_param *cparam)
{
- struct mlx5e_priv *priv = c->priv;
int err, tc;
for (tc = 0; tc < params->num_tc; tc++) {
- int txq_ix = c->ix + tc * priv->max_nch;
+ int txq_ix = c->ix + tc * params->num_channels;
err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix,
params, &cparam->sq, &c->sq[tc], tc);
@@ -2876,26 +2875,21 @@ static void mlx5e_netdev_set_tcs(struct net_device *netdev)
netdev_set_tc_queue(netdev, tc, nch, 0);
}
-static void mlx5e_build_tc2txq_maps(struct mlx5e_priv *priv)
+static void mlx5e_build_txq_maps(struct mlx5e_priv *priv)
{
- int i, tc;
+ int i, ch;
- for (i = 0; i < priv->max_nch; i++)
- for (tc = 0; tc < priv->profile->max_tc; tc++)
- priv->channel_tc2txq[i][tc] = i + tc * priv->max_nch;
-}
+ ch = priv->channels.num;
-static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv)
-{
- struct mlx5e_channel *c;
- struct mlx5e_txqsq *sq;
- int i, tc;
+ for (i = 0; i < ch; i++) {
+ int tc;
+
+ for (tc = 0; tc < priv->channels.params.num_tc; tc++) {
+ struct mlx5e_channel *c = priv->channels.c[i];
+ struct mlx5e_txqsq *sq = &c->sq[tc];
- for (i = 0; i < priv->channels.num; i++) {
- c = priv->channels.c[i];
- for (tc = 0; tc < c->num_tc; tc++) {
- sq = &c->sq[tc];
priv->txq2sq[sq->txq_ix] = sq;
+ priv->channel_tc2realtxq[i][tc] = i + tc * ch;
}
}
}
@@ -2910,7 +2904,7 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
netif_set_real_num_tx_queues(netdev, num_txqs);
netif_set_real_num_rx_queues(netdev, num_rxqs);
- mlx5e_build_tx2sq_maps(priv);
+ mlx5e_build_txq_maps(priv);
mlx5e_activate_channels(&priv->channels);
mlx5e_xdp_tx_enable(priv);
netif_tx_start_all_queues(priv->netdev);
@@ -5021,7 +5015,6 @@ static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
if (err)
mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
mlx5e_build_nic_netdev(netdev);
- mlx5e_build_tc2txq_maps(priv);
mlx5e_health_create_reporters(priv);
return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
index 7e6ebd0505cc..9f09253f9f46 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
@@ -1601,7 +1601,7 @@ static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data,
for (j = 0; j < NUM_SQ_STATS; j++)
sprintf(data + (idx++) * ETH_GSTRING_LEN,
sq_stats_desc[j].format,
- priv->channel_tc2txq[i][tc]);
+ i + tc * max_nch);
for (i = 0; i < max_nch; i++) {
for (j = 0; j < NUM_XSKSQ_STATS * is_xsk; j++)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 0d5d84b5fa23..9b32a9c0f497 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -1626,8 +1626,11 @@ static void __mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *flow)
flow_flag_clear(flow, DUP);
- mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow);
- kvfree(flow->peer_flow);
+ if (refcount_dec_and_test(&flow->peer_flow->refcnt)) {
+ mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow);
+ kfree(flow->peer_flow);
+ }
+
flow->peer_flow = NULL;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
index 66951ff975f4..2565ba8692d9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -93,7 +93,7 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
if (txq_ix >= num_channels)
txq_ix = priv->txq2sq[txq_ix]->ch_ix;
- return priv->channel_tc2txq[txq_ix][up];
+ return priv->channel_tc2realtxq[txq_ix][up];
}
static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 962888a7c3c9..ffcff3ba3701 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -81,7 +81,14 @@ struct vport_ingress {
struct mlx5_fc *drop_counter;
} legacy;
struct {
- struct mlx5_flow_group *metadata_grp;
+ /* Optional group to add an FTE to do internal priority
+ * tagging on ingress packets.
+ */
+