]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
authorDavid S. Miller <davem@davemloft.net>
Mon, 3 Mar 2014 21:42:47 +0000 (16:42 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Mar 2014 21:42:47 +0000 (16:42 -0500)
John W. Linville says:

====================
Please pull this batch of fixes intended for the 3.14 stream...

For the mac80211 bits, Johannes says:

"This time I have a fix to get out of an 'infinite error state' in case
regulatory domain updates failed and two fixes for VHT associations: one
to not disconnect immediately when the AP uses more bandwidth than the
new regdomain would allow after a change due to association country
information getting used, and one for an issue in the code where
mac80211 doesn't correctly ignore a reserved field and then uses an HT
instead of VHT association."

For the iwlwifi bits, Emmanuel says:

"Johannes fixes a long standing bug in the AMPDU status reporting.
Max fixes the listen time which was way too long and causes trouble
to several APs."

Along with those, Bing Zhao marks the mwifiex_usb driver as _not_
supporting USB autosuspend after a number of problems with that have
been reported.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
12 files changed:
Documentation/networking/can.txt
drivers/net/can/flexcan.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c
drivers/net/ethernet/ti/cpsw.c
net/can/raw.c
net/hsr/hsr_framereg.c
net/ipv4/ip_tunnel_core.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/sctp/sm_statefuns.c

index f3089d4235153b6fa03aaf5c8d09c81043bba996..0cbe6ec22d6ff1d6a3c739f05ae61f4dc24781ec 100644 (file)
@@ -554,12 +554,6 @@ solution for a couple of reasons:
   not specified in the struct can_frame and therefore it is only valid in
   CANFD_MTU sized CAN FD frames.
 
-  As long as the payload length is <=8 the received CAN frames from CAN FD
-  capable CAN devices can be received and read by legacy sockets too. When
-  user-generated CAN FD frames have a payload length <=8 these can be send
-  by legacy CAN network interfaces too. Sending CAN FD frames with payload
-  length > 8 to a legacy CAN network interface returns an -EMSGSIZE error.
-
   Implementation hint for new CAN applications:
 
   To build a CAN FD aware application use struct canfd_frame as basic CAN
index 320bef2dba427f266511330bc11b1a4097368520..61376abdab395cd941f9a118c46e9912e17f4452 100644 (file)
 
 #define FLEXCAN_MB_CODE_MASK           (0xf0ffffff)
 
+#define FLEXCAN_TIMEOUT_US             (50)
+
 /*
  * FLEXCAN hardware feature flags
  *
@@ -262,6 +264,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
 }
 #endif
 
+static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
+{
+       if (!priv->reg_xceiver)
+               return 0;
+
+       return regulator_enable(priv->reg_xceiver);
+}
+
+static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
+{
+       if (!priv->reg_xceiver)
+               return 0;
+
+       return regulator_disable(priv->reg_xceiver);
+}
+
 static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
                                              u32 reg_esr)
 {
@@ -269,26 +287,95 @@ static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
                (reg_esr & FLEXCAN_ESR_ERR_BUS);
 }
 
-static inline void flexcan_chip_enable(struct flexcan_priv *priv)
+static int flexcan_chip_enable(struct flexcan_priv *priv)
 {
        struct flexcan_regs __iomem *regs = priv->base;
+       unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
        u32 reg;
 
        reg = flexcan_read(&regs->mcr);
        reg &= ~FLEXCAN_MCR_MDIS;
        flexcan_write(reg, &regs->mcr);
 
-       udelay(10);
+       while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+               usleep_range(10, 20);
+
+       if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK)
+               return -ETIMEDOUT;
+
+       return 0;
 }
 
-static inline void flexcan_chip_disable(struct flexcan_priv *priv)
+static int flexcan_chip_disable(struct flexcan_priv *priv)
 {
        struct flexcan_regs __iomem *regs = priv->base;
+       unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
        u32 reg;
 
        reg = flexcan_read(&regs->mcr);
        reg |= FLEXCAN_MCR_MDIS;
        flexcan_write(reg, &regs->mcr);
+
+       while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+               usleep_range(10, 20);
+
+       if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_LPM_ACK))
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int flexcan_chip_freeze(struct flexcan_priv *priv)
+{
+       struct flexcan_regs __iomem *regs = priv->base;
+       unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
+       u32 reg;
+
+       reg = flexcan_read(&regs->mcr);
+       reg |= FLEXCAN_MCR_HALT;
+       flexcan_write(reg, &regs->mcr);
+
+       while (timeout-- && !(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+               usleep_range(100, 200);
+
+       if (!(flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int flexcan_chip_unfreeze(struct flexcan_priv *priv)
+{
+       struct flexcan_regs __iomem *regs = priv->base;
+       unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
+       u32 reg;
+
+       reg = flexcan_read(&regs->mcr);
+       reg &= ~FLEXCAN_MCR_HALT;
+       flexcan_write(reg, &regs->mcr);
+
+       while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK))
+               usleep_range(10, 20);
+
+       if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_FRZ_ACK)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int flexcan_chip_softreset(struct flexcan_priv *priv)
+{
+       struct flexcan_regs __iomem *regs = priv->base;
+       unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
+
+       flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
+       while (timeout-- && (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST))
+               usleep_range(10, 20);
+
+       if (flexcan_read(&regs->mcr) & FLEXCAN_MCR_SOFTRST)
+               return -ETIMEDOUT;
+
+       return 0;
 }
 
 static int flexcan_get_berr_counter(const struct net_device *dev,
@@ -709,19 +796,14 @@ static int flexcan_chip_start(struct net_device *dev)
        u32 reg_mcr, reg_ctrl;
 
        /* enable module */
-       flexcan_chip_enable(priv);
+       err = flexcan_chip_enable(priv);
+       if (err)
+               return err;
 
        /* soft reset */
-       flexcan_write(FLEXCAN_MCR_SOFTRST, &regs->mcr);
-       udelay(10);
-
-       reg_mcr = flexcan_read(&regs->mcr);
-       if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
-               netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n",
-                          reg_mcr);
-               err = -ENODEV;
-               goto out;
-       }
+       err = flexcan_chip_softreset(priv);
+       if (err)
+               goto out_chip_disable;
 
        flexcan_set_bittiming(dev);
 
