]> Git Repo - linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorDavid S. Miller <[email protected]>
Sat, 11 Feb 2017 07:31:11 +0000 (02:31 -0500)
committerDavid S. Miller <[email protected]>
Sat, 11 Feb 2017 07:31:11 +0000 (02:31 -0500)
15 files changed:
1  2 
MAINTAINERS
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/loopback.c
drivers/net/xen-netfront.c
include/linux/netdevice.h
include/net/lwtunnel.h
net/dsa/dsa2.c
net/ethernet/eth.c
net/ipv4/ping.c
net/ipv6/addrconf.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/packet/af_packet.c
security/selinux/hooks.c

diff --combined MAINTAINERS
index 49acc4cb34b1281903020d3451f5cc761394cda7,107c10e8f2d27f5c0b61a9addf225844ee09f7c5..2a86fb06a134298c656376668f90bbddb2727b5e
@@@ -1091,7 -1091,7 +1091,7 @@@ F:      arch/arm/boot/dts/aspeed-
  F:    drivers/*/*aspeed*
  
  ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  M:    Alexandre Belloni <[email protected]>
  M:    Jean-Christophe Plagniol-Villard <[email protected]>
  L:    [email protected] (moderated for non-subscribers)
@@@ -1773,7 -1773,7 +1773,7 @@@ F:      drivers/soc/renesas
  F:    include/linux/soc/renesas/
  
  ARM/SOCFPGA ARCHITECTURE
- M:    Dinh Nguyen <dinguyen@opensource.altera.com>
+ M:    Dinh Nguyen <dinguyen@kernel.org>
  S:    Maintained
  F:    arch/arm/mach-socfpga/
  F:    arch/arm/boot/dts/socfpga*
@@@ -1783,7 -1783,7 +1783,7 @@@ W:      http://www.rocketboards.or
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
  
  ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT
- M:    Dinh Nguyen <dinguyen@opensource.altera.com>
+ M:    Dinh Nguyen <dinguyen@kernel.org>
  S:    Maintained
  F:    drivers/clk/socfpga/
  
@@@ -2175,56 -2175,56 +2175,56 @@@ F:   include/linux/atm
  F:    include/uapi/linux/atm*
  
  ATMEL AT91 / AT32 MCI DRIVER
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  S:    Maintained
  F:    drivers/mmc/host/atmel-mci.c
  
  ATMEL AT91 SAMA5D2-Compatible Shutdown Controller
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  S:    Supported
  F:    drivers/power/reset/at91-sama5d2_shdwc.c
  
  ATMEL SAMA5D2 ADC DRIVER
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  L:    [email protected]
  S:    Supported
  F:    drivers/iio/adc/at91-sama5d2_adc.c
  
  ATMEL Audio ALSA driver
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  F:    sound/soc/atmel
  
  ATMEL XDMA DRIVER
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  L:    [email protected]
  L:    [email protected]
  S:    Supported
  F:    drivers/dma/at_xdmac.c
  
  ATMEL I2C DRIVER
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  L:    [email protected]
  S:    Supported
  F:    drivers/i2c/busses/i2c-at91.c
  
  ATMEL ISI DRIVER
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  L:    [email protected]
  S:    Supported
  F:    drivers/media/platform/soc_camera/atmel-isi.c
  F:    include/media/atmel-isi.h
  
  ATMEL LCDFB DRIVER
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  L:    [email protected]
  S:    Maintained
  F:    drivers/video/fbdev/atmel_lcdfb.c
  F:    include/video/atmel_lcdc.h
  
  ATMEL MACB ETHERNET DRIVER
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  S:    Supported
  F:    drivers/net/ethernet/cadence/
  
@@@ -2236,32 -2236,32 +2236,32 @@@ S:   Supporte
  F:    drivers/mtd/nand/atmel_nand*
  
  ATMEL SDMMC DRIVER
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  L:    [email protected]
  S:    Supported
  F:    drivers/mmc/host/sdhci-of-at91.c
  
  ATMEL SPI DRIVER
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  S:    Supported
  F:    drivers/spi/spi-atmel.*
  
  ATMEL SSC DRIVER
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  F:    drivers/misc/atmel-ssc.c
  F:    include/linux/atmel-ssc.h
  
  ATMEL Timer Counter (TC) AND CLOCKSOURCE DRIVERS
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  F:    drivers/misc/atmel_tclib.c
  F:    drivers/clocksource/tcb_clksrc.c
  
  ATMEL USBA UDC DRIVER
- M:    Nicolas Ferre <nicolas.ferre@atmel.com>
+ M:    Nicolas Ferre <nicolas.ferre@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  S:    Supported
  F:    drivers/usb/gadget/udc/atmel_usba_udc.*
  S:    Supported
  F:    drivers/net/ethernet/broadcom/bnx2x/
  
 +BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER
 +M:    Michael Chan <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    drivers/net/ethernet/broadcom/bnxt/
 +
  BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
  M:    Florian Fainelli <[email protected]>
  M:    Ray Jui <[email protected]>
@@@ -5638,14 -5632,6 +5638,14 @@@ T:    git git://linuxtv.org/media_tree.gi
  S:    Odd Fixes
  F:    drivers/media/usb/gspca/
  
 +GTP (GPRS Tunneling Protocol)
 +M:    Pablo Neira Ayuso <[email protected]>
 +M:    Harald Welte <[email protected]>
 +L:    [email protected]
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/gtp.git
 +S:    Maintained
 +F:    drivers/net/gtp.c
 +
  GUID PARTITION TABLE (GPT)
  M:    Davidlohr Bueso <[email protected]>
  L:    [email protected]
@@@ -6258,13 -6244,6 +6258,13 @@@ F:    include/net/cfg802154.
  F:    include/net/ieee802154_netdev.h
  F:    Documentation/networking/ieee802154.txt
  
 +IFE PROTOCOL
 +M:    Yotam Gigi <[email protected]>
 +M:    Jamal Hadi Salim <[email protected]>
 +F:    net/ife
 +F:    include/net/ife.h
 +F:    include/uapi/linux/ife.h
 +
  IGORPLUG-USB IR RECEIVER
  M:    Sean Young <[email protected]>
  L:    [email protected]
@@@ -9390,14 -9369,6 +9390,14 @@@ F:    drivers/video/fbdev/sti
  F:    drivers/video/console/sti*
  F:    drivers/video/logo/logo_parisc*
  
 +PARMAN
 +M:    Jiri Pirko <[email protected]>
 +L:    [email protected]
 +S:    Supported
 +F:    lib/parman.c
 +F:    lib/test_parman.c
 +F:    include/linux/parman.h
 +
  PC87360 HARDWARE MONITORING DRIVER
  M:    Jim Cromie <[email protected]>
  L:    [email protected]
@@@ -9765,7 -9736,7 +9765,7 @@@ S:      Maintaine
  F:    drivers/pinctrl/pinctrl-at91.*
  
  PIN CONTROLLER - ATMEL AT91 PIO4
- M:    Ludovic Desroches <ludovic.desroches@atmel.com>
+ M:    Ludovic Desroches <ludovic.desroches@microchip.com>
  L:    [email protected] (moderated for non-subscribers)
  L:    [email protected]
  S:    Supported
  S:    Maintained
  F:    drivers/block/ps3vram.c
  
 +PSAMPLE PACKET SAMPLING SUPPORT:
 +M:    Yotam Gigi <[email protected]>
 +S:    Maintained
 +F:    net/psample
 +F:    include/net/psample.h
 +F:    include/uapi/linux/psample.h
 +
  PSTORE FILESYSTEM
  M:    Anton Vorontsov <[email protected]>
  M:    Colin Cross <[email protected]>
@@@ -10629,7 -10593,7 +10629,7 @@@ F:   drivers/net/wireless/realtek/rtlwifi
  F:    drivers/net/wireless/realtek/rtlwifi/rtl8192ce/
  
  RTL8XXXU WIRELESS DRIVER (rtl8xxxu)
 -M:    Jes Sorensen <Jes.Sorensen@redhat.com>
 +M:    Jes Sorensen <Jes.Sorensen@gmail.com>
  L:    [email protected]
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jes/linux.git rtl8xxxu-devel
  S:    Maintained
@@@ -10895,13 -10859,6 +10895,13 @@@ S: Maintaine
  F:    drivers/staging/media/st-cec/
  F:    Documentation/devicetree/bindings/media/stih-cec.txt
  
 +SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
 +M:    Ursula Braun <[email protected]>
 +L:    [email protected]
 +W:    http://www.ibm.com/developerworks/linux/linux390/
 +S:    Supported
 +F:    net/smc/
 +
  SYNOPSYS DESIGNWARE DMAC DRIVER
  M:    Viresh Kumar <[email protected]>
  M:    Andy Shevchenko <[email protected]>
@@@ -10910,6 -10867,13 +10910,6 @@@ F:  include/linux/dma/dw.
  F:    include/linux/platform_data/dma-dw.h
  F:    drivers/dma/dw/
  
 -SYNOPSYS DESIGNWARE ETHERNET QOS 4.10a driver
 -M: Lars Persson <[email protected]>
 -S: Supported
 -F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
 -F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
 -
  SYNOPSYS DESIGNWARE I2C DRIVER
  M:    Jarkko Nikula <[email protected]>
  R:    Andy Shevchenko <[email protected]>
@@@ -11352,13 -11316,6 +11352,13 @@@ F: arch/arm/mach-s3c24xx/mach-bast.
  F:    arch/arm/mach-s3c24xx/bast-ide.c
  F:    arch/arm/mach-s3c24xx/bast-irq.c
  
 +SIPHASH PRF ROUTINES
 +M:    Jason A. Donenfeld <[email protected]>
 +S:    Maintained
 +F:    lib/siphash.c
 +F:    lib/test_siphash.c
 +F:    include/linux/siphash.h
 +
  TI DAVINCI MACHINE SUPPORT
  M:    Sekhar Nori <[email protected]>
  M:    Kevin Hilman <[email protected]>
@@@ -11930,7 -11887,6 +11930,7 @@@ F:   include/linux/swiotlb.
  
  SWITCHDEV
  M:    Jiri Pirko <[email protected]>
 +M:    Ivan Vecera <[email protected]>
  L:    [email protected]
  S:    Supported
  F:    net/switchdev/
index dfb2bad7ced5f6544a4b4900af4a1e768de3f50a,1e4695270da6cc422c441542783a0ae24dd943a6..4c8e8cf730bbc2ee1d488d42d9d42163d442fb75
@@@ -31,6 -31,7 +31,7 @@@ struct lmac 
        u8                      lmac_type;
        u8                      lane_to_sds;
        bool                    use_training;
+       bool                    autoneg;
        bool                    link_up;
        int                     lmacid; /* ID within BGX */
        int                     lmacid_bd; /* ID on board */
