Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Jul 2015 21:58:07 +0000 (14:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Jul 2015 21:58:07 +0000 (14:58 -0700)
Pull networking fixes from David Miller:

 1) mlx4 driver bug fixes (TX queue wakeups, csum complete indications)
    from Ido Shamay, Eran Ben Elisha, and Or Gerlitz.

 2) Missing unlock in error path of PTP support in renesas driver, from
    Dan Carpenter.

 3) Add Vitesse 8641 phy IDs to vitesse PHY driver, from Shaohui Xie.

 4) Bnx2x driver bug fixes (linearization of encap packets, scratchpad
    parity error notifications, flow-control and speed settings) from
    Yuval Mintz, Manish Chopra, Shahed Shaikh, and Ariel Elior.

 5) ipv6 extension header parsing in the igb chip has a HW errata,
    disable it.  Frm Todd Fujinaka.

 6) Fix PCI link state locking issue in e1000e driver, from Yanir
    Lubetkin.

 7) Cure panics during MTU change in i40e, from Mitch Williams.

 8) Don't leak promisc refs in DSA slave driver, from Gilad Ben-Yossef.

 9) Add missing HAS_DMA dep to VIA Rhine driver, from Geery
    Uytterhoeven.

10) Make sure DMA map/unmap calls are symmetric in bnx2x driver, from
    Michal Schmidt.

11) Workaround for MDIO access problems in bcm7xxx devices, from FLorian
    Fainelli.

12) Fix races in SCTP protocol between OTTB responses and route
    removals, from Alexander Sverdlin.

13) Fix jumbo frame checksum issue with some mvneta devices, from Simon
    Guinot.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (58 commits)
  sock_diag: don't broadcast kernel sockets
  net: mvneta: disable IP checksum with jumbo frames for Armada 370
  ARM: mvebu: update Ethernet compatible string for Armada XP
  net: mvneta: introduce compatible string "marvell, armada-xp-neta"
  api: fix compatibility of linux/in.h with netinet/in.h
  net: icplus: fix typo in constant name
  sis900: Trivial: Fix typos in enums
  stmmac: Trivial: fix typo in constant name
  sctp: Fix race between OOTB responce and route removal
  net-Liquidio: Delete unnecessary checks before the function call "vfree"
  vmxnet3: Bump up driver version number
  amd-xgbe: Add the __GFP_NOWARN flag to Rx buffer allocation
  net: phy: mdio-bcm-unimac: workaround initial read failures for integrated PHYs
  net: bcmgenet: workaround initial read failures for integrated PHYs
  net: phy: bcm7xxx: workaround MDIO management controller initial read
  bnx2x: fix DMA API usage
  net: via: VIA_RHINE and VIA_VELOCITY should depend on HAS_DMA
  net/phy: tune get_phy_c45_ids to support more c45 phy
  bnx2x: fix lockdep splat
  net: fec: don't access RACC register when not available
  ...

69 files changed:
Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-370.dtsi
arch/arm/boot/dts/armada-xp-mv78260.dtsi
arch/arm/boot/dts/armada-xp-mv78460.dtsi
arch/arm/boot/dts/armada-xp.dtsi
drivers/net/ethernet/amd/xgbe/xgbe-desc.c
drivers/net/ethernet/apm/xgene/xgene_enet_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
drivers/net/ethernet/cavium/liquidio/octeon_device.c
drivers/net/ethernet/cavium/liquidio/octeon_droq.c
drivers/net/ethernet/cavium/liquidio/request_manager.c
drivers/net/ethernet/cisco/enic/enic_main.c
drivers/net/ethernet/cisco/enic/vnic_rq.h
drivers/net/ethernet/freescale/Kconfig
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/icplus/ipg.c
drivers/net/ethernet/icplus/ipg.h
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40evf.h
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/igb/e1000_82575.c
drivers/net/ethernet/intel/igb/e1000_defines.h
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx4/intf.c
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/renesas/ravb_ptp.c
drivers/net/ethernet/sis/sis900.h
drivers/net/ethernet/stmicro/stmmac/mmc_core.c
drivers/net/ethernet/via/Kconfig
drivers/net/phy/bcm7xxx.c
drivers/net/phy/mdio-bcm-unimac.c
drivers/net/phy/phy_device.c
drivers/net/phy/vitesse.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/xen-netfront.c
include/net/ax25.h
include/net/sock.h
include/uapi/linux/in.h
include/uapi/linux/libc-compat.h
net/ax25/af_ax25.c
net/ax25/ax25_in.c
net/core/flow_dissector.c
net/core/sock.c
net/dsa/slave.c
net/ipv4/fib_semantics.c
net/sched/cls_flower.c
net/sctp/output.c
net/sctp/socket.c
net/tipc/bcast.c
net/tipc/link.c
net/tipc/link.h

index 750d577e8083ee3f96c8bf823c986c162d4ac5b3..f5a8ca29aff06e84d49e3c75caf125b35c660055 100644 (file)
@@ -1,7 +1,7 @@
 * Marvell Armada 370 / Armada XP Ethernet Controller (NETA)
 
 Required properties:
-- compatible: should be "marvell,armada-370-neta".
+- compatible: "marvell,armada-370-neta" or "marvell,armada-xp-neta".
 - reg: address and length of the register set for the device.
 - interrupts: interrupt for the device
 - phy: See ethernet.txt file in the same directory.
index 7f0252c580e4bd0b32a2e2eb5de440bacbfd3b98..a718866ba52d8e827653c7cbcb3341778f480b83 100644 (file)
                        };
 
                        eth0: ethernet@70000 {
-                               compatible = "marvell,armada-370-neta";
                                reg = <0x70000 0x4000>;
                                interrupts = <8>;
                                clocks = <&gateclk 4>;
                        };
 
                        eth1: ethernet@74000 {
-                               compatible = "marvell,armada-370-neta";
                                reg = <0x74000 0x4000>;
                                interrupts = <10>;
                                clocks = <&gateclk 3>;
index 3f036bd635f4207ac2ffe87e809155a51debaa64..53a1a5abe14739d5c71a64b9689147fa7f0c37cb 100644 (file)
                                        dmacap,memset;
                                };
                        };
+
+                       ethernet@70000 {
+                               compatible = "marvell,armada-370-neta";
+                       };
+
+                       ethernet@74000 {
+                               compatible = "marvell,armada-370-neta";
+                       };
                };
        };
 };
index 8479fdc9e9c2468e072c3592528a263610c2acc1..c5fdc99f0dbebb47f88e135a4013fdfb9d732772 100644 (file)
                        };
 
                        eth3: ethernet@34000 {
-                               compatible = "marvell,armada-370-neta";
+                               compatible = "marvell,armada-xp-neta";
                                reg = <0x34000 0x4000>;
                                interrupts = <14>;
                                clocks = <&gateclk 1>;
index 661d54c815802d1bb1d2e1fa31cb255d90caf12e..0e24f1a38540e30ccc257972537c8982074f4c75 100644 (file)
                        };
 
                        eth3: ethernet@34000 {
-                               compatible = "marvell,armada-370-neta";
+                               compatible = "marvell,armada-xp-neta";
                                reg = <0x34000 0x4000>;
                                interrupts = <14>;
                                clocks = <&gateclk 1>;
index e78ce4ab6b75b03d4fd0785388b1d4d47c4ef1cd..0854d4493da7a8518c241dabe06e91ce22eb5fe9 100644 (file)
                        };
 
                        eth2: ethernet@30000 {
-                               compatible = "marvell,armada-370-neta";
+                               compatible = "marvell,armada-xp-neta";
                                reg = <0x30000 0x4000>;
                                interrupts = <12>;
                                clocks = <&gateclk 2>;
                                };
                        };
 
+                       ethernet@70000 {
+                               compatible = "marvell,armada-xp-neta";
+                       };
+
+                       ethernet@74000 {
+                               compatible = "marvell,armada-xp-neta";
+                       };
+
                        xor@f0900 {
                                compatible = "marvell,orion-xor";
                                reg = <0xF0900 0x100
index dd03ad865cafb83b16389e4f1840a335ff3fe9d4..661cdaa7ea96c26ebc6142c955f12dd19296e49f 100644 (file)
@@ -268,7 +268,7 @@ static int xgbe_alloc_pages(struct xgbe_prv_data *pdata,
        int ret;
 
        /* Try to obtain pages, decreasing order if necessary */
-       gfp |= __GFP_COLD | __GFP_COMP;
+       gfp |= __GFP_COLD | __GFP_COMP | __GFP_NOWARN;
        while (order >= 0) {
                pages = alloc_pages(gfp, order);
                if (pages)
index 95153b234c7158c655d95b7882db729d966a36dc..299eb4315fe647ba8d67302649a2cf928a4d59d5 100644 (file)
@@ -948,7 +948,7 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
        struct resource *res;
        void __iomem *base_addr;
        u32 offset;
-       int ret;
+       int ret = 0;
 
        pdev = pdata->pdev;
        dev = &pdev->dev;
index 7a4aaa3c01b69d43b8f0bd7f1023150f203c7179..cd4ae76bbff2f8acda89154e65cf699e141553e5 100644 (file)
@@ -530,7 +530,6 @@ enum bnx2x_tpa_mode_t {
 
 struct bnx2x_alloc_pool {
        struct page     *page;
-       dma_addr_t      dma;
        unsigned int    offset;
 };
 
@@ -2418,10 +2417,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id,
                                 AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
                                 AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
 
-#define HW_PRTY_ASSERT_SET_3 (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
-               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
-               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
-               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
+#define HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD \
+               (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
+                AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
+                AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
+
+#define HW_PRTY_ASSERT_SET_3 (HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD | \
+                             AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
 
 #define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \
                              AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)
index e2a65334708d8d61703dd44d55ab3ef9d0dda67f..a90d7364334f9dfa3687dc813e068508a342861c 100644 (file)
@@ -563,23 +563,20 @@ static int bnx2x_alloc_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp,
                        return -ENOMEM;
                }
 
-               pool->dma = dma_map_page(&bp->pdev->dev, pool->page, 0,
-                                        PAGE_SIZE, DMA_FROM_DEVICE);
-               if (unlikely(dma_mapping_error(&bp->pdev->dev,
-                                              pool->dma))) {
-                       __free_pages(pool->page, PAGES_PER_SGE_SHIFT);
-                       pool->page = NULL;
-                       BNX2X_ERR("Can't map sge\n");
-                       return -ENOMEM;
-               }
                pool->offset = 0;
        }
 
+       mapping = dma_map_page(&bp->pdev->dev, pool->page,
+                              pool->offset, SGE_PAGE_SIZE, DMA_FROM_DEVICE);
+       if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
+               BNX2X_ERR("Can't map sge\n");
+               return -ENOMEM;
+       }
+
        get_page(pool->page);
        sw_buf->page = pool->page;
        sw_buf->offset = pool->offset;
 
-       mapping = pool->dma + sw_buf->offset;
        dma_unmap_addr_set(sw_buf, mapping, mapping);
 
        sge->addr_hi = cpu_to_le32(U64_HI(mapping));
@@ -648,9 +645,9 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
                        return err;
                }
 
-               dma_unmap_single(&bp->pdev->dev,
-                                dma_unmap_addr(&old_rx_pg, mapping),
-                                SGE_PAGE_SIZE, DMA_FROM_DEVICE);
+               dma_unmap_page(&bp->pdev->dev,
+                              dma_unmap_addr(&old_rx_pg, mapping),
+                              SGE_PAGE_SIZE, DMA_FROM_DEVICE);
                /* Add one frag and update the appropriate fields in the skb */
                if (fp->mode == TPA_MODE_LRO)
                        skb_fill_page_desc(skb, j, old_rx_pg.page,
@@ -3421,8 +3418,13 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
                        u32 wnd_sum = 0;
 
                        /* Headers length */
-                       hlen = (int)(skb_transport_header(skb) - skb->data) +
-                               tcp_hdrlen(skb);
+                       if (xmit_type & XMIT_GSO_ENC)
+                               hlen = (int)(skb_inner_transport_header(skb) -
+                                            skb->data) +
+                                            inner_tcp_hdrlen(skb);
+                       else
+                               hlen = (int)(skb_transport_header(skb) -
+                                            skb->data) + tcp_hdrlen(skb);
 
                        /* Amount of data (w/o headers) on linear part of SKB*/
                        first_bd_sz = skb_headlen(skb) - hlen;
index 2b30081ec26d128ec86c602eb5a097c77c664159..03b7404d5b9ba59c5470fe36ec0746d6b75f7eee 100644 (file)
@@ -807,8 +807,8 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
        /* Since many fragments can share the same page, make sure to
         * only unmap and free the page once.
         */
-       dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping),
-                        SGE_PAGE_SIZE, DMA_FROM_DEVICE);
+       dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping),
+                      SGE_PAGE_SIZE, DMA_FROM_DEVICE);
 
        put_page(page);
 
@@ -974,14 +974,6 @@ static inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp,
        if (!pool->page)
                return;
 
-       /* Page was not fully fragmented.  Unmap unused space */
-       if (pool->offset < PAGE_SIZE) {
-               dma_addr_t dma = pool->dma + pool->offset;
-               int size = PAGE_SIZE - pool->offset;
-
-               dma_unmap_single(&bp->pdev->dev, dma, size, DMA_FROM_DEVICE);
-       }
-
        put_page(pool->page);
 
        pool->page = NULL;
index 48ed005ba73fd3a9d9aa550871b647fdd0b59350..76b9052a961c517978494199d74398264583508c 100644 (file)
@@ -257,14 +257,15 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct bnx2x *bp = netdev_priv(dev);
        int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+       u32 media_type;
 
        /* Dual Media boards present all available port types */
        cmd->supported = bp->port.supported[cfg_idx] |
                (bp->port.supported[cfg_idx ^ 1] &
                 (SUPPORTED_TP | SUPPORTED_FIBRE));
        cmd->advertising = bp->port.advertising[cfg_idx];
