mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) nfnetlink timestamp taken from wrong skb, fix from Florian Westphal.
2) Revert some msleep conversions in rtlwifi as these spots are in
atomic context, from Larry Finger.
3) Validate that NFTA_SET_TABLE attribute is actually specified when we
call nf_tables_getset(). From Phil Turnbull.
4) Don't do mdio_reset in stmmac driver with spinlock held as that can
sleep, from Vincent Palatin.
5) sk_filter() does things other than run a BPF filter, so we should
not elide it's call just because sk->sk_filter is NULL. Fix from
Eric Dumazet.
6) Fix missing backlog updates in several packet schedulers, from Cong
Wang.
7) bnx2x driver should allow VLAN add/remove while the interface is
down, from Michal Schmidt.
8) Several RDS/TCP race fixes from Sowmini Varadhan.
9) fq_codel scheduler doesn't return correct queue length in dumps,
from Eric Dumazet.
10) Fix TCP stats for tail loss probe and early retransmit in ipv6, from
Yuchung Cheng.
11) Properly initialize udp_tunnel_socket_cfg in l2tp_tunnel_create(),
from Guillaume Nault.
12) qfq scheduler leaks SKBs if a kzalloc fails, fix from Florian
Westphal.
13) sock_fprog passed into PACKET_FANOUT_DATA needs compat handling,
from Willem de Bruijn.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (85 commits)
vmxnet3: segCnt can be 1 for LRO packets
packet: compat support for sock_fprog
stmmac: fix parameter to dwmac4_set_umac_addr()
net/mlx5e: Fix blue flame quota logic
net/mlx5e: Use ndo_stop explicitly at shutdown flow
net/mlx5: E-Switch, always set mc_promisc for allmulti vports
net/mlx5: E-Switch, Modify node guid on vf set MAC
net/mlx5: E-Switch, Fix vport enable flow
net/mlx5: E-Switch, Use the correct error check on returned pointers
net/mlx5: E-Switch, Use the correct free() function
net/mlx5: Fix E-Switch flow steering capabilities check
net/mlx5: Fix flow steering NIC capabilities check
net/mlx5: Fix root flow table update
net/mlx5: Fix MLX5_CMD_OP_MAX to be defined correctly
net/mlx5: Fix masking of reserved bits in XRCD number
net/mlx5: Fix the size of modify QP mailbox
mlxsw: spectrum: Don't sleep during ndo_get_phys_port_name()
mlxsw: spectrum: Make split flow match firmware requirements
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel
cfg80211: remove get/set antenna and tx power warnings
...
This commit is contained in:
commit
698ea54dde
93 files changed
+830
-462
No files matched your search
@@ -8009,6 +8009,7 @@ Q: http://patchwork.kernel.org/project/linux-wireless/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/wireless/
|
||||
F: drivers/net/wireless/
|
||||
|
||||
NETXEN (1/10) GbE SUPPORT
|
||||
|
||||
@@ -12895,52 +12895,71 @@ static int __bnx2x_vlan_configure_vid(struct bnx2x *bp, u16 vid, bool add)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
|
||||
static int bnx2x_vlan_configure_vid_list(struct bnx2x *bp)
|
||||
{
|
||||
struct bnx2x_vlan_entry *vlan;
|
||||
int rc = 0;
|
||||
|
||||
if (!bp->vlan_cnt) {
|
||||
DP(NETIF_MSG_IFUP, "No need to re-configure vlan filters\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Configure all non-configured entries */
|
||||
list_for_each_entry(vlan, &bp->vlan_reg, link) {
|
||||
/* Prepare for cleanup in case of errors */
|
||||
if (rc) {
|
||||
vlan->hw = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!vlan->hw)
|
||||
if (vlan->hw)
|
||||
continue;
|
||||
|
||||
DP(NETIF_MSG_IFUP, "Re-configuring vlan 0x%04x\n", vlan->vid);
|
||||
if (bp->vlan_cnt >= bp->vlan_credit)
|
||||
return -ENOBUFS;
|
||||
|
||||
rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
|
||||
if (rc) {
|
||||
BNX2X_ERR("Unable to configure VLAN %d\n", vlan->vid);
|
||||
vlan->hw = false;
|
||||
rc = -EINVAL;
|
||||
continue;
|
||||
BNX2X_ERR("Unable to config VLAN %d\n", vlan->vid);
|
||||
return rc;
|
||||
}
|
||||
|
||||
DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n", vlan->vid);
|
||||
vlan->hw = true;
|
||||
bp->vlan_cnt++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bnx2x_vlan_configure(struct bnx2x *bp, bool set_rx_mode)
|
||||
{
|
||||
bool need_accept_any_vlan;
|
||||
|
||||
need_accept_any_vlan = !!bnx2x_vlan_configure_vid_list(bp);
|
||||
|
||||
if (bp->accept_any_vlan != need_accept_any_vlan) {
|
||||
bp->accept_any_vlan = need_accept_any_vlan;
|
||||
DP(NETIF_MSG_IFUP, "Accept all VLAN %s\n",
|
||||
bp->accept_any_vlan ? "raised" : "cleared");
|
||||
if (set_rx_mode) {
|
||||
if (IS_PF(bp))
|
||||
bnx2x_set_rx_mode_inner(bp);
|
||||
else
|
||||
bnx2x_vfpf_storm_rx_mode(bp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bnx2x_vlan_reconfigure_vid(struct bnx2x *bp)
|
||||
{
|
||||
struct bnx2x_vlan_entry *vlan;
|
||||
|
||||
/* The hw forgot all entries after reload */
|
||||
list_for_each_entry(vlan, &bp->vlan_reg, link)
|
||||
vlan->hw = false;
|
||||
bp->vlan_cnt = 0;
|
||||
|
||||
/* Don't set rx mode here. Our caller will do it. */
|
||||
bnx2x_vlan_configure(bp, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
|
||||
{
|
||||
struct bnx2x *bp = netdev_priv(dev);
|
||||
struct bnx2x_vlan_entry *vlan;
|
||||
bool hw = false;
|
||||
int rc = 0;
|
||||
|
||||
if (!netif_running(bp->dev)) {
|
||||
DP(NETIF_MSG_IFUP,
|
||||
"Ignoring VLAN configuration the interface is down\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid);
|
||||
|
||||
@@ -12948,93 +12967,47 @@ static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
|
||||
if (!vlan)
|
||||
return -ENOMEM;
|
||||
|
||||
bp->vlan_cnt++;
|
||||
if (bp->vlan_cnt > bp->vlan_credit && !bp->accept_any_vlan) {
|
||||
DP(NETIF_MSG_IFUP, "Accept all VLAN raised\n");
|
||||
bp->accept_any_vlan = true;
|
||||
if (IS_PF(bp))
|
||||
bnx2x_set_rx_mode_inner(bp);
|
||||
else
|
||||
bnx2x_vfpf_storm_rx_mode(bp);
|
||||
} else if (bp->vlan_cnt <= bp->vlan_credit) {
|
||||
rc = __bnx2x_vlan_configure_vid(bp, vid, true);
|
||||
hw = true;
|
||||
}
|
||||
|
||||
vlan->vid = vid;
|
||||
vlan->hw = hw;
|
||||
vlan->hw = false;
|
||||
list_add_tail(&vlan->link, &bp->vlan_reg);
|
||||
|
||||
if (!rc) {
|
||||
list_add(&vlan->link, &bp->vlan_reg);
|
||||
} else {
|
||||
bp->vlan_cnt--;
|
||||
kfree(vlan);
|
||||
}
|
||||
if (netif_running(dev))
|
||||
bnx2x_vlan_configure(bp, true);
|
||||
|
||||
DP(NETIF_MSG_IFUP, "Adding VLAN result %d\n", rc);
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnx2x_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
|
||||
{
|
||||
struct bnx2x *bp = netdev_priv(dev);
|
||||
struct bnx2x_vlan_entry *vlan;
|
||||
bool found = false;
|
||||
int rc = 0;
|
||||
|
||||
if (!netif_running(bp->dev)) {
|
||||
DP(NETIF_MSG_IFUP,
|
||||
"Ignoring VLAN configuration the interface is down\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
DP(NETIF_MSG_IFUP, "Removing VLAN %d\n", vid);
|
||||
|
||||
if (!bp->vlan_cnt) {
|
||||
BNX2X_ERR("Unable to kill VLAN %d\n", vid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
list_for_each_entry(vlan, &bp->vlan_reg, link)
|
||||
if (vlan->vid == vid)
|
||||
if (vlan->vid == vid) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (vlan->vid != vid) {
|
||||
if (!found) {
|
||||
BNX2X_ERR("Unable to kill VLAN %d - not found\n", vid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vlan->hw)
|
||||
if (netif_running(dev) && vlan->hw) {
|
||||
rc = __bnx2x_vlan_configure_vid(bp, vid, false);
|
||||
DP(NETIF_MSG_IFUP, "HW deconfigured for VLAN %d\n", vid);
|
||||
bp->vlan_cnt--;
|
||||
}
|
||||
|
||||
list_del(&vlan->link);
|
||||
kfree(vlan);
|
||||
|
||||
bp->vlan_cnt--;
|
||||
|
||||
if (bp->vlan_cnt <= bp->vlan_credit && bp->accept_any_vlan) {
|
||||
/* Configure all non-configured entries */
|
||||
list_for_each_entry(vlan, &bp->vlan_reg, link) {
|
||||
if (vlan->hw)
|
||||
continue;
|
||||
|
||||
rc = __bnx2x_vlan_configure_vid(bp, vlan->vid, true);
|
||||
if (rc) {
|
||||
BNX2X_ERR("Unable to config VLAN %d\n",
|
||||
vlan->vid);
|
||||
continue;
|
||||
}
|
||||
DP(NETIF_MSG_IFUP, "HW configured for VLAN %d\n",
|
||||
vlan->vid);
|
||||
vlan->hw = true;
|
||||
}
|
||||
DP(NETIF_MSG_IFUP, "Accept all VLAN Removed\n");
|
||||
bp->accept_any_vlan = false;
|
||||
if (IS_PF(bp))
|
||||
bnx2x_set_rx_mode_inner(bp);
|
||||
else
|
||||
bnx2x_vfpf_storm_rx_mode(bp);
|
||||
}
|
||||
if (netif_running(dev))
|
||||
bnx2x_vlan_configure(bp, true);
|
||||
|
||||
DP(NETIF_MSG_IFUP, "Removing VLAN result %d\n", rc);
|
||||
|
||||
|
||||
@@ -286,7 +286,9 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
cpu_to_le32(DB_KEY_TX_PUSH | DB_LONG_TX_PUSH | prod);
|
||||
txr->tx_prod = prod;
|
||||
|
||||
tx_buf->is_push = 1;
|
||||
netdev_tx_sent_queue(txq, skb->len);
|
||||
wmb(); /* Sync is_push and byte queue before pushing data */
|
||||
|
||||
push_len = (length + sizeof(*tx_push) + 7) / 8;
|
||||
if (push_len > 16) {
|
||||
@@ -298,7 +300,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
push_len);
|
||||
}
|
||||
|
||||
tx_buf->is_push = 1;
|
||||
goto tx_done;
|
||||
}
|
||||
|
||||
@@ -1112,19 +1113,13 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
|
||||
if (tpa_info->hash_type != PKT_HASH_TYPE_NONE)
|
||||
skb_set_hash(skb, tpa_info->rss_hash, tpa_info->hash_type);
|
||||
|
||||
if (tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) {
|
||||
netdev_features_t features = skb->dev->features;
|
||||
if ((tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) &&
|
||||
(skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
|
||||
u16 vlan_proto = tpa_info->metadata >>
|
||||
RX_CMP_FLAGS2_METADATA_TPID_SFT;
|
||||
u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_VID_MASK;
|
||||
|
||||
if (((features & NETIF_F_HW_VLAN_CTAG_RX) &&
|
||||
vlan_proto == ETH_P_8021Q) ||
|
||||
((features & NETIF_F_HW_VLAN_STAG_RX) &&
|
||||
vlan_proto == ETH_P_8021AD)) {
|
||||
__vlan_hwaccel_put_tag(skb, htons(vlan_proto),
|
||||
tpa_info->metadata &
|
||||
RX_CMP_FLAGS2_METADATA_VID_MASK);
|
||||
}
|
||||
__vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag);
|
||||
}
|
||||
|
||||
skb_checksum_none_assert(skb);
|
||||
@@ -1277,19 +1272,14 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons,
|
||||
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
|
||||
if (rxcmp1->rx_cmp_flags2 &
|
||||
cpu_to_le32(RX_CMP_FLAGS2_META_FORMAT_VLAN)) {
|
||||
netdev_features_t features = skb->dev->features;
|
||||
if ((rxcmp1->rx_cmp_flags2 &
|
||||
cpu_to_le32(RX_CMP_FLAGS2_META_FORMAT_VLAN)) &&
|
||||
(skb->dev->features & NETIF_F_HW_VLAN_CTAG_RX)) {
|
||||
u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data);
|
||||
u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_VID_MASK;
|
||||
u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT;
|
||||
|
||||
if (((features & NETIF_F_HW_VLAN_CTAG_RX) &&
|
||||
vlan_proto == ETH_P_8021Q) ||
|
||||
((features & NETIF_F_HW_VLAN_STAG_RX) &&
|
||||
vlan_proto == ETH_P_8021AD))
|
||||
__vlan_hwaccel_put_tag(skb, htons(vlan_proto),
|
||||
meta_data &
|
||||
RX_CMP_FLAGS2_METADATA_VID_MASK);
|
||||
__vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag);
|
||||
}
|
||||
|
||||
skb_checksum_none_assert(skb);
|
||||
@@ -5466,6 +5456,20 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev,
|
||||
|
||||
if (!bnxt_rfs_capable(bp))
|
||||
features &= ~NETIF_F_NTUPLE;
|
||||
|
||||
/* Both CTAG and STAG VLAN accelaration on the RX side have to be
|
||||
* turned on or off together.
|
||||
*/
|
||||
if ((features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) !=
|
||||
(NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) {
|
||||
if (dev->features & NETIF_F_HW_VLAN_CTAG_RX)
|
||||
features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
|
||||
NETIF_F_HW_VLAN_STAG_RX);
|
||||
else
|
||||
features |= NETIF_F_HW_VLAN_CTAG_RX |
|
||||
NETIF_F_HW_VLAN_STAG_RX;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5015), /* T502-bt */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5016), /* T580-OCP-SO */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5017), /* T520-OCP-SO */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5018), /* T540-BT */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5080), /* Custom T540-cr */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5081), /* Custom T540-LL-cr */
|
||||
CH_PCI_ID_TABLE_FENTRY(0x5082), /* Custom T504-cr */
|
||||
|
||||
@@ -1195,7 +1195,7 @@ static int ethoc_probe(struct platform_device *pdev)
|
||||
priv->mdio = mdiobus_alloc();
|
||||
if (!priv->mdio) {
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
goto free2;
|
||||
}
|
||||
|
||||
priv->mdio->name = "ethoc-mdio";
|
||||
@@ -1208,7 +1208,7 @@ static int ethoc_probe(struct platform_device *pdev)
|
||||
ret = mdiobus_register(priv->mdio);
|
||||
if (ret) {
|
||||
dev_err(&netdev->dev, "failed to register MDIO bus\n");
|
||||
goto free;
|
||||
goto free2;
|
||||
}
|
||||
|
||||
ret = ethoc_mdio_probe(netdev);
|
||||
@@ -1241,9 +1241,10 @@ error2:
|
||||
error:
|
||||
mdiobus_unregister(priv->mdio);
|
||||
mdiobus_free(priv->mdio);
|
||||
free:
|
||||
free2:
|
||||
if (priv->clk)
|
||||
clk_disable_unprepare(priv->clk);
|
||||
free:
|
||||
free_netdev(netdev);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@@ -2416,24 +2416,24 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ec->rx_max_coalesced_frames > 255) {
|
||||
pr_err("Rx coalesced frames exceed hardware limiation");
|
||||
pr_err("Rx coalesced frames exceed hardware limitation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ec->tx_max_coalesced_frames > 255) {
|
||||
pr_err("Tx coalesced frame exceed hardware limiation");
|
||||
pr_err("Tx coalesced frame exceed hardware limitation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr);
|
||||
if (cycle > 0xFFFF) {
|
||||
pr_err("Rx coalesed usec exceeed hardware limiation");
|
||||
pr_err("Rx coalesced usec exceed hardware limitation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr);
|
||||
if (cycle > 0xFFFF) {
|
||||
pr_err("Rx coalesed usec exceeed hardware limiation");
|
||||
pr_err("Rx coalesced usec exceed hardware limitation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -2440,7 +2440,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
tx_queue->tx_ring_size);
|
||||
|
||||
if (likely(!nr_frags)) {
|
||||
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
|
||||
if (likely(!do_tstamp))
|
||||
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
|
||||
} else {
|
||||
u32 lstatus_start = lstatus;
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
|
||||
static void mtk_phy_link_adjust(struct net_device *dev)
|
||||
{
|
||||
struct mtk_mac *mac = netdev_priv(dev);
|
||||
u16 lcl_adv = 0, rmt_adv = 0;
|
||||
u8 flowctrl;
|
||||
u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
|
||||
MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
|
||||
MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
|
||||
@@ -150,11 +152,30 @@ static void mtk_phy_link_adjust(struct net_device *dev)
|
||||
if (mac->phy_dev->link)
|
||||
mcr |= MAC_MCR_FORCE_LINK;
|
||||
|
||||
if (mac->phy_dev->duplex)
|
||||
if (mac->phy_dev->duplex) {
|
||||
mcr |= MAC_MCR_FORCE_DPX;
|
||||
|
||||
if (mac->phy_dev->pause)
|
||||
mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
|
||||
if (mac->phy_dev->pause)
|
||||
rmt_adv = LPA_PAUSE_CAP;
|
||||
if (mac->phy_dev->asym_pause)
|
||||
rmt_adv |= LPA_PAUSE_ASYM;
|
||||
|
||||
if (mac->phy_dev->advertising & ADVERTISED_Pause)
|
||||
lcl_adv |= ADVERTISE_PAUSE_CAP;
|
||||
if (mac->phy_dev->advertising & ADVERTISED_Asym_Pause)
|
||||
lcl_adv |= ADVERTISE_PAUSE_ASYM;
|
||||
|
||||
flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
|
||||
|
||||
if (flowctrl & FLOW_CTRL_TX)
|
||||
mcr |= MAC_MCR_FORCE_TX_FC;
|
||||
if (flowctrl & FLOW_CTRL_RX)
|
||||
mcr |= MAC_MCR_FORCE_RX_FC;
|
||||
|
||||
netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n",
|
||||
flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
|
||||
flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
|
||||
|
||||
@@ -208,10 +229,16 @@ static int mtk_phy_connect(struct mtk_mac *mac)
|
||||
u32 val, ge_mode;
|
||||
|
||||
np = of_parse_phandle(mac->of_node, "phy-handle", 0);
|
||||
if (!np && of_phy_is_fixed_link(mac->of_node))
|
||||
if (!of_phy_register_fixed_link(mac->of_node))
|
||||
np = of_node_get(mac->of_node);
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
switch (of_get_phy_mode(np)) {
|
||||
case PHY_INTERFACE_MODE_RGMII_TXID:
|
||||
case PHY_INTERFACE_MODE_RGMII_RXID:
|
||||
case PHY_INTERFACE_MODE_RGMII_ID:
|
||||
case PHY_INTERFACE_MODE_RGMII:
|
||||
ge_mode = 0;
|
||||
break;
|
||||
@@ -236,7 +263,8 @@ static int mtk_phy_connect(struct mtk_mac *mac)
|
||||
mac->phy_dev->autoneg = AUTONEG_ENABLE;
|
||||
mac->phy_dev->speed = 0;
|
||||
mac->phy_dev->duplex = 0;
|
||||
mac->phy_dev->supported &= PHY_BASIC_FEATURES;
|
||||
mac->phy_dev->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
|
||||
SUPPORTED_Asym_Pause;
|
||||
mac->phy_dev->advertising = mac->phy_dev->supported |
|
||||
ADVERTISED_Autoneg;
|
||||
phy_start_aneg(mac->phy_dev);
|
||||
@@ -280,7 +308,7 @@ static int mtk_mdio_init(struct mtk_eth *eth)
|
||||
return 0;
|
||||
|
||||
err_free_bus:
|
||||
kfree(eth->mii_bus);
|
||||
mdiobus_free(eth->mii_bus);
|
||||
|
||||
err_put_node:
|
||||
of_node_put(mii_np);
|
||||
@@ -295,7 +323,7 @@ static void mtk_mdio_cleanup(struct mtk_eth *eth)
|
||||
|
||||
mdiobus_unregister(eth->mii_bus);
|
||||
of_node_put(eth->mii_bus->dev.of_node);
|
||||
kfree(eth->mii_bus);
|
||||
mdiobus_free(eth->mii_bus);
|
||||
}
|
||||
|
||||
static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
|
||||
|
||||
@@ -3192,10 +3192,7 @@ static void mlx5e_destroy_netdev(struct mlx5_core_dev *mdev, void *vpriv)
|
||||
flush_workqueue(priv->wq);
|
||||
if (test_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &mdev->intf_state)) {
|
||||
netif_device_detach(netdev);
|
||||
mutex_lock(&priv->state_lock);
|
||||
if (test_bit(MLX5E_STATE_OPENED, &priv->state))
|
||||
mlx5e_close_locked(netdev);
|
||||
mutex_unlock(&priv->state_lock);
|
||||
mlx5e_close(netdev);
|
||||
} else {
|
||||
unregister_netdev(netdev);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,8 @@ static netdev_tx_t mlx5e_sq_xmit(struct mlx5e_sq *sq, struct sk_buff *skb)
|
||||
while ((sq->pc & wq->sz_m1) > sq->edge)
|
||||
mlx5e_send_nop(sq, false);
|
||||
|
||||
sq->bf_budget = bf ? sq->bf_budget - 1 : 0;
|
||||
if (bf)
|
||||
sq->bf_budget--;
|
||||
|
||||
sq->stats.packets++;
|
||||
sq->stats.bytes += num_bytes;
|
||||
|
||||
@@ -383,7 +383,7 @@ __esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule,
|
||||
match_v,
|
||||
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
|
||||
0, &dest);
|
||||
if (IS_ERR_OR_NULL(flow_rule)) {
|
||||
if (IS_ERR(flow_rule)) {
|
||||
pr_warn(
|
||||
"FDB: Failed to add flow rule: dmac_v(%pM) dmac_c(%pM) -> vport(%d), err(%ld)\n",
|
||||
dmac_v, dmac_c, vport, PTR_ERR(flow_rule));
|
||||
@@ -457,7 +457,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
|
||||
|
||||
table_size = BIT(MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
|
||||
fdb = mlx5_create_flow_table(root_ns, 0, table_size, 0);
|
||||
if (IS_ERR_OR_NULL(fdb)) {
|
||||
if (IS_ERR(fdb)) {
|
||||
err = PTR_ERR(fdb);
|
||||
esw_warn(dev, "Failed to create FDB Table err %d\n", err);
|
||||
goto out;
|
||||
@@ -474,7 +474,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, table_size - 3);
|
||||
eth_broadcast_addr(dmac);
|
||||
g = mlx5_create_flow_group(fdb, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create flow group err(%d)\n", err);
|
||||
goto out;
|
||||
@@ -489,7 +489,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
|
||||
eth_zero_addr(dmac);
|
||||
dmac[0] = 0x01;
|
||||
g = mlx5_create_flow_group(fdb, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create allmulti flow group err(%d)\n", err);
|
||||
goto out;
|
||||
@@ -506,7 +506,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, table_size - 1);
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, table_size - 1);
|
||||
g = mlx5_create_flow_group(fdb, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create promisc flow group err(%d)\n", err);
|
||||
goto out;
|
||||
@@ -529,7 +529,7 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
kfree(flow_group_in);
|
||||
kvfree(flow_group_in);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -651,6 +651,7 @@ static void update_allmulti_vports(struct mlx5_eswitch *esw,
|
||||
esw_fdb_set_vport_rule(esw,
|
||||
mac,
|
||||
vport_idx);
|
||||
iter_vaddr->mc_promisc = true;
|
||||
break;
|
||||
case MLX5_ACTION_DEL:
|
||||
if (!iter_vaddr)
|
||||
@@ -1060,7 +1061,7 @@ static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
|
||||
return;
|
||||
|
||||
acl = mlx5_create_vport_flow_table(root_ns, 0, table_size, 0, vport->vport);
|
||||
if (IS_ERR_OR_NULL(acl)) {
|
||||
if (IS_ERR(acl)) {
|
||||
err = PTR_ERR(acl);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] egress flow Table, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1075,7 +1076,7 @@ static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 0);
|
||||
|
||||
vlan_grp = mlx5_create_flow_group(acl, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(vlan_grp)) {
|
||||
if (IS_ERR(vlan_grp)) {
|
||||
err = PTR_ERR(vlan_grp);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] egress allowed vlans flow group, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1086,7 +1087,7 @@ static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 1);
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1);
|
||||
drop_grp = mlx5_create_flow_group(acl, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(drop_grp)) {
|
||||
if (IS_ERR(drop_grp)) {
|
||||
err = PTR_ERR(drop_grp);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] egress drop flow group, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1097,7 +1098,7 @@ static void esw_vport_enable_egress_acl(struct mlx5_eswitch *esw,
|
||||
vport->egress.drop_grp = drop_grp;
|
||||
vport->egress.allowed_vlans_grp = vlan_grp;
|
||||
out:
|
||||
kfree(flow_group_in);
|
||||
kvfree(flow_group_in);
|
||||
if (err && !IS_ERR_OR_NULL(vlan_grp))
|
||||
mlx5_destroy_flow_group(vlan_grp);
|
||||
if (err && !IS_ERR_OR_NULL(acl))
|
||||
@@ -1174,7 +1175,7 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
|
||||
return;
|
||||
|
||||
acl = mlx5_create_vport_flow_table(root_ns, 0, table_size, 0, vport->vport);
|
||||
if (IS_ERR_OR_NULL(acl)) {
|
||||
if (IS_ERR(acl)) {
|
||||
err = PTR_ERR(acl);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] ingress flow Table, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1192,7 +1193,7 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 0);
|
||||
|
||||
g = mlx5_create_flow_group(acl, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] ingress untagged spoofchk flow group, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1207,7 +1208,7 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1);
|
||||
|
||||
g = mlx5_create_flow_group(acl, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] ingress untagged flow group, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1223,7 +1224,7 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 2);
|
||||
|
||||
g = mlx5_create_flow_group(acl, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] ingress spoofchk flow group, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1236,7 +1237,7 @@ static void esw_vport_enable_ingress_acl(struct mlx5_eswitch *esw,
|
||||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 3);
|
||||
|
||||
g = mlx5_create_flow_group(acl, flow_group_in);
|
||||
if (IS_ERR_OR_NULL(g)) {
|
||||
if (IS_ERR(g)) {
|
||||
err = PTR_ERR(g);
|
||||
esw_warn(dev, "Failed to create E-Switch vport[%d] ingress drop flow group, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1259,7 +1260,7 @@ out:
|
||||
mlx5_destroy_flow_table(vport->ingress.acl);
|
||||
}
|
||||
|
||||
kfree(flow_group_in);
|
||||
kvfree(flow_group_in);
|
||||
}
|
||||
|
||||
static void esw_vport_cleanup_ingress_rules(struct mlx5_eswitch *esw,
|
||||
@@ -1363,7 +1364,7 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
|
||||
match_v,
|
||||
MLX5_FLOW_CONTEXT_ACTION_ALLOW,
|
||||
0, NULL);
|
||||
if (IS_ERR_OR_NULL(vport->ingress.allow_rule)) {
|
||||
if (IS_ERR(vport->ingress.allow_rule)) {
|
||||
err = PTR_ERR(vport->ingress.allow_rule);
|
||||
pr_warn("vport[%d] configure ingress allow rule, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1380,7 +1381,7 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
|
||||
match_v,
|
||||
MLX5_FLOW_CONTEXT_ACTION_DROP,
|
||||
0, NULL);
|
||||
if (IS_ERR_OR_NULL(vport->ingress.drop_rule)) {
|
||||
if (IS_ERR(vport->ingress.drop_rule)) {
|
||||
err = PTR_ERR(vport->ingress.drop_rule);
|
||||
pr_warn("vport[%d] configure ingress drop rule, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1439,7 +1440,7 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw,
|
||||
match_v,
|
||||
MLX5_FLOW_CONTEXT_ACTION_ALLOW,
|
||||
0, NULL);
|
||||
if (IS_ERR_OR_NULL(vport->egress.allowed_vlan)) {
|
||||
if (IS_ERR(vport->egress.allowed_vlan)) {
|
||||
err = PTR_ERR(vport->egress.allowed_vlan);
|
||||
pr_warn("vport[%d] configure egress allowed vlan rule failed, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1457,7 +1458,7 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw,
|
||||
match_v,
|
||||
MLX5_FLOW_CONTEXT_ACTION_DROP,
|
||||
0, NULL);
|
||||
if (IS_ERR_OR_NULL(vport->egress.drop_rule)) {
|
||||
if (IS_ERR(vport->egress.drop_rule)) {
|
||||
err = PTR_ERR(vport->egress.drop_rule);
|
||||
pr_warn("vport[%d] configure egress drop rule failed, err(%d)\n",
|
||||
vport->vport, err);
|
||||
@@ -1491,14 +1492,11 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
|
||||
|
||||
/* Sync with current vport context */
|
||||
vport->enabled_events = enable_events;
|
||||
esw_vport_change_handle_locked(vport);
|
||||
|
||||
vport->enabled = true;
|
||||
|
||||
/* only PF is trusted by default */
|
||||
vport->trusted = (vport_num) ? false : true;
|
||||
|
||||
arm_vport_context_events_cmd(esw->dev, vport_num, enable_events);
|
||||
esw_vport_change_handle_locked(vport);
|
||||
|
||||
esw->enabled_vports++;
|
||||
esw_debug(esw->dev, "Enabled VPORT(%d)\n", vport_num);
|
||||
@@ -1728,11 +1726,24 @@ void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe)
|
||||
(esw && MLX5_CAP_GEN(esw->dev, vport_group_manager) && mlx5_core_is_pf(esw->dev))
|
||||
#define LEGAL_VPORT(esw, vport) (vport >= 0 && vport < esw->total_vports)
|
||||
|
||||
static void node_guid_gen_from_mac(u64 *node_guid, u8 mac[ETH_ALEN])
|
||||
{
|
||||
((u8 *)node_guid)[7] = mac[0];
|
||||
((u8 *)node_guid)[6] = mac[1];
|
||||
((u8 *)node_guid)[5] = mac[2];
|
||||
((u8 *)node_guid)[4] = 0xff;
|
||||
((u8 *)node_guid)[3] = 0xfe;
|
||||
((u8 *)node_guid)[2] = mac[3];
|
||||
((u8 *)node_guid)[1] = mac[4];
|
||||
((u8 *)node_guid)[0] = mac[5];
|
||||
}
|
||||
|
||||
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
|
||||
int vport, u8 mac[ETH_ALEN])
|
||||
{
|
||||
int err = 0;
|
||||
struct mlx5_vport *evport;
|
||||
u64 node_guid;
|
||||
int err = 0;
|
||||
|
||||
if (!ESW_ALLOWED(esw))
|
||||
return -EPERM;
|
||||
@@ -1756,11 +1767,17 @@ int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
|
||||
return err;
|
||||
}
|
||||
|
||||
node_guid_gen_from_mac(&node_guid, mac);
|
||||
err = mlx5_modify_nic_vport_node_guid(esw->dev, vport, node_guid);
|
||||
if (err)
|
||||
mlx5_core_warn(esw->dev,
|
||||
"Failed to set vport %d node guid, err = %d. RDMA_CM will not function properly for this VF.\n",
|
||||
vport, err);
|
||||
|
||||
mutex_lock(&esw->state_lock);
|
||||
if (evport->enabled)
|
||||
err = esw_vport_ingress_config(esw, evport);
|
||||
mutex_unlock(&esw->state_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1292,8 +1292,8 @@ static int update_root_ft_destroy(struct mlx5_flow_table *ft)
|
||||
ft->id);
|
||||
return err;
|
||||
}
|
||||
root->root_ft = new_root_ft;
|
||||
}
|
||||
root->root_ft = new_root_ft;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1767,6 +1767,9 @@ static void cleanup_root_ns(struct mlx5_core_dev *dev)
|
||||
|
||||
void mlx5_cleanup_fs(struct mlx5_core_dev *dev)
|
||||
{
|
||||
if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
|
||||
return;
|
||||
|
||||
cleanup_root_ns(dev);
|
||||
cleanup_single_prio_root_ns(dev, dev->priv.fdb_root_ns);
|
||||
cleanup_single_prio_root_ns(dev, dev->priv.esw_egress_root_ns);
|
||||
@@ -1828,29 +1831,36 @@ int mlx5_init_fs(struct mlx5_core_dev *dev)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (MLX5_CAP_GEN(dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
|
||||
return 0;
|
||||
|
||||
err = mlx5_init_fc_stats(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (MLX5_CAP_GEN(dev, nic_flow_table)) {
|
||||
if (MLX5_CAP_GEN(dev, nic_flow_table) &&
|
||||
MLX5_CAP_FLOWTABLE_NIC_RX(dev, ft_support)) {
|
||||
err = init_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (MLX5_CAP_GEN(dev, eswitch_flow_table)) {
|
||||
err = init_fdb_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) {
|
||||
err = init_egress_acl_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) {
|
||||
err = init_ingress_acl_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, ft_support)) {
|
||||
err = init_fdb_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
if (MLX5_CAP_ESW_EGRESS_ACL(dev, ft_support)) {
|
||||
err = init_egress_acl_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
if (MLX5_CAP_ESW_INGRESS_ACL(dev, ft_support)) {
|
||||
err = init_ingress_acl_root_ns(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -418,7 +418,7 @@ int mlx5_core_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn)
|
||||
if (out.hdr.status)
|
||||
err = mlx5_cmd_status_to_err(&out.hdr);
|
||||
else
|
||||
*xrcdn = be32_to_cpu(out.xrcdn);
|
||||
*xrcdn = be32_to_cpu(out.xrcdn) & 0xffffff;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -508,6 +508,44 @@ int mlx5_query_nic_vport_node_guid(struct mlx5_core_dev *mdev, u64 *node_guid)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_node_guid);
|
||||
|
||||
int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev,
|
||||
u32 vport, u64 node_guid)
|
||||
{
|
||||
int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
|
||||
void *nic_vport_context;
|
||||
u8 *guid;
|
||||
void *in;
|
||||
int err;
|
||||
|
||||
if (!vport)
|
||||
return -EINVAL;
|
||||
if (!MLX5_CAP_GEN(mdev, vport_group_manager))
|
||||
return -EACCES;
|
||||
if (!MLX5_CAP_ESW(mdev, nic_vport_node_guid_modify))
|
||||
return -ENOTSUPP;
|
||||
|
||||
in = mlx5_vzalloc(inlen);
|
||||
if (!in)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(modify_nic_vport_context_in, in,
|
||||
field_select.node_guid, 1);
|
||||
MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
|
||||
MLX5_SET(modify_nic_vport_context_in, in, other_vport, !!vport);
|
||||
|
||||
nic_vport_context = MLX5_ADDR_OF(modify_nic_vport_context_in,
|
||||
in, nic_vport_context);
|
||||
guid = MLX5_ADDR_OF(nic_vport_context, nic_vport_context,
|
||||
node_guid);
|
||||
MLX5_SET64(nic_vport_context, nic_vport_context, node_guid, node_guid);
|
||||
|
||||
err = mlx5_modify_nic_vport_context(mdev, in, inlen);
|
||||
|
||||
kvfree(in);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_query_nic_vport_qkey_viol_cntr(struct mlx5_core_dev *mdev,
|
||||
u16 *qkey_viol_cntr)
|
||||
{
|
||||
|
||||
@@ -247,13 +247,21 @@ static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
|
||||
}
|
||||
|
||||
static int __mlxsw_sp_port_swid_set(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
u8 swid)
|
||||
{
|
||||
char pspa_pl[MLXSW_REG_PSPA_LEN];
|
||||
|
||||
mlxsw_reg_pspa_pack(pspa_pl, swid, local_port);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pspa), pspa_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_swid_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 swid)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
char pspa_pl[MLXSW_REG_PSPA_LEN];
|
||||
|
||||
mlxsw_reg_pspa_pack(pspa_pl, swid, mlxsw_sp_port->local_port);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pspa), pspa_pl);
|
||||
return __mlxsw_sp_port_swid_set(mlxsw_sp, mlxsw_sp_port->local_port,
|
||||
swid);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
@@ -305,9 +313,9 @@ mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl);
|
||||
}
|
||||
|
||||
static int __mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
|
||||
u8 local_port, u8 *p_module,
|
||||
u8 *p_width, u8 *p_lane)
|
||||
static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
|
||||
u8 local_port, u8 *p_module,
|
||||
u8 *p_width, u8 *p_lane)
|
||||
{
|
||||
char pmlp_pl[MLXSW_REG_PMLP_LEN];
|
||||
int err;
|
||||
@@ -322,16 +330,6 @@ static int __mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
|
||||
u8 local_port, u8 *p_module,
|
||||
u8 *p_width)
|
||||
{
|
||||
u8 lane;
|
||||
|
||||
return __mlxsw_sp_port_module_info_get(mlxsw_sp, local_port, p_module,
|
||||
p_width, &lane);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
u8 module, u8 width, u8 lane)
|
||||
{
|
||||
@@ -949,17 +947,11 @@ static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name,
|
||||
size_t len)
|
||||
{
|
||||
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
|
||||
u8 module, width, lane;
|
||||
u8 module = mlxsw_sp_port->mapping.module;
|
||||
u8 width = mlxsw_sp_port->mapping.width;
|
||||
u8 lane = mlxsw_sp_port->mapping.lane;
|
||||
int err;
|
||||
|
||||
err = __mlxsw_sp_port_module_info_get(mlxsw_sp_port->mlxsw_sp,
|
||||
mlxsw_sp_port->local_port,
|
||||
&module, &width, &lane);
|
||||
if (err) {
|
||||
netdev_err(dev, "Failed to retrieve module information\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!mlxsw_sp_port->split)
|
||||
err = snprintf(name, len, "p%d", module + 1);
|
||||
else
|
||||
@@ -1681,8 +1673,8 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
bool split, u8 module, u8 width)
|
||||
static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
bool split, u8 module, u8 width, u8 lane)
|
||||
{
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
struct net_device *dev;
|
||||
@@ -1697,6 +1689,9 @@ static int __mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
|
||||
mlxsw_sp_port->local_port = local_port;
|
||||
mlxsw_sp_port->split = split;
|
||||
mlxsw_sp_port->mapping.module = module;
|
||||
mlxsw_sp_port->mapping.width = width;
|
||||
mlxsw_sp_port->mapping.lane = lane;
|
||||
bytes = DIV_ROUND_UP(VLAN_N_VID, BITS_PER_BYTE);
|
||||
mlxsw_sp_port->active_vlans = kzalloc(bytes, GFP_KERNEL);
|
||||
if (!mlxsw_sp_port->active_vlans) {
|
||||
@@ -1839,28 +1834,6 @@ err_port_active_vlans_alloc:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
bool split, u8 module, u8 width, u8 lane)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = mlxsw_sp_port_module_map(mlxsw_sp, local_port, module, width,
|
||||
lane);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = __mlxsw_sp_port_create(mlxsw_sp, local_port, split, module,
|
||||
width);
|
||||
if (err)
|
||||
goto err_port_create;
|
||||
|
||||
return 0;
|
||||
|
||||
err_port_create:
|
||||
mlxsw_sp_port_module_unmap(mlxsw_sp, local_port);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_port_vports_fini(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||
{
|
||||
struct net_device *dev = mlxsw_sp_port->dev;
|
||||
@@ -1909,8 +1882,8 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
|
||||
|
||||
static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
u8 module, width, lane;
|
||||
size_t alloc_size;
|
||||
u8 module, width;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
@@ -1921,13 +1894,14 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
|
||||
|
||||
for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++) {
|
||||
err = mlxsw_sp_port_module_info_get(mlxsw_sp, i, &module,
|
||||
&width);
|
||||
&width, &lane);
|
||||
if (err)
|
||||
goto err_port_module_info_get;
|
||||
if (!width)
|
||||
continue;
|
||||
mlxsw_sp->port_to_module[i] = module;
|
||||
err = __mlxsw_sp_port_create(mlxsw_sp, i, false, module, width);
|
||||
err = mlxsw_sp_port_create(mlxsw_sp, i, false, module, width,
|
||||
lane);
|
||||
if (err)
|
||||
goto err_port_create;
|
||||
}
|
||||
@@ -1948,12 +1922,85 @@ static u8 mlxsw_sp_cluster_base_port_get(u8 local_port)
|
||||
return local_port - offset;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port,
|
||||
u8 module, unsigned int count)
|
||||
{
|
||||
u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
|
||||
int err, i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
err = mlxsw_sp_port_module_map(mlxsw_sp, base_port + i, module,
|
||||
width, i * width);
|
||||
if (err)
|
||||
goto err_port_module_map;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
err = __mlxsw_sp_port_swid_set(mlxsw_sp, base_port + i, 0);
|
||||
if (err)
|
||||
goto err_port_swid_set;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
err = mlxsw_sp_port_create(mlxsw_sp, base_port + i, true,
|
||||
module, width, i * width);
|
||||
if (err)
|
||||
goto err_port_create;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_port_create:
|
||||
for (i--; i >= 0; i--)
|
||||
mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
|
||||
i = count;
|
||||
err_port_swid_set:
|
||||
for (i--; i >= 0; i--)
|
||||
__mlxsw_sp_port_swid_set(mlxsw_sp, base_port + i,
|
||||
MLXSW_PORT_SWID_DISABLED_PORT);
|
||||
i = count;
|
||||
err_port_module_map:
|
||||
for (i--; i >= 0; i--)
|
||||
mlxsw_sp_port_module_unmap(mlxsw_sp, base_port + i);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
|
||||
u8 base_port, unsigned int count)
|
||||
{
|
||||
u8 local_port, module, width = MLXSW_PORT_MODULE_MAX_WIDTH;
|
||||
int i;
|
||||
|
||||
/* Split by four means we need to re-create two ports, otherwise
|
||||
* only one.
|
||||
*/
|
||||
count = count / 2;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
local_port = base_port + i * 2;
|
||||
module = mlxsw_sp->port_to_module[local_port];
|
||||
|
||||
mlxsw_sp_port_module_map(mlxsw_sp, local_port, module, width,
|
||||
0);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
__mlxsw_sp_port_swid_set(mlxsw_sp, base_port + i * 2, 0);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
local_port = base_port + i * 2;
|
||||
module = mlxsw_sp->port_to_module[local_port];
|
||||
|
||||
mlxsw_sp_port_create(mlxsw_sp, local_port, false, module,
|
||||
width, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
unsigned int count)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
|
||||
u8 module, cur_width, base_port;
|
||||
int i;
|
||||
int err;
|
||||
@@ -1965,18 +2012,14 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
module = mlxsw_sp_port->mapping.module;
|
||||
cur_width = mlxsw_sp_port->mapping.width;
|
||||
|
||||
if (count != 2 && count != 4) {
|
||||
netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = mlxsw_sp_port_module_info_get(mlxsw_sp, local_port, &module,
|
||||
&cur_width);
|
||||
if (err) {
|
||||
netdev_err(mlxsw_sp_port->dev, "Failed to get port's width\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
|
||||
netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
|
||||
return -EINVAL;
|
||||
@@ -2001,25 +2044,16 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
for (i = 0; i < count; i++)
|
||||
mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
err = mlxsw_sp_port_create(mlxsw_sp, base_port + i, true,
|
||||
module, width, i * width);
|
||||
if (err) {
|
||||
dev_err(mlxsw_sp->bus_info->dev, "Failed to create split port\n");
|
||||
goto err_port_create;
|
||||
}
|
||||
err = mlxsw_sp_port_split_create(mlxsw_sp, base_port, module, count);
|
||||
if (err) {
|
||||
dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n");
|
||||
goto err_port_split_create;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_port_create:
|
||||
for (i--; i >= 0; i--)
|
||||
mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
|
||||
for (i = 0; i < count / 2; i++) {
|
||||
module = mlxsw_sp->port_to_module[base_port + i * 2];
|
||||
mlxsw_sp_port_create(mlxsw_sp, base_port + i * 2, false,
|
||||
module, MLXSW_PORT_MODULE_MAX_WIDTH, 0);
|
||||
}
|
||||
err_port_split_create:
|
||||
mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2027,10 +2061,9 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
u8 module, cur_width, base_port;
|
||||
u8 cur_width, base_port;
|
||||
unsigned int count;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
mlxsw_sp_port = mlxsw_sp->ports[local_port];
|
||||
if (!mlxsw_sp_port) {
|
||||
@@ -2044,12 +2077,7 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = mlxsw_sp_port_module_info_get(mlxsw_sp, local_port, &module,
|
||||
&cur_width);
|
||||
if (err) {
|
||||
netdev_err(mlxsw_sp_port->dev, "Failed to get port's width\n");
|
||||
return err;
|
||||
}
|
||||
cur_width = mlxsw_sp_port->mapping.width;
|
||||
count = cur_width == 1 ? 4 : 2;
|
||||
|
||||
base_port = mlxsw_sp_cluster_base_port_get(local_port);
|
||||
@@ -2061,14 +2089,7 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port)
|
||||
for (i = 0; i < count; i++)
|
||||
mlxsw_sp_port_remove(mlxsw_sp, base_port + i);
|
||||
|
||||
for (i = 0; i < count / 2; i++) {
|
||||
module = mlxsw_sp->port_to_module[base_port + i * 2];
|
||||
err = mlxsw_sp_port_create(mlxsw_sp, base_port + i * 2, false,
|
||||
module, MLXSW_PORT_MODULE_MAX_WIDTH,
|
||||
0);
|
||||
if (err)
|
||||
dev_err(mlxsw_sp->bus_info->dev, "Failed to reinstantiate port\n");
|
||||
}
|
||||
mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -229,6 +229,11 @@ struct mlxsw_sp_port {
|
||||
struct ieee_maxrate *maxrate;
|
||||
struct ieee_pfc *pfc;
|
||||
} dcb;
|
||||
struct {
|
||||
u8 module;
|
||||
u8 width;
|
||||
u8 lane;
|
||||
} mapping;
|
||||
/* 802.1Q bridge VLANs */
|
||||
unsigned long *active_vlans;
|
||||
unsigned long *untagged_vlans;
|
||||
|
||||
@@ -1105,6 +1105,39 @@ static int qed_get_port_type(u32 media_type)
|
||||
return port_type;
|
||||
}
|
||||
|
||||
static int qed_get_link_data(struct qed_hwfn *hwfn,
|
||||
struct qed_mcp_link_params *params,
|
||||
struct qed_mcp_link_state *link,
|
||||
struct qed_mcp_link_capabilities *link_caps)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!IS_PF(hwfn->cdev)) {
|
||||
qed_vf_get_link_params(hwfn, params);
|
||||
qed_vf_get_link_state(hwfn, link);
|
||||
qed_vf_get_link_caps(hwfn, link_caps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = qed_mcp_get_link_params(hwfn);
|
||||
if (!p)
|
||||
return -ENXIO;
|
||||
memcpy(params, p, sizeof(*params));
|
||||
|
||||
p = qed_mcp_get_link_state(hwfn);
|
||||
if (!p)
|
||||
return -ENXIO;
|
||||
memcpy(link, p, sizeof(*link));
|
||||
|
||||
p = qed_mcp_get_link_capabilities(hwfn);
|
||||
if (!p)
|
||||
return -ENXIO;
|
||||
memcpy(link_caps, p, sizeof(*link_caps));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qed_fill_link(struct qed_hwfn *hwfn,
|
||||
struct qed_link_output *if_link)
|
||||
{
|
||||
@@ -1116,15 +1149,9 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
|
||||
memset(if_link, 0, sizeof(*if_link));
|
||||
|
||||
/* Prepare source inputs */
|
||||
if (IS_PF(hwfn->cdev)) {
|
||||
memcpy(¶ms, qed_mcp_get_link_params(hwfn), sizeof(params));
|
||||
memcpy(&link, qed_mcp_get_link_state(hwfn), sizeof(link));
|
||||
memcpy(&link_caps, qed_mcp_get_link_capabilities(hwfn),
|
||||
sizeof(link_caps));
|
||||
} else {
|
||||
qed_vf_get_link_params(hwfn, ¶ms);
|
||||
qed_vf_get_link_state(hwfn, &link);
|
||||
qed_vf_get_link_caps(hwfn, &link_caps);
|
||||
if (qed_get_link_data(hwfn, ¶ms, &link, &link_caps)) {
|
||||
dev_warn(&hwfn->cdev->pdev->dev, "no link data available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the link parameters to pass to protocol driver */
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
#include "qed_vf.h"
|
||||
#define QED_VF_ARRAY_LENGTH (3)
|
||||
|
||||
#ifdef CONFIG_QED_SRIOV
|
||||
#define IS_VF(cdev) ((cdev)->b_is_vf)
|
||||
#define IS_PF(cdev) (!((cdev)->b_is_vf))
|
||||
#ifdef CONFIG_QED_SRIOV
|
||||
#define IS_PF_SRIOV(p_hwfn) (!!((p_hwfn)->cdev->p_iov_info))
|
||||
#else
|
||||
#define IS_VF(cdev) (0)
|
||||
#define IS_PF(cdev) (1)
|
||||
#define IS_PF_SRIOV(p_hwfn) (0)
|
||||
#endif
|
||||
#define IS_PF_SRIOV_ALLOC(p_hwfn) (!!((p_hwfn)->pf_iov_info))
|
||||
|
||||
@@ -87,7 +87,9 @@ static const struct pci_device_id qede_pci_tbl[] = {
|
||||
{PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_57980S_100), QEDE_PRIVATE_PF},
|
||||
{PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_57980S_50), QEDE_PRIVATE_PF},
|
||||
{PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_57980S_25), QEDE_PRIVATE_PF},
|
||||
#ifdef CONFIG_QED_SRIOV
|
||||
{PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_57980S_IOV), QEDE_PRIVATE_VF},
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -189,11 +189,12 @@ static u32 mcdi_to_ethtool_cap(u32 media, u32 cap)
|
||||
|
||||
case MC_CMD_MEDIA_XFP:
|
||||
case MC_CMD_MEDIA_SFP_PLUS:
|
||||
result |= SUPPORTED_FIBRE;
|
||||
break;
|
||||
|
||||
case MC_CMD_MEDIA_QSFP_PLUS:
|
||||
result |= SUPPORTED_FIBRE;
|
||||
if (cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
|
||||
result |= SUPPORTED_1000baseT_Full;
|
||||
if (cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
|
||||
result |= SUPPORTED_10000baseT_Full;
|
||||
if (cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
|
||||
result |= SUPPORTED_40000baseCR4_Full;
|
||||
break;
|
||||
|
||||
Loaded 20 of 93 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user