bnxt_re: Add bnxt_re backports
authorSelvin Xavier <selvin.xavier@broadcom.com>
Tue, 22 Aug 2017 21:11:23 +0000 (14:11 -0700)
committerSelvin Xavier <selvin.xavier@broadcom.com>
Tue, 22 Aug 2017 21:11:23 +0000 (14:11 -0700)
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
patches/0015-BACKPORT-bnxt_re-bnxt_re-backports.patch [new file with mode: 0644]

diff --git a/patches/0015-BACKPORT-bnxt_re-bnxt_re-backports.patch b/patches/0015-BACKPORT-bnxt_re-bnxt_re-backports.patch
new file mode 100644 (file)
index 0000000..9732ce7
--- /dev/null
@@ -0,0 +1,725 @@
+From 669e648a47126dd70437ac974996f914153d37b1 Mon Sep 17 00:00:00 2001
+From: Selvin Xavier <selvin.xavier@broadcom.com>
+Date: Tue, 22 Aug 2017 13:55:02 -0700
+Subject: [PATCH] BACKPORT-bnxt_re: bnxt_re backports
+
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+---
+ drivers/infiniband/hw/bnxt_re/ib_verbs.c          |  15 +-
+ drivers/net/ethernet/broadcom/bnxt/bnxt.c         | 214 ++++++++++++++----
+ drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 259 ++++++++++++++++++++--
+ drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c   |   6 +-
+ drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h   |   2 +-
+ 5 files changed, 428 insertions(+), 68 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+index d93a05f..cc53e6d 100644
+--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+@@ -225,16 +225,25 @@ int bnxt_re_modify_device(struct ib_device *ibdev,
+ static void __to_ib_speed_width(struct net_device *netdev, u8 *speed, u8 *width)
+ {
+-      struct ethtool_link_ksettings lksettings;
+       u32 espeed;
+-
++#ifdef HAVE___ETHTOOL_GET_LINK_KSETTINGS
++      struct ethtool_link_ksettings lksettings;
+       if (netdev->ethtool_ops && netdev->ethtool_ops->get_link_ksettings) {
+               memset(&lksettings, 0, sizeof(lksettings));
+               rtnl_lock();
+               netdev->ethtool_ops->get_link_ksettings(netdev, &lksettings);
+               rtnl_unlock();
+               espeed = lksettings.base.speed;
+-      } else {
++      }
++#else
++      struct ethtool_cmd ecmd;
++       if (netdev->ethtool_ops && netdev->ethtool_ops->get_settings) {
++                memset(&ecmd, 0, sizeof(ecmd));
++                netdev->ethtool_ops->get_settings(netdev, &ecmd);
++                espeed = ecmd.speed;
++        }
++#endif
++      else {
+               espeed = SPEED_UNKNOWN;
+       }
+       switch (espeed) {
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index d913237..f18d0cc 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -3311,17 +3311,54 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
+       req.ethertype = htons(ETH_P_IP);
+       memcpy(req.src_macaddr, fltr->src_mac_addr, ETH_ALEN);
+       req.ip_addr_type = CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4;
+-      req.ip_protocol = keys->basic.ip_proto;
++#ifdef HAVE_SKB_FLOW_DISSECT_FLOW_KEYS
++        req.ip_protocol = keys->basic.ip_proto;
++
++        if (keys->basic.n_proto == htons(ETH_P_IPV6)) {
++                int i;
++
++                req.ethertype = htons(ETH_P_IPV6);
++                req.ip_addr_type =
++                        CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6;
++                *(struct in6_addr *)&req.src_ipaddr[0] =
++                        keys->addrs.v6addrs.src;
++                *(struct in6_addr *)&req.dst_ipaddr[0] =
++                        keys->addrs.v6addrs.dst;
++                for (i = 0; i < 4; i++) {
++                        req.src_ipaddr_mask[i] = cpu_to_be32(0xffffffff);
++                        req.dst_ipaddr_mask[i] = cpu_to_be32(0xffffffff);
++                }
++        } else {
++                req.src_ipaddr[0] = keys->addrs.v4addrs.src;
++                req.src_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
++                req.dst_ipaddr[0] = keys->addrs.v4addrs.dst;
++                req.dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
++        }
++#ifdef HAVE_NEW_FLOW_DISSECTOR
++        if (keys->control.flags & FLOW_DIS_ENCAPSULATION) {
++                req.enables |= cpu_to_le32(BNXT_NTP_TUNNEL_FLTR_FLAG);
++                req.tunnel_type =
++                        CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL;
++        }
++#endif
++
++        req.src_port = keys->ports.src;
++        req.src_port_mask = cpu_to_be16(0xffff);
++        req.dst_port = keys->ports.dst;
++        req.dst_port_mask = cpu_to_be16(0xffff);
++#else
++        req.ip_protocol = keys->ip_proto;
+-      req.src_ipaddr[0] = keys->addrs.v4addrs.src;
+-      req.src_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
+-      req.dst_ipaddr[0] = keys->addrs.v4addrs.dst;
+-      req.dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
++        req.src_ipaddr[0] = keys->src;
++        req.src_ipaddr_mask[0] = 0xffffffff;
++        req.dst_ipaddr[0] = keys->dst;
++        req.dst_ipaddr_mask[0] = 0xffffffff;
+-      req.src_port = keys->ports.src;
+-      req.src_port_mask = cpu_to_be16(0xffff);
+-      req.dst_port = keys->ports.dst;
+-      req.dst_port_mask = cpu_to_be16(0xffff);
++        req.src_port = keys->port16[0];
++        req.src_port_mask = 0xffff;
++        req.dst_port = keys->port16[1];
++        req.dst_port_mask = 0xffff;
++#endif
+       req.dst_id = cpu_to_le16(vnic->fw_vnic_id);
+       mutex_lock(&bp->hwrm_cmd_lock);
+@@ -5661,8 +5698,10 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
+                       netdev_warn(bp->dev, "failed to update phy settings\n");
+       }
++#ifdef HAVE_UDP_TUNNEL_GET_RX_INFO
+       if (irq_re_init)
+               udp_tunnel_get_rx_info(bp->dev);
++#endif
+       set_bit(BNXT_STATE_OPEN, &bp->state);
+       bnxt_enable_int(bp);
+@@ -6508,34 +6547,68 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
+       return 0;
+ }
++#ifdef HAVE_NDO_SETUP_TC
++#ifdef HAVE_NDO_SETUP_TC_4_PARAMS
+ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                        struct tc_to_netdev *ntc)
++#else
++static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
++                         struct tc_to_netdev *ntc)
++#endif
+ {
+       if (ntc->type != TC_SETUP_MQPRIO)
+               return -EINVAL;
+       return bnxt_setup_mq_tc(dev, ntc->tc);
+ }
++#endif
+ #ifdef CONFIG_RFS_ACCEL
++#ifdef HAVE_SKB_FLOW_DISSECT_FLOW_KEYS 
+ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
+-                          struct bnxt_ntuple_filter *f2)
+-{
+-      struct flow_keys *keys1 = &f1->fkeys;
+-      struct flow_keys *keys2 = &f2->fkeys;
+-
+-      if (keys1->addrs.v4addrs.src == keys2->addrs.v4addrs.src &&
+-          keys1->addrs.v4addrs.dst == keys2->addrs.v4addrs.dst &&
+-          keys1->ports.ports == keys2->ports.ports &&
+-          keys1->basic.ip_proto == keys2->basic.ip_proto &&
+-          keys1->basic.n_proto == keys2->basic.n_proto &&
+-          ether_addr_equal(f1->src_mac_addr, f2->src_mac_addr) &&
+-          ether_addr_equal(f1->dst_mac_addr, f2->dst_mac_addr))
+-              return true;
++                            struct bnxt_ntuple_filter *f2)
++{
++        struct flow_keys *keys1 = &f1->fkeys;
++        struct flow_keys *keys2 = &f2->fkeys;
++
++        if (keys1->addrs.v4addrs.src == keys2->addrs.v4addrs.src &&
++            keys1->addrs.v4addrs.dst == keys2->addrs.v4addrs.dst &&
++            keys1->ports.ports == keys2->ports.ports &&
++            keys1->basic.ip_proto == keys2->basic.ip_proto &&
++            keys1->basic.n_proto == keys2->basic.n_proto &&
++#ifdef HAVE_NEW_FLOW_DISSECTOR
++            keys1->control.flags == keys2->control.flags &&
++#endif
++            ether_addr_equal(f1->src_mac_addr, f2->src_mac_addr) &&
++            ether_addr_equal(f1->dst_mac_addr, f2->dst_mac_addr))
++                return true;
+-      return false;
++        return false;
+ }
++#else
++
++static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
++                            struct bnxt_ntuple_filter *f2)
++{
++        struct flow_keys *keys1 = &f1->fkeys;
++        struct flow_keys *keys2 = &f2->fkeys;
++
++        if (keys1->src == keys2->src &&
++            keys1->dst == keys2->dst &&
++            keys1->ports == keys2->ports &&
++            keys1->ip_proto == keys2->ip_proto &&
++#ifdef HAVE_N_PROTO
++            keys1->n_proto == keys2->n_proto &&
++#endif
++            ether_addr_equal(f1->src_mac_addr, f2->src_mac_addr) &&
++            ether_addr_equal(f1->dst_mac_addr, f2->dst_mac_addr))
++                return true;
++
++        return false;
++}
++#endif  /* HAVE_SKB_FLOW_DISSECT_FLOW_KEYS*/
++
+ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+                             u16 rxq_index, u32 flow_id)
+ {
+@@ -6570,17 +6643,54 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+               return -ENOMEM;
+       fkeys = &new_fltr->fkeys;
+-      if (!skb_flow_dissect_flow_keys(skb, fkeys, 0)) {
+-              rc = -EPROTONOSUPPORT;
+-              goto err_free;
+-      }
++#ifdef HAVE_SKB_FLOW_DISSECT_FLOW_KEYS 
++        if (!skb_flow_dissect_flow_keys(skb, fkeys, 0)) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++
++        if ((fkeys->basic.n_proto != htons(ETH_P_IP) &&
++             fkeys->basic.n_proto != htons(ETH_P_IPV6)) ||
++            ((fkeys->basic.ip_proto != IPPROTO_TCP) &&
++             (fkeys->basic.ip_proto != IPPROTO_UDP))) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++        if (fkeys->basic.n_proto == htons(ETH_P_IPV6) &&
++            bp->hwrm_spec_code < 0x10601) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++#ifdef HAVE_NEW_FLOW_DISSECTOR
++        if ((fkeys->control.flags & FLOW_DIS_ENCAPSULATION) &&
++            bp->hwrm_spec_code < 0x10601) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++#endif
++#else
++        if (!skb_flow_dissect(skb, fkeys)) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++
++#ifdef HAVE_N_PROTO
++        if ((fkeys->n_proto != htons(ETH_P_IP)) ||
++            ((fkeys->ip_proto != IPPROTO_TCP) &&
++             (fkeys->ip_proto != IPPROTO_UDP))) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++#else
++        if ((skb->protocol != htons(ETH_P_IP)) ||
++            ((fkeys->ip_proto != IPPROTO_TCP) &&
++             (fkeys->ip_proto != IPPROTO_UDP))) {
++                rc = -EPROTONOSUPPORT;
++                goto err_free;
++        }
++#endif
++#endif
+-      if ((fkeys->basic.n_proto != htons(ETH_P_IP)) ||
+-          ((fkeys->basic.ip_proto != IPPROTO_TCP) &&
+-           (fkeys->basic.ip_proto != IPPROTO_UDP))) {
+-              rc = -EPROTONOSUPPORT;
+-              goto err_free;
+-      }
+       memcpy(new_fltr->dst_mac_addr, eth->h_dest, ETH_ALEN);
+       memcpy(new_fltr->src_mac_addr, eth->h_source, ETH_ALEN);
+@@ -6678,6 +6788,7 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
+ #endif /* CONFIG_RFS_ACCEL */
++#ifdef HAVE_UDP_TUNNEL_GET_RX_INFO
+ static void bnxt_udp_tunnel_add(struct net_device *dev,
+                               struct udp_tunnel_info *ti)
+ {
+@@ -6756,6 +6867,7 @@ static void bnxt_udp_tunnel_del(struct net_device *dev,
+       schedule_work(&bp->sp_task);
+ }
++#endif
+ static const struct net_device_ops bnxt_netdev_ops = {
+       .ndo_open               = bnxt_open,
+@@ -6781,12 +6893,21 @@ static const struct net_device_ops bnxt_netdev_ops = {
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = bnxt_poll_controller,
+ #endif
++#ifdef HAVE_NDO_SETUP_TC
++#ifdef HAVE_NDO_SETUP_TC_4_PARAMS
+       .ndo_setup_tc           = bnxt_setup_tc,
++#else
++      .ndo_setup_tc           = bnxt_setup_mq_tc,
++#endif
++#endif
+ #ifdef CONFIG_RFS_ACCEL
+       .ndo_rx_flow_steer      = bnxt_rx_flow_steer,
+ #endif
++#ifdef HAVE_UDP_TUNNEL_GET_RX_INFO
+       .ndo_udp_tunnel_add     = bnxt_udp_tunnel_add,
+       .ndo_udp_tunnel_del     = bnxt_udp_tunnel_del,
++#endif
++
+ #ifdef CONFIG_NET_RX_BUSY_POLL
+       .ndo_busy_poll          = bnxt_busy_poll,
+ #endif
+@@ -7052,9 +7173,14 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+       dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
+                          NETIF_F_TSO | NETIF_F_TSO6 |
+                          NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
++#if 0
+                          NETIF_F_GSO_IPXIP4 |
+-                         NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
+-                         NETIF_F_GSO_PARTIAL | NETIF_F_RXHASH |
++#endif
++                         NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM
++#ifdef HAVE_NET_DEVICE_GSO_PARTIAL_FEATURES
++                         | NETIF_F_GSO_PARTIAL
++#endif
++                         | NETIF_F_RXHASH |
+                          NETIF_F_RXCSUM | NETIF_F_GRO;
+       if (!BNXT_CHIP_TYPE_NITRO_A0(bp))
+@@ -7064,10 +7190,20 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+                       NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
+                       NETIF_F_TSO | NETIF_F_TSO6 |
+                       NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
+-                      NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM |
+-                      NETIF_F_GSO_IPXIP4 | NETIF_F_GSO_PARTIAL;
++                      NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM
++#if 0
++                      | NETIF_F_GSO_IPXIP4 
++#endif
++#ifdef HAVE_NET_DEVICE_GSO_PARTIAL_FEATURES
++                       | NETIF_F_GSO_PARTIAL
++#endif
++                      ;
++
++
++#ifdef HAVE_NET_DEVICE_GSO_PARTIAL_FEATURES
+       dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
+                                   NETIF_F_GSO_GRE_CSUM;
++#endif
+       dev->vlan_features = dev->hw_features | NETIF_F_HIGHDMA;
+       dev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX |
+                           NETIF_F_HW_VLAN_STAG_RX | NETIF_F_HW_VLAN_STAG_TX;
+@@ -7075,8 +7211,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+       dev->priv_flags |= IFF_UNICAST_FLT;
+       /* MTU range: 60 - 9500 */
+-      dev->min_mtu = ETH_ZLEN;
+-      dev->max_mtu = 9500;
++      //dev->min_mtu = ETH_ZLEN;
++      //dev->max_mtu = 9500;
+       bnxt_dcb_init(bp);
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index 784aa77..198caa5 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -524,27 +524,50 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
+ fltr_found:
+       fkeys = &fltr->fkeys;
+-      if (fkeys->basic.ip_proto == IPPROTO_TCP)
+-              fs->flow_type = TCP_V4_FLOW;
+-      else if (fkeys->basic.ip_proto == IPPROTO_UDP)
+-              fs->flow_type = UDP_V4_FLOW;
+-      else
+-              goto fltr_err;
+-
+-      fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src;
+-      fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0);
+-
+-      fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst;
+-      fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0);
+-      fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src;
+-      fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0);
++#ifdef NEW_FLOW_KEYS
++        if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
++                if (fkeys->basic.ip_proto == IPPROTO_TCP)
++                        fs->flow_type = TCP_V4_FLOW;
++                else if (fkeys->basic.ip_proto == IPPROTO_UDP)
++                        fs->flow_type = UDP_V4_FLOW;
++                else
++                        goto fltr_err;
++
++                fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src;
++                fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0);
++
++                fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst;
++                fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0);
++
++                fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src;
++                fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0);
++
++                fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst;
++                fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0);
++        }
++#else
++        if (fkeys->ip_proto == IPPROTO_TCP)
++                fs->flow_type = TCP_V4_FLOW;
++        else if (fkeys->ip_proto == IPPROTO_UDP)
++                fs->flow_type = UDP_V4_FLOW;
++        else
++                goto fltr_err;
++
++        fs->h_u.tcp_ip4_spec.ip4src = fkeys->src;
++        fs->m_u.tcp_ip4_spec.ip4src = (__be32) ~0;
++
++        fs->h_u.tcp_ip4_spec.ip4dst = fkeys->dst;
++        fs->m_u.tcp_ip4_spec.ip4dst = (__be32) ~0;
++
++        fs->h_u.tcp_ip4_spec.psrc = fkeys->port16[0];
++        fs->m_u.tcp_ip4_spec.psrc = (__be16) ~0;
++
++        fs->h_u.tcp_ip4_spec.pdst = fkeys->port16[1];
++        fs->m_u.tcp_ip4_spec.pdst = (__be16) ~0;
++#endif
+-      fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst;
+-      fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0);
+-      fs->ring_cookie = fltr->rxq;
+-      rc = 0;
+ fltr_err:
+       rcu_read_unlock();
+@@ -832,6 +855,7 @@ u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause)
+       return speed_mask;
+ }
++#ifdef HAVE_ETHTOOL_xLINKSETTINGS
+ #define BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, name)\
+ {                                                                     \
+       if ((fw_speeds) & BNXT_LINK_SPEED_MSK_100MB)                    \
+@@ -930,6 +954,50 @@ static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info,
+               ethtool_link_ksettings_add_link_mode(lk_ksettings, supported,
+                                                    Autoneg);
+ }
++#else
++
++static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info)
++{
++        u16 fw_speeds = link_info->advertising;
++        u8 fw_pause = 0;
++
++        if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL)
++                fw_pause = link_info->auto_pause_setting;
++
++        return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause);
++}
++
++static u32 bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info)
++{
++        u16 fw_speeds = link_info->lp_auto_link_speeds;
++        u8 fw_pause = 0;
++
++        if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL)
++                fw_pause = link_info->lp_pause;
++
++        return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause);
++}
++
++static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info)
++{
++        u16 fw_speeds = link_info->support_speeds;
++        u32 supported;
++
++        supported = _bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0);
++        return supported | SUPPORTED_Pause | SUPPORTED_Asym_Pause;
++}
++
++static u32 bnxt_fw_to_ethtool_support_adv_spds(struct bnxt_link_info *link_info)
++{
++        u16 fw_speeds = link_info->support_auto_speeds;
++        u32 supported;
++
++        supported = _bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0);
++        if (supported)
++                supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
++        return supported;
++}
++#endif
+ u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
+ {
+@@ -955,6 +1023,7 @@ u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
+       }
+ }
++#ifdef HAVE_ETHTOOL_xLINKSETTINGS
+ static int bnxt_get_link_ksettings(struct net_device *dev,
+                                  struct ethtool_link_ksettings *lk_ksettings)
+ {
+@@ -1014,6 +1083,71 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
+       return 0;
+ }
++#else 
++static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++        struct bnxt *bp = netdev_priv(dev);
++        struct bnxt_link_info *link_info = &bp->link_info;
++        u32 ethtool_speed;
++
++        cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info);
++
++        if (link_info->support_auto_speeds)
++                cmd->supported |= SUPPORTED_Autoneg;
++
++        if (link_info->autoneg) {
++                cmd->advertising =
++                        bnxt_fw_to_ethtool_advertised_spds(link_info);
++                cmd->advertising |= ADVERTISED_Autoneg;
++                cmd->autoneg = AUTONEG_ENABLE;
++                if (link_info->phy_link_status == BNXT_LINK_LINK)
++                        cmd->lp_advertising =
++                                bnxt_fw_to_ethtool_lp_adv(link_info);
++                ethtool_speed = bnxt_fw_to_ethtool_speed(link_info->link_speed);
++                if (!netif_carrier_ok(dev))
++                        cmd->duplex = DUPLEX_UNKNOWN;
++                else if (link_info->duplex & BNXT_LINK_DUPLEX_FULL)
++                        cmd->duplex = DUPLEX_FULL;
++                else
++                        cmd->duplex = DUPLEX_HALF;
++        } else {
++                cmd->autoneg = AUTONEG_DISABLE;
++                cmd->advertising = 0;
++                ethtool_speed =
++                        bnxt_fw_to_ethtool_speed(link_info->req_link_speed);
++                cmd->duplex = DUPLEX_HALF;
++                if (link_info->req_duplex == BNXT_LINK_DUPLEX_FULL)
++                        cmd->duplex = DUPLEX_FULL;
++        }
++        ethtool_cmd_speed_set(cmd, ethtool_speed);
++
++        cmd->port = PORT_NONE;
++        if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) {
++                cmd->port = PORT_TP;
++                cmd->supported |= SUPPORTED_TP;
++                cmd->advertising |= ADVERTISED_TP;
++        } else {
++                cmd->supported |= SUPPORTED_FIBRE;
++                cmd->advertising |= ADVERTISED_FIBRE;
++
++                if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC)
++                        cmd->port = PORT_DA;
++                else if (link_info->media_type ==
++                         PORT_PHY_QCFG_RESP_MEDIA_TYPE_FIBRE)
++                        cmd->port = PORT_FIBRE;
++        }
++
++        if (link_info->transceiver ==
++            PORT_PHY_QCFG_RESP_XCVR_PKG_TYPE_XCVR_INTERNAL)
++                cmd->transceiver = XCVR_INTERNAL;
++        else
++                cmd->transceiver = XCVR_EXTERNAL;
++        cmd->phy_address = link_info->phy_addr;
++
++        return 0;
++}
++
++#endif
+ static u32 bnxt_get_fw_speed(struct net_device *dev, u16 ethtool_speed)
+ {
+@@ -1084,6 +1218,7 @@ u16 bnxt_get_fw_auto_link_speeds(u32 advertising)
+       return fw_speed_mask;
+ }
++#ifdef HAVE_ETHTOOL_xLINKSETTINGS
+ static int bnxt_set_link_ksettings(struct net_device *dev,
+                          const struct ethtool_link_ksettings *lk_ksettings)
+ {
+@@ -1143,6 +1278,85 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
+ set_setting_exit:
+       return rc;
+ }
++#else
++static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++        int rc = 0;
++        struct bnxt *bp = netdev_priv(dev);
++        struct bnxt_link_info *link_info = &bp->link_info;
++        bool set_pause = false;
++        u16 fw_advertising = 0;
++        u32 speed;
++
++        if (!BNXT_SINGLE_PF(bp))
++                return -EOPNOTSUPP;
++
++        if (cmd->autoneg == AUTONEG_ENABLE) {
++                u32 supported_spds =
++                        bnxt_fw_to_ethtool_support_adv_spds(link_info);
++
++                if (!supported_spds) {
++                        netdev_err(dev, "Autoneg not supported\n");
++                        rc = -EINVAL;
++                        goto set_setting_exit;
++                }
++                if (cmd->advertising & ~(supported_spds | ADVERTISED_Autoneg |
++                                         ADVERTISED_TP | ADVERTISED_FIBRE)) {
++                        netdev_err(dev, "Unsupported advertising mask (adv: 0x%x)\n",
++                                   cmd->advertising);
++                        rc = -EINVAL;
++                        goto set_setting_exit;
++                }
++                fw_advertising = bnxt_get_fw_auto_link_speeds(cmd->advertising);
++                link_info->autoneg |= BNXT_AUTONEG_SPEED;
++                if (!fw_advertising)
++                        link_info->advertising = link_info->support_auto_speeds;
++                else
++                        link_info->advertising = fw_advertising;
++                /* any change to autoneg will cause link change, therefore the
++ *                  * driver should put back the original pause setting in autoneg
++ *                                   */
++                set_pause = true;
++        } else {
++                u16 fw_speed;
++                u8 phy_type = link_info->phy_type;
++
++                if (phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASET  ||
++                    phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASETE ||
++                    link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) {
++
++                        netdev_err(dev, "10GBase-T devices must autoneg\n");
++                        rc = -EINVAL;
++                        goto set_setting_exit;
++                }
++                /* TODO: currently don't support half duplex */
++                if (cmd->duplex == DUPLEX_HALF) {
++                        netdev_err(dev, "HALF DUPLEX is not supported!\n");
++                        rc = -EINVAL;
++                        goto set_setting_exit;
++                }
++                /* If received a request for an unknown duplex, assume full*/
++                if (cmd->duplex == DUPLEX_UNKNOWN)
++                        cmd->duplex = DUPLEX_FULL;
++                speed = ethtool_cmd_speed(cmd);
++                fw_speed = bnxt_get_fw_speed(dev, speed);
++                if (!fw_speed) {
++                        rc = -EINVAL;
++                        goto set_setting_exit;
++                }
++                link_info->req_link_speed = fw_speed;
++                link_info->req_duplex = BNXT_LINK_DUPLEX_FULL;
++                link_info->autoneg = 0;
++                link_info->advertising = 0;
++        }
++
++        if (netif_running(dev))
++                rc = bnxt_hwrm_set_link_setting(bp, set_pause, false);
++
++set_setting_exit:
++        return rc;
++}
++#endif
+ static void bnxt_get_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *epause)
+@@ -2040,8 +2254,13 @@ static int bnxt_nway_reset(struct net_device *dev)
+ }
+ const struct ethtool_ops bnxt_ethtool_ops = {
+-      .get_link_ksettings     = bnxt_get_link_ksettings,
+-      .set_link_ksettings     = bnxt_set_link_ksettings,
++#ifdef HAVE_ETHTOOL_xLINKSETTINGS
++        .get_link_ksettings     = bnxt_get_link_ksettings,
++        .set_link_ksettings     = bnxt_set_link_ksettings,
++#else
++        .get_settings           = bnxt_get_settings,
++        .set_settings           = bnxt_set_settings,
++#endif
+       .get_pauseparam         = bnxt_get_pauseparam,
+       .set_pauseparam         = bnxt_set_pauseparam,
+       .get_drvinfo            = bnxt_get_drvinfo,
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+index c696025..477e265 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+@@ -173,8 +173,7 @@ int bnxt_set_vf_mac(struct net_device *dev, int vf_id, u8 *mac)
+       return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+ }
+-int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos,
+-                   __be16 vlan_proto)
++int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos)
+ {
+       struct hwrm_func_cfg_input req = {0};
+       struct bnxt *bp = netdev_priv(dev);
+@@ -185,9 +184,6 @@ int bnxt_set_vf_vlan(struct net_device *dev, int vf_id, u16 vlan_id, u8 qos,
+       if (bp->hwrm_spec_code < 0x10201)
+               return -ENOTSUPP;
+-      if (vlan_proto != htons(ETH_P_8021Q))
+-              return -EPROTONOSUPPORT;
+-
+       rc = bnxt_vf_ndo_prep(bp, vf_id);
+       if (rc)
+               return rc;
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
+index 1ab72e4..0392670 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.h
+@@ -12,7 +12,7 @@
+ int bnxt_get_vf_config(struct net_device *, int, struct ifla_vf_info *);
+ int bnxt_set_vf_mac(struct net_device *, int, u8 *);
+-int bnxt_set_vf_vlan(struct net_device *, int, u16, u8, __be16);
++int bnxt_set_vf_vlan(struct net_device *, int, u16, u8);
+ int bnxt_set_vf_bw(struct net_device *, int, int, int);
+ int bnxt_set_vf_link_state(struct net_device *, int, int);
+ int bnxt_set_vf_spoofchk(struct net_device *, int, bool);
+-- 
+2.5.5
+