-       if (bp->link_params.phy[bnx2x_get_cur_phy_idx(bp)].media_type ==
-           ETH_PHY_SFP_1G_FIBER) {
+       media_type = bp->link_params.phy[bnx2x_get_cur_phy_idx(bp)].media_type;
+       if (media_type == ETH_PHY_SFP_1G_FIBER) {
                cmd->supported &= ~(SUPPORTED_10000baseT_Full);
                cmd->advertising &= ~(ADVERTISED_10000baseT_Full);
        }
@@ -312,12 +313,26 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        cmd->lp_advertising |= ADVERTISED_100baseT_Full;
                if (status & LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE)
                        cmd->lp_advertising |= ADVERTISED_1000baseT_Half;
-               if (status & LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE)
-                       cmd->lp_advertising |= ADVERTISED_1000baseT_Full;
+               if (status & LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE) {
+                       if (media_type == ETH_PHY_KR) {
+                               cmd->lp_advertising |=
+                                       ADVERTISED_1000baseKX_Full;
+                       } else {
+                               cmd->lp_advertising |=
+                                       ADVERTISED_1000baseT_Full;
+                       }
+               }
                if (status & LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE)
                        cmd->lp_advertising |= ADVERTISED_2500baseX_Full;
-               if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE)
-                       cmd->lp_advertising |= ADVERTISED_10000baseT_Full;
+               if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE) {
+                       if (media_type == ETH_PHY_KR) {
+                               cmd->lp_advertising |=
+                                       ADVERTISED_10000baseKR_Full;
+                       } else {
+                               cmd->lp_advertising |=
+                                       ADVERTISED_10000baseT_Full;
+                       }
+               }
                if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE)
                        cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full;
        }
@@ -564,15 +579,20 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                                return -EINVAL;
                        }
 
-                       if (!(bp->port.supported[cfg_idx] &
-                             SUPPORTED_1000baseT_Full)) {
+                       if (bp->port.supported[cfg_idx] &
+                            SUPPORTED_1000baseT_Full) {
+                               advertising = (ADVERTISED_1000baseT_Full |
+                                              ADVERTISED_TP);
+
+                       } else if (bp->port.supported[cfg_idx] &
+                                  SUPPORTED_1000baseKX_Full) {
+                               advertising = ADVERTISED_1000baseKX_Full;
+                       } else {
                                DP(BNX2X_MSG_ETHTOOL,
                                   "1G full not supported\n");
                                return -EINVAL;
                        }
 
-                       advertising = (ADVERTISED_1000baseT_Full |
-                                      ADVERTISED_TP);
                        break;
 
                case SPEED_2500:
@@ -600,17 +620,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                                return -EINVAL;
                        }
                        phy_idx = bnx2x_get_cur_phy_idx(bp);
-                       if (!(bp->port.supported[cfg_idx]
-                             & SUPPORTED_10000baseT_Full) ||
-                           (bp->link_params.phy[phy_idx].media_type ==
+                       if ((bp->port.supported[cfg_idx] &
+                            SUPPORTED_10000baseT_Full) &&
+                           (bp->link_params.phy[phy_idx].media_type !=
                             ETH_PHY_SFP_1G_FIBER)) {
+                               advertising = (ADVERTISED_10000baseT_Full |
+                                              ADVERTISED_FIBRE);
+                       } else if (bp->port.supported[cfg_idx] &
+                              SUPPORTED_10000baseKR_Full) {
+                               advertising = (ADVERTISED_10000baseKR_Full |
+                                              ADVERTISED_FIBRE);
+                       } else {
                                DP(BNX2X_MSG_ETHTOOL,
                                   "10G full not supported\n");
                                return -EINVAL;
                        }
 
-                       advertising = (ADVERTISED_10000baseT_Full |
-                                      ADVERTISED_FIBRE);
                        break;
 
                default:
@@ -633,6 +658,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        bp->link_params.multi_phy_config = new_multi_phy_config;
        if (netif_running(dev)) {
                bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+               bnx2x_force_link_reset(bp);
                bnx2x_link_set(bp);
        }
 
@@ -1204,6 +1230,7 @@ static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
        if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
                DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM,
                   "cannot get access to nvram interface\n");
+               bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
                return -EBUSY;
        }
 
@@ -1944,6 +1971,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
 
        if (netif_running(dev)) {
                bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+               bnx2x_force_link_reset(bp);
                bnx2x_link_set(bp);
        }
 
index 21a0d6afca4a53a24100289585f1e9b6d59ee497..a0b03c27e0a302c08fd1a78c5dbd2dd7606ae16a 100644 (file)
@@ -3392,9 +3392,9 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
        case BNX2X_FLOW_CTRL_AUTO:
                switch (params->req_fc_auto_adv) {
                case BNX2X_FLOW_CTRL_BOTH:
+               case BNX2X_FLOW_CTRL_RX:
                        *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
                        break;
-               case BNX2X_FLOW_CTRL_RX:
                case BNX2X_FLOW_CTRL_TX:
                        *ieee_fc |=
                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
@@ -3488,14 +3488,21 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
 }
 
-static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
-{                                              /*  LD      LP   */
+static void bnx2x_pause_resolve(struct bnx2x_phy *phy,
+                               struct link_params *params,
+                               struct link_vars *vars,
+                               u32 pause_result)
+{
+       struct bnx2x *bp = params->bp;
+                                               /*  LD      LP   */
        switch (pause_result) {                 /* ASYM P ASYM P */
        case 0xb:                               /*   1  0   1  1 */
+               DP(NETIF_MSG_LINK, "Flow Control: TX only\n");
                vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
                break;
 
        case 0xe:                               /*   1  1   1  0 */
+               DP(NETIF_MSG_LINK, "Flow Control: RX only\n");
                vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
                break;
 
@@ -3503,10 +3510,22 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
        case 0x7:                               /*   0  1   1  1 */
        case 0xd:                               /*   1  1   0  1 */
        case 0xf:                               /*   1  1   1  1 */
-               vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
+               /* If the user selected to advertise RX ONLY,
+                * although we advertised both, need to enable
+                * RX only.
+                */
+               if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
+                       DP(NETIF_MSG_LINK, "Flow Control: RX & TX\n");
+                       vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
+               } else {
+                       DP(NETIF_MSG_LINK, "Flow Control: RX only\n");
+                       vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
+               }
                break;
 
        default:
+               DP(NETIF_MSG_LINK, "Flow Control: None\n");
+               vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
                break;
        }
        if (pause_result & (1<<0))
@@ -3567,7 +3586,7 @@ static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
        pause_result |= (lp_pause &
                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
        DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
-       bnx2x_pause_resolve(vars, pause_result);
+       bnx2x_pause_resolve(phy, params, vars, pause_result);
 
 }
 
@@ -5396,7 +5415,7 @@ static void bnx2x_update_adv_fc(struct bnx2x_phy *phy,
                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
                DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result);
        }
-       bnx2x_pause_resolve(vars, pause_result);
+       bnx2x_pause_resolve(phy, params, vars, pause_result);
 
 }
 
@@ -7129,7 +7148,7 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
                pause_result |= (lp_pause &
                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
 
-               bnx2x_pause_resolve(vars, pause_result);
+               bnx2x_pause_resolve(phy, params, vars, pause_result);
                DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
                           pause_result);
        }
@@ -11474,7 +11493,9 @@ static const struct bnx2x_phy phy_warpcore = {
                           SUPPORTED_100baseT_Half |
                           SUPPORTED_100baseT_Full |
                           SUPPORTED_1000baseT_Full |
+                          SUPPORTED_1000baseKX_Full |
                           SUPPORTED_10000baseT_Full |
+                          SUPPORTED_10000baseKR_Full |
                           SUPPORTED_20000baseKR2_Full |
                           SUPPORTED_20000baseMLD2_Full |
                           SUPPORTED_FIBRE |
@@ -11980,8 +12001,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
                        break;
                case PORT_HW_CFG_NET_SERDES_IF_KR:
                        phy->media_type = ETH_PHY_KR;
-                       phy->supported &= (SUPPORTED_1000baseT_Full |
-                                          SUPPORTED_10000baseT_Full |
+                       phy->supported &= (SUPPORTED_1000baseKX_Full |
+                                          SUPPORTED_10000baseKR_Full |
                                           SUPPORTED_FIBRE |
                                           SUPPORTED_Autoneg |
                                           SUPPORTED_Pause |
@@ -11999,8 +12020,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
                        phy->media_type = ETH_PHY_KR;
                        phy->flags |= FLAGS_WC_DUAL_MODE;
                        phy->supported &= (SUPPORTED_20000baseKR2_Full |
-                                          SUPPORTED_10000baseT_Full |
-                                          SUPPORTED_1000baseT_Full |
+                                          SUPPORTED_10000baseKR_Full |
+                                          SUPPORTED_1000baseKX_Full |
                                           SUPPORTED_Autoneg |
                                           SUPPORTED_FIBRE |
                                           SUPPORTED_Pause |
index 33501bcddc48eb1f6157a08e3e3d1e08dc087c25..c27af12314ed29ae19e73a9c00f56c062a5aa830 100644 (file)
@@ -2287,13 +2287,11 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio, u32 mode)
 void bnx2x_calc_fc_adv(struct bnx2x *bp)
 {
        u8 cfg_idx = bnx2x_get_link_cfg_idx(bp);
+
+       bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
+                                          ADVERTISED_Pause);
        switch (bp->link_vars.ieee_fc &
                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) {
-       case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
-               bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
-                                                  ADVERTISED_Pause);
-               break;
-
        case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
                bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause |
                                                  ADVERTISED_Pause);
@@ -2304,8 +2302,6 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp)
                break;
 
        default:
-               bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
-                                                  ADVERTISED_Pause);
                break;
        }
 }