@@@ -461,7 -462,17 +462,17 @@@ static int bgx_lmac_sgmii_init(struct b
        /* power down, reset autoneg, autoneg enable */
        cfg = bgx_reg_read(bgx, lmacid, BGX_GMP_PCS_MRX_CTL);
        cfg &= ~PCS_MRX_CTL_PWR_DN;
-       cfg |= (PCS_MRX_CTL_RST_AN | PCS_MRX_CTL_AN_EN);
+       cfg |= PCS_MRX_CTL_RST_AN;
+       if (lmac->phydev) {
+               cfg |= PCS_MRX_CTL_AN_EN;
+       } else {
+               /* In scenarios where PHY driver is not present or it's a
+                * non-standard PHY, FW sets AN_EN to inform Linux driver
+                * to do auto-neg and link polling or not.
+                */
+               if (cfg & PCS_MRX_CTL_AN_EN)
+                       lmac->autoneg = true;
+       }
        bgx_reg_write(bgx, lmacid, BGX_GMP_PCS_MRX_CTL, cfg);
  
        if (lmac->lmac_type == BGX_MODE_QSGMII) {
                return 0;
        }
  
-       if (lmac->lmac_type == BGX_MODE_SGMII) {
+       if ((lmac->lmac_type == BGX_MODE_SGMII) && lmac->phydev) {
                if (bgx_poll_reg(bgx, lmacid, BGX_GMP_PCS_MRX_STATUS,
                                 PCS_MRX_STATUS_AN_CPT, false)) {
                        dev_err(&bgx->pdev->dev, "BGX AN_CPT not completed\n");
@@@ -678,12 -689,71 +689,71 @@@ static int bgx_xaui_check_link(struct l
        return -1;
  }
  
+ static void bgx_poll_for_sgmii_link(struct lmac *lmac)
+ {
+       u64 pcs_link, an_result;
+       u8 speed;
+       pcs_link = bgx_reg_read(lmac->bgx, lmac->lmacid,
+                               BGX_GMP_PCS_MRX_STATUS);
+       /*Link state bit is sticky, read it again*/
+       if (!(pcs_link & PCS_MRX_STATUS_LINK))
+               pcs_link = bgx_reg_read(lmac->bgx, lmac->lmacid,
+                                       BGX_GMP_PCS_MRX_STATUS);
+       if (bgx_poll_reg(lmac->bgx, lmac->lmacid, BGX_GMP_PCS_MRX_STATUS,
+                        PCS_MRX_STATUS_AN_CPT, false)) {
+               lmac->link_up = false;
+               lmac->last_speed = SPEED_UNKNOWN;
+               lmac->last_duplex = DUPLEX_UNKNOWN;
+               goto next_poll;
+       }
+       lmac->link_up = ((pcs_link & PCS_MRX_STATUS_LINK) != 0) ? true : false;
+       an_result = bgx_reg_read(lmac->bgx, lmac->lmacid,
+                                BGX_GMP_PCS_ANX_AN_RESULTS);
+       speed = (an_result >> 3) & 0x3;
+       lmac->last_duplex = (an_result >> 1) & 0x1;
+       switch (speed) {
+       case 0:
+               lmac->last_speed = 10;
+               break;
+       case 1:
+               lmac->last_speed = 100;
+               break;
+       case 2:
+               lmac->last_speed = 1000;
+               break;
+       default:
+               lmac->link_up = false;
+               lmac->last_speed = SPEED_UNKNOWN;
+               lmac->last_duplex = DUPLEX_UNKNOWN;
+               break;
+       }
+ next_poll:
+       if (lmac->last_link != lmac->link_up) {
+               if (lmac->link_up)
+                       bgx_sgmii_change_link_state(lmac);
+               lmac->last_link = lmac->link_up;
+       }
+       queue_delayed_work(lmac->check_link, &lmac->dwork, HZ * 3);
+ }
  static void bgx_poll_for_link(struct work_struct *work)
  {
        struct lmac *lmac;
        u64 spu_link, smu_link;
  
        lmac = container_of(work, struct lmac, dwork.work);
+       if (lmac->is_sgmii) {
+               bgx_poll_for_sgmii_link(lmac);
+               return;
+       }
  
        /* Receive link is latching low. Force it high and verify it */
        bgx_reg_modify(lmac->bgx, lmac->lmacid,
@@@ -775,9 -845,21 +845,21 @@@ static int bgx_lmac_enable(struct bgx *
            (lmac->lmac_type != BGX_MODE_XLAUI) &&
            (lmac->lmac_type != BGX_MODE_40G_KR) &&
            (lmac->lmac_type != BGX_MODE_10G_KR)) {
-               if (!lmac->phydev)
-                       return -ENODEV;
+               if (!lmac->phydev) {
+                       if (lmac->autoneg) {
+                               bgx_reg_write(bgx, lmacid,
+                                             BGX_GMP_PCS_LINKX_TIMER,
+                                             PCS_LINKX_TIMER_COUNT);
+                               goto poll;
+                       } else {
+                               /* Default to below link speed and duplex */
+                               lmac->link_up = true;
+                               lmac->last_speed = 1000;
+                               lmac->last_duplex = 1;
+                               bgx_sgmii_change_link_state(lmac);
+                               return 0;
+                       }
+               }
                lmac->phydev->dev_flags = 0;
  
                if (phy_connect_direct(&lmac->netdev, lmac->phydev,
                        return -ENODEV;
  
                phy_start_aneg(lmac->phydev);
-       } else {
-               lmac->check_link = alloc_workqueue("check_link", WQ_UNBOUND |
-                                                  WQ_MEM_RECLAIM, 1);
-               if (!lmac->check_link)
-                       return -ENOMEM;
-               INIT_DELAYED_WORK(&lmac->dwork, bgx_poll_for_link);
-               queue_delayed_work(lmac->check_link, &lmac->dwork, 0);
+               return 0;
        }
  
+ poll:
+       lmac->check_link = alloc_workqueue("check_link", WQ_UNBOUND |
+                                          WQ_MEM_RECLAIM, 1);
+       if (!lmac->check_link)
+               return -ENOMEM;
+       INIT_DELAYED_WORK(&lmac->dwork, bgx_poll_for_link);
+       queue_delayed_work(lmac->check_link, &lmac->dwork, 0);
        return 0;
  }
  
@@@ -894,15 -978,17 +978,15 @@@ static void bgx_print_qlm_mode(struct b
        struct device *dev = &bgx->pdev->dev;
        struct lmac *lmac;
        char str[20];
 -      u8 dlm;
  
 -      if (lmacid > bgx->max_lmac)
 +      if (!bgx->is_dlm && lmacid)
                return;
  
        lmac = &bgx->lmac[lmacid];
 -      dlm = (lmacid / 2) + (bgx->bgx_id * 2);
        if (!bgx->is_dlm)
                sprintf(str, "BGX%d QLM mode", bgx->bgx_id);
        else
 -              sprintf(str, "BGX%d DLM%d mode", bgx->bgx_id, dlm);
 +              sprintf(str, "BGX%d LMAC%d mode", bgx->bgx_id, lmacid);
  
        switch (lmac->lmac_type) {
        case BGX_MODE_SGMII:
@@@ -988,6 -1074,7 +1072,6 @@@ static void lmac_set_training(struct bg
  static void bgx_set_lmac_config(struct bgx *bgx, u8 idx)
  {
        struct lmac *lmac;
 -      struct lmac *olmac;
        u64 cmr_cfg;
        u8 lmac_type;
        u8 lane_to_sds;
                return;
        }
  
 -      /* On 81xx BGX can be split across 2 DLMs
 -       * firmware programs lmac_type of LMAC0 and LMAC2
 +      /* For DLMs or SLMs on 80/81/83xx so many lane configurations
 +       * are possible and vary across boards. Also Kernel doesn't have
 +       * any way to identify board type/info and since firmware does,
 +       * just take lmac type and serdes lane config as is.
         */
 -      if ((idx == 0) || (idx == 2)) {
 -              cmr_cfg = bgx_reg_read(bgx, idx, BGX_CMRX_CFG);
 -              lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
 -              lane_to_sds = (u8)(cmr_cfg & 0xFF);
 -              /* Check if config is not reset value */
 -              if ((lmac_type == 0) && (lane_to_sds == 0xE4))
 -                      lmac->lmac_type = BGX_MODE_INVALID;
 -              else
 -                      lmac->lmac_type = lmac_type;
 -              lmac_set_training(bgx, lmac, lmac->lmacid);
 -              lmac_set_lane2sds(bgx, lmac);
 -
 -              olmac = &bgx->lmac[idx + 1];
 -              /*  Check if other LMAC on the same DLM is already configured by
 -               *  firmware, if so use the same config or else set as same, as
 -               *  that of LMAC 0/2.
 -               *  This check is needed as on 80xx only one lane of each of the
 -               *  DLM of BGX0 is used, so have to rely on firmware for
 -               *  distingushing 80xx from 81xx.
 -               */
 -              cmr_cfg = bgx_reg_read(bgx, idx + 1, BGX_CMRX_CFG);
 -              lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
 -              lane_to_sds = (u8)(cmr_cfg & 0xFF);
 -              if ((lmac_type == 0) && (lane_to_sds == 0xE4)) {
 -                      olmac->lmac_type = lmac->lmac_type;
 -                      lmac_set_lane2sds(bgx, olmac);
 -              } else {
 -                      olmac->lmac_type = lmac_type;
 -                      olmac->lane_to_sds = lane_to_sds;
 -              }
 -              lmac_set_training(bgx, olmac, olmac->lmacid);
 -      }
 -}
 -
 -static bool is_dlm0_in_bgx_mode(struct bgx *bgx)
 -{
 -      struct lmac *lmac;
 -
 -      if (!bgx->is_dlm)
 -              return true;
 -
 -      lmac = &bgx->lmac[0];
 -      if (lmac->lmac_type == BGX_MODE_INVALID)
 -              return false;
 -
 -      return true;
 +      cmr_cfg = bgx_reg_read(bgx, idx, BGX_CMRX_CFG);
 +      lmac_type = (u8)((cmr_cfg >> 8) & 0x07);
 +      lane_to_sds = (u8)(cmr_cfg & 0xFF);
 +      /* Check if config is reset value */
 +      if ((lmac_type == 0) && (lane_to_sds == 0xE4))
 +              lmac->lmac_type = BGX_MODE_INVALID;
 +      else
 +              lmac->lmac_type = lmac_type;
 +      lmac->lane_to_sds = lane_to_sds;
 +      lmac_set_training(bgx, lmac, lmac->lmacid);
  }
  
  static void bgx_get_qlm_mode(struct bgx *bgx)
  {
        struct lmac *lmac;
 -      struct lmac *lmac01;
 -      struct lmac *lmac23;
        u8  idx;
  
        /* Init all LMAC's type to invalid */
        if (bgx->lmac_count > bgx->max_lmac)
                bgx->lmac_count = bgx->max_lmac;
  
 -      for (idx = 0; idx < bgx->max_lmac; idx++)
 -              bgx_set_lmac_config(bgx, idx);
 -
 -      if (!bgx->is_dlm || bgx->is_rgx) {
 -              bgx_print_qlm_mode(bgx, 0);
 -              return;
 -      }
 -
 -      if (bgx->lmac_count) {
 -              bgx_print_qlm_mode(bgx, 0);
 -              bgx_print_qlm_mode(bgx, 2);
 -      }
 -
 -      /* If DLM0 is not in BGX mode then LMAC0/1 have
 -       * to be configured with serdes lanes of DLM1
 -       */
 -      if (is_dlm0_in_bgx_mode(bgx) || (bgx->lmac_count > 2))
 -              return;
        for (idx = 0; idx < bgx->lmac_count; idx++) {
 -              lmac01 = &bgx->lmac[idx];
 -              lmac23 = &bgx->lmac[idx + 2];
 -              lmac01->lmac_type = lmac23->lmac_type;
 -              lmac01->lane_to_sds = lmac23->lane_to_sds;
 +              bgx_set_lmac_config(bgx, idx);
 +              bgx_print_qlm_mode(bgx, idx);
        }
  }
  
index fefe371e59071629f7fdf98c92d05b7311559994,8aed72860e7c0eece690c97ae38b1fbedfa58557..fca37e2c7f017d76aa537daede5f7af14cb8e152
@@@ -305,8 -305,8 +305,8 @@@ int hns_nic_net_xmit_hw(struct net_devi
                        struct hns_nic_ring_data *ring_data)
  {
        struct hns_nic_priv *priv = netdev_priv(ndev);
-       struct device *dev = priv->dev;
        struct hnae_ring *ring = ring_data->ring;
+       struct device *dev = ring_to_dev(ring);
        struct netdev_queue *dev_queue;
        struct skb_frag_struct *frag;
        int buf_num;
@@@ -797,6 -797,7 +797,6 @@@ static void hns_nic_rx_up_pro(struct hn
  
        skb->protocol = eth_type_trans(skb, ndev);
        (void)napi_gro_receive(&ring_data->napi, skb);
 -      ndev->last_rx = jiffies;
  }
  
  static int hns_desc_unused(struct hnae_ring *ring)
@@@ -1202,48 -1203,43 +1202,48 @@@ static void hns_set_irq_affinity(struc
        struct hns_nic_ring_data *rd;
        int i;
        int cpu;
 -      cpumask_t mask;
 +      cpumask_var_t mask;
 +
 +      if (!alloc_cpumask_var(&mask, GFP_KERNEL))
 +              return;
  
        /*diffrent irq banlance for 16core and 32core*/
        if (h->q_num == num_possible_cpus()) {
                for (i = 0; i < h->q_num * 2; i++) {
                        rd = &priv->ring_data[i];
                        if (cpu_online(rd->queue_index)) {
 -                              cpumask_clear(&mask);
 +                              cpumask_clear(mask);
                                cpu = rd->queue_index;
 -                              cpumask_set_cpu(cpu, &mask);
 +                              cpumask_set_cpu(cpu, mask);
                                (void)irq_set_affinity_hint(rd->ring->irq,
 -                                                          &mask);
 +                                                          mask);
                        }
                }
        } else {
                for (i = 0; i < h->q_num; i++) {
                        rd = &priv->ring_data[i];
                        if (cpu_online(rd->queue_index * 2)) {
 -                              cpumask_clear(&mask);
 +                              cpumask_clear(mask);
                                cpu = rd->queue_index * 2;
 -                              cpumask_set_cpu(cpu, &mask);
 +                              cpumask_set_cpu(cpu, mask);
                                (void)irq_set_affinity_hint(rd->ring->irq,
 -                                                          &mask);
 +                                                          mask);
                        }
                }
  
                for (i = h->q_num; i < h->q_num * 2; i++) {
                        rd = &priv->ring_data[i];
                        if (cpu_online(rd->queue_index * 2 + 1)) {
 -                              cpumask_clear(&mask);
 +                              cpumask_clear(mask);
                                cpu = rd->queue_index * 2 + 1;
 -                              cpumask_set_cpu(cpu, &mask);
 +                              cpumask_set_cpu(cpu, mask);
                                (void)irq_set_affinity_hint(rd->ring->irq,
 -                                                          &mask);
 +                                                          mask);
                        }
                }
        }
 +
 +      free_cpumask_var(mask);
  }
  
  static int hns_nic_init_irq(struct hns_nic_priv *priv)
@@@ -1629,8 -1625,8 +1629,8 @@@ void hns_nic_set_rx_mode(struct net_dev
                netdev_err(ndev, "sync uc address fail\n");
  }
  
 -struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev,
 -                                            struct rtnl_link_stats64 *stats)
 +static void hns_nic_get_stats64(struct net_device *ndev,
 +                              struct rtnl_link_stats64 *stats)
  {
        int idx = 0;
        u64 tx_bytes = 0;
        stats->tx_window_errors = ndev->stats.tx_window_errors;
        stats->rx_compressed = ndev->stats.rx_compressed;
        stats->tx_compressed = ndev->stats.tx_compressed;
 -
 -      return stats;
  }
  
  static u16
diff --combined drivers/net/loopback.c
index 30a493936e63b1898f36e0a9b200ede3b96fb9c8,0844f849641346b092e83923c1d196709b355e4c..b23b71981fd55689daa817d41191063300bdaaf5
@@@ -97,8 -97,8 +97,8 @@@ static netdev_tx_t loopback_xmit(struc
        return NETDEV_TX_OK;
  }
  
 -static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev,
 -                                                    struct rtnl_link_stats64 *stats)
 +static void loopback_get_stats64(struct net_device *dev,
 +                               struct rtnl_link_stats64 *stats)
  {
        u64 bytes = 0;
        u64 packets = 0;
        stats->tx_packets = packets;
        stats->rx_bytes   = bytes;
        stats->tx_bytes   = bytes;
 -      return stats;
  }
  
  static u32 always_on(struct net_device *dev)
@@@ -163,6 -164,7 +163,7 @@@ static void loopback_setup(struct net_d
  {
        dev->mtu                = 64 * 1024;
        dev->hard_header_len    = ETH_HLEN;     /* 14   */
+       dev->min_header_len     = ETH_HLEN;     /* 14   */
        dev->addr_len           = ETH_ALEN;     /* 6    */
        dev->type               = ARPHRD_LOOPBACK;      /* 0x0001*/
        dev->flags              = IFF_LOOPBACK;
index cf82b5b42056ed03c86fb9d675efb0fbb2f03883,1e4125a98291245f5e806a79247a92ca1418092b..d23703d9724998c7d3e724c489cca3a491910b6b
@@@ -281,6 -281,7 +281,7 @@@ static void xennet_alloc_rx_buffers(str
  {
        RING_IDX req_prod = queue->rx.req_prod_pvt;
        int notify;
+       int err = 0;
  
        if (unlikely(!netif_carrier_ok(queue->info->netdev)))
                return;
                struct xen_netif_rx_request *req;
  
                skb = xennet_alloc_one_rx_buffer(queue);
-               if (!skb)
+               if (!skb) {
+                       err = -ENOMEM;
                        break;
+               }
  
                id = xennet_rxidx(req_prod);
  
  
        queue->rx.req_prod_pvt = req_prod;
  
-       /* Not enough requests? Try again later. */
-       if (req_prod - queue->rx.sring->req_prod < NET_RX_SLOTS_MIN) {
+       /* Try again later if there are not enough requests or skb allocation
+        * failed.
+        * Enough requests is quantified as the sum of newly created slots and
+        * the unconsumed slots at the backend.
+        */
+       if (req_prod - queue->rx.rsp_cons < NET_RX_SLOTS_MIN ||
+           unlikely(err)) {
                mod_timer(&queue->rx_refill_timer, jiffies + (HZ/10));
                return;
        }
@@@ -1051,7 -1059,7 +1059,7 @@@ err
        if (work_done < budget) {
                int more_to_do = 0;
  
 -              napi_complete(napi);
 +              napi_complete_done(napi, work_done);
  
                RING_FINAL_CHECK_FOR_RESPONSES(&queue->rx, more_to_do);
                if (more_to_do)
@@@ -1073,8 -1081,8 +1081,8 @@@ static int xennet_change_mtu(struct net
        return 0;
  }
  
 -static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev,
 -                                                  struct rtnl_link_stats64 *tot)
 +static void xennet_get_stats64(struct net_device *dev,
 +                             struct rtnl_link_stats64 *tot)
  {
        struct netfront_info *np = netdev_priv(dev);
        int cpu;
  
        tot->rx_errors  = dev->stats.rx_errors;
        tot->tx_dropped = dev->stats.tx_dropped;
 -
 -      return tot;
  }
  
  static void xennet_release_tx_bufs(struct netfront_queue *queue)
@@@ -1377,6 -1387,8 +1385,8 @@@ static void xennet_disconnect_backend(s
        for (i = 0; i < num_queues && info->queues; ++i) {
                struct netfront_queue *queue = &info->queues[i];
  
+               del_timer_sync(&queue->rx_refill_timer);
                if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
                        unbind_from_irqhandler(queue->tx_irq, queue);
                if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
@@@ -1731,7 -1743,6 +1741,6 @@@ static void xennet_destroy_queues(struc
  
                if (netif_running(info->netdev))
                        napi_disable(&queue->napi);
-               del_timer_sync(&queue->rx_refill_timer);
                netif_napi_del(&queue->napi);
        }
  
@@@ -1820,27 -1831,19 +1829,19 @@@ static int talk_to_netback(struct xenbu
                xennet_destroy_queues(info);
  
        err = xennet_create_queues(info, &num_queues);
-       if (err < 0)
-               goto destroy_ring;
+       if (err < 0) {
+               xenbus_dev_fatal(dev, err, "creating queues");
+               kfree(info->queues);
+               info->queues = NULL;
+               goto out;
+       }
  
        /* Create shared ring, alloc event channel -- for each queue */
        for (i = 0; i < num_queues; ++i) {
                queue = &info->queues[i];
                err = setup_netfront(dev, queue, feature_split_evtchn);
-               if (err) {
-                       /* setup_netfront() will tidy up the current
-                        * queue on error, but we need to clean up
-                        * those already allocated.
-                        */
-                       if (i > 0) {
-                               rtnl_lock();
-                               netif_set_real_num_tx_queues(info->netdev, i);
-                               rtnl_unlock();
-                               goto destroy_ring;
-                       } else {
-                               goto out;
-                       }
-               }
+               if (err)
+                       goto destroy_ring;
        }
  
  again:
@@@ -1930,9 -1933,10 +1931,10 @@@ abort_transaction_no_dev_fatal
        xenbus_transaction_end(xbt, 1);
   destroy_ring:
        xennet_disconnect_backend(info);
-       kfree(info->queues);
-       info->queues = NULL;
+       xennet_destroy_queues(info);
   out:
+       unregister_netdev(info->netdev);
+       xennet_free_netdev(info->netdev);
        return err;
  }
  
index 58afbd1cc6597695da1d61cfa86f790a2379a49f,27914672602d9d573e6a3da271cec33ccef51b16..54c82b5df0ba54f2e676d0c9f5197057d3edde1a
@@@ -463,6 -463,7 +463,6 @@@ static inline bool napi_reschedule(stru
        return false;
  }
  
 -bool __napi_complete(struct napi_struct *n);
  bool napi_complete_done(struct napi_struct *n, int work_done);
  /**
   *    napi_complete - NAPI processing complete
@@@ -916,8 -917,8 +916,8 @@@ struct netdev_xdp 
   *    Callback used when the transmitter has not made any progress
   *    for dev->watchdog ticks.
   *
 - * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,
 - *                      struct rtnl_link_stats64 *storage);
 + * void (*ndo_get_stats64)(struct net_device *dev,
 + *                         struct rtnl_link_stats64 *storage);
   * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
   *    Called when a user wants to get the network device usage
   *    statistics. Drivers must do one of the following:
   *      with PF and querying it may introduce a theoretical security risk.
   * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting);
   * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
 - * int (*ndo_setup_tc)(struct net_device *dev, u8 tc)
 - *    Called to setup 'tc' number of traffic classes in the net device. This
 - *    is always called from the stack with the rtnl lock held and netif tx
 - *    queues stopped. This allows the netdevice to perform queue management
 - *    safely.
 + * int (*ndo_setup_tc)(struct net_device *dev, u32 handle,
 + *                   __be16 protocol, struct tc_to_netdev *tc);
 + *    Called to setup any 'tc' scheduler, classifier or action on @dev.
 + *    This is always called from the stack with the rtnl lock held and netif
 + *    tx queues stopped. This allows the netdevice to perform queue
 + *    management safely.
   *
   *    Fiber Channel over Ethernet (FCoE) offload functions.
   * int (*ndo_fcoe_enable)(struct net_device *dev);
@@@ -1166,8 -1166,8 +1166,8 @@@ struct net_device_ops 
                                                   struct neigh_parms *);
        void                    (*ndo_tx_timeout) (struct net_device *dev);
  
 -      struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,
 -                                                   struct rtnl_link_stats64 *storage);
 +      void                    (*ndo_get_stats64)(struct net_device *dev,
 +                                                 struct rtnl_link_stats64 *storage);
        bool                    (*ndo_has_offload_stats)(const struct net_device *dev, int attr_id);
        int                     (*ndo_get_offload_stats)(int attr_id,
                                                         const struct net_device *dev,
        int                     (*ndo_netpoll_setup)(struct net_device *dev,
                                                     struct netpoll_info *info);
        void                    (*ndo_netpoll_cleanup)(struct net_device *dev);
 -#endif
 -#ifdef CONFIG_NET_RX_BUSY_POLL
 -      int                     (*ndo_busy_poll)(struct napi_struct *dev);
  #endif
        int                     (*ndo_set_vf_mac)(struct net_device *dev,
                                                  int queue, u8 *mac);
@@@ -1508,6 -1511,7 +1508,7 @@@ enum netdev_priv_flags 
   *    @max_mtu:       Interface Maximum MTU value
   *    @type:          Interface hardware type
   *    @hard_header_len: Maximum hardware header length.
+  *    @min_header_len:  Minimum hardware header length
   *
   *    @needed_headroom: Extra headroom the hardware may need, but not in all
   *                      cases can this be guaranteed
   *    @ax25_ptr:      AX.25 specific data
   *    @ieee80211_ptr: IEEE 802.11 specific data, assign before registering
   *
 - *    @last_rx:       Time of last Rx
   *    @dev_addr:      Hw address (before bcast,
   *                    because most packets are unicast)
   *
@@@ -1724,6 -1729,7 +1725,7 @@@ struct net_device 
        unsigned int            max_mtu;
        unsigned short          type;
        unsigned short          hard_header_len;
+       unsigned short          min_header_len;
  
        unsigned short          needed_headroom;
        unsigned short          needed_tailroom;
  /*
   * Cache lines mostly used on receive path (including eth_type_trans())
   */
 -      unsigned long           last_rx;
 -
        /* Interface address info used in eth_type_trans() */
        unsigned char           *dev_addr;
  
@@@ -2688,6 -2696,8 +2690,8 @@@ static inline bool dev_validate_header(
  {
        if (likely(len >= dev->hard_header_len))
                return true;
+       if (len < dev->min_header_len)
+               return false;
  
        if (capable(CAP_SYS_RAWIO)) {
                memset(ll_header + len, 0, dev->hard_header_len - len);
@@@ -3101,19 -3111,7 +3105,19 @@@ static inline bool netif_subqueue_stopp
        return __netif_subqueue_stopped(dev, skb_get_queue_mapping(skb));
  }
  
 -void netif_wake_subqueue(struct net_device *dev, u16 queue_index);
 +/**
 + *    netif_wake_subqueue - allow sending packets on subqueue
 + *    @dev: network device
 + *    @queue_index: sub queue index
 + *
 + * Resume individual transmit queue of a device with multiple transmit queues.
 + */
 +static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
 +{
 +      struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
 +
 +      netif_tx_wake_queue(txq);
 +}
  
  #ifdef CONFIG_XPS
  int netif_set_xps_queue(struct net_device *dev, const struct cpumask *mask,
@@@ -3807,10 -3805,6 +3811,10 @@@ void netdev_stats_to_stats64(struct rtn
  extern int            netdev_max_backlog;
  extern int            netdev_tstamp_prequeue;
  extern int            weight_p;
 +extern int            dev_weight_rx_bias;
 +extern int            dev_weight_tx_bias;
 +extern int            dev_rx_weight;
 +extern int            dev_tx_weight;
  
  bool netdev_has_upper_dev(struct net_device *dev, struct net_device *upper_dev);
  struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
@@@ -3888,6 -3882,10 +3892,6 @@@ void *netdev_lower_dev_get_private(stru
                                   struct net_device *lower_dev);
  void netdev_lower_state_changed(struct net_device *lower_dev,
                                void *lower_state_info);
 -int netdev_default_l2upper_neigh_construct(struct net_device *dev,
 -                                         struct neighbour *n);
 -void netdev_default_l2upper_neigh_destroy(struct net_device *dev,
 -                                        struct neighbour *n);
  
  /* RSS keys are 40 or 52 bytes long */
  #define NETDEV_RSS_KEY_LEN 52
@@@ -4340,15 -4338,6 +4344,15 @@@ do {                                                          
  })
  #endif
  
 +/* if @cond then downgrade to debug, else print at @level */
 +#define netif_cond_dbg(priv, type, netdev, cond, level, fmt, args...)     \
 +      do {                                                              \
 +              if (cond)                                                 \
 +                      netif_dbg(priv, type, netdev, fmt, ##args);       \
 +              else                                                      \
 +                      netif_ ## level(priv, type, netdev, fmt, ##args); \
 +      } while (0)
 +
  #if defined(VERBOSE_DEBUG)
  #define netif_vdbg    netif_dbg
  #else
diff --combined include/net/lwtunnel.h
index 45399ed132bff247d7824009b73303252be1a8c9,0388b9c5f5e2c7257cc0eb19be469974becab5ed..ebfe237aad7e0fb4c9d165a0090708134768c239
@@@ -33,7 -33,7 +33,7 @@@ struct lwtunnel_state 
  };
  
  struct lwtunnel_encap_ops {
 -      int (*build_state)(struct net_device *dev, struct nlattr *encap,
 +      int (*build_state)(struct nlattr *encap,
                           unsigned int family, const void *cfg,
                           struct lwtunnel_state **ts);
        void (*destroy_state)(struct lwtunnel_state *lws);
@@@ -109,7 -109,7 +109,7 @@@ int lwtunnel_encap_del_ops(const struc
                           unsigned int num);
  int lwtunnel_valid_encap_type(u16 encap_type);
  int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len);
 -int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
 +int lwtunnel_build_state(u16 encap_type,
                         struct nlattr *encap,
                         unsigned int family, const void *cfg,
                         struct lwtunnel_state **lws);
@@@ -178,10 -178,13 +178,13 @@@ static inline int lwtunnel_valid_encap_
  }
  static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
  {
-       return -EOPNOTSUPP;
+       /* return 0 since we are not walking attr looking for
+        * RTA_ENCAP_TYPE attribute on nexthops.
+        */
+       return 0;
  }
  
 -static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
 +static inline int lwtunnel_build_state(u16 encap_type,
                                       struct nlattr *encap,
                                       unsigned int family, const void *cfg,
                                       struct lwtunnel_state **lws)
diff --combined net/dsa/dsa2.c
index 6f5f0a2ad256df3202202337f2a4e9f104d43c75,0f99297b2fb3517942bf74fee08ed3e61d65a4f0..737be6470c7f27ba032d01667e039f3c03c17ae8
@@@ -57,6 -57,7 +57,6 @@@ static struct dsa_switch_tree *dsa_add_
        if (!dst)
                return NULL;
        dst->tree = tree;
 -      dst->cpu_switch = -1;
        INIT_LIST_HEAD(&dst->list);
        list_add_tail(&dsa_switch_trees, &dst->list);
        kref_init(&dst->refcount);
@@@ -78,43 -79,47 +78,43 @@@ static void dsa_dst_del_ds(struct dsa_s
        kref_put(&dst->refcount, dsa_free_dst);
  }
  
 -static bool dsa_port_is_dsa(struct device_node *port)
 +/* For platform data configurations, we need to have a valid name argument to
 + * differentiate a disabled port from an enabled one
 + */
 +static bool dsa_port_is_valid(struct dsa_port *port)
  {
 -      const char *name;
 -
 -      name = of_get_property(port, "label", NULL);
 -      if (!name)
 -              return false;
 +      return !!(port->dn || port->name);
 +}
  
 -      if (!strcmp(name, "dsa"))
 +static bool dsa_port_is_dsa(struct dsa_port *port)
 +{
 +      if (port->name && !strcmp(port->name, "dsa"))
                return true;
 -
 -      return false;
 +      else
 +              return !!of_parse_phandle(port->dn, "link", 0);
  }
  
 -static bool dsa_port_is_cpu(struct device_node *port)
 +static bool dsa_port_is_cpu(struct dsa_port *port)
  {
 -      const char *name;
 -
 -      name = of_get_property(port, "label", NULL);
 -      if (!name)
 -              return false;
 -
 -      if (!strcmp(name, "cpu"))
 +      if (port->name && !strcmp(port->name, "cpu"))
                return true;
 -
 -      return false;
 +      else
 +              return !!of_parse_phandle(port->dn, "ethernet", 0);
  }
  
 -static bool dsa_ds_find_port(struct dsa_switch *ds,
 -                           struct device_node *port)
 +static bool dsa_ds_find_port_dn(struct dsa_switch *ds,
 +                              struct device_node *port)
  {
        u32 index;
  
 -      for (index = 0; index < DSA_MAX_PORTS; index++)
 +      for (index = 0; index < ds->num_ports; index++)
                if (ds->ports[index].dn == port)
                        return true;
        return false;
  }
  
 -static struct dsa_switch *dsa_dst_find_port(struct dsa_switch_tree *dst,
 -                                          struct device_node *port)
 +static struct dsa_switch *dsa_dst_find_port_dn(struct dsa_switch_tree *dst,
 +                                             struct device_node *port)
  {
        struct dsa_switch *ds;
        u32 index;
                if (!ds)
                        continue;
  
 -              if (dsa_ds_find_port(ds, port))
 +              if (dsa_ds_find_port_dn(ds, port))
                        return ds;
        }
  
  
  static int dsa_port_complete(struct dsa_switch_tree *dst,
                             struct dsa_switch *src_ds,
 -                           struct device_node *port,
 +                           struct dsa_port *port,
                             u32 src_port)
  {
        struct device_node *link;
        struct dsa_switch *dst_ds;
  
        for (index = 0;; index++) {
 -              link = of_parse_phandle(port, "link", index);
 +              link = of_parse_phandle(port->dn, "link", index);
                if (!link)
                        break;
  
 -              dst_ds = dsa_dst_find_port(dst, link);
 +              dst_ds = dsa_dst_find_port_dn(dst, link);
                of_node_put(link);
  
                if (!dst_ds)
   */
  static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds)
  {
 -      struct device_node *port;
 +      struct dsa_port *port;
        u32 index;
        int err;
  
 -      for (index = 0; index < DSA_MAX_PORTS; index++) {
 -              port = ds->ports[index].dn;
 -              if (!port)
 +      for (index = 0; index < ds->num_ports; index++) {
 +              port = &ds->ports[index];
 +              if (!dsa_port_is_valid(port))
                        continue;
  
                if (!dsa_port_is_dsa(port))
@@@ -210,7 -215,7 +210,7 @@@ static int dsa_dst_complete(struct dsa_
        return 0;
  }
  
 -static int dsa_dsa_port_apply(struct device_node *port, u32 index,
 +static int dsa_dsa_port_apply(struct dsa_port *port, u32 index,
                              struct dsa_switch *ds)
  {
        int err;
        return 0;
  }
  
 -static void dsa_dsa_port_unapply(struct device_node *port, u32 index,
 +static void dsa_dsa_port_unapply(struct dsa_port *port, u32 index,
                                 struct dsa_switch *ds)
  {
        dsa_cpu_dsa_destroy(port);
  }
  
 -static int dsa_cpu_port_apply(struct device_node *port, u32 index,
 +static int dsa_cpu_port_apply(struct dsa_port *port, u32 index,
                              struct dsa_switch *ds)
  {
        int err;
        return 0;
  }
  
 -static void dsa_cpu_port_unapply(struct device_node *port, u32 index,
 +static void dsa_cpu_port_unapply(struct dsa_port *port, u32 index,
                                 struct dsa_switch *ds)
  {
        dsa_cpu_dsa_destroy(port);
  
  }
  
 -static int dsa_user_port_apply(struct device_node *port, u32 index,
 +static int dsa_user_port_apply(struct dsa_port *port, u32 index,
                               struct dsa_switch *ds)
  {
 -      const char *name;
 +      const char *name = port->name;
        int err;
  
 -      name = of_get_property(port, "label", NULL);
 +      if (port->dn)
 +              name = of_get_property(port->dn, "label", NULL);
 +      if (!name)
 +              name = "eth%d";
  
        err = dsa_slave_create(ds, ds->dev, index, name);
        if (err) {
                dev_warn(ds->dev, "Failed to create slave %d: %d\n",
                         index, err);
+               ds->ports[index].netdev = NULL;
                return err;
        }
  
        return 0;
  }
  
 -static void dsa_user_port_unapply(struct device_node *port, u32 index,
 +static void dsa_user_port_unapply(struct dsa_port *port, u32 index,
                                  struct dsa_switch *ds)
  {
        if (ds->ports[index].netdev) {
  
  static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
  {
 -      struct device_node *port;
 +      struct dsa_port *port;
        u32 index;
        int err;
  
        if (err < 0)
                return err;
  
 +      err = dsa_switch_register_notifier(ds);
 +      if (err)
 +              return err;
 +
        if (ds->ops->set_addr) {
                err = ds->ops->set_addr(ds, dst->master_netdev->dev_addr);
                if (err < 0)
                        return err;
        }
  
 -      for (index = 0; index < DSA_MAX_PORTS; index++) {
 -              port = ds->ports[index].dn;
 -              if (!port)
 +      for (index = 0; index < ds->num_ports; index++) {
 +              port = &ds->ports[index];
 +              if (!dsa_port_is_valid(port))
                        continue;
  
                if (dsa_port_is_dsa(port)) {
  
  static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
  {
 -      struct device_node *port;
 +      struct dsa_port *port;
        u32 index;
  
 -      for (index = 0; index < DSA_MAX_PORTS; index++) {
 -              port = ds->ports[index].dn;
 -              if (!port)
 +      for (index = 0; index < ds->num_ports; index++) {
 +              port = &ds->ports[index];
 +              if (!dsa_port_is_valid(port))
                        continue;
  
                if (dsa_port_is_dsa(port)) {
  
        if (ds->slave_mii_bus && ds->ops->phy_read)
                mdiobus_unregister(ds->slave_mii_bus);
 +
 +      dsa_switch_unregister_notifier(ds);
  }
  
  static int dsa_dst_apply(struct dsa_switch_tree *dst)
                        return err;
        }
  
 -      if (dst->ds[0]) {
 -              err = dsa_cpu_port_ethtool_setup(dst->ds[0]);
 +      if (dst->cpu_switch) {
 +              err = dsa_cpu_port_ethtool_setup(dst->cpu_switch);
                if (err)
                        return err;
        }
@@@ -439,14 -436,14 +440,14 @@@ static void dsa_dst_unapply(struct dsa_
                dsa_ds_unapply(dst, ds);
        }
  
 -      if (dst->ds[0])
 -              dsa_cpu_port_ethtool_restore(dst->ds[0]);
 +      if (dst->cpu_switch)
 +              dsa_cpu_port_ethtool_restore(dst->cpu_switch);
  
        pr_info("DSA: tree %d unapplied\n", dst->tree);
        dst->applied = false;
  }
  
 -static int dsa_cpu_parse(struct device_node *port, u32 index,
 +static int dsa_cpu_parse(struct dsa_port *port, u32 index,
                         struct dsa_switch_tree *dst,
                         struct dsa_switch *ds)
  {
        struct net_device *ethernet_dev;
        struct device_node *ethernet;
  
 -      ethernet = of_parse_phandle(port, "ethernet", 0);
 -      if (!ethernet)
 -              return -EINVAL;
 +      if (port->dn) {
 +              ethernet = of_parse_phandle(port->dn, "ethernet", 0);
 +              if (!ethernet)
 +                      return -EINVAL;
 +              ethernet_dev = of_find_net_device_by_node(ethernet);
 +      } else {
 +              ethernet_dev = dsa_dev_to_net_device(ds->cd->netdev[index]);
 +              dev_put(ethernet_dev);
 +      }
  
 -      ethernet_dev = of_find_net_device_by_node(ethernet);
        if (!ethernet_dev)
                return -EPROBE_DEFER;
  
        if (!dst->master_netdev)
                dst->master_netdev = ethernet_dev;
  
 -      if (dst->cpu_switch == -1) {
 -              dst->cpu_switch = ds->index;
 +      if (!dst->cpu_switch) {
 +              dst->cpu_switch = ds;
                dst->cpu_port = index;
        }
  
  
  static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
  {
 -      struct device_node *port;
 +      struct dsa_port *port;
        u32 index;
        int err;
  
 -      for (index = 0; index < DSA_MAX_PORTS; index++) {
 -              port = ds->ports[index].dn;
 -              if (!port)
 +      for (index = 0; index < ds->num_ports; index++) {
 +              port = &ds->ports[index];
 +              if (!dsa_port_is_valid(port))
                        continue;
  
                if (dsa_port_is_cpu(port)) {
@@@ -550,7 -542,7 +551,7 @@@ static int dsa_parse_ports_dn(struct de
                if (err)
                        return err;
  
 -              if (reg >= DSA_MAX_PORTS)
 +              if (reg >= ds->num_ports)
                        return -EINVAL;
  
                ds->ports[reg].dn = port;
                 * to have access to a correct value, just like what
                 * net/dsa/dsa.c::dsa_switch_setup_one does.
                 */
 -              if (!dsa_port_is_cpu(port))
 +              if (!dsa_port_is_cpu(&ds->ports[reg]))
                        ds->enabled_port_mask |= 1 << reg;
        }
  
        return 0;
  }
  
 -static int dsa_parse_member(struct device_node *np, u32 *tree, u32 *index)
 +static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds)
 +{
 +      bool valid_name_found = false;
 +      unsigned int i;
 +
 +      for (i = 0; i < DSA_MAX_PORTS; i++) {
 +              if (!cd->port_names[i])
 +                      continue;
 +
 +              ds->ports[i].name = cd->port_names[i];
 +
 +              /* Initialize enabled_port_mask now for drv->setup()
 +               * to have access to a correct value, just like what
 +               * net/dsa/dsa.c::dsa_switch_setup_one does.
 +               */
 +              if (!dsa_port_is_cpu(&ds->ports[i]))
 +                      ds->enabled_port_mask |= 1 << i;
 +
 +              valid_name_found = true;
 +      }
 +
 +      if (!valid_name_found && i == DSA_MAX_PORTS)
 +              return -EINVAL;
 +
 +      return 0;
 +}
 +
 +static int dsa_parse_member_dn(struct device_node *np, u32 *tree, u32 *index)
  {
        int err;
  
        return 0;
  }
  
 +static int dsa_parse_member(struct dsa_chip_data *pd, u32 *tree, u32 *index)
 +{
 +      if (!pd)
 +              return -ENODEV;
 +
 +      /* We do not support complex trees with dsa_chip_data */
 +      *tree = 0;
 +      *index = 0;
 +
 +      return 0;
 +}
 +
  static struct device_node *dsa_get_ports(struct dsa_switch *ds,
                                         struct device_node *np)
  {
        return ports;
  }
  
 -static int _dsa_register_switch(struct dsa_switch *ds, struct device_node *np)
 +static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev)
  {
 -      struct device_node *ports = dsa_get_ports(ds, np);
 +      struct dsa_chip_data *pdata = dev->platform_data;
 +      struct device_node *np = dev->of_node;
        struct dsa_switch_tree *dst;
 +      struct device_node *ports;
        u32 tree, index;
        int i, err;
  
 -      err = dsa_parse_member(np, &tree, &index);
 -      if (err)
 -              return err;
 +      if (np) {
 +              err = dsa_parse_member_dn(np, &tree, &index);
 +              if (err)
 +                      return err;
  
 -      if (IS_ERR(ports))
 -              return PTR_ERR(ports);
 +              ports = dsa_get_ports(ds, np);
 +              if (IS_ERR(ports))
 +                      return PTR_ERR(ports);
  
 -      err = dsa_parse_ports_dn(ports, ds);
 -      if (err)
 -              return err;
 +              err = dsa_parse_ports_dn(ports, ds);
 +              if (err)
 +                      return err;
 +      } else {
 +              err = dsa_parse_member(pdata, &tree, &index);
 +              if (err)
 +                      return err;
 +
 +              err = dsa_parse_ports(pdata, ds);
 +              if (err)
 +                      return err;
 +      }
  
        dst = dsa_get_dst(tree);
        if (!dst) {
  
        ds->dst = dst;
        ds->index = index;
 +      ds->cd = pdata;
  
        /* Initialize the routing table */
        for (i = 0; i < DSA_MAX_SWITCHES; ++i)
        }
  
        err = dsa_dst_parse(dst);
 -      if (err)
 +      if (err) {
 +              if (err == -EPROBE_DEFER) {
 +                      dsa_dst_del_ds(dst, ds, ds->index);
 +                      return err;
 +              }
 +
                goto out_del_dst;
 +      }
  
        err = dsa_dst_apply(dst);
        if (err) {
@@@ -738,34 -671,12 +739,34 @@@ out
        return err;
  }
  
 -int dsa_register_switch(struct dsa_switch *ds, struct device_node *np)
 +struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
 +{
 +      size_t size = sizeof(struct dsa_switch) + n * sizeof(struct dsa_port);
 +      struct dsa_switch *ds;
 +      int i;
 +
 +      ds = devm_kzalloc(dev, size, GFP_KERNEL);
 +      if (!ds)
 +              return NULL;
 +
 +      ds->dev = dev;
 +      ds->num_ports = n;
 +
 +      for (i = 0; i < ds->num_ports; ++i) {
 +              ds->ports[i].index = i;
 +              ds->ports[i].ds = ds;
 +      }
 +
 +      return ds;
 +}
 +EXPORT_SYMBOL_GPL(dsa_switch_alloc);
 +
 +int dsa_register_switch(struct dsa_switch *ds, struct device *dev)
  {
        int err;
  
        mutex_lock(&dsa2_mutex);
 -      err = _dsa_register_switch(ds, np);
 +      err = _dsa_register_switch(ds, dev);
        mutex_unlock(&dsa2_mutex);
  
        return err;
diff --combined net/ethernet/eth.c
index efdaaab735fced4a3ed2ab38620d6f4d4de1566e,516c87e75de7009e9e4f0cbdc80f8160c318fdf4..d21be3b3d9cccd901e4baba06df0d32e69b05d09
@@@ -356,6 -356,7 +356,7 @@@ void ether_setup(struct net_device *dev
        dev->header_ops         = &eth_header_ops;
        dev->type               = ARPHRD_ETHER;
        dev->hard_header_len    = ETH_HLEN;
+       dev->min_header_len     = ETH_HLEN;
        dev->mtu                = ETH_DATA_LEN;
        dev->min_mtu            = ETH_MIN_MTU;
        dev->max_mtu            = ETH_DATA_LEN;
@@@ -392,34 -393,6 +393,34 @@@ struct net_device *alloc_etherdev_mqs(i
  }
  EXPORT_SYMBOL(alloc_etherdev_mqs);
  
 +static void devm_free_netdev(struct device *dev, void *res)
 +{
 +      free_netdev(*(struct net_device **)res);
 +}
 +
 +struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
 +                                         unsigned int txqs, unsigned int rxqs)
 +{
 +      struct net_device **dr;
 +      struct net_device *netdev;
 +
 +      dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
 +      if (!dr)
 +              return NULL;
 +
 +      netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
 +      if (!netdev) {
 +              devres_free(dr);
 +              return NULL;
 +      }
 +
 +      *dr = netdev;
 +      devres_add(dev, dr);
 +
 +      return netdev;
 +}
 +EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
 +
  ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
  {
        return scnprintf(buf, PAGE_SIZE, "%*phC\n", len, addr);
diff --combined net/ipv4/ping.c
index 6ee792d83d5befcac511470033ced09475a8f661,68d77b1f1495bb8dace1f6aa9c0e9a6ee5b2e5dd..2af6244b83e27ae384e96cf071c10c5a89674804
@@@ -433,9 -433,9 +433,9 @@@ int ping_bind(struct sock *sk, struct s
                goto out;
        }
  
 -      pr_debug("after bind(): num = %d, dif = %d\n",
 -               (int)isk->inet_num,
 -               (int)sk->sk_bound_dev_if);
 +      pr_debug("after bind(): num = %hu, dif = %d\n",
 +               isk->inet_num,
 +               sk->sk_bound_dev_if);
  
        err = 0;
        if (sk->sk_family == AF_INET && isk->inet_rcv_saddr)
@@@ -642,6 -642,8 +642,8 @@@ static int ping_v4_push_pending_frames(
  {
        struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
  
+       if (!skb)
+               return 0;
        pfh->wcheck = csum_partial((char *)&pfh->icmph,
                sizeof(struct icmphdr), pfh->wcheck);
        pfh->icmph.checksum = csum_fold(pfh->wcheck);
@@@ -848,8 -850,7 +850,8 @@@ out
        return err;
  
  do_confirm:
 -      dst_confirm(&rt->dst);
 +      if (msg->msg_flags & MSG_PROBE)
 +              dst_confirm_neigh(&rt->dst, &fl4.daddr);
        if (!(msg->msg_flags & MSG_PROBE) || len)
                goto back_from_confirm;
        err = 0;
diff --combined net/ipv6/addrconf.c
index a69ae7d4e6f8178a3d476c897a459671559ed85a,a7bcc0ab5e99543a08410abe6ff3dbfc9b3753b7..3a2025f5bf2c333a37d18329cdec88fdc1827870
@@@ -243,7 -243,6 +243,7 @@@ static struct ipv6_devconf ipv6_devcon
        .seg6_require_hmac      = 0,
  #endif
        .enhanced_dad           = 1,
 +      .addr_gen_mode          = IN6_ADDR_GEN_MODE_EUI64,
  };
  
  static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
        .seg6_require_hmac      = 0,
  #endif
        .enhanced_dad           = 1,
 +      .addr_gen_mode          = IN6_ADDR_GEN_MODE_EUI64,
  };
  
  /* Check if a valid qdisc is available */
@@@ -388,9 -386,9 +388,9 @@@ static struct inet6_dev *ipv6_add_dev(s
        memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
  
        if (ndev->cnf.stable_secret.initialized)
 -              ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
 +              ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
        else
 -              ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64;
 +              ndev->cnf.addr_gen_mode = ipv6_devconf_dflt.addr_gen_mode;
  
        ndev->cnf.mtu6 = dev->mtu;
        ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
@@@ -2146,14 -2144,12 +2146,14 @@@ static int ipv6_generate_eui64(u8 *eui
        case ARPHRD_SIT:
                return addrconf_ifid_sit(eui, dev);
        case ARPHRD_IPGRE:
 +      case ARPHRD_TUNNEL:
                return addrconf_ifid_gre(eui, dev);
        case ARPHRD_6LOWPAN:
                return addrconf_ifid_eui64(eui, dev);
        case ARPHRD_IEEE1394:
                return addrconf_ifid_ieee1394(eui, dev);
        case ARPHRD_TUNNEL6:
 +      case ARPHRD_IP6GRE:
                return addrconf_ifid_ip6tnl(eui, dev);
        }
        return -1;
@@@ -2391,8 -2387,8 +2391,8 @@@ static void manage_tempaddrs(struct ine
  
  static bool is_addr_mode_generate_stable(struct inet6_dev *idev)
  {
 -      return idev->addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY ||
 -             idev->addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
 +      return idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY ||
 +             idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_RANDOM;
  }
  
  int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
@@@ -3156,7 -3152,7 +3156,7 @@@ static void addrconf_addr_gen(struct in
  
        ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
  
 -      switch (idev->addr_gen_mode) {
 +      switch (idev->cnf.addr_gen_mode) {
        case IN6_ADDR_GEN_MODE_RANDOM:
                ipv6_gen_mode_random_init(idev);
                /* fallthrough */
@@@ -3197,9 -3193,6 +3197,9 @@@ static void addrconf_dev_config(struct 
            (dev->type != ARPHRD_IEEE1394) &&
            (dev->type != ARPHRD_TUNNEL6) &&
            (dev->type != ARPHRD_6LOWPAN) &&
 +          (dev->type != ARPHRD_IP6GRE) &&
 +          (dev->type != ARPHRD_IPGRE) &&
 +          (dev->type != ARPHRD_TUNNEL) &&
            (dev->type != ARPHRD_NONE)) {
                /* Alas, we support only Ethernet autoconfiguration. */
                return;
  
        /* this device type has no EUI support */
        if (dev->type == ARPHRD_NONE &&
 -          idev->addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)
 -              idev->addr_gen_mode = IN6_ADDR_GEN_MODE_RANDOM;
 +          idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64)
 +              idev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_RANDOM;
  
        addrconf_addr_gen(idev, false);
  }
@@@ -4022,6 -4015,12 +4022,12 @@@ static void addrconf_dad_completed(stru
  
        if (bump_id)
                rt_genid_bump_ipv6(dev_net(dev));
+       /* Make sure that a new temporary address will be created
+        * before this temporary address becomes deprecated.
+        */
+       if (ifp->flags & IFA_F_TEMPORARY)
+               addrconf_verify_rtnl();
  }
  
  static void addrconf_dad_run(struct inet6_dev *idev)
@@@ -4901,13 -4900,6 +4907,13 @@@ static void inet6_ifa_notify(int event
        struct net *net = dev_net(ifa->idev->dev);
        int err = -ENOBUFS;
  
 +      /* Don't send DELADDR notification for TENTATIVE address,
 +       * since NEWADDR notification is sent only after removing
 +       * TENTATIVE flag.
 +       */
 +      if (ifa->flags & IFA_F_TENTATIVE && event == RTM_DELADDR)
 +              return;
 +
        skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
        if (!skb)
                goto errout;
@@@ -4995,7 -4987,6 +5001,7 @@@ static inline void ipv6_store_devconf(s
        array[DEVCONF_SEG6_REQUIRE_HMAC] = cnf->seg6_require_hmac;
  #endif
        array[DEVCONF_ENHANCED_DAD] = cnf->enhanced_dad;
 +      array[DEVCONF_ADDR_GEN_MODE] = cnf->addr_gen_mode;
  }
  
  static inline size_t inet6_ifla6_size(void)
@@@ -5107,7 -5098,7 +5113,7 @@@ static int inet6_fill_ifla6_attrs(struc
        if (!nla)
                goto nla_put_failure;
  
 -      if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->addr_gen_mode))
 +      if (nla_put_u8(skb, IFLA_INET6_ADDR_GEN_MODE, idev->cnf.addr_gen_mode))
                goto nla_put_failure;
  
        read_lock_bh(&idev->lock);
@@@ -5225,26 -5216,6 +5231,26 @@@ static int inet6_validate_link_af(cons
        return nla_parse_nested(tb, IFLA_INET6_MAX, nla, inet6_af_policy);
  }
  
 +static int check_addr_gen_mode(int mode)
 +{
 +      if (mode != IN6_ADDR_GEN_MODE_EUI64 &&
 +          mode != IN6_ADDR_GEN_MODE_NONE &&
 +          mode != IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
 +          mode != IN6_ADDR_GEN_MODE_RANDOM)
 +              return -EINVAL;
 +      return 1;
 +}
 +
 +static int check_stable_privacy(struct inet6_dev *idev, struct net *net,
 +                              int mode)
 +{
 +      if (mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
 +          !idev->cnf.stable_secret.initialized &&
 +          !net->ipv6.devconf_dflt->stable_secret.initialized)
 +              return -EINVAL;
 +      return 1;
 +}
 +
  static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
  {
        int err = -EINVAL;
        if (tb[IFLA_INET6_ADDR_GEN_MODE]) {
                u8 mode = nla_get_u8(tb[IFLA_INET6_ADDR_GEN_MODE]);
  
 -              if (mode != IN6_ADDR_GEN_MODE_EUI64 &&
 -                  mode != IN6_ADDR_GEN_MODE_NONE &&
 -                  mode != IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
 -                  mode != IN6_ADDR_GEN_MODE_RANDOM)
 -                      return -EINVAL;
 -
 -              if (mode == IN6_ADDR_GEN_MODE_STABLE_PRIVACY &&
 -                  !idev->cnf.stable_secret.initialized &&
 -                  !dev_net(dev)->ipv6.devconf_dflt->stable_secret.initialized)
 +              if (check_addr_gen_mode(mode) < 0 ||
 +                  check_stable_privacy(idev, dev_net(dev), mode) < 0)
                        return -EINVAL;
  
 -              idev->addr_gen_mode = mode;
 +              idev->cnf.addr_gen_mode = mode;
                err = 0;
        }
  
@@@ -5677,47 -5655,6 +5683,47 @@@ int addrconf_sysctl_proxy_ndp(struct ct
        return ret;
  }
  
 +static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
 +                                       void __user *buffer, size_t *lenp,
 +                                       loff_t *ppos)
 +{
 +      int ret = 0;
 +      int new_val;
 +      struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1;
 +      struct net *net = (struct net *)ctl->extra2;
 +
 +      ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 +
 +      if (write) {
 +              new_val = *((int *)ctl->data);
 +
 +              if (check_addr_gen_mode(new_val) < 0)
 +                      return -EINVAL;
 +
 +              /* request for default */
 +              if (&net->ipv6.devconf_dflt->addr_gen_mode == ctl->data) {
 +                      ipv6_devconf_dflt.addr_gen_mode = new_val;
 +
 +              /* request for individual net device */
 +              } else {
 +                      if (!idev)
 +                              return ret;
 +
 +                      if (check_stable_privacy(idev, net, new_val) < 0)
 +                              return -EINVAL;
 +
 +                      if (idev->cnf.addr_gen_mode != new_val) {
 +                              idev->cnf.addr_gen_mode = new_val;
 +                              rtnl_lock();
 +                              addrconf_dev_config(idev->dev);
 +                              rtnl_unlock();
 +                      }
 +              }
 +      }
 +
 +      return ret;
 +}
 +
  static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
                                         void __user *buffer, size_t *lenp,
                                         loff_t *ppos)
                        struct inet6_dev *idev = __in6_dev_get(dev);
  
                        if (idev) {
 -                              idev->addr_gen_mode =
 +                              idev->cnf.addr_gen_mode =
                                        IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
                        }
                }
        } else {
                struct inet6_dev *idev = ctl->extra1;
  
 -              idev->addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
 +              idev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
        }
  
  out:
@@@ -6162,13 -6099,6 +6168,13 @@@ static const struct ctl_table addrconf_
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
 +      {
 +              .procname               = "addr_gen_mode",
 +              .data                   = &ipv6_devconf.addr_gen_mode,
 +              .maxlen                 = sizeof(int),
 +              .mode                   = 0644,
 +              .proc_handler   = addrconf_sysctl_addr_gen_mode,
 +      },
        {
                /* sentinel */
        }
diff --combined net/l2tp/l2tp_ip.c
index b07a859f21bd3f96999aa9c58f09c0f57667e90b,28c21546d5b60dcd07bbf6347389e97c918bf40f..c59712057dc838170f47f917cc3676f9f06f958b
@@@ -11,6 -11,7 +11,7 @@@
  
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  
+ #include <asm/ioctls.h>
  #include <linux/icmp.h>
  #include <linux/module.h>
  #include <linux/skbuff.h>
@@@ -53,26 -54,19 +54,26 @@@ static struct sock *__l2tp_ip_bind_look
        struct sock *sk;
  
        sk_for_each_bound(sk, &l2tp_ip_bind_table) {
 -              struct inet_sock *inet = inet_sk(sk);
 -              struct l2tp_ip_sock *l2tp = l2tp_ip_sk(sk);
 +              const struct l2tp_ip_sock *l2tp = l2tp_ip_sk(sk);
 +              const struct inet_sock *inet = inet_sk(sk);
  
 -              if (l2tp == NULL)
 +              if (!net_eq(sock_net(sk), net))
                        continue;
  
 -              if ((l2tp->conn_id == tunnel_id) &&
 -                  net_eq(sock_net(sk), net) &&
 -                  !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
 -                  (!inet->inet_daddr || !raddr || inet->inet_daddr == raddr) &&
 -                  (!sk->sk_bound_dev_if || !dif ||
 -                   sk->sk_bound_dev_if == dif))
 -                      goto found;
 +              if (sk->sk_bound_dev_if && dif && sk->sk_bound_dev_if != dif)
 +                      continue;
 +
 +              if (inet->inet_rcv_saddr && laddr &&
 +                  inet->inet_rcv_saddr != laddr)
 +                      continue;
 +
 +              if (inet->inet_daddr && raddr && inet->inet_daddr != raddr)
 +                      continue;
 +
 +              if (l2tp->conn_id != tunnel_id)
 +                      continue;
 +
 +              goto found;
        }
  
        sk = NULL;
@@@ -265,7 -259,7 +266,7 @@@ static int l2tp_ip_bind(struct sock *sk
        if (!sock_flag(sk, SOCK_ZAPPED))
                goto out;
  
 -      if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip))
 +      if (sk->sk_state != TCP_CLOSE)
                goto out;
  
        chk_addr_ret = inet_addr_type(net, addr->l2tp_addr.s_addr);
@@@ -560,6 -554,30 +561,30 @@@ out
        return err ? err : copied;
  }
  
+ int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+ {
+       struct sk_buff *skb;
+       int amount;
+       switch (cmd) {
+       case SIOCOUTQ:
+               amount = sk_wmem_alloc_get(sk);
+               break;
+       case SIOCINQ:
+               spin_lock_bh(&sk->sk_receive_queue.lock);
+               skb = skb_peek(&sk->sk_receive_queue);
+               amount = skb ? skb->len : 0;
+               spin_unlock_bh(&sk->sk_receive_queue.lock);
+               break;
+       default:
+               return -ENOIOCTLCMD;
+       }
+       return put_user(amount, (int __user *)arg);
+ }
+ EXPORT_SYMBOL(l2tp_ioctl);
  static struct proto l2tp_ip_prot = {
        .name              = "L2TP/IP",
        .owner             = THIS_MODULE,
        .bind              = l2tp_ip_bind,
        .connect           = l2tp_ip_connect,
        .disconnect        = l2tp_ip_disconnect,
-       .ioctl             = udp_ioctl,
+       .ioctl             = l2tp_ioctl,
        .destroy           = l2tp_ip_destroy_sock,
        .setsockopt        = ip_setsockopt,
        .getsockopt        = ip_getsockopt,
diff --combined net/l2tp/l2tp_ip6.c
index 734798a00ca03bb0b06363aa39964fbb252f7093,f47c45250f86c9189e0a6bbfd92b21cbe2069406..a4abcbc4c09ae65424a701a1200b7535fa3635ac
@@@ -57,8 -57,8 +57,8 @@@ static inline struct l2tp_ip6_sock *l2t
        return (struct l2tp_ip6_sock *)sk;
  }
  
 -static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
 -                                         struct in6_addr *laddr,
 +static struct sock *__l2tp_ip6_bind_lookup(const struct net *net,
 +                                         const struct in6_addr *laddr,
                                           const struct in6_addr *raddr,
                                           int dif, u32 tunnel_id)
  {
        sk_for_each_bound(sk, &l2tp_ip6_bind_table) {
                const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk);
                const struct in6_addr *sk_raddr = &sk->sk_v6_daddr;
 -              struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
 +              const struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
  
 -              if (l2tp == NULL)
 +              if (!net_eq(sock_net(sk), net))
                        continue;
  
 -              if ((l2tp->conn_id == tunnel_id) &&
 -                  net_eq(sock_net(sk), net) &&
 -                  (!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) &&
 -                  (!raddr || ipv6_addr_any(sk_raddr) || ipv6_addr_equal(sk_raddr, raddr)) &&
 -                  (!sk->sk_bound_dev_if || !dif ||
 -                   sk->sk_bound_dev_if == dif))
 -                      goto found;
 +              if (sk->sk_bound_dev_if && dif && sk->sk_bound_dev_if != dif)
 +                      continue;
 +
 +              if (sk_laddr && !ipv6_addr_any(sk_laddr) &&
 +                  !ipv6_addr_any(laddr) && !ipv6_addr_equal(sk_laddr, laddr))
 +                      continue;
 +
 +              if (!ipv6_addr_any(sk_raddr) && raddr &&
 +                  !ipv6_addr_any(raddr) && !ipv6_addr_equal(sk_raddr, raddr))
 +                      continue;
 +
 +              if (l2tp->conn_id != tunnel_id)
 +                      continue;
 +
 +              goto found;
        }
  
        sk = NULL;
@@@ -658,8 -650,7 +658,8 @@@ out
        return err < 0 ? err : len;
  
  do_confirm:
 -      dst_confirm(dst);
 +      if (msg->msg_flags & MSG_PROBE)
 +              dst_confirm_neigh(dst, &fl6.daddr);
        if (!(msg->msg_flags & MSG_PROBE) || len)
                goto back_from_confirm;
        err = 0;
@@@ -731,7 -722,7 +731,7 @@@ static struct proto l2tp_ip6_prot = 
        .bind              = l2tp_ip6_bind,
        .connect           = l2tp_ip6_connect,
        .disconnect        = l2tp_ip6_disconnect,
-       .ioctl             = udp_ioctl,
+       .ioctl             = l2tp_ioctl,
        .destroy           = l2tp_ip6_destroy_sock,
        .setsockopt        = ipv6_setsockopt,
        .getsockopt        = ipv6_getsockopt,
diff --combined net/packet/af_packet.c
index 9854baad66abba0ffee8445999211695ccfc7502,d56ee46b11fc9524e457e5fe8adf10c105a66ab6..a984f6f9ab4e5c36a1d09c883bfd9dd3d0aacc1a
@@@ -409,9 -409,6 +409,9 @@@ static void __packet_set_status(struct 
                flush_dcache_page(pgv_to_page(&h.h2->tp_status));
                break;
        case TPACKET_V3:
 +              h.h3->tp_status = status;
 +              flush_dcache_page(pgv_to_page(&h.h3->tp_status));
 +              break;
        default:
                WARN(1, "TPACKET version not supported.\n");
                BUG();
@@@ -435,8 -432,6 +435,8 @@@ static int __packet_get_status(struct p
                flush_dcache_page(pgv_to_page(&h.h2->tp_status));
                return h.h2->tp_status;
        case TPACKET_V3:
 +              flush_dcache_page(pgv_to_page(&h.h3->tp_status));
 +              return h.h3->tp_status;
        default:
                WARN(1, "TPACKET version not supported.\n");
                BUG();
@@@ -481,9 -476,6 +481,9 @@@ static __u32 __packet_set_timestamp(str
                h.h2->tp_nsec = ts.tv_nsec;
                break;
        case TPACKET_V3:
 +              h.h3->tp_sec = ts.tv_sec;
 +              h.h3->tp_nsec = ts.tv_nsec;
 +              break;
        default:
                WARN(1, "TPACKET version not supported.\n");
                BUG();
@@@ -2505,13 -2497,6 +2505,13 @@@ static int tpacket_parse_header(struct 
        ph.raw = frame;
  
        switch (po->tp_version) {
 +      case TPACKET_V3:
 +              if (ph.h3->tp_next_offset != 0) {
 +                      pr_warn_once("variable sized slot not supported");
 +                      return -EINVAL;
 +              }
 +              tp_len = ph.h3->tp_len;
 +              break;
        case TPACKET_V2:
                tp_len = ph.h2->tp_len;
                break;
                off_max = po->tx_ring.frame_size - tp_len;
                if (po->sk.sk_type == SOCK_DGRAM) {
                        switch (po->tp_version) {
 +                      case TPACKET_V3:
 +                              off = ph.h3->tp_net;
 +                              break;
                        case TPACKET_V2:
                                off = ph.h2->tp_net;
                                break;
                        }
                } else {
                        switch (po->tp_version) {
 +                      case TPACKET_V3:
 +                              off = ph.h3->tp_mac;
 +                              break;
                        case TPACKET_V2:
                                off = ph.h2->tp_mac;
                                break;
@@@ -2776,7 -2755,7 +2776,7 @@@ static int packet_snd(struct socket *so
        struct virtio_net_hdr vnet_hdr = { 0 };
        int offset = 0;
        struct packet_sock *po = pkt_sk(sk);
-       int hlen, tlen;
+       int hlen, tlen, linear;
        int extra_len = 0;
  
        /*
        err = -ENOBUFS;
        hlen = LL_RESERVED_SPACE(dev);
        tlen = dev->needed_tailroom;
-       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len,
-                              __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len),
+       linear = __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len);
+       linear = max(linear, min_t(int, len, dev->hard_header_len));
+       skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
                               msg->msg_flags & MSG_DONTWAIT, &err);
        if (skb == NULL)
                goto out_unlock;
@@@ -4134,6 -4114,11 +4135,6 @@@ static int packet_set_ring(struct sock 
        struct tpacket_req *req = &req_u->req;
  
        lock_sock(sk);
 -      /* Opening a Tx-ring is NOT supported in TPACKET_V3 */
 -      if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
 -              net_warn_ratelimited("Tx-ring is not supported.\n");
 -              goto out;
 -      }
  
        rb = tx_ring ? &po->tx_ring : &po->rx_ring;
        rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
                        goto out;
                switch (po->tp_version) {
                case TPACKET_V3:
 -              /* Transmit path is not supported. We checked
 -               * it above but just being paranoid
 -               */
 -                      if (!tx_ring)
 +                      /* Block transmit is not supported yet */
 +                      if (!tx_ring) {
                                init_prb_bdqc(po, rb, pg_vec, req_u);
 +                      } else {
 +                              struct tpacket_req3 *req3 = &req_u->req3;
 +
 +                              if (req3->tp_retire_blk_tov ||
 +                                  req3->tp_sizeof_priv ||
 +                                  req3->tp_feature_req_word) {
 +                                      err = -EINVAL;
 +                                      goto out;
 +                              }
 +                      }
                        break;
                default:
                        break;
diff --combined security/selinux/hooks.c
index 53cb6da5f1c68b245de060b3d88463bd6c7b9779,d98550abe16d40250be4327197c48866953b5645..5eebce1af9a43f881bf0676bed54a525df68c91b
@@@ -4365,8 -4365,7 +4365,8 @@@ static int selinux_socket_bind(struct s
  
                        inet_get_local_port_range(sock_net(sk), &low, &high);
  
 -                      if (snum < max(PROT_SOCK, low) || snum > high) {
 +                      if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
 +                          snum > high) {
                                err = sel_netport_sid(sk->sk_protocol,
                                                      snum, &sid);
                                if (err)
@@@ -5888,7 -5887,7 +5888,7 @@@ static int selinux_setprocattr(struct t
                return error;
  
        /* Obtain a SID for the context, if one was specified. */
-       if (size && str[1] && str[1] != '\n') {
+       if (size && str[0] && str[0] != '\n') {
                if (str[size-1] == '\n') {
                        str[size-1] = 0;
                        size--;
This page took 0.240593 seconds and 4 git commands to generate.