@@ -788,16 +870,14 @@ static int flexcan_chip_start(struct net_device *dev)
        if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
                flexcan_write(0x0, &regs->rxfgmask);
 
-       if (priv->reg_xceiver)  {
-               err = regulator_enable(priv->reg_xceiver);
-               if (err)
-                       goto out;
-       }
+       err = flexcan_transceiver_enable(priv);
+       if (err)
+               goto out_chip_disable;
 
        /* synchronize with the can bus */
-       reg_mcr = flexcan_read(&regs->mcr);
-       reg_mcr &= ~FLEXCAN_MCR_HALT;
-       flexcan_write(reg_mcr, &regs->mcr);
+       err = flexcan_chip_unfreeze(priv);
+       if (err)
+               goto out_transceiver_disable;
 
        priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
@@ -810,7 +890,9 @@ static int flexcan_chip_start(struct net_device *dev)
 
        return 0;
 
- out:
+ out_transceiver_disable:
+       flexcan_transceiver_disable(priv);
+ out_chip_disable:
        flexcan_chip_disable(priv);
        return err;
 }
@@ -825,18 +907,17 @@ static void flexcan_chip_stop(struct net_device *dev)
 {
        struct flexcan_priv *priv = netdev_priv(dev);
        struct flexcan_regs __iomem *regs = priv->base;
-       u32 reg;
+
+       /* freeze + disable module */
+       flexcan_chip_freeze(priv);
+       flexcan_chip_disable(priv);
 
        /* Disable all interrupts */
        flexcan_write(0, &regs->imask1);
+       flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
+                     &regs->ctrl);
 