@@ -2351,12 +2347,16 @@ int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
                if (load_mode == LOAD_DIAG) {
                        struct link_params *lp = &bp->link_params;
                        lp->loopback_mode = LOOPBACK_XGXS;
-                       /* do PHY loopback at 10G speed, if possible */
-                       if (lp->req_line_speed[cfx_idx] < SPEED_10000) {
+                       /* Prefer doing PHY loopback at highest speed */
+                       if (lp->req_line_speed[cfx_idx] < SPEED_20000) {
                                if (lp->speed_cap_mask[cfx_idx] &
-                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
                                        lp->req_line_speed[cfx_idx] =
-                                       SPEED_10000;
+                                       SPEED_20000;
+                               else if (lp->speed_cap_mask[cfx_idx] &
+                                           PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
+                                               lp->req_line_speed[cfx_idx] =
+                                               SPEED_10000;
                                else
                                        lp->req_line_speed[cfx_idx] =
                                        SPEED_1000;
@@ -4867,9 +4867,7 @@ static bool bnx2x_check_blocks_with_parity3(struct bnx2x *bp, u32 sig,
                                res = true;
                                break;
                        case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY:
-                               if (print)
-                                       _print_next_block((*par_num)++,
-                                                         "MCP SCPAD");
+                               (*par_num)++;
                                /* clear latched SCPAD PATIRY from MCP */
                                REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
                                       1UL << 10);
@@ -4931,6 +4929,7 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
            (sig[3] & HW_PRTY_ASSERT_SET_3) ||
            (sig[4] & HW_PRTY_ASSERT_SET_4)) {
                int par_num = 0;
+
                DP(NETIF_MSG_HW, "Was parity error: HW block parity attention:\n"
                                 "[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x [4]:0x%08x\n",
                          sig[0] & HW_PRTY_ASSERT_SET_0,
@@ -4938,9 +4937,18 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
                          sig[2] & HW_PRTY_ASSERT_SET_2,
                          sig[3] & HW_PRTY_ASSERT_SET_3,
                          sig[4] & HW_PRTY_ASSERT_SET_4);
-               if (print)
-                       netdev_err(bp->dev,
-                                  "Parity errors detected in blocks: ");
+               if (print) {
+                       if (((sig[0] & HW_PRTY_ASSERT_SET_0) ||
+                            (sig[1] & HW_PRTY_ASSERT_SET_1) ||
+                            (sig[2] & HW_PRTY_ASSERT_SET_2) ||
+                            (sig[4] & HW_PRTY_ASSERT_SET_4)) ||
+                            (sig[3] & HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD)) {
+                               netdev_err(bp->dev,
+                                          "Parity errors detected in blocks: ");
+                       } else {
+                               print = false;
+                       }
+               }
                res |= bnx2x_check_blocks_with_parity0(bp,
                        sig[0] & HW_PRTY_ASSERT_SET_0, &par_num, print);
                res |= bnx2x_check_blocks_with_parity1(bp,
@@ -8431,7 +8439,7 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
                                         BNX2X_ETH_MAC, &ramrod_flags);
        } else { /* vf */
                return bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr,
-                                            bp->fp->index, true);
+                                            bp->fp->index, set);
        }
 }
 
@@ -9323,7 +9331,8 @@ unload_error:
         * function stop ramrod is sent, since as part of this ramrod FW access
         * PTP registers.
         */
-       bnx2x_stop_ptp(bp);
+       if (bp->flags & PTP_SUPPORTED)
+               bnx2x_stop_ptp(bp);
 
        /* Disable HW interrupts, NAPI */
        bnx2x_netif_stop(bp, 1);
@@ -11147,6 +11156,12 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                                bp->port.advertising[idx] |=
                                        (ADVERTISED_1000baseT_Full |
                                         ADVERTISED_TP);
+                       } else if (bp->port.supported[idx] &
+                                  SUPPORTED_1000baseKX_Full) {
+                               bp->link_params.req_line_speed[idx] =
+                                       SPEED_1000;
+                               bp->port.advertising[idx] |=
+                                       ADVERTISED_1000baseKX_Full;
                        } else {
                                BNX2X_ERR("NVRAM config error. Invalid link_config 0x%x  speed_cap_mask 0x%x\n",
                                    link_config,
@@ -11179,6 +11194,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp)
                                bp->port.advertising[idx] |=
                                        (ADVERTISED_10000baseT_Full |
                                                ADVERTISED_FIBRE);
+                       } else if (bp->port.supported[idx] &
+                                  SUPPORTED_10000baseKR_Full) {
+                               bp->link_params.req_line_speed[idx] =
+                                       SPEED_10000;
+                               bp->port.advertising[idx] |=
+                                       (ADVERTISED_10000baseKR_Full |
+                                               ADVERTISED_FIBRE);
                        } else {
                                BNX2X_ERR("NVRAM config error. Invalid link_config 0x%x  speed_cap_mask 0x%x\n",
                                    link_config,
index 07cdf9bbffef2ee85ff3d589f33c1a10aea405d5..4ad415ac8cfe4a56ffd00858d1f70d9f1ab01456 100644 (file)
@@ -424,7 +424,7 @@ static void __bnx2x_vlan_mac_h_exec_pending(struct bnx2x *bp,
        o->head_exe_request = false;
        o->saved_ramrod_flags = 0;
        rc = bnx2x_exe_queue_step(bp, &o->exe_queue, &ramrod_flags);
-       if (rc != 0) {
+       if ((rc != 0) && (rc != 1)) {
                BNX2X_ERR("execution of pending commands failed with rc %d\n",
                          rc);
 #ifdef BNX2X_STOP_ON_ERROR
index 6f2887a5e0be693d625b6328349a2ad3b66d19ba..6159deab8c9850a0231ef3b3f1fad6dfaa31a588 100644 (file)
@@ -594,6 +594,7 @@ struct bcmgenet_priv {
        wait_queue_head_t wq;
        struct phy_device *phydev;
        struct device_node *phy_dn;
+       struct device_node *mdio_dn;
        struct mii_bus *mii_bus;
        u16 gphy_rev;
        struct clk *clk_eee;
index 6bef04e2f7354b2a9cadeac7eda5ea66e2fd25da..adf23d2ac4888e89f63c4246e7c3b33eaf3d0fd0 100644 (file)
@@ -408,6 +408,52 @@ static int bcmgenet_mii_probe(struct net_device *dev)
        return 0;
 }
 
+/* Workaround for integrated BCM7xxx Gigabit PHYs which have a problem with
+ * their internal MDIO management controller making them fail to successfully
+ * be read from or written to for the first transaction.  We insert a dummy
+ * BMSR read here to make sure that phy_get_device() and get_phy_id() can
+ * correctly read the PHY MII_PHYSID1/2 registers and successfully register a
+ * PHY device for this peripheral.
+ *
+ * Once the PHY driver is registered, we can workaround subsequent reads from
+ * there (e.g: during system-wide power management).
+ *
+ * bus->reset is invoked before mdiobus_scan during mdiobus_register and is
+ * therefore the right location to stick that workaround. Since we do not want
+ * to read from non-existing PHYs, we either use bus->phy_mask or do a manual
+ * Device Tree scan to limit the search area.
+ */
+static int bcmgenet_mii_bus_reset(struct mii_bus *bus)
+{
+       struct net_device *dev = bus->priv;
+       struct bcmgenet_priv *priv = netdev_priv(dev);
+       struct device_node *np = priv->mdio_dn;
+       struct device_node *child = NULL;
+       u32 read_mask = 0;
+       int addr = 0;
+
+       if (!np) {
+               read_mask = 1 << priv->phy_addr;
+       } else {
+               for_each_available_child_of_node(np, child) {
+                       addr = of_mdio_parse_addr(&dev->dev, child);
+                       if (addr < 0)
+                               continue;
+
+                       read_mask |= 1 << addr;
+               }
+       }
+
+       for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+               if (read_mask & 1 << addr) {
+                       dev_dbg(&dev->dev, "Workaround for PHY @ %d\n", addr);
+                       mdiobus_read(bus, addr, MII_BMSR);
+               }
+       }
+
+       return 0;
+}
+
 static int bcmgenet_mii_alloc(struct bcmgenet_priv *priv)
 {
        struct mii_bus *bus;
@@ -427,6 +473,7 @@ static int bcmgenet_mii_alloc(struct bcmgenet_priv *priv)
        bus->parent = &priv->pdev->dev;
        bus->read = bcmgenet_mii_read;
        bus->write = bcmgenet_mii_write;
+       bus->reset = bcmgenet_mii_bus_reset;
        snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d",
                 priv->pdev->name, priv->pdev->id);
 
@@ -443,7 +490,6 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
 {
        struct device_node *dn = priv->pdev->dev.of_node;
        struct device *kdev = &priv->pdev->dev;
-       struct device_node *mdio_dn;
        char *compat;
        int ret;
 
@@ -451,14 +497,14 @@ static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
        if (!compat)
                return -ENOMEM;
 
-       mdio_dn = of_find_compatible_node(dn, NULL, compat);
+       priv->mdio_dn = of_find_compatible_node(dn, NULL, compat);
        kfree(compat);
-       if (!mdio_dn) {
+       if (!priv->mdio_dn) {
                dev_err(kdev, "unable to find MDIO bus node\n");
                return -ENODEV;
        }
 
-       ret = of_mdiobus_register(priv->mii_bus, mdio_dn);
+       ret = of_mdiobus_register(priv->mii_bus, priv->mdio_dn);
        if (ret) {
                dev_err(kdev, "failed to register MDIO bus\n");
                return ret;
index 160f8077692ce487a7d8cb87aa41d62dc21c1ddc..29f33083178431ac3735094683663d1e4ab2b836 100644 (file)
@@ -434,8 +434,9 @@ static int lio_set_phys_id(struct net_device *netdev,
                        if (ret)
                                return ret;
 
-                       octnet_mdio45_access(lio, 1, LIO68XX_LED_BEACON_ADDR,
-                                            &lio->phy_beacon_val);
+                       ret = octnet_mdio45_access(lio, 1,
+                                                  LIO68XX_LED_BEACON_ADDR,
+                                                  &lio->phy_beacon_val);
                        if (ret)
                                return ret;
 
index 0d3106b464b29548ddca47eaebb56d08e879b552..f67641a2ff9eff652a7998f4c6d8f8fab873fc63 100644 (file)
@@ -650,14 +650,12 @@ void octeon_free_device_mem(struct octeon_device *oct)
 
        for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES; i++) {
                /* could check  mask as well */
-               if (oct->droq[i])
-                       vfree(oct->droq[i]);
+               vfree(oct->droq[i]);
        }
 
        for (i = 0; i < MAX_OCTEON_INSTR_QUEUES; i++) {
                /* could check mask as well */
-               if (oct->instr_queue[i])
-                       vfree(oct->instr_queue[i]);
+               vfree(oct->instr_queue[i]);
        }
 
        i = oct->octeon_id;
@@ -1078,10 +1076,7 @@ octeon_unregister_dispatch_fn(struct octeon_device *oct, u16 opcode,
                oct->dispatch.count--;
 
        spin_unlock_bh(&oct->dispatch.lock);
-
-       if (dfree)
-               vfree(dfree);
-
+       vfree(dfree);
        return retval;
 }
 
index 94b502a0cf33e54b954768688c3e35c056ed1d55..4dba86eaa04559649b012cbeff8707c47a176927 100644 (file)
@@ -216,9 +216,7 @@ int octeon_delete_droq(struct octeon_device *oct, u32 q_no)
        dev_dbg(&oct->pci_dev->dev, "%s[%d]\n", __func__, q_no);
 
        octeon_droq_destroy_ring_buffers(oct, droq);
-
-       if (droq->recv_buf_list)
-               vfree(droq->recv_buf_list);
+       vfree(droq->recv_buf_list);
 
        if (droq->info_base_addr)
                cnnic_free_aligned_dma(oct->pci_dev, droq->info_list,
index 356796bf9b871e82f4e300206e24757072bfa870..a2a24652c8f32826882f82910b76d38c8df49593 100644 (file)
@@ -175,8 +175,7 @@ int octeon_delete_instr_queue(struct octeon_device *oct, u32 iq_no)
                desc_size =
                    CFG_GET_IQ_INSTR_TYPE(CHIP_FIELD(oct, cn6xxx, conf));
 
-       if (iq->request_list)
-               vfree(iq->request_list);
+       vfree(iq->request_list);
 
        if (iq->base_addr) {
                q_size = iq->max_count * desc_size;
index eadae1b412c652974dde24a9a76c5d74a8c3fa29..da2004e2a74176959ece42065a26267aa2924a2b 100644 (file)
@@ -1208,7 +1208,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
                napi_complete(napi);
                vnic_intr_unmask(&enic->intr[intr]);
        }
-       enic_poll_unlock_napi(&enic->rq[cq_rq]);
+       enic_poll_unlock_napi(&enic->rq[cq_rq], napi);
 
        return rq_work_done;
 }
@@ -1414,7 +1414,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
                 */
                enic_calc_int_moderation(enic, &enic->rq[rq]);
 
-       enic_poll_unlock_napi(&enic->rq[rq]);
+       enic_poll_unlock_napi(&enic->rq[rq], napi);
        if (work_done < work_to_do) {
 
                /* Some work done, but not enough to stay in polling,
index 8111d5202df2f38c26a8c241a7bb1c1e7cda8228..b9c82f143d7e099948c9bd5e540fee64eeb68b46 100644 (file)
@@ -21,6 +21,7 @@
 #define _VNIC_RQ_H_
 
 #include <linux/pci.h>
+#include <linux/netdevice.h>
 
 #include "vnic_dev.h"
 #include "vnic_cq.h"
@@ -75,6 +76,12 @@ struct vnic_rq_buf {
        uint64_t wr_id;
 };
 
+enum enic_poll_state {
+       ENIC_POLL_STATE_IDLE,
+       ENIC_POLL_STATE_NAPI,
+       ENIC_POLL_STATE_POLL
+};
+
 struct vnic_rq {
        unsigned int index;
        struct vnic_dev *vdev;
@@ -86,19 +93,7 @@ struct vnic_rq {
        void *os_buf_head;
        unsigned int pkts_outstanding;
 #ifdef CONFIG_NET_RX_BUSY_POLL
-#define ENIC_POLL_STATE_IDLE           0
-#define ENIC_POLL_STATE_NAPI           (1 << 0) /* NAPI owns this poll */
-#define ENIC_POLL_STATE_POLL           (1 << 1) /* poll owns this poll */
-#define ENIC_POLL_STATE_NAPI_YIELD     (1 << 2) /* NAPI yielded this poll */
-#define ENIC_POLL_STATE_POLL_YIELD     (1 << 3) /* poll yielded this poll */
-#define ENIC_POLL_YIELD                        (ENIC_POLL_STATE_NAPI_YIELD |   \
-                                        ENIC_POLL_STATE_POLL_YIELD)
-#define ENIC_POLL_LOCKED               (ENIC_POLL_STATE_NAPI |         \
-                                        ENIC_POLL_STATE_POLL)
-#define ENIC_POLL_USER_PEND            (ENIC_POLL_STATE_POLL |         \
-                                        ENIC_POLL_STATE_POLL_YIELD)
-       unsigned int bpoll_state;
-       spinlock_t bpoll_lock;
+       atomic_t bpoll_state;
 #endif /* CONFIG_NET_RX_BUSY_POLL */
 };
 
@@ -215,76 +210,43 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
 #ifdef CONFIG_NET_RX_BUSY_POLL
 static inline void enic_busy_poll_init_lock(struct vnic_rq *rq)
 {
-       spin_lock_init(&rq->bpoll_lock);
-       rq->bpoll_state = ENIC_POLL_STATE_IDLE;
+       atomic_set(&rq->bpoll_state, ENIC_POLL_STATE_IDLE);
 }
 
 static inline bool enic_poll_lock_napi(struct vnic_rq *rq)
 {
-       bool rc = true;
-
-       spin_lock(&rq->bpoll_lock);
-       if (rq->bpoll_state & ENIC_POLL_LOCKED) {
-               WARN_ON(rq->bpoll_state & ENIC_POLL_STATE_NAPI);
-               rq->bpoll_state |= ENIC_POLL_STATE_NAPI_YIELD;
-               rc = false;
-       } else {
-               rq->bpoll_state = ENIC_POLL_STATE_NAPI;
-       }
-       spin_unlock(&rq->bpoll_lock);
+       int rc = atomic_cmpxchg(&rq->bpoll_state, ENIC_POLL_STATE_IDLE,
+                               ENIC_POLL_STATE_NAPI);
 
-       return rc;
+       return (rc == ENIC_POLL_STATE_IDLE);
 }
 
-static inline bool enic_poll_unlock_napi(struct vnic_rq *rq)
+static inline void enic_poll_unlock_napi(struct vnic_rq *rq,
+                                        struct napi_struct *napi)
 {
-       bool rc = false;
-
-       spin_lock(&rq->bpoll_lock);
-       WARN_ON(rq->bpoll_state &
-               (ENIC_POLL_STATE_POLL | ENIC_POLL_STATE_NAPI_YIELD));
-       if (rq->bpoll_state & ENIC_POLL_STATE_POLL_YIELD)
-               rc = true;
-       rq->bpoll_state = ENIC_POLL_STATE_IDLE;
-       spin_unlock(&rq->bpoll_lock);
-
-       return rc;
+       WARN_ON(atomic_read(&rq->bpoll_state) != ENIC_POLL_STATE_NAPI);
+       napi_gro_flush(napi, false);
+       atomic_set(&rq->bpoll_state, ENIC_POLL_STATE_IDLE);
 }
 
 static inline bool enic_poll_lock_poll(struct vnic_rq *rq)
 {
-       bool rc = true;
-
-       spin_lock_bh(&rq->bpoll_lock);
-       if (rq->bpoll_state & ENIC_POLL_LOCKED) {
-               rq->bpoll_state |= ENIC_POLL_STATE_POLL_YIELD;
-               rc = false;
-       } else {
-               rq->bpoll_state |= ENIC_POLL_STATE_POLL;
-       }
-       spin_unlock_bh(&rq->bpoll_lock);
+       int rc = atomic_cmpxchg(&rq->bpoll_state, ENIC_POLL_STATE_IDLE,
+                               ENIC_POLL_STATE_POLL);
 
-       return rc;
+       return (rc == ENIC_POLL_STATE_IDLE);
 }
 
-static inline bool enic_poll_unlock_poll(struct vnic_rq *rq)
-{
-       bool rc = false;
 
-       spin_lock_bh(&rq->bpoll_lock);
-       WARN_ON(rq->bpoll_state & ENIC_POLL_STATE_NAPI);
-       if (rq->bpoll_state & ENIC_POLL_STATE_POLL_YIELD)
-               rc = true;
-       rq->bpoll_state = ENIC_POLL_STATE_IDLE;
-       spin_unlock_bh(&rq->bpoll_lock);
-
-       return rc;
+static inline void enic_poll_unlock_poll(struct vnic_rq *rq)
+{
+       WARN_ON(atomic_read(&rq->bpoll_state) != ENIC_POLL_STATE_POLL);
+       atomic_set(&rq->bpoll_state, ENIC_POLL_STATE_IDLE);
 }
 
 static inline bool enic_poll_busy_polling(struct vnic_rq *rq)
 {
-       WARN_ON(!(rq->bpoll_state & ENIC_POLL_LOCKED));
-       return rq->bpoll_state & ENIC_POLL_USER_PEND;
+       return atomic_read(&rq->bpoll_state) & ENIC_POLL_STATE_POLL;
 }
 
 #else
@@ -298,7 +260,8 @@ static inline bool enic_poll_lock_napi(struct vnic_rq *rq)
        return true;
 }
 
-static inline bool enic_poll_unlock_napi(struct vnic_rq *rq)
+static inline bool enic_poll_unlock_napi(struct vnic_rq *rq,
+                                        struct napi_struct *napi)
 {
        return false;
 }
index b8de87b03046a13d2f1eff527137446de5081a41..ff76d4e9dc1ba5eab90413f82592a876092a8ddf 100644 (file)
@@ -83,12 +83,12 @@ config UGETH_TX_ON_DEMAND
 
 config GIANFAR
        tristate "Gianfar Ethernet"
-       depends on FSL_SOC
        select FSL_PQ_MDIO
        select PHYLIB
        select CRC32
        ---help---
          This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
-         and MPC86xx family of chips, and the FEC on the 8540.
+         and MPC86xx family of chips, the eTSEC on LS1021A and the FEC
+         on the 8540.
 
 endif # NET_VENDOR_FREESCALE
index a86af8a7485dad1be3caf4a55b6d77c7c7b5c884..1eee73cccdf58deba85c810399930ffa55dfa03c 100644 (file)
@@ -428,6 +428,8 @@ struct bufdesc_ex {
 #define FEC_QUIRK_BUG_CAPTURE          (1 << 10)
 /* Controller has only one MDIO bus */
 #define FEC_QUIRK_SINGLE_MDIO          (1 << 11)
+/* Controller supports RACC register */
+#define FEC_QUIRK_HAS_RACC             (1 << 12)
 
 struct fec_enet_priv_tx_q {
        int index;
index e464aeaeed2cd9ece504a2e1494b2869dfadd138..1f89c59b43535f9b65e946c7468cb1fcb13a2022 100644 (file)
@@ -85,28 +85,30 @@ static struct platform_device_id fec_devtype[] = {
                .driver_data = 0,
        }, {
                .name = "imx25-fec",
-               .driver_data = FEC_QUIRK_USE_GASKET,
+               .driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_HAS_RACC,
        }, {
                .name = "imx27-fec",
-               .driver_data = 0,
+               .driver_data = FEC_QUIRK_HAS_RACC,
        }, {
                .name = "imx28-fec",
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
-                               FEC_QUIRK_SINGLE_MDIO,
+                               FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC,
        }, {
                .name = "imx6q-fec",
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
                                FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
-                               FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358,
+                               FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
+                               FEC_QUIRK_HAS_RACC,
        }, {
                .name = "mvf600-fec",
-               .driver_data = FEC_QUIRK_ENET_MAC,
+               .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
        }, {
                .name = "imx6sx-fec",
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
                                FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
                                FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
-                               FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE,
+                               FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+                               FEC_QUIRK_HAS_RACC,
        }, {
                /* sentinel */
        }
@@ -970,13 +972,15 @@ fec_restart(struct net_device *ndev)
        writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
 #if !defined(CONFIG_M5272)
-       /* set RX checksum */
-       val = readl(fep->hwp + FEC_RACC);
-       if (fep->csum_flags & FLAG_RX_CSUM_ENABLED)
-               val |= FEC_RACC_OPTIONS;
-       else
-               val &= ~FEC_RACC_OPTIONS;
-       writel(val, fep->hwp + FEC_RACC);
+       if (fep->quirks & FEC_QUIRK_HAS_RACC) {
+               /* set RX checksum */
+               val = readl(fep->hwp + FEC_RACC);
+               if (fep->csum_flags & FLAG_RX_CSUM_ENABLED)
+                       val |= FEC_RACC_OPTIONS;
+               else
+                       val &= ~FEC_RACC_OPTIONS;
+               writel(val, fep->hwp + FEC_RACC);
+       }
 #endif
 
        /*
index ff2903652f4bbc5ffafcedcd5cb501f31b0436e9..c3b6af83f070e40f083d7580055242fc053c11a2 100644 (file)
@@ -1028,7 +1028,7 @@ static struct net_device_stats *ipg_nic_get_stats(struct net_device *dev)
 
        /* detailed rx_errors */
        sp->stats.rx_length_errors += ipg_r16(IPG_INRANGELENGTHERRORS) +
-               ipg_r16(IPG_FRAMETOOLONGERRRORS);
+               ipg_r16(IPG_FRAMETOOLONGERRORS);
        sp->stats.rx_crc_errors += ipg_r16(IPG_FRAMECHECKSEQERRORS);
 
        /* Unutilized IPG statistic registers. */
index a21e4f5702b57800271bfc8e5d340dd795dbfa58..de606281f97befcc63e1925875a0686f31faff26 100644 (file)
@@ -102,7 +102,7 @@ enum ipg_regs {
 #define        IPG_MCSTFRAMESRCVDOK            0xB8
 #define        IPG_BCSTFRAMESRCVDOK            0xBE
 #define        IPG_MACCONTROLFRAMESRCVD        0xC6
-#define        IPG_FRAMETOOLONGERRRORS         0xC8
+#define        IPG_FRAMETOOLONGERRORS          0xC8
 #define        IPG_INRANGELENGTHERRORS         0xCA
 #define        IPG_FRAMECHECKSEQERRORS         0xCC
 #define        IPG_FRAMESLOSTRXERRORS          0xCE
index b074b9a667b32cceae00965a0031632431e972fe..91a5a0ae9cd73932648492ce532b0e1260f1419c 100644 (file)
@@ -237,17 +237,19 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw)
        if (ret_val)
                return false;
 out:
-       if ((hw->mac.type == e1000_pch_lpt) ||
-           (hw->mac.type == e1000_pch_spt)) {
-               /* Unforce SMBus mode in PHY */
-               e1e_rphy_locked(hw, CV_SMB_CTRL, &phy_reg);
-               phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
-               e1e_wphy_locked(hw, CV_SMB_CTRL, phy_reg);
+       if ((hw->mac.type == e1000_pch_lpt) || (hw->mac.type == e1000_pch_spt)) {
+               /* Only unforce SMBus if ME is not active */
+               if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+                       /* Unforce SMBus mode in PHY */
+                       e1e_rphy_locked(hw, CV_SMB_CTRL, &phy_reg);
+                       phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
+                       e1e_wphy_locked(hw, CV_SMB_CTRL, phy_reg);
 
-               /* Unforce SMBus mode in MAC */
-               mac_reg = er32(CTRL_EXT);
-               mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
-               ew32(CTRL_EXT, mac_reg);
+                       /* Unforce SMBus mode in MAC */
+                       mac_reg = er32(CTRL_EXT);
+                       mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
+                       ew32(CTRL_EXT, mac_reg);
+               }
        }
 
        return true;
@@ -1087,6 +1089,7 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
        u32 mac_reg;
        s32 ret_val = 0;
        u16 phy_reg;
+       u16 oem_reg = 0;
 
        if ((hw->mac.type < e1000_pch_lpt) ||
            (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPT_I217_LM) ||
@@ -1128,33 +1131,37 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
        if (ret_val)
                goto out;
 
+       /* Force SMBus mode in PHY */
+       ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
+       if (ret_val)
+               goto release;
+       phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
+       e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
+
+       /* Force SMBus mode in MAC */
+       mac_reg = er32(CTRL_EXT);
+       mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
+       ew32(CTRL_EXT, mac_reg);
+
        /* Si workaround for ULP entry flow on i127/rev6 h/w.  Enable
         * LPLU and disable Gig speed when entering ULP
         */
        if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6)) {
                ret_val = e1000_read_phy_reg_hv_locked(hw, HV_OEM_BITS,
-                                                      &phy_reg);
+                                                      &oem_reg);
                if (ret_val)
                        goto release;
+
+               phy_reg = oem_reg;
                phy_reg |= HV_OEM_BITS_LPLU | HV_OEM_BITS_GBE_DIS;
+
                ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
                                                        phy_reg);
+
                if (ret_val)
                        goto release;
        }
 
-       /* Force SMBus mode in PHY */
-       ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
-       if (ret_val)
-               goto release;
-       phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
-       e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
-
-       /* Force SMBus mode in MAC */
-       mac_reg = er32(CTRL_EXT);
-       mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
-       ew32(CTRL_EXT, mac_reg);
-
        /* Set Inband ULP Exit, Reset to SMBus mode and
         * Disable SMBus Release on PERST# in PHY
         */
@@ -1166,10 +1173,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
        if (to_sx) {
                if (er32(WUFC) & E1000_WUFC_LNKC)
                        phy_reg |= I218_ULP_CONFIG1_WOL_HOST;
+               else
+                       phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
 
                phy_reg |= I218_ULP_CONFIG1_STICKY_ULP;
+               phy_reg &= ~I218_ULP_CONFIG1_INBAND_EXIT;
        } else {
                phy_reg |= I218_ULP_CONFIG1_INBAND_EXIT;
+               phy_reg &= ~I218_ULP_CONFIG1_STICKY_ULP;
+               phy_reg &= ~I218_ULP_CONFIG1_WOL_HOST;
        }
        e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
 
@@ -1181,6 +1193,15 @@ s32 e1000_enable_ulp_lpt_lp(struct e1000_hw *hw, bool to_sx)
        /* Commit ULP changes in PHY by starting auto ULP configuration */
        phy_reg |= I218_ULP_CONFIG1_START;
        e1000_write_phy_reg_hv_locked(hw, I218_ULP_CONFIG1, phy_reg);
+
+       if ((hw->phy.type == e1000_phy_i217) && (hw->phy.revision == 6) &&
+           to_sx && (er32(STATUS) & E1000_STATUS_LU)) {
+               ret_val = e1000_write_phy_reg_hv_locked(hw, HV_OEM_BITS,
+                                                       oem_reg);
+               if (ret_val)
+                       goto release;
+       }
+
 release:
        hw->phy.ops.release(hw);
 out:
@@ -1379,16 +1400,20 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
        if (((hw->mac.type == e1000_pch2lan) ||
             (hw->mac.type == e1000_pch_lpt) ||
             (hw->mac.type == e1000_pch_spt)) && link) {
-               u32 reg;
+               u16 speed, duplex;
 
-               reg = er32(STATUS);
+               e1000e_get_speed_and_duplex_copper(hw, &speed, &duplex);
                tipg_reg = er32(TIPG);
                tipg_reg &= ~E1000_TIPG_IPGT_MASK;
 
-               if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
+               if (duplex == HALF_DUPLEX && speed == SPEED_10) {
                        tipg_reg |= 0xFF;
                        /* Reduce Rx latency in analog PHY */
                        emi_val = 0;
+               } else if (hw->mac.type == e1000_pch_spt &&
+                          duplex == FULL_DUPLEX && speed != SPEED_1000) {
+                       tipg_reg |= 0xC;
+                       emi_val = 1;
                } else {
 
                        /* Roll back the default values */
@@ -1412,14 +1437,59 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 
                if (ret_val)
                        return ret_val;
+
+               if (hw->mac.type == e1000_pch_spt) {
+                       u16 data;
+                       u16 ptr_gap;
+
+                       if (speed == SPEED_1000) {
+                               ret_val = hw->phy.ops.acquire(hw);
+                               if (ret_val)
+                                       return ret_val;
+
+                               ret_val = e1e_rphy_locked(hw,
+                                                         PHY_REG(776, 20),
+                                                         &data);
+                               if (ret_val) {
+                                       hw->phy.ops.release(hw);
+                                       return ret_val;
+                               }
+
+                               ptr_gap = (data & (0x3FF << 2)) >> 2;
+                               if (ptr_gap < 0x18) {
+                                       data &= ~(0x3FF << 2);
+                                       data |= (0x18 << 2);
+                                       ret_val =
+                                           e1e_wphy_locked(hw,
+                                                           PHY_REG(776, 20),
+                                                           data);
+                               }
+                               hw->phy.ops.release(hw);
+                               if (ret_val)
+                                       return ret_val;
+                       }
+               }
+       }
+
+       /* I217 Packet Loss issue:
+        * ensure that FEXTNVM4 Beacon Duration is set correctly
+        * on power up.
+        * Set the Beacon Duration for I217 to 8 usec
+        */
+       if ((hw->mac.type == e1000_pch_lpt) || (hw->mac.type == e1000_pch_spt)) {
+               u32 mac_reg;
+
+               mac_reg = er32(FEXTNVM4);
+               mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
+               mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
+               ew32(FEXTNVM4, mac_reg);
        }
 
        /* Work-around I218 hang issue */
        if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
            (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V) ||
            (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_LM3) ||
-           (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3) ||
-           (hw->mac.type == e1000_pch_spt)) {
+           (hw->adapter->pdev->device == E1000_DEV_ID_PCH_I218_V3)) {
                ret_val = e1000_k1_workaround_lpt_lp(hw, link);
                if (ret_val)
                        return ret_val;
index e62b9dcb91fe51309ff7280a20fcbd4d37000548..89d788d8f263e5c362c10166dc76fa59f517e12c 100644 (file)
@@ -6354,13 +6354,14 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
 }
 
 /**
- * e1000e_disable_aspm - Disable ASPM states
+ * __e1000e_disable_aspm - Disable ASPM states
  * @pdev: pointer to PCI device struct
  * @state: bit-mask of ASPM states to disable
+ * @locked: indication if this context holds pci_bus_sem locked.
  *
  * Some devices *must* have certain ASPM states disabled per hardware errata.
  **/
-static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state, int locked)
 {
        struct pci_dev *parent = pdev->bus->self;
        u16 aspm_dis_mask = 0;
@@ -6399,7 +6400,10 @@ static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
                 "L1" : "");
 
 #ifdef CONFIG_PCIEASPM
-       pci_disable_link_state_locked(pdev, state);
+       if (locked)
+               pci_disable_link_state_locked(pdev, state);
+       else
+               pci_disable_link_state(pdev, state);
 
        /* Double-check ASPM control.  If not disabled by the above, the
         * BIOS is preventing that from happening (or CONFIG_PCIEASPM is
@@ -6422,6 +6426,32 @@ static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
                                           aspm_dis_mask);
 }
 
+/**
+ * e1000e_disable_aspm - Disable ASPM states.
+ * @pdev: pointer to PCI device struct
+ * @state: bit-mask of ASPM states to disable
+ *
+ * This function acquires the pci_bus_sem!
+ * Some devices *must* have certain ASPM states disabled per hardware errata.
+ **/
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+       __e1000e_disable_aspm(pdev, state, 0);
+}
+
+/**
+ * e1000e_disable_aspm_locked   Disable ASPM states.
+ * @pdev: pointer to PCI device struct
+ * @state: bit-mask of ASPM states to disable
+ *
+ * This function must be called with pci_bus_sem acquired!
+ * Some devices *must* have certain ASPM states disabled per hardware errata.
+ **/
+static void e1000e_disable_aspm_locked(struct pci_dev *pdev, u16 state)
+{
+       __e1000e_disable_aspm(pdev, state, 1);
+}
+
 #ifdef CONFIG_PM
 static int __e1000_resume(struct pci_dev *pdev)
 {
@@ -6435,7 +6465,7 @@ static int __e1000_resume(struct pci_dev *pdev)
        if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
                aspm_disable_flag |= PCIE_LINK_STATE_L1;
        if (aspm_disable_flag)
-               e1000e_disable_aspm(pdev, aspm_disable_flag);
+               e1000e_disable_aspm_locked(pdev, aspm_disable_flag);
 
        pci_set_master(pdev);
 
index f54996f196293d8cf0c1942effe40c2e0e77b77e..395f32f226c08ac924e7d3e707ef7124b2744ec5 100644 (file)
@@ -484,6 +484,8 @@ int i40evf_setup_tx_descriptors(struct i40e_ring *tx_ring)
        if (!dev)
                return -ENOMEM;
 
+       /* warn if we are about to overwrite the pointer */
+       WARN_ON(tx_ring->tx_bi);
        bi_size = sizeof(struct i40e_tx_buffer) * tx_ring->count;
        tx_ring->tx_bi = kzalloc(bi_size, GFP_KERNEL);
        if (!tx_ring->tx_bi)
@@ -644,6 +646,8 @@ int i40evf_setup_rx_descriptors(struct i40e_ring *rx_ring)
        struct device *dev = rx_ring->dev;
        int bi_size;
 
+       /* warn if we are about to overwrite the pointer */
+       WARN_ON(rx_ring->rx_bi);
        bi_size = sizeof(struct i40e_rx_buffer) * rx_ring->count;
        rx_ring->rx_bi = kzalloc(bi_size, GFP_KERNEL);
        if (!rx_ring->rx_bi)
index 1b98c25b3092ac4b753eb280a9e38bc3d1fe08bd..fea3b75a9a35fcdc58b9d5f5d0f6125dbf62e0cf 100644 (file)
@@ -264,7 +264,6 @@ extern const char i40evf_driver_version[];
 
 int i40evf_up(struct i40evf_adapter *adapter);
 void i40evf_down(struct i40evf_adapter *adapter);
-void i40evf_reinit_locked(struct i40evf_adapter *adapter);
 void i40evf_reset(struct i40evf_adapter *adapter);
 void i40evf_set_ethtool_ops(struct net_device *netdev);
 void i40evf_update_stats(struct i40evf_adapter *adapter);
index f4e77665bc54b9058c85c2c8e62add23fa49b9b8..2b53c870e7f113ca0695afab3636446e1015e4e8 100644 (file)
@@ -267,8 +267,10 @@ static int i40evf_set_ringparam(struct net_device *netdev,
        adapter->tx_desc_count = new_tx_count;
        adapter->rx_desc_count = new_rx_count;
 
-       if (netif_running(netdev))
-               i40evf_reinit_locked(adapter);
+       if (netif_running(netdev)) {
+               adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
+               schedule_work(&adapter->reset_task);
+       }
 
        return 0;
 }
index 7c53aca4b5a6f0b8726c32bee935478d65e3cd47..4ab4ebba07a18e5b1b0539cf0c0b8a7122f6fdc2 100644 (file)
@@ -170,7 +170,8 @@ static void i40evf_tx_timeout(struct net_device *netdev)
        struct i40evf_adapter *adapter = netdev_priv(netdev);
 
        adapter->tx_timeout_count++;
-       if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) {
+       if (!(adapter->flags & (I40EVF_FLAG_RESET_PENDING |
+                               I40EVF_FLAG_RESET_NEEDED))) {
                adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
                schedule_work(&adapter->reset_task);
        }
@@ -1460,7 +1461,7 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
        for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
                lut = 0;
                for (j = 0; j < 4; j++) {
-                       if (cqueue == adapter->vsi_res->num_queue_pairs)
+                       if (cqueue == adapter->num_active_queues)
                                cqueue = 0;
                        lut |= ((cqueue) << (8 * j));
                        cqueue++;
@@ -1470,8 +1471,8 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
        i40e_flush(hw);
 }
 
-#define I40EVF_RESET_WAIT_MS 100
-#define I40EVF_RESET_WAIT_COUNT 200
+#define I40EVF_RESET_WAIT_MS 10
+#define I40EVF_RESET_WAIT_COUNT 500
 /**
  * i40evf_reset_task - Call-back task to handle hardware reset
  * @work: pointer to work_struct
@@ -1495,10 +1496,17 @@ static void i40evf_reset_task(struct work_struct *work)
                                &adapter->crit_section))
                usleep_range(500, 1000);
 
+       i40evf_misc_irq_disable(adapter);
        if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) {
-               dev_info(&adapter->pdev->dev, "Requesting reset from PF\n");
+               adapter->flags &= ~I40EVF_FLAG_RESET_NEEDED;
+               /* Restart the AQ here. If we have been reset but didn't
+                * detect it, or if the PF had to reinit, our AQ will be hosed.
+                */
+               i40evf_shutdown_adminq(hw);
+               i40evf_init_adminq(hw);
                i40evf_request_reset(adapter);
        }
+       adapter->flags |= I40EVF_FLAG_RESET_PENDING;
 
        /* poll until we see the reset actually happen */
        for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
@@ -1507,10 +1515,10 @@ static void i40evf_reset_task(struct work_struct *work)
                if ((rstat_val != I40E_VFR_VFACTIVE) &&
                    (rstat_val != I40E_VFR_COMPLETED))
                        break;
-               msleep(I40EVF_RESET_WAIT_MS);
+               usleep_range(500, 1000);
        }
        if (i == I40EVF_RESET_WAIT_COUNT) {
-               adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
+               dev_info(&adapter->pdev->dev, "Never saw reset\n");
                goto continue_reset; /* act like the reset happened */
        }
 
@@ -1518,11 +1526,12 @@ static void i40evf_reset_task(struct work_struct *work)
        for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
                rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
                            I40E_VFGEN_RSTAT_VFR_STATE_MASK;
-               if ((rstat_val == I40E_VFR_VFACTIVE) ||
-                   (rstat_val == I40E_VFR_COMPLETED))
+               if (rstat_val == I40E_VFR_VFACTIVE)
                        break;
                msleep(I40EVF_RESET_WAIT_MS);
        }
+       /* extra wait to make sure minimum wait is met */
+       msleep(I40EVF_RESET_WAIT_MS);
        if (i == I40EVF_RESET_WAIT_COUNT) {
                struct i40evf_mac_filter *f, *ftmp;
                struct i40evf_vlan_filter *fv, *fvtmp;
@@ -1534,11 +1543,10 @@ static void i40evf_reset_task(struct work_struct *work)
 
                if (netif_running(adapter->netdev)) {
                        set_bit(__I40E_DOWN, &adapter->vsi.state);
-                       i40evf_irq_disable(adapter);
-                       i40evf_napi_disable_all(adapter);
-                       netif_tx_disable(netdev);
-                       netif_tx_stop_all_queues(netdev);
                        netif_carrier_off(netdev);
+                       netif_tx_disable(netdev);
+                       i40evf_napi_disable_all(adapter);
+                       i40evf_irq_disable(adapter);
                        i40evf_free_traffic_irqs(adapter);
                        i40evf_free_all_tx_resources(adapter);
                        i40evf_free_all_rx_resources(adapter);
@@ -1550,6 +1558,7 @@ static void i40evf_reset_task(struct work_struct *work)
                        list_del(&f->list);
                        kfree(f);
                }
+
                list_for_each_entry_safe(fv, fvtmp, &adapter->vlan_filter_list,
                                         list) {
                        list_del(&fv->list);
@@ -1564,22 +1573,27 @@ static void i40evf_reset_task(struct work_struct *work)
                i40evf_shutdown_adminq(hw);
                adapter->netdev->flags &= ~IFF_UP;
                clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
+               adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
+               dev_info(&adapter->pdev->dev, "Reset task did not complete, VF disabled\n");
                return; /* Do not attempt to reinit. It's dead, Jim. */
        }
 
 continue_reset:
-       adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
-
-       i40evf_irq_disable(adapter);
-
        if (netif_running(adapter->netdev)) {
-               i40evf_napi_disable_all(adapter);
-               netif_tx_disable(netdev);
-               netif_tx_stop_all_queues(netdev);
                netif_carrier_off(netdev);
+               netif_tx_stop_all_queues(netdev);
+               i40evf_napi_disable_all(adapter);
        }
+       i40evf_irq_disable(adapter);
 
        adapter->state = __I40EVF_RESETTING;
+       adapter->flags &= ~I40EVF_FLAG_RESET_PENDING;
+
+       /* free the Tx/Rx rings and descriptors, might be better to just
+        * re-use them sometime in the future
+        */
+       i40evf_free_all_rx_resources(adapter);
+       i40evf_free_all_tx_resources(adapter);
 
        /* kill and reinit the admin queue */
        if (i40evf_shutdown_adminq(hw))
@@ -1603,6 +1617,7 @@ continue_reset:
        adapter->aq_required = I40EVF_FLAG_AQ_ADD_MAC_FILTER;
        adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
        clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
+       i40evf_misc_irq_enable(adapter);
 
        mod_timer(&adapter->watchdog_timer, jiffies + 2);
 
@@ -1624,7 +1639,10 @@ continue_reset:
                        goto reset_err;
 
                i40evf_irq_enable(adapter, true);
+       } else {
+               adapter->state = __I40EVF_DOWN;
        }