-       /* Disable + halt module */
-       reg = flexcan_read(&regs->mcr);
-       reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
-       flexcan_write(reg, &regs->mcr);
-
-       if (priv->reg_xceiver)
-               regulator_disable(priv->reg_xceiver);
+       flexcan_transceiver_disable(priv);
        priv->can.state = CAN_STATE_STOPPED;
 
        return;
@@ -866,7 +947,7 @@ static int flexcan_open(struct net_device *dev)
        /* start chip and queuing */
        err = flexcan_chip_start(dev);
        if (err)
-               goto out_close;
+               goto out_free_irq;
 
        can_led_event(dev, CAN_LED_EVENT_OPEN);
 
@@ -875,6 +956,8 @@ static int flexcan_open(struct net_device *dev)
 
        return 0;
 
+ out_free_irq:
+       free_irq(dev->irq, dev);
  out_close:
        close_candev(dev);
  out_disable_per:
@@ -945,12 +1028,16 @@ static int register_flexcandev(struct net_device *dev)
                goto out_disable_ipg;
 
        /* select "bus clock", chip must be disabled */
-       flexcan_chip_disable(priv);
+       err = flexcan_chip_disable(priv);
+       if (err)
+               goto out_disable_per;
        reg = flexcan_read(&regs->ctrl);
        reg |= FLEXCAN_CTRL_CLK_SRC;
        flexcan_write(reg, &regs->ctrl);
 
-       flexcan_chip_enable(priv);
+       err = flexcan_chip_enable(priv);
+       if (err)
+               goto out_chip_disable;
 
        /* set freeze, halt and activate FIFO, restrict register access */
        reg = flexcan_read(&regs->mcr);
@@ -967,14 +1054,15 @@ static int register_flexcandev(struct net_device *dev)
        if (!(reg & FLEXCAN_MCR_FEN)) {
                netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
                err = -ENODEV;
-               goto out_disable_per;
+               goto out_chip_disable;
        }
 
        err = register_candev(dev);
 
- out_disable_per:
        /* disable core and turn off clocks */
+ out_chip_disable:
        flexcan_chip_disable(priv);
+ out_disable_per:
        clk_disable_unprepare(priv->clk_per);
  out_disable_ipg:
        clk_disable_unprepare(priv->clk_ipg);
@@ -1104,9 +1192,10 @@ static int flexcan_probe(struct platform_device *pdev)
 static int flexcan_remove(struct platform_device *pdev)
 {
        struct net_device *dev = platform_get_drvdata(pdev);
+       struct flexcan_priv *priv = netdev_priv(dev);
 
        unregister_flexcandev(dev);
-
+       netif_napi_del(&priv->napi);
        free_candev(dev);
 
        return 0;
@@ -1117,8 +1206,11 @@ static int flexcan_suspend(struct device *device)
 {
        struct net_device *dev = dev_get_drvdata(device);
        struct flexcan_priv *priv = netdev_priv(dev);
+       int err;
 
-       flexcan_chip_disable(priv);
+       err = flexcan_chip_disable(priv);
+       if (err)
+               return err;
 
        if (netif_running(dev)) {
                netif_stop_queue(dev);
@@ -1139,9 +1231,7 @@ static int flexcan_resume(struct device *device)
                netif_device_attach(dev);
                netif_start_queue(dev);
        }
-       flexcan_chip_enable(priv);
-
-       return 0;
+       return flexcan_chip_enable(priv);
 }
 #endif /* CONFIG_PM_SLEEP */
 
index 8d09615da585671a4d0fa9d00dc9cc6ba80f6517..05529e273050e3718c0ca1e105ce05174fdfe618 100644 (file)
@@ -350,11 +350,13 @@ struct be_drv_stats {
        u32 roce_drops_crc;
 };
 
+/* A vlan-id of 0xFFFF must be used to clear transparent vlan-tagging */
+#define BE_RESET_VLAN_TAG_ID   0xFFFF
+
 struct be_vf_cfg {
        unsigned char mac_addr[ETH_ALEN];
        int if_handle;
        int pmac_id;
-       u16 def_vid;
        u16 vlan_tag;
        u32 tx_rate;
 };
index 04ac9c6a0d3972d4e18ee91a8ce3a8bf2e141cd7..36c80612e21a3ebe6ee52447e9075dc4022f005e 100644 (file)
@@ -913,24 +913,14 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter,
        return BE3_chip(adapter) && be_ipv6_exthdr_check(skb);
 }
 
-static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
-                                          struct sk_buff *skb,
-                                          bool *skip_hw_vlan)
+static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
+                                                 struct sk_buff *skb,
+                                                 bool *skip_hw_vlan)
 {
        struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
        unsigned int eth_hdr_len;
        struct iphdr *ip;
 
-       /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or less
-        * may cause a transmit stall on that port. So the work-around is to
-        * pad short packets (<= 32 bytes) to a 36-byte length.
-        */
-       if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
-               if (skb_padto(skb, 36))
-                       goto tx_drop;
-               skb->len = 36;
-       }
-
        /* For padded packets, BE HW modifies tot_len field in IP header
         * incorrecly when VLAN tag is inserted by HW.
         * For padded packets, Lancer computes incorrect checksum.
@@ -959,7 +949,7 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
            vlan_tx_tag_present(skb)) {
                skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);
                if (unlikely(!skb))
-                       goto tx_drop;
+                       goto err;
        }
 
        /* HW may lockup when VLAN HW tagging is requested on
@@ -981,15 +971,39 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
            be_vlan_tag_tx_chk(adapter, skb)) {
                skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan);
                if (unlikely(!skb))
-                       goto tx_drop;
+                       goto err;
        }
 
        return skb;
 tx_drop:
        dev_kfree_skb_any(skb);
+err:
        return NULL;
 }
 
+static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
+                                          struct sk_buff *skb,
+                                          bool *skip_hw_vlan)
+{
+       /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or
+        * less may cause a transmit stall on that port. So the work-around is
+        * to pad short packets (<= 32 bytes) to a 36-byte length.
+        */
+       if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
+               if (skb_padto(skb, 36))
+                       return NULL;
+               skb->len = 36;
+       }
+
+       if (BEx_chip(adapter) || lancer_chip(adapter)) {
+               skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan);
+               if (!skb)
+                       return NULL;
+       }
+
+       return skb;
+}
+
 static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
@@ -1157,6 +1171,14 @@ ret:
        return status;
 }
 
+static void be_clear_promisc(struct be_adapter *adapter)
+{
+       adapter->promiscuous = false;
+       adapter->flags &= ~BE_FLAGS_VLAN_PROMISC;
+
+       be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
+}
+
 static void be_set_rx_mode(struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
@@ -1170,9 +1192,7 @@ static void be_set_rx_mode(struct net_device *netdev)
 
        /* BE was previously in promiscuous mode; disable it */
        if (adapter->promiscuous) {
-               adapter->promiscuous = false;
-               be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
-
+               be_clear_promisc(adapter);
                if (adapter->vlans_added)
                        be_vid_config(adapter);
        }
@@ -1287,24 +1307,20 @@ static int be_set_vf_vlan(struct net_device *netdev,
 
        if (vlan || qos) {
                vlan |= qos << VLAN_PRIO_SHIFT;
-               if (vf_cfg->vlan_tag != vlan) {
-                       /* If this is new value, program it. Else skip. */
-                       vf_cfg->vlan_tag = vlan;
+               if (vf_cfg->vlan_tag != vlan)
                        status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
                                                       vf_cfg->if_handle, 0);
-               }
        } else {
                /* Reset Transparent Vlan Tagging. */
-               vf_cfg->vlan_tag = 0;
-               vlan = vf_cfg->def_vid;
-               status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
-                                              vf_cfg->if_handle, 0);
+               status = be_cmd_set_hsw_config(adapter, BE_RESET_VLAN_TAG_ID,
+                                              vf + 1, vf_cfg->if_handle, 0);
        }
 