+
        return;
 reset_err:
        dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
@@ -1667,6 +1685,11 @@ static void i40evf_adminq_task(struct work_struct *work)
                        memset(event.msg_buf, 0, I40EVF_MAX_AQ_BUF_SIZE);
        } while (pending);
 
+       if ((adapter->flags &
+            (I40EVF_FLAG_RESET_PENDING | I40EVF_FLAG_RESET_NEEDED)) ||
+           adapter->state == __I40EVF_RESETTING)
+               goto freedom;
+
        /* check for error indications */
        val = rd32(hw, hw->aq.arq.len);
        oldval = val;
@@ -1702,6 +1725,7 @@ static void i40evf_adminq_task(struct work_struct *work)
        if (oldval != val)
                wr32(hw, hw->aq.asq.len, val);
 
+freedom:
        kfree(event.msg_buf);
 out:
        /* re-enable Admin queue interrupt cause */
@@ -1896,47 +1920,6 @@ static struct net_device_stats *i40evf_get_stats(struct net_device *netdev)
        return &adapter->net_stats;
 }
 
-/**
- * i40evf_reinit_locked - Software reinit
- * @adapter: board private structure
- *
- * Reinititalizes the ring structures in response to a software configuration
- * change. Roughly the same as close followed by open, but skips releasing
- * and reallocating the interrupts.
- **/
-void i40evf_reinit_locked(struct i40evf_adapter *adapter)
-{
-       struct net_device *netdev = adapter->netdev;
-       int err;
-
-       WARN_ON(in_interrupt());
-
-       i40evf_down(adapter);
-
-       /* allocate transmit descriptors */
-       err = i40evf_setup_all_tx_resources(adapter);
-       if (err)
-               goto err_reinit;
-
-       /* allocate receive descriptors */
-       err = i40evf_setup_all_rx_resources(adapter);
-       if (err)
-               goto err_reinit;
-
-       i40evf_configure(adapter);
-
-       err = i40evf_up_complete(adapter);
-       if (err)
-               goto err_reinit;
-
-       i40evf_irq_enable(adapter, true);
-       return;
-
-err_reinit:
-       dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
-       i40evf_close(netdev);
-}
-
 /**
  * i40evf_change_mtu - Change the Maximum Transfer Unit
  * @netdev: network interface device structure
@@ -1952,9 +1935,10 @@ static int i40evf_change_mtu(struct net_device *netdev, int new_mtu)
        if ((new_mtu < 68) || (max_frame > I40E_MAX_RXBUFFER))
                return -EINVAL;
 
-       /* must set new MTU before calling down or up */
        netdev->mtu = new_mtu;
-       i40evf_reinit_locked(adapter);
+       adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
+       schedule_work(&adapter->reset_task);
+
        return 0;
 }
 