-
-       if (status)
+       if (!status)
+               vf_cfg->vlan_tag = vlan;
+       else
                dev_info(&adapter->pdev->dev,
-                               "VLAN %d config on VF %d failed\n", vlan, vf);
+                        "VLAN %d config on VF %d failed\n", vlan, vf);
        return status;
 }
 
@@ -3013,11 +3029,11 @@ static int be_vf_setup_init(struct be_adapter *adapter)
 
 static int be_vf_setup(struct be_adapter *adapter)
 {
+       struct device *dev = &adapter->pdev->dev;
        struct be_vf_cfg *vf_cfg;
-       u16 def_vlan, lnk_speed;
        int status, old_vfs, vf;
-       struct device *dev = &adapter->pdev->dev;
        u32 privileges;
+       u16 lnk_speed;
 
        old_vfs = pci_num_vf(adapter->pdev);
        if (old_vfs) {
@@ -3084,12 +3100,6 @@ static int be_vf_setup(struct be_adapter *adapter)
                if (!status)
                        vf_cfg->tx_rate = lnk_speed;
 
-               status = be_cmd_get_hsw_config(adapter, &def_vlan,
-                                              vf + 1, vf_cfg->if_handle, NULL);
-               if (status)
-                       goto err;
-               vf_cfg->def_vid = def_vlan;
-
                if (!old_vfs)
                        be_cmd_enable_vf(adapter, vf + 1);
        }
index 77f1bce432d2998b3d14b5b6f56c694a877a1ae6..7d4f54912bad526077b145109dc003e532b88d70 100644 (file)
@@ -807,7 +807,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio,
            !type->tc_param_valid)
                return;
 
-       if (tc < 0 || (tc > QLC_DCB_MAX_TC))
+       if (tc < 0 || (tc >= QLC_DCB_MAX_TC))
                return;
 
        tc_cfg = &type->tc_cfg[tc];
@@ -843,7 +843,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid,
            !type->tc_param_valid)
                return;
 
-       if (pgid < 0 || pgid > QLC_DCB_MAX_PG)
+       if (pgid < 0 || pgid >= QLC_DCB_MAX_PG)
                return;
 
        pgcfg = &type->pg_cfg[pgid];