index 0f69ef81751a3d8154db558cc8f3d11e882928a0..b0182dd313464ccceb85dd19c9489fcd7b3cd9c6 100644 (file)
@@ -1,5 +1,5 @@
 /* Intel(R) Gigabit Ethernet Linux driver
- * Copyright(c) 2007-2014 Intel Corporation.
+ * Copyright(c) 2007-2015 Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -1900,8 +1900,8 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
  *  igb_rx_fifo_flush_82575 - Clean rx fifo after RX enable
  *  @hw: pointer to the HW structure
  *
- *  After rx enable if managability is enabled then there is likely some
- *  bad data at the start of the fifo and possibly in the DMA fifo.  This
+ *  After rx enable if manageability is enabled then there is likely some
+ *  bad data at the start of the fifo and possibly in the DMA fifo. This
  *  function clears the fifos and flushes any packets that came in as rx was
  *  being enabled.
  **/
@@ -1910,6 +1910,11 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
        u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
        int i, ms_wait;
 
+       /* disable IPv6 options as per hardware errata */
+       rfctl = rd32(E1000_RFCTL);
+       rfctl |= E1000_RFCTL_IPV6_EX_DIS;
+       wr32(E1000_RFCTL, rfctl);
+
        if (hw->mac.type != e1000_82575 ||
            !(rd32(E1000_MANC) & E1000_MANC_RCV_TCO_EN))
                return;
@@ -1937,7 +1942,6 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
         * incoming packets are rejected.  Set enable and wait 2ms so that
         * any packet that was coming in as RCTL.EN was set is flushed
         */
-       rfctl = rd32(E1000_RFCTL);
        wr32(E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
 
        rlpml = rd32(E1000_RLPML);
index 217f8138851bf3e229d6a0035b442e0cc3ae8175..f8684aa285be8cac987263db6676f9d1076b5f9b 100644 (file)
 #define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
 
 /* Header split receive */
-#define E1000_RFCTL_LEF        0x00040000
+#define E1000_RFCTL_IPV6_EX_DIS         0x00010000
+#define E1000_RFCTL_LEF                 0x00040000
 
 /* Collision related configuration parameters */
 #define E1000_COLLISION_THRESHOLD       15
index f287186192bb655ba2dc1a205fb251351d593e98..2f70a9b152bd1789349d9c4d995852e95be1e70d 100644 (file)
@@ -58,7 +58,7 @@
 
 #define MAJ 5
 #define MIN 2
-#define BUILD 15
+#define BUILD 18
 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
 __stringify(BUILD) "-k"
 char igb_driver_name[] = "igb";
index 5bdf78231a4e78f09c360e4a2e5c0c7c5f82482b..370e20ed224c5c76eaca92954be5800d09d81ada 100644 (file)
@@ -310,6 +310,7 @@ struct mvneta_port {
        unsigned int link;
        unsigned int duplex;
        unsigned int speed;
+       unsigned int tx_csum_limit;
        int use_inband_status:1;
 };
 
@@ -2508,8 +2509,10 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu)
 
        dev->mtu = mtu;
 
-       if (!netif_running(dev))
+       if (!netif_running(dev)) {
+               netdev_update_features(dev);
                return 0;
+       }
 
        /* The interface is running, so we have to force a
         * reallocation of the queues
@@ -2538,9 +2541,26 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu)
        mvneta_start_dev(pp);
        mvneta_port_up(pp);
 
+       netdev_update_features(dev);
+
        return 0;
 }
 
+static netdev_features_t mvneta_fix_features(struct net_device *dev,
+                                            netdev_features_t features)
+{
+       struct mvneta_port *pp = netdev_priv(dev);
+
+       if (pp->tx_csum_limit && dev->mtu > pp->tx_csum_limit) {
+               features &= ~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+               netdev_info(dev,
+                           "Disable IP checksum for MTU greater than %dB\n",
+                           pp->tx_csum_limit);
+       }
+
+       return features;
+}
+
 /* Get mac address */
 static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr)
 {
@@ -2862,6 +2882,7 @@ static const struct net_device_ops mvneta_netdev_ops = {
        .ndo_set_rx_mode     = mvneta_set_rx_mode,
        .ndo_set_mac_address = mvneta_set_mac_addr,
        .ndo_change_mtu      = mvneta_change_mtu,
+       .ndo_fix_features    = mvneta_fix_features,
        .ndo_get_stats64     = mvneta_get_stats64,
        .ndo_do_ioctl        = mvneta_ioctl,
 };
@@ -3107,6 +3128,9 @@ static int mvneta_probe(struct platform_device *pdev)
                }
        }
 
+       if (of_device_is_compatible(dn, "marvell,armada-370-neta"))
+               pp->tx_csum_limit = 1600;
+
        pp->tx_ring_size = MVNETA_MAX_TXD;
        pp->rx_ring_size = MVNETA_MAX_RXD;
 
@@ -3185,6 +3209,7 @@ static int mvneta_remove(struct platform_device *pdev)
 
 static const struct of_device_id mvneta_match[] = {
        { .compatible = "marvell,armada-370-neta" },
+       { .compatible = "marvell,armada-xp-neta" },
        { }
 };
 MODULE_DEVICE_TABLE(of, mvneta_match);
index 77179d7ae4cc786c9bc4bb4ea39763522da54d64..e0de2fd1ce124d3d668659b89544d172164037f4 100644 (file)
@@ -1977,10 +1977,6 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv)
                        mlx4_en_destroy_cq(priv, &priv->rx_cq[i]);
        }
 
-       if (priv->base_tx_qpn) {
-               mlx4_qp_release_range(priv->mdev->dev, priv->base_tx_qpn, priv->tx_ring_num);
-               priv->base_tx_qpn = 0;
-       }
 }
 
 int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