index 651087b5c8da57c9f9226925ef33f61372986531..ffd4d12acf6dc59e162a7894b88da1eecf933e69 100644 (file)
@@ -1164,11 +1164,17 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
 
 static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv)
 {
+       u32 slave_port;
+
+       slave_port = cpsw_get_slave_port(priv, slave->slave_num);
+
        if (!slave->phy)
                return;
        phy_stop(slave->phy);
        phy_disconnect(slave->phy);
        slave->phy = NULL;
+       cpsw_ale_control_set(priv->ale, slave_port,
+                            ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
 }
 
 static int cpsw_ndo_open(struct net_device *ndev)
index 8be757cca2ec444171982cb8c33ef58ab27310be..081e81fd017fa53f7a6ed3afd341601b43377531 100644 (file)
@@ -121,13 +121,9 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
        if (!ro->recv_own_msgs && oskb->sk == sk)
                return;
 
-       /* do not pass frames with DLC > 8 to a legacy socket */
-       if (!ro->fd_frames) {
-               struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;
-
-               if (unlikely(cfd->len > CAN_MAX_DLEN))
-                       return;
-       }
+       /* do not pass non-CAN2.0 frames to a legacy socket */
+       if (!ro->fd_frames && oskb->len != CAN_MTU)
+               return;
 
        /* clone the given skb to be able to enqueue it into the rcv queue */
        skb = skb_clone(oskb, GFP_ATOMIC);
@@ -738,9 +734,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
                       struct msghdr *msg, size_t size, int flags)
 {
        struct sock *sk = sock->sk;
-       struct raw_sock *ro = raw_sk(sk);
        struct sk_buff *skb;
-       int rxmtu;
        int err = 0;
        int noblock;
 
@@ -751,20 +745,10 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                return err;
 
-       /*
-        * when serving a legacy socket the DLC <= 8 is already checked inside
-        * raw_rcv(). Now check if we need to pass a canfd_frame to a legacy
-        * socket and cut the possible CANFD_MTU/CAN_MTU length to CAN_MTU
-        */
-       if (!ro->fd_frames)
-               rxmtu = CAN_MTU;
-       else
-               rxmtu = skb->len;
-
-       if (size < rxmtu)
+       if (size < skb->len)
                msg->msg_flags |= MSG_TRUNC;
        else
-               size = rxmtu;
+               size = skb->len;
 
        err = memcpy_toiovec(msg->msg_iov, skb->data, size);
        if (err < 0) {
index 327060c6c874b337cf6edf9bd37c5b8181c0beee..7ae0d7f6dbd0bff10516e9415050d7aa41a07da0 100644 (file)
@@ -297,7 +297,7 @@ static bool seq_nr_after(u16 a, u16 b)
 
 void hsr_register_frame_in(struct node_entry *node, enum hsr_dev_idx dev_idx)
 {
-       if ((dev_idx < 0) || (dev_idx >= HSR_MAX_DEV)) {
+       if ((dev_idx < 0) || (dev_idx >= HSR_MAX_SLAVE)) {
                WARN_ONCE(1, "%s: Invalid dev_idx (%d)\n", __func__, dev_idx);
                return;
        }
index 8d69626f2206900dfbb336063034875743a3936e..6f847dd56dbc7fb53a7f3dc9dfc8330e507ec0e9 100644 (file)
@@ -108,7 +108,6 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
        nf_reset(skb);
        secpath_reset(skb);
        skb_clear_hash_if_not_l4(skb);
-       skb_dst_drop(skb);
        skb->vlan_tci = 0;
        skb_set_queue_mapping(skb, 0);
        skb->pkt_type = PACKET_HOST;
index 227cba79fa6b1f490f27a3aaf013070fbf9c8015..eeaac399420de043bb466603fcb03ff83076438a 100644 (file)
@@ -1945,8 +1945,9 @@ void tcp_enter_loss(struct sock *sk, int how)
                if (skb == tcp_send_head(sk))
                        break;
 
-               if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS)
+               if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
                        tp->undo_marker = 0;
+
                TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED;
                if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || how) {
                        TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
index d718482fd11c1073b42140a8dddfbb26624d6bfd..f0eb4e337ec88fc631a30adc0d168817e5812ced 100644 (file)
@@ -2337,6 +2337,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
        unsigned int cur_mss;
+       int err;
 
        /* Inconslusive MTU probe */
        if (icsk->icsk_mtup.probe_size) {
@@ -2400,11 +2401,15 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
                     skb_headroom(skb) >= 0xFFFF)) {
                struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
                                                   GFP_ATOMIC);
-               return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
-                             -ENOBUFS;
+               err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
+                            -ENOBUFS;
        } else {
-               return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+               err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
        }
+
+       if (likely(!err))
+               TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS;
+       return err;
 }
 
 int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
index 591b44d3b7de6bb39faa994cddc72851422ec08f..ae65b6b5973a9bceca7825037317f9fc9f39e2db 100644 (file)
@@ -758,6 +758,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net,
                struct sctp_chunk auth;
                sctp_ierror_t ret;
 
+               /* Make sure that we and the peer are AUTH capable */
+               if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) {
+                       kfree_skb(chunk->auth_chunk);
+                       sctp_association_free(new_asoc);
+                       return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
+               }
+
                /* set-up our fake chunk so that we can process it */
                auth.skb = chunk->auth_chunk;
                auth.asoc = chunk->asoc;