index 35f726c17e48c80bdadfc07ba6a43974619c6938..7a4f20bb7fcb4c2640ad8111f5a98ff95088075c 100644 (file)
@@ -718,7 +718,7 @@ static int get_fixed_ipv6_csum(__wsum hw_checksum, struct sk_buff *skb,
 }
 #endif
 static int check_csum(struct mlx4_cqe *cqe, struct sk_buff *skb, void *va,
-                     int hwtstamp_rx_filter)
+                     netdev_features_t dev_features)
 {
        __wsum hw_checksum = 0;
 
@@ -726,14 +726,8 @@ static int check_csum(struct mlx4_cqe *cqe, struct sk_buff *skb, void *va,
 
        hw_checksum = csum_unfold((__force __sum16)cqe->checksum);
 
-       if (((struct ethhdr *)va)->h_proto == htons(ETH_P_8021Q) &&
-           hwtstamp_rx_filter != HWTSTAMP_FILTER_NONE) {
-               /* next protocol non IPv4 or IPv6 */
-               if (((struct vlan_hdr *)hdr)->h_vlan_encapsulated_proto
-                   != htons(ETH_P_IP) &&
-                   ((struct vlan_hdr *)hdr)->h_vlan_encapsulated_proto
-                   != htons(ETH_P_IPV6))
-                       return -1;
+       if (cqe->vlan_my_qpn & cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK) &&
+           !(dev_features & NETIF_F_HW_VLAN_CTAG_RX)) {
                hw_checksum = get_fixed_vlan_csum(hw_checksum, hdr);
                hdr += sizeof(struct vlan_hdr);
        }
@@ -896,7 +890,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
 
                        if (ip_summed == CHECKSUM_COMPLETE) {
                                void *va = skb_frag_address(skb_shinfo(gro_skb)->frags);
-                               if (check_csum(cqe, gro_skb, va, ring->hwtstamp_rx_filter)) {
+                               if (check_csum(cqe, gro_skb, va,
+                                              dev->features)) {
                                        ip_summed = CHECKSUM_NONE;
                                        ring->csum_none++;
                                        ring->csum_complete--;
@@ -951,7 +946,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                }
 
                if (ip_summed == CHECKSUM_COMPLETE) {
-                       if (check_csum(cqe, skb, skb->data, ring->hwtstamp_rx_filter)) {
+                       if (check_csum(cqe, skb, skb->data, dev->features)) {
                                ip_summed = CHECKSUM_NONE;
                                ring->csum_complete--;
                                ring->csum_none++;
index 7bed3a88579fa9db92d7e42ad7d43265bd8a3d41..c10d98f6ad967b13640b5d9b2fe033f377565ff0 100644 (file)
@@ -66,6 +66,7 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
        ring->size = size;
        ring->size_mask = size - 1;
        ring->stride = stride;
+       ring->full_size = ring->size - HEADROOM - MAX_DESC_TXBBS;
 
        tmp = size * sizeof(struct mlx4_en_tx_info);
        ring->tx_info = kmalloc_node(tmp, GFP_KERNEL | __GFP_NOWARN, node);
@@ -180,6 +181,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
                mlx4_bf_free(mdev->dev, &ring->bf);
        mlx4_qp_remove(mdev->dev, &ring->qp);
        mlx4_qp_free(mdev->dev, &ring->qp);
+       mlx4_qp_release_range(priv->mdev->dev, ring->qpn, 1);
        mlx4_en_unmap_buffer(&ring->wqres.buf);
        mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
        kfree(ring->bounce_buf);
@@ -231,6 +233,11 @@ void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv,
                       MLX4_QP_STATE_RST, NULL, 0, 0, &ring->qp);
 }
 
+static inline bool mlx4_en_is_tx_ring_full(struct mlx4_en_tx_ring *ring)
+{
+       return ring->prod - ring->cons > ring->full_size;
+}
+
 static void mlx4_en_stamp_wqe(struct mlx4_en_priv *priv,
                              struct mlx4_en_tx_ring *ring, int index,
                              u8 owner)
@@ -473,11 +480,10 @@ static bool mlx4_en_process_tx_cq(struct net_device *dev,
 
        netdev_tx_completed_queue(ring->tx_queue, packets, bytes);
 
-       /*
-        * Wakeup Tx queue if this stopped, and at least 1 packet
-        * was completed
+       /* Wakeup Tx queue if this stopped, and ring is not full.
         */
-       if (netif_tx_queue_stopped(ring->tx_queue) && txbbs_skipped > 0) {
+       if (netif_tx_queue_stopped(ring->tx_queue) &&
+           !mlx4_en_is_tx_ring_full(ring)) {
                netif_tx_wake_queue(ring->tx_queue);
                ring->wake_queue++;
        }
@@ -921,8 +927,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
        skb_tx_timestamp(skb);
 
        /* Check available TXBBs And 2K spare for prefetch */
-       stop_queue = (int)(ring->prod - ring_cons) >
-                     ring->size - HEADROOM - MAX_DESC_TXBBS;
+       stop_queue = mlx4_en_is_tx_ring_full(ring);
        if (unlikely(stop_queue)) {
                netif_tx_stop_queue(ring->tx_queue);
                ring->queue_stopped++;
@@ -991,8 +996,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
                smp_rmb();
 
                ring_cons = ACCESS_ONCE(ring->cons);
-               if (unlikely(((int)(ring->prod - ring_cons)) <=
-                            ring->size - HEADROOM - MAX_DESC_TXBBS)) {
+               if (unlikely(!mlx4_en_is_tx_ring_full(ring))) {
                        netif_tx_wake_queue(ring->tx_queue);
                        ring->wake_queue++;
                }
index 6fce58718837202bd82739dd8592b753ece7ef42..0d80aed5904371c2a2358a99618e7a2328b50c09 100644 (file)
@@ -93,8 +93,14 @@ int mlx4_register_interface(struct mlx4_interface *intf)
        mutex_lock(&intf_mutex);
 
        list_add_tail(&intf->list, &intf_list);
-       list_for_each_entry(priv, &dev_list, dev_list)
+       list_for_each_entry(priv, &dev_list, dev_list) {
+               if (mlx4_is_mfunc(&priv->dev) && (intf->flags & MLX4_INTFF_BONDING)) {
+                       mlx4_dbg(&priv->dev,
+                                "SRIOV, disabling HA mode for intf proto %d\n", intf->protocol);
+                       intf->flags &= ~MLX4_INTFF_BONDING;
+               }
                mlx4_add_device(intf, priv);
+       }
 
        mutex_unlock(&intf_mutex);
 
index d5f9adb6a78491d37522caa4de869e4695f83f25..666d1669eb5233f9a8e6baf5773621159375af25 100644 (file)
@@ -279,6 +279,7 @@ struct mlx4_en_tx_ring {
        u32                     size; /* number of TXBBs */
        u32                     size_mask;
        u16                     stride;
+       u32                     full_size;
        u16                     cqn;    /* index of port CQ associated with this ring */
        u32                     buf_size;
        __be32                  doorbell_qpn;
@@ -580,7 +581,6 @@ struct mlx4_en_priv {
        int vids[128];
        bool wol;
        struct device *ddev;
-       int base_tx_qpn;
        struct hlist_head mac_hash[MLX4_EN_MAC_HASH_SIZE];
        struct hwtstamp_config hwtstamp_config;
        u32 counter_index;
index 42656da5050063ca382a6bb24375ec08ff672385..7a8ce920c49e709b067321ae91306153f4f24390 100644 (file)
@@ -116,8 +116,10 @@ static int ravb_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
        priv->ptp.current_addend = addend;
 
        gccr = ravb_read(ndev, GCCR);
-       if (gccr & GCCR_LTI)
+       if (gccr & GCCR_LTI) {
+               spin_unlock_irqrestore(&priv->lock, flags);
                return -EBUSY;
+       }
        ravb_write(ndev, addend & GTI_TIV, GTI);
        ravb_write(ndev, gccr | GCCR_LTI, GCCR);
 
index 1341f33e60843029e1e1ecd035fcbebc0fccc1cb..7d430d3229310a45e3fa67df26d5570dc7b8992c 100644 (file)
@@ -56,7 +56,7 @@ enum sis900_configuration_register_bits {
        EDB_MASTER_EN = 0x00002000
 };
 
-enum sis900_eeprom_access_reigster_bits {
+enum sis900_eeprom_access_register_bits {
        MDC  = 0x00000040, MDDIR = 0x00000020, MDIO = 0x00000010, /* 7016 specific */
        EECS = 0x00000008, EECLK = 0x00000004, EEDO = 0x00000002,
        EEDI = 0x00000001
@@ -73,7 +73,7 @@ enum sis900_interrupt_register_bits {
        RxERR  = 0x00000004, RxDESC = 0x00000002, RxOK  = 0x00000001
 };
 
-enum sis900_interrupt_enable_reigster_bits {
+enum sis900_interrupt_enable_register_bits {
        IE = 0x00000001
 };
 
index 08c483bd2ec7bd94d5434f9567c75f609ce27d35..3f20bb1fe570c086e53d0bb5d1ca8124d971fe5d 100644 (file)
@@ -73,7 +73,7 @@
 #define MMC_RX_OCTETCOUNT_G            0x00000188
 #define MMC_RX_BROADCASTFRAME_G                0x0000018c
 #define MMC_RX_MULTICASTFRAME_G                0x00000190
-#define MMC_RX_CRC_ERRROR              0x00000194
+#define MMC_RX_CRC_ERROR               0x00000194
 #define MMC_RX_ALIGN_ERROR             0x00000198
 #define MMC_RX_RUN_ERROR               0x0000019C
 #define MMC_RX_JABBER_ERROR            0x000001A0
@@ -196,7 +196,7 @@ void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc)
        mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G);
        mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G);
        mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G);
-       mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERRROR);
+       mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERROR);
        mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR);
        mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR);
        mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR);
index 8b0b1d6aca72c4a36c718862a064da6418dfc9f7..2f1264b882b9555f02e0b1cb50aa914d13c929fa 100644 (file)
@@ -18,6 +18,7 @@ if NET_VENDOR_VIA
 config VIA_RHINE
        tristate "VIA Rhine support"
        depends on (PCI || OF_IRQ)
+       depends on HAS_DMA
        select CRC32
        select MII
        ---help---
@@ -42,6 +43,7 @@ config VIA_RHINE_MMIO
 config VIA_VELOCITY
        tristate "VIA Velocity support"
        depends on (PCI || (OF_ADDRESS && OF_IRQ))
+       depends on HAS_DMA
        select CRC32
        select CRC_CCITT
        select MII
index 4dea85bfc545b86d5874031531a9ce4963facbe2..6b701b3ded749642b6cdf2309e7b25d2b373ed37 100644 (file)
@@ -246,6 +246,13 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
        pr_info_once("%s: %s PHY revision: 0x%02x, patch: %d\n",
                     dev_name(&phydev->dev), phydev->drv->name, rev, patch);
 
+       /* Dummy read to a register to workaround an issue upon reset where the
+        * internal inverter may not allow the first MDIO transaction to pass
+        * the MDIO management controller and make us return 0xffff for such
+        * reads.
+        */
+       phy_read(phydev, MII_BMSR);
+
        switch (rev) {
        case 0xb0:
                ret = bcm7xxx_28nm_b0_afe_config_init(phydev);
index fc7abc50b4f17544741d1166960fb549b8554fbd..6a52a7f0fa0dc5cace471b118a9e989d8c2713ea 100644 (file)
@@ -120,6 +120,48 @@ static int unimac_mdio_write(struct mii_bus *bus, int phy_id,
        return 0;
 }
 
+/* Workaround for integrated BCM7xxx Gigabit PHYs which have a problem with
+ * their internal MDIO management controller making them fail to successfully
+ * be read from or written to for the first transaction.  We insert a dummy
+ * BMSR read here to make sure that phy_get_device() and get_phy_id() can
+ * correctly read the PHY MII_PHYSID1/2 registers and successfully register a
+ * PHY device for this peripheral.
+ *
+ * Once the PHY driver is registered, we can workaround subsequent reads from
+ * there (e.g: during system-wide power management).
+ *
+ * bus->reset is invoked before mdiobus_scan during mdiobus_register and is
+ * therefore the right location to stick that workaround. Since we do not want
+ * to read from non-existing PHYs, we either use bus->phy_mask or do a manual
+ * Device Tree scan to limit the search area.
+ */
+static int unimac_mdio_reset(struct mii_bus *bus)
+{
+       struct device_node *np = bus->dev.of_node;
+       struct device_node *child;
+       u32 read_mask = 0;
+       int addr;
+
+       if (!np) {
+               read_mask = ~bus->phy_mask;
+       } else {
+               for_each_available_child_of_node(np, child) {
+                       addr = of_mdio_parse_addr(&bus->dev, child);
+                       if (addr < 0)
+                               continue;
+
+                       read_mask |= 1 << addr;
+               }
+       }
+
+       for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+               if (read_mask & 1 << addr)
+                       mdiobus_read(bus, addr, MII_BMSR);
+       }
+
+       return 0;
+}
+
 static int unimac_mdio_probe(struct platform_device *pdev)
 {
        struct unimac_mdio_priv *priv;
@@ -155,6 +197,7 @@ static int unimac_mdio_probe(struct platform_device *pdev)
        bus->parent = &pdev->dev;
        bus->read = unimac_mdio_read;
        bus->write = unimac_mdio_write;
+       bus->reset = unimac_mdio_reset;
        snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
 
        bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
index bdfe51fc3a6507154edfcaf8be3413884bcf702f..0302483de24066a64446699cb360b2fb2ad6a890 100644 (file)
@@ -230,7 +230,7 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
        for (i = 1;
             i < num_ids && c45_ids->devices_in_package == 0;
             i++) {
-               reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2;
+retry:         reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2;
                phy_reg = mdiobus_read(bus, addr, reg_addr);
                if (phy_reg < 0)
                        return -EIO;
@@ -242,12 +242,20 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
                        return -EIO;
                c45_ids->devices_in_package |= (phy_reg & 0xffff);
 
-               /* If mostly Fs, there is no device there,
-                * let's get out of here.
-                */
                if ((c45_ids->devices_in_package & 0x1fffffff) == 0x1fffffff) {
-                       *phy_id = 0xffffffff;
-                       return 0;
+                       if (i) {
+                               /*  If mostly Fs, there is no device there,
+                                *  then let's continue to probe more, as some
+                                *  10G PHYs have zero Devices In package,
+                                *  e.g. Cortina CS4315/CS4340 PHY.
+                                */
+                               i = 0;
+                               goto retry;
+                       } else {
+                               /* no device there, let's get out of here */
+                               *phy_id = 0xffffffff;
+                               return 0;
+                       }
                }
        }
 
@@ -796,10 +804,11 @@ static int genphy_config_advert(struct phy_device *phydev)
        if (phydev->supported & (SUPPORTED_1000baseT_Half |
                                 SUPPORTED_1000baseT_Full)) {
                adv |= ethtool_adv_to_mii_ctrl1000_t(advertise);
-               if (adv != oldadv)
-                       changed = 1;
        }
 
+       if (adv != oldadv)
+               changed = 1;
+
        err = phy_write(phydev, MII_CTRL1000, adv);
        if (err < 0)
                return err;
index 76cad712ddb2c7c6bc2794389380e4e0a862d5f5..17cad185169dd28fd3cae12e69d918371fe9d06f 100644 (file)
@@ -66,6 +66,7 @@
 #define PHY_ID_VSC8244                 0x000fc6c0
 #define PHY_ID_VSC8514                 0x00070670
 #define PHY_ID_VSC8574                 0x000704a0
+#define PHY_ID_VSC8641                 0x00070431
 #define PHY_ID_VSC8662                 0x00070660
 #define PHY_ID_VSC8221                 0x000fc550
 #define PHY_ID_VSC8211                 0x000fc4b0
@@ -271,6 +272,18 @@ static struct phy_driver vsc82xx_driver[] = {
        .ack_interrupt  = &vsc824x_ack_interrupt,
        .config_intr    = &vsc82xx_config_intr,
        .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_VSC8641,
+       .name           = "Vitesse VSC8641",
+       .phy_id_mask    = 0x000ffff0,
+       .features       = PHY_GBIT_FEATURES,
+       .flags          = PHY_HAS_INTERRUPT,
+       .config_init    = &vsc824x_config_init,
+       .config_aneg    = &vsc82x4_config_aneg,
+       .read_status    = &genphy_read_status,
+       .ack_interrupt  = &vsc824x_ack_interrupt,
+       .config_intr    = &vsc82xx_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
 }, {
        .phy_id         = PHY_ID_VSC8662,
        .name           = "Vitesse VSC8662",
@@ -318,6 +331,7 @@ static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
        { PHY_ID_VSC8244, 0x000fffc0 },
        { PHY_ID_VSC8514, 0x000ffff0 },
        { PHY_ID_VSC8574, 0x000ffff0 },
+       { PHY_ID_VSC8641, 0x000ffff0 },
        { PHY_ID_VSC8662, 0x000ffff0 },
        { PHY_ID_VSC8221, 0x000ffff0 },
        { PHY_ID_VSC8211, 0x000ffff0 },
index e9f1075f7d4c2055ccbf00c24b41c86a77a87558..2652245631d12f5016915721d5f93268cb4453c1 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.3.5.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.2.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01030500
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040200
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index b3e9491bc8ec81ccf55fa55dc5c0690259317555..f948c46d51329970c186b2886c267ffba2e807db 100644 (file)
@@ -1244,10 +1244,6 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
        np                   = netdev_priv(netdev);
        np->xbdev            = dev;
 
-       /* No need to use rtnl_lock() before the call below as it
-        * happens before register_netdev().
-        */
-       netif_set_real_num_tx_queues(netdev, 0);
        np->queues = NULL;
 
        err = -ENOMEM;
@@ -1899,9 +1895,6 @@ abort_transaction_no_dev_fatal:
        xennet_disconnect_backend(info);
        kfree(info->queues);
        info->queues = NULL;
-       rtnl_lock();
-       netif_set_real_num_tx_queues(info->netdev, 0);
-       rtnl_unlock();
  out:
        return err;
 }
index 16a923a3a43a8825d167b75025baca0b1b5d741c..e602f8177ebfbf3148bce0734a87ecac1b0eb590 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/atomic.h>
 #include <net/neighbour.h>
+#include <net/sock.h>
 
 #define        AX25_T1CLAMPLO                  1
 #define        AX25_T1CLAMPHI                  (30 * HZ)
@@ -246,7 +247,20 @@ typedef struct ax25_cb {
        atomic_t                refcount;
 } ax25_cb;
 
-#define ax25_sk(__sk) ((ax25_cb *)(__sk)->sk_protinfo)
+struct ax25_sock {
+       struct sock             sk;
+       struct ax25_cb          *cb;
+};
+
+static inline struct ax25_sock *ax25_sk(const struct sock *sk)
+{
+       return (struct ax25_sock *) sk;
+}
+
+static inline struct ax25_cb *sk_to_ax25(const struct sock *sk)
+{
+       return ax25_sk(sk)->cb;
+}
 
 #define ax25_for_each(__ax25, list) \
        hlist_for_each_entry(__ax25, list, ax25_node)
index 14d539c040d70dfebaa5dae16312fc48536559a7..05a8c1aea25187c1692efcb1e350bb2c7f75a30b 100644 (file)
@@ -277,7 +277,6 @@ struct cg_proto;
   *    @sk_incoming_cpu: record cpu processing incoming packets
   *    @sk_txhash: computed flow hash for use on transmit
   *    @sk_filter: socket filtering instructions
-  *    @sk_protinfo: private area, net family specific, when not using slab
   *    @sk_timer: sock cleanup timer
   *    @sk_stamp: time stamp of last packet received
   *    @sk_tsflags: SO_TIMESTAMPING socket options
@@ -416,7 +415,6 @@ struct sock {
        const struct cred       *sk_peer_cred;
        long                    sk_rcvtimeo;
        long                    sk_sndtimeo;
-       void                    *sk_protinfo;
        struct timer_list       sk_timer;
        ktime_t                 sk_stamp;
        u16                     sk_tsflags;
index 83d6236a2f083d787f4ed887b71aa41c76330d9e..eaf94919291aaf78419a5f43b17d66eb07f12600 100644 (file)
 #define _UAPI_LINUX_IN_H
 
 #include <linux/types.h>
+#include <linux/libc-compat.h>
 #include <linux/socket.h>
 
+#if __UAPI_DEF_IN_IPPROTO
 /* Standard well-defined IP protocols.  */
 enum {
   IPPROTO_IP = 0,              /* Dummy protocol for TCP               */
@@ -75,12 +77,14 @@ enum {
 #define IPPROTO_RAW            IPPROTO_RAW
   IPPROTO_MAX
 };
+#endif
 
-
+#if __UAPI_DEF_IN_ADDR
 /* Internet address. */
 struct in_addr {
        __be32  s_addr;
 };
+#endif
 
 #define IP_TOS         1
 #define IP_TTL         2
@@ -158,6 +162,7 @@ struct in_addr {
 
 /* Request struct for multicast socket ops */
 
+#if __UAPI_DEF_IP_MREQ
 struct ip_mreq  {
        struct in_addr imr_multiaddr;   /* IP multicast address of group */
        struct in_addr imr_interface;   /* local IP address of interface */
@@ -209,14 +214,18 @@ struct group_filter {
 #define GROUP_FILTER_SIZE(numsrc) \
        (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
        + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+#endif
 
+#if __UAPI_DEF_IN_PKTINFO
 struct in_pktinfo {
        int             ipi_ifindex;
        struct in_addr  ipi_spec_dst;
        struct in_addr  ipi_addr;
 };
+#endif
 
 /* Structure describing an Internet (IP) socket address. */
+#if  __UAPI_DEF_SOCKADDR_IN
 #define __SOCK_SIZE__  16              /* sizeof(struct sockaddr)      */
 struct sockaddr_in {
   __kernel_sa_family_t sin_family;     /* Address family               */
@@ -228,8 +237,9 @@ struct sockaddr_in {
                        sizeof(unsigned short int) - sizeof(struct in_addr)];
 };
 #define sin_zero       __pad           /* for BSD UNIX comp. -FvK      */
+#endif
 
-
+#if __UAPI_DEF_IN_CLASS
 /*
  * Definitions of the bits in an Internet address integer.
  * On subnets, host and network parts are found according
@@ -280,7 +290,7 @@ struct sockaddr_in {
 #define INADDR_ALLHOSTS_GROUP  0xe0000001U     /* 224.0.0.1   */
 #define INADDR_ALLRTRS_GROUP    0xe0000002U    /* 224.0.0.2 */
 #define INADDR_MAX_LOCAL_GROUP  0xe00000ffU    /* 224.0.0.255 */
-
+#endif
 
 /* <asm/byteorder.h> contains the htonl type stuff.. */
 #include <asm/byteorder.h> 
index fa673e9cc040aefcee4e96ee3e4bd6892c5be562..7d024ceb075d8d4cd657c1c25db37a748940fc89 100644 (file)
 
 /* GLIBC headers included first so don't define anything
  * that would already be defined. */
+#define __UAPI_DEF_IN_ADDR             0
+#define __UAPI_DEF_IN_IPPROTO          0
+#define __UAPI_DEF_IN_PKTINFO          0
+#define __UAPI_DEF_IP_MREQ             0
+#define __UAPI_DEF_SOCKADDR_IN         0
+#define __UAPI_DEF_IN_CLASS            0
+
 #define __UAPI_DEF_IN6_ADDR            0
 /* The exception is the in6_addr macros which must be defined
  * if the glibc code didn't define them. This guard matches
 /* Linux headers included first, and we must define everything
  * we need. The expectation is that glibc will check the
  * __UAPI_DEF_* defines and adjust appropriately. */
+#define __UAPI_DEF_IN_ADDR             1
+#define __UAPI_DEF_IN_IPPROTO          1
+#define __UAPI_DEF_IN_PKTINFO          1
+#define __UAPI_DEF_IP_MREQ             1
+#define __UAPI_DEF_SOCKADDR_IN         1
+#define __UAPI_DEF_IN_CLASS            1
+
 #define __UAPI_DEF_IN6_ADDR            1
 /* We unconditionally define the in6_addr macros and glibc must
  * coordinate. */
  * that we need. */
 #else /* !defined(__GLIBC__) */
 
+/* Definitions for in.h */
+#define __UAPI_DEF_IN_ADDR             1
+#define __UAPI_DEF_IN_IPPROTO          1
+#define __UAPI_DEF_IN_PKTINFO          1
+#define __UAPI_DEF_IP_MREQ             1
+#define __UAPI_DEF_SOCKADDR_IN         1
+#define __UAPI_DEF_IN_CLASS            1
+
 /* Definitions for in6.h */
 #define __UAPI_DEF_IN6_ADDR            1
 #define __UAPI_DEF_IN6_ADDR_ALT                1
index 9c891d0412a298428e7abd306347beee749f5b0d..ae3a47f9d1d5298406ca33900624fe49c9c85719 100644 (file)
@@ -57,7 +57,7 @@ static const struct proto_ops ax25_proto_ops;
 
 static void ax25_free_sock(struct sock *sk)
 {
-       ax25_cb_put(ax25_sk(sk));
+       ax25_cb_put(sk_to_ax25(sk));
 }
 
 /*
@@ -306,7 +306,7 @@ void ax25_destroy_socket(ax25_cb *ax25)
                while ((skb = skb_dequeue(&ax25->sk->sk_receive_queue)) != NULL) {
                        if (skb->sk != ax25->sk) {
                                /* A pending connection */
-                               ax25_cb *sax25 = ax25_sk(skb->sk);
+                               ax25_cb *sax25 = sk_to_ax25(skb->sk);
 
                                /* Queue the unaccepted socket for death */
                                sock_orphan(skb->sk);
@@ -551,7 +551,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
                return -EFAULT;
 
        lock_sock(sk);
-       ax25 = ax25_sk(sk);
+       ax25 = sk_to_ax25(sk);
 
        switch (optname) {
        case AX25_WINDOW:
@@ -697,7 +697,7 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname,
        length = min_t(unsigned int, maxlen, sizeof(int));
 
        lock_sock(sk);
-       ax25 = ax25_sk(sk);
+       ax25 = sk_to_ax25(sk);
 
        switch (optname) {
        case AX25_WINDOW:
@@ -796,7 +796,7 @@ out:
 static struct proto ax25_proto = {
        .name     = "AX25",
        .owner    = THIS_MODULE,
-       .obj_size = sizeof(struct sock),
+       .obj_size = sizeof(struct ax25_sock),
 };
 
 static int ax25_create(struct net *net, struct socket *sock, int protocol,
@@ -858,7 +858,7 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol,
        if (sk == NULL)
                return -ENOMEM;
 
-       ax25 = sk->sk_protinfo = ax25_create_cb();
+       ax25 = ax25_sk(sk)->cb = ax25_create_cb();
        if (!ax25) {
                sk_free(sk);
                return -ENOMEM;
@@ -910,7 +910,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
        sk->sk_state    = TCP_ESTABLISHED;
        sock_copy_flags(sk, osk);
 
-       oax25 = ax25_sk(osk);
+       oax25 = sk_to_ax25(osk);
 
        ax25->modulus = oax25->modulus;
        ax25->backoff = oax25->backoff;
@@ -938,7 +938,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
                }
        }
 
-       sk->sk_protinfo = ax25;
+       ax25_sk(sk)->cb = ax25;
        sk->sk_destruct = ax25_free_sock;
        ax25->sk    = sk;
 
@@ -956,7 +956,7 @@ static int ax25_release(struct socket *sock)
        sock_hold(sk);
        sock_orphan(sk);
        lock_sock(sk);
-       ax25 = ax25_sk(sk);
+       ax25 = sk_to_ax25(sk);
 
        if (sk->sk_type == SOCK_SEQPACKET) {
                switch (ax25->state) {
@@ -1066,7 +1066,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 
        lock_sock(sk);
 
-       ax25 = ax25_sk(sk);
+       ax25 = sk_to_ax25(sk);
        if (!sock_flag(sk, SOCK_ZAPPED)) {
                err = -EINVAL;
                goto out;
@@ -1113,7 +1113,7 @@ static int __must_check ax25_connect(struct socket *sock,
        struct sockaddr *uaddr, int addr_len, int flags)
 {
        struct sock *sk = sock->sk;
-       ax25_cb *ax25 = ax25_sk(sk), *ax25t;
+       ax25_cb *ax25 = sk_to_ax25(sk), *ax25t;
        struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
        ax25_digi *digi = NULL;
        int ct = 0, err = 0;
@@ -1394,7 +1394,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
 
        memset(fsa, 0, sizeof(*fsa));
        lock_sock(sk);
-       ax25 = ax25_sk(sk);
+       ax25 = sk_to_ax25(sk);
 
        if (peer != 0) {
                if (sk->sk_state != TCP_ESTABLISHED) {
@@ -1446,7 +1446,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
                return -EINVAL;
 
        lock_sock(sk);
-       ax25 = ax25_sk(sk);
+       ax25 = sk_to_ax25(sk);
 
        if (sock_flag(sk, SOCK_ZAPPED)) {
                err = -EADDRNOTAVAIL;
@@ -1621,7 +1621,7 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
        if (skb == NULL)
                goto out;
 
-       if (!ax25_sk(sk)->pidincl)
+       if (!sk_to_ax25(sk)->pidincl)
                skb_pull(skb, 1);               /* Remove PID */
 
        skb_reset_transport_header(skb);
@@ -1762,7 +1762,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
        case SIOCAX25GETINFO:
        case SIOCAX25GETINFOOLD: {
-               ax25_cb *ax25 = ax25_sk(sk);
+               ax25_cb *ax25 = sk_to_ax25(sk);
                struct ax25_info_struct ax25_info;
 
                ax25_info.t1        = ax25->t1   / HZ;
index 29a3687237aa4288ed078e222c80b8fa85021a8f..bb5a0e4e98d9df09ec535a20ea73253817fe64db 100644 (file)
@@ -353,7 +353,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
                        return 0;
                }
 
-               ax25 = ax25_sk(make);
+               ax25 = sk_to_ax25(make);
                skb_set_owner_r(skb, make);
                skb_queue_head(&sk->sk_receive_queue, skb);
 
index 476e5dda59e19822dba98a931369ff2666c59c0d..2a834c6179b9973e45274d793e7d744939e5f49e 100644 (file)
@@ -129,7 +129,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
        struct flow_dissector_key_ports *key_ports;
        struct flow_dissector_key_tags *key_tags;
        struct flow_dissector_key_keyid *key_keyid;
-       u8 ip_proto;
+       u8 ip_proto = 0;
 
        if (!data) {
                data = skb->data;
index 1e1fe9a68d835983d760d50f9ef6a11309ffcfc1..08f16db46070a1520fcdd6892477093e9474af4f 100644 (file)
@@ -1454,7 +1454,7 @@ void sk_destruct(struct sock *sk)
 
 static void __sk_free(struct sock *sk)
 {
-       if (unlikely(sock_diag_has_destroy_listeners(sk)))
+       if (unlikely(sock_diag_has_destroy_listeners(sk) && sk->sk_net_refcnt))
                sock_diag_broadcast_destroy(sk);
        else
                sk_destruct(sk);
@@ -2269,7 +2269,6 @@ static void sock_def_write_space(struct sock *sk)
 
 static void sock_def_destruct(struct sock *sk)
 {
-       kfree(sk->sk_protinfo);
 }
 
 void sk_send_sigurg(struct sock *sk)
index 04ffad311704852a5d2c35c99eea2f1c4293f5e1..0917123790eaf09b001c97a733039185fdb0a800 100644 (file)
@@ -112,7 +112,7 @@ static int dsa_slave_open(struct net_device *dev)
 
 clear_promisc:
        if (dev->flags & IFF_PROMISC)
-               dev_set_promiscuity(master, 0);
+               dev_set_promiscuity(master, -1);
 clear_allmulti:
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(master, -1);
index 3bfccd83551ce71cc2b69efe233426f3e70ea854..c7358ea4ae93530a7f6ef110a2dc204f19ac830e 100644 (file)
@@ -1045,7 +1045,7 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
                    nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))
                        goto nla_put_failure;
                if (fi->fib_nh->nh_flags & RTNH_F_LINKDOWN) {
-                       in_dev = __in_dev_get_rcu(fi->fib_nh->nh_dev);
+                       in_dev = __in_dev_get_rtnl(fi->fib_nh->nh_dev);
                        if (in_dev &&
                            IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev))
                                rtm->rtm_flags |= RTNH_F_DEAD;
@@ -1074,7 +1074,7 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
 
                        rtnh->rtnh_flags = nh->nh_flags & 0xFF;
                        if (nh->nh_flags & RTNH_F_LINKDOWN) {
-                               in_dev = __in_dev_get_rcu(nh->nh_dev);
+                               in_dev = __in_dev_get_rtnl(nh->nh_dev);
                                if (in_dev &&
                                    IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev))
                                        rtnh->rtnh_flags |= RTNH_F_DEAD;
index b92d3f49c23e0dd93ac2ff0766bb97f1add15baa..9d37ccd95062a6840d1bb1e140b173dd1fe0b9d0 100644 (file)
@@ -216,8 +216,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
        [TCA_FLOWER_KEY_IPV6_DST_MASK]  = { .len = sizeof(struct in6_addr) },
        [TCA_FLOWER_KEY_TCP_SRC]        = { .type = NLA_U16 },
        [TCA_FLOWER_KEY_TCP_DST]        = { .type = NLA_U16 },
-       [TCA_FLOWER_KEY_TCP_SRC]        = { .type = NLA_U16 },
-       [TCA_FLOWER_KEY_TCP_DST]        = { .type = NLA_U16 },
+       [TCA_FLOWER_KEY_UDP_SRC]        = { .type = NLA_U16 },
+       [TCA_FLOWER_KEY_UDP_DST]        = { .type = NLA_U16 },
 };
 
 static void fl_set_key_val(struct nlattr **tb,
index fc5e45b8a832d94367178536a341001021a19c44..abe7c2db24120a13992131e2be9a19c70a297de0 100644 (file)
@@ -599,7 +599,9 @@ out:
        return err;
 no_route:
        kfree_skb(nskb);
-       IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
+
+       if (asoc)
+               IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
 
        /* FIXME: Returning the 'err' will effect all the associations
         * associated with a socket, although only one of the paths of the
index 5f6c4e61325b65822be525d75ebe3bb7357b97e7..1425ec2bbd5ae359a8e0408a89a6da6bb60bd87e 100644 (file)
@@ -2121,12 +2121,6 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        if (sp->subscribe.sctp_data_io_event)
                sctp_ulpevent_read_sndrcvinfo(event, msg);
 
-#if 0
-       /* FIXME: we should be calling IP/IPv6 layers.  */
-       if (sk->sk_protinfo.af_inet.cmsg_flags)
-               ip_cmsg_recv(msg, skb);
-#endif
-
        err = copied;
 
        /* If skb's length exceeds the user's buffer, update the skb and
index 4906ca3c0f3a576a529eacb26631f8585291ae40..a816382fc8af1b9efb016f888493ca4dcc65fe3b 100644 (file)
@@ -108,6 +108,11 @@ void tipc_bclink_remove_node(struct net *net, u32 addr)
 
        tipc_bclink_lock(net);
        tipc_nmap_remove(&tn->bclink->bcast_nodes, addr);
+
+       /* Last node? => reset backlog queue */
+       if (!tn->bclink->bcast_nodes.count)
+               tipc_link_purge_backlog(&tn->bclink->link);
+
        tipc_bclink_unlock(net);
 }
 
index ca8b8e0f49b526ebbf7a87e2cc89491ecfedf988..eaa9fe54b4aebfb531610611637915dc1b0c7256 100644 (file)
@@ -404,7 +404,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
        l_ptr->reasm_buf = NULL;
 }
 
-static void tipc_link_purge_backlog(struct tipc_link *l)
+void tipc_link_purge_backlog(struct tipc_link *l)
 {
        __skb_queue_purge(&l->backlogq);
        l->backlog[TIPC_LOW_IMPORTANCE].len = 0;
index 0c02c973e98558c699f006cce06b81768891b08b..ae0a0ea572f2961aca2617f9244ea74ebba15c6a 100644 (file)
@@ -218,6 +218,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr);
 int tipc_link_is_up(struct tipc_link *l_ptr);
 int tipc_link_is_active(struct tipc_link *l_ptr);
 void tipc_link_purge_queues(struct tipc_link *l_ptr);
+void tipc_link_purge_backlog(struct tipc_link *l);
 void tipc_link_reset_all(struct tipc_node *node);
 void tipc_link_reset(struct tipc_link *l_ptr);
 int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,