Merge branch 'master' of git://1984.lsi.us.es/nf
authorDavid S. Miller <davem@davemloft.net>
Thu, 13 Sep 2012 17:53:06 +0000 (13:53 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 13 Sep 2012 17:53:06 +0000 (13:53 -0400)
Pablo Neira Ayuso say:

====================
The following patchset contains four updates for your net tree, they are:

* Fix crash on timewait sockets, since the TCP early demux was added,
  in nfnetlink_log, from Eric Dumazet.

* Fix broken syslog log-level for xt_LOG and ebt_log since printk format was
  converted from <.> to a 2 bytes pattern using ASCII SOH, from Joe Perches.

* Two security fixes for the TCP connection tracking targeting off-path attacks,
  from Jozsef Kadlecsik. The problem was discovered by Jan Wrobel and it is
  documented in: http://mixedbit.org/reflection_scan/reflection_scan.pdf.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
66 files changed:
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/net/can/mcp251x.c
drivers/net/ethernet/i825xx/znet.c
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/seeq/sgiseeq.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/sierra_net.c
drivers/net/usb/usbnet.c
drivers/net/wan/ixp4xx_hss.c
drivers/net/wireless/ath/ath9k/ar9003_paprd.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/brcm80211/brcmfmac/usb.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.h
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2500usb.h
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.h
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rt2x00/rt73usb.h
include/linux/mlx4/device.h
include/net/bluetooth/smp.h
include/net/xfrm.h
net/bluetooth/hci_conn.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/smp.c
net/caif/cfsrvl.c
net/core/dev.c
net/core/sock.c
net/ipv4/udp.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_eth.c
net/mac80211/cfg.c
net/mac80211/mlme.c
net/netrom/af_netrom.c
net/openvswitch/actions.c
net/openvswitch/datapath.c
net/openvswitch/flow.h
net/sched/sch_cbq.c
net/sched/sch_fq_codel.c
net/sctp/output.c
net/wireless/nl80211.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_replay.c

index 11f36e5..fc2de55 100644 (file)
@@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = {
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C) },
+       { USB_DEVICE(0x0489, 0xE036) },
 
        { }     /* Terminating entry */
 };
@@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
 
        { }     /* Terminating entry */
 };
index cef3bac..654e248 100644 (file)
@@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = {
        /* Generic Bluetooth USB device */
        { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
+       /* Apple-specific (Broadcom) devices */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },
+
        /* Broadcom SoftSailing reporting vendor specific */
        { USB_DEVICE(0x0a5c, 0x21e1) },
 
@@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = {
 
        /* Broadcom BCM20702A0 */
        { USB_DEVICE(0x0489, 0xe042) },
-       { USB_DEVICE(0x0a5c, 0x21e3) },
-       { USB_DEVICE(0x0a5c, 0x21e6) },
-       { USB_DEVICE(0x0a5c, 0x21e8) },
-       { USB_DEVICE(0x0a5c, 0x21f3) },
-       { USB_DEVICE(0x0a5c, 0x21f4) },
        { USB_DEVICE(0x413c, 0x8197) },
 
        /* Foxconn - Hon Hai */
        { USB_DEVICE(0x0489, 0xe033) },
 
+       /*Broadcom devices with vendor specific id */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
+
        { }     /* Terminating entry */
 };
 
@@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = {
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
 
        /* Broadcom BCM2035 */
        { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
index 5e402cf..f027942 100644 (file)
@@ -5059,6 +5059,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
                                printk(KERN_INFO
                                       "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
                                       E1_cnt + 1, pt);
+                               kfree(hc);
                                return -EINVAL;
                        }
                        maskcheck |= hc->bmask[pt];
@@ -5086,6 +5087,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
        if ((poll >> 1) > sizeof(hc->silence_data)) {
                printk(KERN_ERR "HFCMULTI error: silence_data too small, "
                       "please fix\n");
+               kfree(hc);
                return -EINVAL;
        }
        for (i = 0; i < (poll >> 1); i++)
index a580db2..26e7129 100644 (file)
 #define INSTRUCTION_LOAD_TXB(n)        (0x40 + 2 * (n))
 #define INSTRUCTION_READ_RXB(n)        (((n) == 0) ? 0x90 : 0x94)
 #define INSTRUCTION_RESET      0xC0
+#define RTS_TXB0               0x01
+#define RTS_TXB1               0x02
+#define RTS_TXB2               0x04
+#define INSTRUCTION_RTS(n)     (0x80 | ((n) & 0x07))
+
 
 /* MPC251x registers */
 #define CANSTAT              0x0e
@@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf,
 static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
                          int tx_buf_idx)
 {
+       struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
        u32 sid, eid, exide, rtr;
        u8 buf[SPI_TRANSFER_BUF_LEN];
 
@@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame,
        buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc;
        memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc);
        mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx);
-       mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ);
+
+       /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */
+       priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx);
+       mcp251x_spi_trans(priv->spi, 1);
 }
 
 static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf,
index bd1f1ef..ba4e0ce 100644 (file)
@@ -139,8 +139,11 @@ struct znet_private {
 /* Only one can be built-in;-> */
 static struct net_device *znet_dev;
 
+#define NETIDBLK_MAGIC         "NETIDBLK"
+#define NETIDBLK_MAGIC_SIZE    8
+
 struct netidblk {
-       char magic[8];          /* The magic number (string) "NETIDBLK" */
+       char magic[NETIDBLK_MAGIC_SIZE];        /* The magic number (string) "NETIDBLK" */
        unsigned char netid[8]; /* The physical station address */
        char nettype, globalopt;
        char vendor[8];         /* The machine vendor and product name. */
@@ -373,14 +376,16 @@ static int __init znet_probe (void)
        struct znet_private *znet;
        struct net_device *dev;
        char *p;
+       char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE);
        int err = -ENOMEM;
 
        /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
-       for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++)
-               if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
+       for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++)
+               if (*p == 'N' &&
+                   strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0)
                        break;
 
-       if (p >= (char *)phys_to_virt(0x100000)) {
+       if (p > plast) {
                if (znet_debug > 1)
                        printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
                return -ENODEV;
index 9010cea..b68d28a 100644 (file)
@@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
        }
 
        if (adapter->rx_queue.queue_addr != NULL) {
-               if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) {
-                       dma_unmap_single(dev,
-                                       adapter->rx_queue.queue_dma,
-                                       adapter->rx_queue.queue_len,
-                                       DMA_BIDIRECTIONAL);
-                       adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
-               }
-               kfree(adapter->rx_queue.queue_addr);
+               dma_free_coherent(dev, adapter->rx_queue.queue_len,
+                                 adapter->rx_queue.queue_addr,
+                                 adapter->rx_queue.queue_dma);
                adapter->rx_queue.queue_addr = NULL;
        }
 
@@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev)
                goto err_out;
        }
 
+       dev = &adapter->vdev->dev;
+
        adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) *
                                                rxq_entries;
-       adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len,
-                                               GFP_KERNEL);
+       adapter->rx_queue.queue_addr =
+           dma_alloc_coherent(dev, adapter->rx_queue.queue_len,
+                              &adapter->rx_queue.queue_dma, GFP_KERNEL);
 
        if (!adapter->rx_queue.queue_addr) {
                netdev_err(netdev, "unable to allocate rx queue pages\n");
@@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev)
                goto err_out;
        }
 
-       dev = &adapter->vdev->dev;
-
        adapter->buffer_list_dma = dma_map_single(dev,
                        adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL);
        adapter->filter_list_dma = dma_map_single(dev,
                        adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL);
-       adapter->rx_queue.queue_dma = dma_map_single(dev,
-                       adapter->rx_queue.queue_addr,
-                       adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL);
 
        if ((dma_mapping_error(dev, adapter->buffer_list_dma)) ||
-           (dma_mapping_error(dev, adapter->filter_list_dma)) ||
-           (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) {
+           (dma_mapping_error(dev, adapter->filter_list_dma))) {
                netdev_err(netdev, "unable to map filter or buffer list "
                           "pages\n");
                rc = -ENOMEM;
index 827b72d..2f816c6 100644 (file)
@@ -1234,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                                mlx4_info(dev, "non-primary physical function, skipping.\n");
                        else
                                mlx4_err(dev, "QUERY_FW command failed, aborting.\n");
-                       goto unmap_bf;
+                       return err;
                }
 
                err = mlx4_load_fw(dev);
                if (err) {
                        mlx4_err(dev, "Failed to start FW, aborting.\n");
-                       goto unmap_bf;
+                       return err;
                }
 
                mlx4_cfg.log_pg_sz_m = 1;
@@ -1304,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                err = mlx4_init_slave(dev);
                if (err) {
                        mlx4_err(dev, "Failed to initialize slave\n");
-                       goto unmap_bf;
+                       return err;
                }
 
                err = mlx4_slave_cap(dev);
@@ -1324,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
        err = mlx4_QUERY_ADAPTER(dev, &adapter);
        if (err) {
                mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n");
-               goto err_close;
+               goto unmap_bf;
        }
 
        priv->eq_table.inta_pin = adapter.inta_pin;
@@ -1332,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
 
        return 0;
 
+unmap_bf:
+       unmap_bf_area(dev);
+
 err_close:
        mlx4_close_hca(dev);
 
@@ -1344,8 +1347,6 @@ err_stop_fw:
                mlx4_UNMAP_FA(dev);
                mlx4_free_icm(dev, priv->fw.fw_icm, 0);
        }
-unmap_bf:
-       unmap_bf_area(dev);
        return err;
 }
 
@@ -1996,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
 slave_start:
-       if (mlx4_cmd_init(dev)) {
+       err = mlx4_cmd_init(dev);
+       if (err) {
                mlx4_err(dev, "Failed to init command interface, aborting.\n");
                goto err_sriov;
        }
index a018ea2..e151c21 100644 (file)
@@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
        return err;
 }
 
-static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num,
+static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port,
                                              enum mlx4_steer_type steer,
                                              u32 qpn)
 {
-       struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num];
+       struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1];
        struct mlx4_promisc_qp *pqp;
 
        list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) {
@@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port,
        /* If the given qpn is also a promisc qp,
         * it should be inserted to duplicates list
         */
-       pqp = get_promisc_qp(dev, 0, steer, qpn);
+       pqp = get_promisc_qp(dev, port, steer, qpn);
        if (pqp) {
                dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
                if (!dqp) {
@@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port,
 
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
-       pqp = get_promisc_qp(dev, 0, steer, qpn);
+       pqp = get_promisc_qp(dev, port, steer, qpn);
        if (!pqp)
                return 0; /* nothing to do */
 
@@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port,
        s_steer = &mlx4_priv(dev)->steer[port - 1];
 
        /* if qp is not promisc, it cannot be duplicated */
-       if (!get_promisc_qp(dev, 0, steer, qpn))
+       if (!get_promisc_qp(dev, port, steer, qpn))
                return false;
 
        /* The qp is promisc qp so it is a duplicate on this index
@@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port,
        members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
        for (i = 0;  i < members_count; i++) {
                qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK;
-               if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) {
+               if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) {
                        /* the qp is not promisc, the entry can't be removed */
                        goto out;
                }
@@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
 
        mutex_lock(&priv->mcg_table.mutex);
 
-       if (get_promisc_qp(dev, 0, steer, qpn)) {
+       if (get_promisc_qp(dev, port, steer, qpn)) {
                err = 0;  /* Noting to do, already exists */
                goto out_mutex;
        }
@@ -503,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port,
        s_steer = &mlx4_priv(dev)->steer[port - 1];
        mutex_lock(&priv->mcg_table.mutex);
 
-       pqp = get_promisc_qp(dev, 0, steer, qpn);
+       pqp = get_promisc_qp(dev, port, steer, qpn);
        if (unlikely(!pqp)) {
                mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn);
                /* nothing to do */
@@ -650,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port,
        return err;
 }
 
-struct mlx4_net_trans_rule_hw_ctrl {
-       __be32 ctrl;
-       __be32 vf_vep_port;
-       __be32 qpn;
-       __be32 reserved;
-};
-
 static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
                                  struct mlx4_net_trans_rule_hw_ctrl *hw)
 {
@@ -680,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl,
        hw->qpn = cpu_to_be32(ctrl->qpn);
 }
 
-struct mlx4_net_trans_rule_hw_ib {
-       u8      size;
-       u8      rsvd1;
-       __be16  id;
-       u32     rsvd2;
-       __be32  qpn;
-       __be32  qpn_mask;
-       u8      dst_gid[16];
-       u8      dst_gid_msk[16];
-} __packed;
-
-struct mlx4_net_trans_rule_hw_eth {
-       u8      size;
-       u8      rsvd;
-       __be16  id;
-       u8      rsvd1[6];
-       u8      dst_mac[6];
-       u16     rsvd2;
-       u8      dst_mac_msk[6];
-       u16     rsvd3;
-       u8      src_mac[6];
-       u16     rsvd4;
-       u8      src_mac_msk[6];
-       u8      rsvd5;
-       u8      ether_type_enable;
-       __be16  ether_type;
-       __be16  vlan_id_msk;
-       __be16  vlan_id;
-} __packed;
-
-struct mlx4_net_trans_rule_hw_tcp_udp {
-       u8      size;
-       u8      rsvd;
-       __be16  id;
-       __be16  rsvd1[3];
-       __be16  dst_port;
-       __be16  rsvd2;
-       __be16  dst_port_msk;
-       __be16  rsvd3;
-       __be16  src_port;
-       __be16  rsvd4;
-       __be16  src_port_msk;
-} __packed;
-
-struct mlx4_net_trans_rule_hw_ipv4 {
-       u8      size;
-       u8      rsvd;
-       __be16  id;
-       __be32  rsvd1;
-       __be32  dst_ip;
-       __be32  dst_ip_msk;
-       __be32  src_ip;
-       __be32  src_ip_msk;
-} __packed;
-
-struct _rule_hw {
-       union {
-               struct {
-                       u8 size;
-                       u8 rsvd;
-                       __be16 id;
-               };
-               struct mlx4_net_trans_rule_hw_eth eth;
-               struct mlx4_net_trans_rule_hw_ib ib;
-               struct mlx4_net_trans_rule_hw_ipv4 ipv4;
-               struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp;
-       };
+const u16 __sw_id_hw[] = {
+       [MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
+       [MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
+       [MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
+       [MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
+       [MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
+       [MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006
 };
 
 static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec,
                            struct _rule_hw *rule_hw)
 {
-       static const u16 __sw_id_hw[] = {
-               [MLX4_NET_TRANS_RULE_ID_ETH]     = 0xE001,
-               [MLX4_NET_TRANS_RULE_ID_IB]      = 0xE005,
-               [MLX4_NET_TRANS_RULE_ID_IPV6]    = 0xE003,
-               [MLX4_NET_TRANS_RULE_ID_IPV4]    = 0xE002,
-               [MLX4_NET_TRANS_RULE_ID_TCP]     = 0xE004,
-               [MLX4_NET_TRANS_RULE_ID_UDP]     = 0xE006
-       };
-
        static const size_t __rule_hw_sz[] = {
                [MLX4_NET_TRANS_RULE_ID_ETH] =
                        sizeof(struct mlx4_net_trans_rule_hw_eth),
index 4d9df8f..dba69d9 100644 (file)
@@ -690,6 +690,82 @@ struct mlx4_steer {
        struct list_head steer_entries[MLX4_NUM_STEERS];
 };
 
+struct mlx4_net_trans_rule_hw_ctrl {
+       __be32 ctrl;
+       __be32 vf_vep_port;
+       __be32 qpn;
+       __be32 reserved;
+};
+
+struct mlx4_net_trans_rule_hw_ib {
+       u8 size;
+       u8 rsvd1;
+       __be16 id;
+       u32 rsvd2;
+       __be32 qpn;
+       __be32 qpn_mask;
+       u8 dst_gid[16];
+       u8 dst_gid_msk[16];
+} __packed;
+
+struct mlx4_net_trans_rule_hw_eth {
+       u8      size;
+       u8      rsvd;
+       __be16  id;
+       u8      rsvd1[6];
+       u8      dst_mac[6];
+       u16     rsvd2;
+       u8      dst_mac_msk[6];
+       u16     rsvd3;
+       u8      src_mac[6];
+       u16     rsvd4;
+       u8      src_mac_msk[6];
+       u8      rsvd5;
+       u8      ether_type_enable;
+       __be16  ether_type;
+       __be16  vlan_id_msk;
+       __be16  vlan_id;
+} __packed;
+
+struct mlx4_net_trans_rule_hw_tcp_udp {
+       u8      size;
+       u8      rsvd;
+       __be16  id;
+       __be16  rsvd1[3];
+       __be16  dst_port;
+       __be16  rsvd2;
+       __be16  dst_port_msk;
+       __be16  rsvd3;
+       __be16  src_port;
+       __be16  rsvd4;
+       __be16  src_port_msk;
+} __packed;
+
+struct mlx4_net_trans_rule_hw_ipv4 {
+       u8      size;
+       u8      rsvd;
+       __be16  id;
+       __be32  rsvd1;
+       __be32  dst_ip;
+       __be32  dst_ip_msk;
+       __be32  src_ip;
+       __be32  src_ip_msk;
+} __packed;
+
+struct _rule_hw {
+       union {
+               struct {
+                       u8 size;
+                       u8 rsvd;
+                       __be16 id;
+               };
+               struct mlx4_net_trans_rule_hw_eth eth;
+               struct mlx4_net_trans_rule_hw_ib ib;
+               struct mlx4_net_trans_rule_hw_ipv4 ipv4;
+               struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp;
+       };
+};
+
 struct mlx4_priv {
        struct mlx4_dev         dev;
 
index 94ceddd..293c9e8 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/mlx4/cmd.h>
 #include <linux/mlx4/qp.h>
 #include <linux/if_ether.h>
+#include <linux/etherdevice.h>
 
 #include "mlx4.h"
 #include "fw.h"
@@ -2776,18 +2777,133 @@ ex_put:
        return err;
 }
 
+/*
+ * MAC validation for Flow Steering rules.
+ * VF can attach rules only with a mac address which is assigned to it.
+ */
+static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header,
+                                  struct list_head *rlist)
+{
+       struct mac_res *res, *tmp;
+       __be64 be_mac;
+
+       /* make sure it isn't multicast or broadcast mac*/
+       if (!is_multicast_ether_addr(eth_header->eth.dst_mac) &&
+           !is_broadcast_ether_addr(eth_header->eth.dst_mac)) {
+               list_for_each_entry_safe(res, tmp, rlist, list) {
+                       be_mac = cpu_to_be64(res->mac << 16);
+                       if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN))
+                               return 0;
+               }
+               pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n",
+                      eth_header->eth.dst_mac, slave);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * In case of missing eth header, append eth header with a MAC address
+ * assigned to the VF.
+ */
+static int add_eth_header(struct mlx4_dev *dev, int slave,
+                         struct mlx4_cmd_mailbox *inbox,
+                         struct list_head *rlist, int header_id)
+{
+       struct mac_res *res, *tmp;
+       u8 port;
+       struct mlx4_net_trans_rule_hw_ctrl *ctrl;
+       struct mlx4_net_trans_rule_hw_eth *eth_header;
+       struct mlx4_net_trans_rule_hw_ipv4 *ip_header;
+       struct mlx4_net_trans_rule_hw_tcp_udp *l4_header;
+       __be64 be_mac = 0;
+       __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16);
+
+       ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
+       port = be32_to_cpu(ctrl->vf_vep_port) & 0xff;
+       eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1);
+
+       /* Clear a space in the inbox for eth header */
+       switch (header_id) {
+       case MLX4_NET_TRANS_RULE_ID_IPV4:
+               ip_header =
+                       (struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1);
+               memmove(ip_header, eth_header,
+                       sizeof(*ip_header) + sizeof(*l4_header));
+               break;
+       case MLX4_NET_TRANS_RULE_ID_TCP:
+       case MLX4_NET_TRANS_RULE_ID_UDP:
+               l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *)
+                           (eth_header + 1);
+               memmove(l4_header, eth_header, sizeof(*l4_header));
+               break;
+       default:
+               return -EINVAL;
+       }
+       list_for_each_entry_safe(res, tmp, rlist, list) {
+               if (port == res->port) {
+                       be_mac = cpu_to_be64(res->mac << 16);
+                       break;
+               }
+       }
+       if (!be_mac) {
+               pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n",
+                      port);
+               return -EINVAL;
+       }
+
+       memset(eth_header, 0, sizeof(*eth_header));
+       eth_header->size = sizeof(*eth_header) >> 2;
+       eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]);
+       memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN);
+       memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN);
+
+       return 0;
+
+}
+
 int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
                                         struct mlx4_vhcr *vhcr,
                                         struct mlx4_cmd_mailbox *inbox,
                                         struct mlx4_cmd_mailbox *outbox,
                                         struct mlx4_cmd_info *cmd)
 {
+
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
+       struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];
        int err;
+       struct mlx4_net_trans_rule_hw_ctrl *ctrl;
+       struct _rule_hw  *rule_header;
+       int header_id;
 
        if (dev->caps.steering_mode !=
            MLX4_STEERING_MODE_DEVICE_MANAGED)
                return -EOPNOTSUPP;
 
+       ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
+       rule_header = (struct _rule_hw *)(ctrl + 1);
+       header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id));
+
+       switch (header_id) {
+       case MLX4_NET_TRANS_RULE_ID_ETH:
+               if (validate_eth_header_mac(slave, rule_header, rlist))
+                       return -EINVAL;
+               break;
+       case MLX4_NET_TRANS_RULE_ID_IPV4:
+       case MLX4_NET_TRANS_RULE_ID_TCP:
+       case MLX4_NET_TRANS_RULE_ID_UDP:
+               pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n");
+               if (add_eth_header(dev, slave, inbox, rlist, header_id))
+                       return -EINVAL;
+               vhcr->in_modifier +=
+                       sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2;
+               break;
+       default:
+               pr_err("Corrupted mailbox.\n");
+               return -EINVAL;
+       }
+
        err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
                           vhcr->in_modifier, 0,
                           MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
index bb8c822..4d15bf4 100644 (file)
@@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev)
        sp->srings = sr;
        sp->rx_desc = sp->srings->rxvector;
        sp->tx_desc = sp->srings->txvector;
+       spin_lock_init(&sp->tx_lock);
 
        /* A couple calculations now, saves many cycles later. */
        setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS);
index adfab3f..17b8f3e 100644 (file)
@@ -398,7 +398,6 @@ static const struct usb_device_id products[] = {
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
        {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)},    /* HP un2400 Gobi Modem Device */
-       {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)},    /* HP un2430 Mobile Broadband Module */
        {QMI_GOBI1K_DEVICE(0x04da, 0x250d)},    /* Panasonic Gobi Modem device */
        {QMI_GOBI1K_DEVICE(0x413c, 0x8172)},    /* Dell Gobi Modem device */
        {QMI_GOBI1K_DEVICE(0x1410, 0xa001)},    /* Novatel Gobi Modem device */
@@ -440,6 +439,7 @@ static const struct usb_device_id products[] = {
        {QMI_GOBI_DEVICE(0x16d8, 0x8002)},      /* CMDTech Gobi 2000 Modem device (VU922) */
        {QMI_GOBI_DEVICE(0x05c6, 0x9205)},      /* Gobi 2000 Modem device */
        {QMI_GOBI_DEVICE(0x1199, 0x9013)},      /* Sierra Wireless Gobi 3000 Modem device (MC8355) */
+       {QMI_GOBI_DEVICE(0x03f0, 0x371d)},      /* HP un2430 Mobile Broadband Module */
        {QMI_GOBI_DEVICE(0x1199, 0x9015)},      /* Sierra Wireless Gobi 3000 Modem device */
        {QMI_GOBI_DEVICE(0x1199, 0x9019)},      /* Sierra Wireless Gobi 3000 Modem device */
        {QMI_GOBI_DEVICE(0x1199, 0x901b)},      /* Sierra Wireless MC7770 */
index 7be49ea..8e22417 100644 (file)
@@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
                return -EIO;
        }
 
-       *datap = *attrdata;
+       *datap = le16_to_cpu(*attrdata);
 
        kfree(attrdata);
        return result;
index fd4b26d..fc9f578 100644 (file)
@@ -1201,19 +1201,26 @@ deferred:
 }
 EXPORT_SYMBOL_GPL(usbnet_start_xmit);
 
-static void rx_alloc_submit(struct usbnet *dev, gfp_t flags)
+static int rx_alloc_submit(struct usbnet *dev, gfp_t flags)
 {
        struct urb      *urb;
        int             i;
+       int             ret = 0;
 
        /* don't refill the queue all at once */
        for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) {
                urb = usb_alloc_urb(0, flags);
                if (urb != NULL) {
-                       if (rx_submit(dev, urb, flags) == -ENOLINK)
-                               return;
+                       ret = rx_submit(dev, urb, flags);
+                       if (ret)
+                               goto err;
+               } else {
+                       ret = -ENOMEM;
+                       goto err;
                }
        }
+err:
+       return ret;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param)
                int     temp = dev->rxq.qlen;
 
                if (temp < RX_QLEN(dev)) {
-                       rx_alloc_submit(dev, GFP_ATOMIC);
+                       if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK)
+                               return;
                        if (temp != dev->rxq.qlen)
                                netif_dbg(dev, link, dev->net,
                                          "rxqlen %d --> %d\n",
index aaaca9a..3f575af 100644 (file)
@@ -10,6 +10,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/cdev.h>
 #include <linux/dma-mapping.h>
index 2c9f7d7..0ed3846 100644 (file)
@@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
        };
        int training_power;
        int i, val;
+       u32 am2pm_mask = ah->paprd_ratemask;
 
        if (IS_CHAN_2GHZ(ah->curchan))
                training_power = ar9003_get_training_power_2g(ah);
@@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
        }
        ah->paprd_training_power = training_power;
 
+       if (AR_SREV_9330(ah))
+               am2pm_mask = 0;
+
        REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
                      ah->paprd_ratemask);
        REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
-                     ah->paprd_ratemask);
+                     am2pm_mask);
        REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
                      ah->paprd_ratemask_ht40);
 
@@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
 }
 EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
 
+static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah,
+                                      struct ath9k_hw_cal_data *caldata,
+                                      int chain)
+{
+       u32 *pa_in = caldata->pa_table[chain];
+       int capdiv_offset, quick_drop_offset;
+       int capdiv2g, quick_drop;
+       int count = 0;
+       int i;
+
+       if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah))
+               return false;
+
+       capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
+                                 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G);
+
+       quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
+                                   AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
+
+       if (quick_drop)
+               quick_drop -= 0x40;
+
+       for (i = 0; i < NUM_BIN + 1; i++) {
+               if (pa_in[i] == 1400)
+                       count++;
+       }
+
+       if (AR_SREV_9485(ah)) {
+               if (pa_in[23] < 800) {
+                       capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150);
+                       capdiv2g += capdiv_offset;
+                       if (capdiv2g > 7) {
+                               capdiv2g = 7;
+                               if (pa_in[23] < 600) {
+                                       quick_drop++;
+                                       if (quick_drop > 0)
+                                               quick_drop = 0;
+                               }
+                       }
+               } else if (pa_in[23] == 1400) {
+                       quick_drop_offset = min_t(int, count / 3, 2);
+                       quick_drop += quick_drop_offset;
+                       capdiv2g += quick_drop_offset / 2;
+
+                       if (capdiv2g > 7)
+                               capdiv2g = 7;
+
+                       if (quick_drop > 0) {
+                               quick_drop = 0;
+                               capdiv2g -= quick_drop_offset;
+                               if (capdiv2g < 0)
+                                       capdiv2g = 0;
+                       }
+               } else {
+                       return false;
+               }
+       } else if (AR_SREV_9330(ah)) {
+               if (pa_in[23] < 1000) {
+                       capdiv_offset = (1000 - pa_in[23]) / 100;
+                       capdiv2g += capdiv_offset;
+                       if (capdiv_offset > 3) {
+                               capdiv_offset = 1;
+                               quick_drop--;
+                       }
+
+                       capdiv2g += capdiv_offset;
+                       if (capdiv2g > 6)
+                               capdiv2g = 6;
+                       if (quick_drop < -4)
+                               quick_drop = -4;
+               } else if (pa_in[23] == 1400) {
+                       if (count > 3) {
+                               quick_drop++;
+                               capdiv2g -= count / 4;
+                               if (quick_drop > -2)
+                                       quick_drop = -2;
+                       } else {
+                               capdiv2g--;
+                       }
+
+                       if (capdiv2g < 0)
+                               capdiv2g = 0;
+               } else {
+                       return false;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
+                     AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g);
+       REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
+                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
+                     quick_drop);
+
+       return true;
+}
+
 int ar9003_paprd_create_curve(struct ath_hw *ah,
                              struct ath9k_hw_cal_data *caldata, int chain)
 {
@@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,
        if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))
                status = -2;
 
+       if (ar9003_paprd_retrain_pa_in(ah, caldata, chain))
+               status = -EINPROGRESS;
+
        REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
                    AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
 
index 7bfbaf0..84d3d49 100644 (file)
 #define AR_PHY_AIC_CTRL_4_B0   (AR_SM_BASE + 0x4c0)
 #define AR_PHY_AIC_STAT_2_B0   (AR_SM_BASE + 0x4cc)
 
+#define AR_PHY_65NM_CH0_TXRF3       0x16048
+#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G         0x0000001e
+#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S       1
+
 #define AR_PHY_65NM_CH0_SYNTH4      0x1608c
 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)
 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1)
index bacdb8f..9f83f71 100644 (file)
@@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
 {
        struct ath_btcoex *btcoex = &sc->btcoex;
 
-       ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
+       if (btcoex->hw_timer_enabled)
+               ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
 }
 
 u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
index 60b6a9d..48af401 100644 (file)
@@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
                ah->config.spurchans[i][1] = AR_NO_SPUR;
        }
 
-       /* PAPRD needs some more work to be enabled */
-       ah->config.paprd_disable = 1;
-
        ah->config.rx_intr_mitigation = true;
        ah->config.pcieSerDesWrite = true;
 
@@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
        else
                imr_reg |= AR_IMR_TXOK;
 
-       if (opmode == NL80211_IFTYPE_AP)
-               imr_reg |= AR_IMR_MIB;
-
        ENABLE_REGWRITE_BUFFER(ah);
 
        REG_WRITE(ah, AR_IMR, imr_reg);
@@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                /* Operating channel changed, reset channel calibration data */
                memset(caldata, 0, sizeof(*caldata));
                ath9k_init_nfcal_hist_buffer(ah, chan);
+       } else if (caldata) {
+               caldata->paprd_packet_sent = false;
        }
        ah->noise = ath9k_hw_getchan_noise(ah, chan);
 
@@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                pCap->tx_desc_len = sizeof(struct ar9003_txc);
                pCap->txs_len = sizeof(struct ar9003_txs);
                if (!ah->config.paprd_disable &&
-                   ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
+                   ah->eep_ops->get_eeprom(ah, EEP_PAPRD) &&
+                   !AR_SREV_9462(ah))
                        pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
        } else {
                pCap->tx_desc_len = sizeof(struct ath_desc);
index ce7332c..6599a75 100644 (file)
@@ -405,6 +405,7 @@ struct ath9k_hw_cal_data {
        int8_t iCoff;
        int8_t qCoff;
        bool rtt_done;
+       bool paprd_packet_sent;
        bool paprd_done;
        bool nfcal_pending;
        bool nfcal_interference;
index d4549e9..825a29c 100644 (file)
@@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work)
        int chain_ok = 0;
        int chain;
        int len = 1800;
+       int ret;
 
-       if (!caldata)
+       if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done)
                return;
 
        ath9k_ps_wakeup(sc);
@@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work)
                        continue;
 
                chain_ok = 0;
-
-               ath_dbg(common, CALIBRATE,
-                       "Sending PAPRD frame for thermal measurement on chain %d\n",
-                       chain);
-               if (!ath_paprd_send_frame(sc, skb, chain))
-                       goto fail_paprd;
-
                ar9003_paprd_setup_gain_table(ah, chain);
 
                ath_dbg(common, CALIBRATE,
@@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work)
                        break;
                }
 
-               if (ar9003_paprd_create_curve(ah, caldata, chain)) {
+               ret = ar9003_paprd_create_curve(ah, caldata, chain);
+               if (ret == -EINPROGRESS) {
+                       ath_dbg(common, CALIBRATE,
+                               "PAPRD curve on chain %d needs to be re-trained\n",
+                               chain);
+                       break;
+               } else if (ret) {
                        ath_dbg(common, CALIBRATE,
                                "PAPRD create curve failed on chain %d\n",
                                chain);
index 2c9da6b..0d4155a 100644 (file)
@@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
 
        ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
 
+       if (sc->sc_ah->caldata)
+               sc->sc_ah->caldata->paprd_packet_sent = true;
+
        if (!(tx_flags & ATH_TX_ERROR))
                /* Frame was ACKed */
                tx_info->flags |= IEEE80211_TX_STAT_ACK;
index a299d42..58f89fa 100644 (file)
@@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb)
        else
                devinfo->bus_pub.bus->dstats.tx_errors++;
 
-       dev_kfree_skb(req->skb);
+       brcmu_pkt_buf_free_skb(req->skb);
        req->skb = NULL;
        brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
 
@@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
                devinfo->bus_pub.bus->dstats.rx_packets++;
        } else {
                devinfo->bus_pub.bus->dstats.rx_errors++;
-               dev_kfree_skb(skb);
+               brcmu_pkt_buf_free_skb(skb);
                brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
                return;
        }
@@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb)
                if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
                        brcmf_dbg(ERROR, "rx protocol error\n");
                        brcmu_pkt_buf_free_skb(skb);
+                       brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
                        devinfo->bus_pub.bus->dstats.rx_errors++;
                } else {
                        brcmf_rx_packet(devinfo->dev, ifidx, skb);
                        brcmf_usb_rx_refill(devinfo, req);
                }
        } else {
-               dev_kfree_skb(skb);
+               brcmu_pkt_buf_free_skb(skb);
+               brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
        }
        return;
 
@@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
        usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
                          skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
                          req);
-       req->urb->transfer_flags |= URB_ZERO_PACKET;
        req->devinfo = devinfo;
+       brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
 
        ret = usb_submit_urb(req->urb, GFP_ATOMIC);
-       if (ret == 0) {
-               brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
-       } else {
-               dev_kfree_skb(req->skb);
+       if (ret) {
+               brcmf_usb_del_fromq(devinfo, req);
+               brcmu_pkt_buf_free_skb(req->skb);
                req->skb = NULL;
                brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
        }
@@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
 
        req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
        if (!req) {
+               brcmu_pkt_buf_free_skb(skb);
                brcmf_dbg(ERROR, "no req to send\n");
                return -ENOMEM;
        }
-       if (!req->urb) {
-               brcmf_dbg(ERROR, "no urb for req %p\n", req);
-               return -ENOBUFS;
-       }
 
        req->skb = skb;
        req->devinfo = devinfo;
        usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
                          skb->data, skb->len, brcmf_usb_tx_complete, req);
        req->urb->transfer_flags |= URB_ZERO_PACKET;
+       brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
        ret = usb_submit_urb(req->urb, GFP_ATOMIC);
-       if (!ret) {
-               brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
-       } else {
+       if (ret) {
+               brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n");
+               brcmf_usb_del_fromq(devinfo, req);
+               brcmu_pkt_buf_free_skb(req->skb);
                req->skb = NULL;
                brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
        }
index 28c5fbb..c36e923 100644 (file)
@@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
        }
 
        if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
-               scb_val.val = cpu_to_le32(0);
+               memset(&scb_val, 0, sizeof(scb_val));
                err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
                                      sizeof(struct brcmf_scb_val_le));
-               if (err)
+               if (err) {
                        WL_ERR("Could not get rssi (%d)\n", err);
-
-               rssi = le32_to_cpu(scb_val.val);
-               sinfo->filled |= STATION_INFO_SIGNAL;
-               sinfo->signal = rssi;
-               WL_CONN("RSSI %d dBm\n", rssi);
+               } else {
+                       rssi = le32_to_cpu(scb_val.val);
+                       sinfo->filled |= STATION_INFO_SIGNAL;
+                       sinfo->signal = rssi;
+                       WL_CONN("RSSI %d dBm\n", rssi);
+               }
        }
 
 done:
index e970897..4cb2343 100644 (file)
@@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev)
 
        mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
 
+       /* If we're powered off anyway, just let the mmc layer remove the
+        * card. */
+       if (!lbs_iface_active(card->priv))
+               return -ENOSYS;
+
        dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
                 sdio_func_id(func), flags);
 
index c68adec..565527a 100644 (file)
@@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
        cmd_code = le16_to_cpu(host_cmd->command);
        cmd_size = le16_to_cpu(host_cmd->size);
 
-       skb_trim(cmd_node->cmd_skb, cmd_size);
+       /* Adjust skb length */
+       if (cmd_node->cmd_skb->len > cmd_size)
+               /*
+                * cmd_size is less than sizeof(struct host_cmd_ds_command).
+                * Trim off the unused portion.
+                */
+               skb_trim(cmd_node->cmd_skb, cmd_size);
+       else if (cmd_node->cmd_skb->len < cmd_size)
+               /*
+                * cmd_size is larger than sizeof(struct host_cmd_ds_command)
+                * because we have appended custom IE TLV. Increase skb length
+                * accordingly.
+                */
+               skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);
 
        do_gettimeofday(&tstamp);
        dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
index 8b9dbd7..64328af 100644 (file)
@@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u32 reg;
 
        /*
         * Allocate eeprom data.
@@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
+       rt2x00_set_field32(&reg, GPIOCSR_BIT8, 1);
+       rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt2400pci_probe_hw_mode(rt2x00dev);
index d3a4a68..7564ae9 100644 (file)
 #define GPIOCSR_BIT5                   FIELD32(0x00000020)
 #define GPIOCSR_BIT6                   FIELD32(0x00000040)
 #define GPIOCSR_BIT7                   FIELD32(0x00000080)
+#define GPIOCSR_BIT8                   FIELD32(0x00000100)
 
 /*
  * BBPPCSR: BBP Pin control register.
index d2cf8a4..3de0406 100644 (file)
@@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u32 reg;
 
        /*
         * Allocate eeprom data.
@@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
+       rt2x00_set_field32(&reg, GPIOCSR_DIR0, 1);
+       rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt2500pci_probe_hw_mode(rt2x00dev);
index 3aae36b..89fee31 100644 (file)
@@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
        u16 reg;
 
        rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
-       return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
+       return rt2x00_get_field16(reg, MAC_CSR19_BIT7);
 }
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
@@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u16 reg;
 
        /*
         * Allocate eeprom data.
@@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
+       rt2x00_set_field16(&reg, MAC_CSR19_BIT8, 0);
+       rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt2500usb_probe_hw_mode(rt2x00dev);
index b493306..196bd51 100644 (file)
  * MAC_CSR19: GPIO control register.
  */
 #define MAC_CSR19                      0x0426
-#define MAC_CSR19_BIT0                 FIELD32(0x0001)
-#define MAC_CSR19_BIT1                 FIELD32(0x0002)
-#define MAC_CSR19_BIT2                 FIELD32(0x0004)
-#define MAC_CSR19_BIT3                 FIELD32(0x0008)
-#define MAC_CSR19_BIT4                 FIELD32(0x0010)
-#define MAC_CSR19_BIT5                 FIELD32(0x0020)
-#define MAC_CSR19_BIT6                 FIELD32(0x0040)
-#define MAC_CSR19_BIT7                 FIELD32(0x0080)
+#define MAC_CSR19_BIT0                 FIELD16(0x0001)
+#define MAC_CSR19_BIT1                 FIELD16(0x0002)
+#define MAC_CSR19_BIT2                 FIELD16(0x0004)
+#define MAC_CSR19_BIT3                 FIELD16(0x0008)
+#define MAC_CSR19_BIT4                 FIELD16(0x0010)
+#define MAC_CSR19_BIT5                 FIELD16(0x0020)
+#define MAC_CSR19_BIT6                 FIELD16(0x0040)
+#define MAC_CSR19_BIT7                 FIELD16(0x0080)
+#define MAC_CSR19_BIT8                 FIELD16(0x0100)
 
 /*
  * MAC_CSR20: LED control register.
index cb8c2ac..b93516d 100644 (file)
@@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
                rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
                msleep(1);
                rt2800_register_read(rt2x00dev, LDO_CFG0, &reg);
+               rt2x00_set_field32(&reg, LDO_CFG0_LDO_CORE_VLEVEL, 0);
                rt2x00_set_field32(&reg, LDO_CFG0_BGSEL, 1);
                rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
        }
index 98aa426..4765bbd 100644 (file)
@@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u32 reg;
 
        /*
         * Allocate eeprom data.
@@ -996,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT2, 1);
+       rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt2800_probe_hw_mode(rt2x00dev);
index 6cf3365..6b4226b 100644 (file)
@@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
        skb_pull(entry->skb, RXINFO_DESC_SIZE);
 
        /*
-        * FIXME: we need to check for rx_pkt_len validity
+        * Check for rx_pkt_len validity. Return if invalid, leaving
+        * rxdesc->size zeroed out by the upper level.
         */
+       if (unlikely(rx_pkt_len == 0 ||
+                       rx_pkt_len > entry->queue->data_size)) {
+               ERROR(entry->queue->rt2x00dev,
+                       "Bad frame size %d, forcing to 0\n", rx_pkt_len);
+               return;
+       }
+
        rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
 
        /*
@@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u32 reg;
 
        /*
         * Allocate eeprom data.
@@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+       rt2x00_set_field32(&reg, GPIO_CTRL_CFG_GPIOD_BIT2, 1);
+       rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt2800_probe_hw_mode(rt2x00dev);
@@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x1690, 0x0744) },
        { USB_DEVICE(0x1690, 0x0761) },
        { USB_DEVICE(0x1690, 0x0764) },
+       /* ASUS */
+       { USB_DEVICE(0x0b05, 0x179d) },
        /* Cisco */
        { USB_DEVICE(0x167b, 0x4001) },
        /* EnGenius */
@@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
        { USB_DEVICE(0x0b05, 0x1760) },
        { USB_DEVICE(0x0b05, 0x1761) },
        { USB_DEVICE(0x0b05, 0x1790) },
-       { USB_DEVICE(0x0b05, 0x179d) },
        /* AzureWave */
        { USB_DEVICE(0x13d3, 0x3262) },
        { USB_DEVICE(0x13d3, 0x3284) },
index a6b88bd..3f07e36 100644 (file)
@@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
         */
        if (unlikely(rxdesc.size == 0 ||
                     rxdesc.size > entry->queue->data_size)) {
-               WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
+               ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
                        rxdesc.size, entry->queue->data_size);
                dev_kfree_skb(entry->skb);
                goto renew_skb;
index 3f7bc5c..b8ec961 100644 (file)
@@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u32 reg;
 
        /*
         * Disable power saving.
@@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT13, 1);
+       rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt61pci_probe_hw_mode(rt2x00dev);
index e3cd6db..8f3da5a 100644 (file)
@@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry {
 #define MAC_CSR13_BIT10                        FIELD32(0x00000400)
 #define MAC_CSR13_BIT11                        FIELD32(0x00000800)
 #define MAC_CSR13_BIT12                        FIELD32(0x00001000)
+#define MAC_CSR13_BIT13                        FIELD32(0x00002000)
 
 /*
  * MAC_CSR14: LED control register.
index ba6e434..248436c 100644 (file)
@@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
        int retval;
+       u32 reg;
 
        /*
         * Allocate eeprom data.
@@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
                return retval;
 
        /*
+        * Enable rfkill polling by setting GPIO direction of the
+        * rfkill switch GPIO pin correctly.
+        */
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT15, 0);
+       rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg);
+
+       /*
         * Initialize hw specifications.
         */
        retval = rt73usb_probe_hw_mode(rt2x00dev);
index 9f6b470..df1cc11 100644 (file)
@@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry {
 #define MAC_CSR13_BIT10                        FIELD32(0x00000400)
 #define MAC_CSR13_BIT11                        FIELD32(0x00000800)
 #define MAC_CSR13_BIT12                        FIELD32(0x00001000)
+#define MAC_CSR13_BIT13                        FIELD32(0x00002000)
+#define MAC_CSR13_BIT14                        FIELD32(0x00004000)
+#define MAC_CSR13_BIT15                        FIELD32(0x00008000)
 
 /*
  * MAC_CSR14: LED control register.
index bd6c9fc..6e1b0f9 100644 (file)
@@ -796,6 +796,19 @@ enum mlx4_net_trans_rule_id {
        MLX4_NET_TRANS_RULE_NUM, /* should be last */
 };
 
+extern const u16 __sw_id_hw[];
+
+static inline int map_hw_to_sw_id(u16 header_id)
+{
+
+       int i;
+       for (i = 0; i < MLX4_NET_TRANS_RULE_NUM; i++) {
+               if (header_id == __sw_id_hw[i])
+                       return i;
+       }
+       return -EINVAL;
+}
+
 enum mlx4_net_trans_promisc_mode {
        MLX4_FS_PROMISC_NONE = 0,
        MLX4_FS_PROMISC_UPLINK,
index ca356a7..8b27927 100644 (file)
@@ -136,7 +136,7 @@ struct smp_chan {
 };
 
 /* SMP Commands */
-int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level);
+int smp_conn_security(struct hci_conn *hcon, __u8 sec_level);
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb);
 int smp_distribute_keys(struct l2cap_conn *conn, __u8 force);
 int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
index 976a81a..639dd13 100644 (file)
@@ -273,6 +273,9 @@ struct xfrm_replay {
        int     (*check)(struct xfrm_state *x,
                         struct sk_buff *skb,
                         __be32 net_seq);
+       int     (*recheck)(struct xfrm_state *x,
+                          struct sk_buff *skb,
+                          __be32 net_seq);
        void    (*notify)(struct xfrm_state *x, int event);
        int     (*overflow)(struct xfrm_state *x, struct sk_buff *skb);
 };
index 5ad7da2..3c094e7 100644 (file)
@@ -29,6 +29,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/a2mp.h>
+#include <net/bluetooth/smp.h>
 
 static void hci_le_connect(struct hci_conn *conn)
 {
@@ -619,6 +620,9 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
        BT_DBG("hcon %p", conn);
 
+       if (conn->type == LE_LINK)
+               return smp_conn_security(conn, sec_level);
+
        /* For sdp we don't need the link key. */
        if (sec_level == BT_SECURITY_SDP)
                return 1;
index daa149b..4ea1710 100644 (file)
@@ -1199,14 +1199,15 @@ clean:
 static void l2cap_conn_ready(struct l2cap_conn *conn)
 {
        struct l2cap_chan *chan;
+       struct hci_conn *hcon = conn->hcon;
 
        BT_DBG("conn %p", conn);
 
-       if (!conn->hcon->out && conn->hcon->type == LE_LINK)
+       if (!hcon->out && hcon->type == LE_LINK)
                l2cap_le_conn_ready(conn);
 
-       if (conn->hcon->out && conn->hcon->type == LE_LINK)
-               smp_conn_security(conn, conn->hcon->pending_sec_level);
+       if (hcon->out && hcon->type == LE_LINK)
+               smp_conn_security(hcon, hcon->pending_sec_level);
 
        mutex_lock(&conn->chan_lock);
 
@@ -1219,8 +1220,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
                        continue;
                }
 
-               if (conn->hcon->type == LE_LINK) {
-                       if (smp_conn_security(conn, chan->sec_level))
+               if (hcon->type == LE_LINK) {
+                       if (smp_conn_security(hcon, chan->sec_level))
                                l2cap_chan_ready(chan);
 
                } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
index 1497edd..34bbe1c 100644 (file)
@@ -616,7 +616,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
                                break;
                        }
 
-                       if (smp_conn_security(conn, sec.level))
+                       if (smp_conn_security(conn->hcon, sec.level))
                                break;
                        sk->sk_state = BT_CONFIG;
                        chan->state = BT_CONFIG;
index 901a616..8c225ef 100644 (file)
@@ -267,10 +267,10 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
        mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type,
                         hcon->dst_type, reason);
 
-       if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) {
-               cancel_delayed_work_sync(&conn->security_timer);
+       cancel_delayed_work_sync(&conn->security_timer);
+
+       if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags))
                smp_chan_destroy(conn);
-       }
 }
 
 #define JUST_WORKS     0x00
@@ -760,9 +760,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
        return 0;
 }
 
-int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
+int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
 {
-       struct hci_conn *hcon = conn->hcon;
+       struct l2cap_conn *conn = hcon->l2cap_data;
        struct smp_chan *smp = conn->smp_chan;
        __u8 authreq;
 
index dd485f6..ba217e9 100644 (file)
@@ -211,9 +211,10 @@ void caif_client_register_refcnt(struct cflayer *adapt_layer,
                                        void (*put)(struct cflayer *lyr))
 {
        struct cfsrvl *service;
-       service = container_of(adapt_layer->dn, struct cfsrvl, layer);
 
-       WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL);
+       if (WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL))
+               return;
+       service = container_of(adapt_layer->dn, struct cfsrvl, layer);
        service->hold = hold;
        service->put = put;
 }
index 8398836..d7fe32c 100644 (file)
@@ -2647,15 +2647,16 @@ void __skb_get_rxhash(struct sk_buff *skb)
        if (!skb_flow_dissect(skb, &keys))
                return;
 
-       if (keys.ports) {
-               if ((__force u16)keys.port16[1] < (__force u16)keys.port16[0])
-                       swap(keys.port16[0], keys.port16[1]);
+       if (keys.ports)
                skb->l4_rxhash = 1;
-       }
 
        /* get a consistent hash (same value on both flow directions) */
-       if ((__force u32)keys.dst < (__force u32)keys.src)
+       if (((__force u32)keys.dst < (__force u32)keys.src) ||
+           (((__force u32)keys.dst == (__force u32)keys.src) &&
+            ((__force u16)keys.port16[1] < (__force u16)keys.port16[0]))) {
                swap(keys.dst, keys.src);
+               swap(keys.port16[0], keys.port16[1]);
+       }
 
        hash = jhash_3words((__force u32)keys.dst,
                            (__force u32)keys.src,
index 8f67ced..3057920 100644 (file)
@@ -1523,7 +1523,14 @@ EXPORT_SYMBOL(sock_rfree);
 
 void sock_edemux(struct sk_buff *skb)
 {
-       sock_put(skb->sk);
+       struct sock *sk = skb->sk;
+
+#ifdef CONFIG_INET
+       if (sk->sk_state == TCP_TIME_WAIT)
+               inet_twsk_put(inet_twsk(sk));
+       else
+#endif
+               sock_put(sk);
 }
 EXPORT_SYMBOL(sock_edemux);
 
index 6f6d1ac..2814f66 100644 (file)
@@ -1226,6 +1226,11 @@ try_again:
 
        if (unlikely(err)) {
                trace_kfree_skb(skb, udp_recvmsg);
+               if (!peeked) {
+                       atomic_inc(&sk->sk_drops);
+                       UDP_INC_STATS_USER(sock_net(sk),
+                                          UDP_MIB_INERRORS, is_udplite);
+               }
                goto out_free;
        }
 
index a3e60cc..acd32e3 100644 (file)
@@ -403,8 +403,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                tp->mtu_info = ntohl(info);
                if (!sock_owned_by_user(sk))
                        tcp_v6_mtu_reduced(sk);
-               else
-                       set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags);
+               else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED,
+                                          &tp->tsq_flags))
+                       sock_hold(sk);
                goto out;
        }
 
index 99d0077..07e2bfe 100644 (file)
@@ -394,6 +394,17 @@ try_again:
        }
        if (unlikely(err)) {
                trace_kfree_skb(skb, udpv6_recvmsg);
+               if (!peeked) {
+                       atomic_inc(&sk->sk_drops);
+                       if (is_udp4)
+                               UDP_INC_STATS_USER(sock_net(sk),
+                                                  UDP_MIB_INERRORS,
+                                                  is_udplite);
+                       else
+                               UDP6_INC_STATS_USER(sock_net(sk),
+                                                   UDP_MIB_INERRORS,
+                                                   is_udplite);
+               }
                goto out_free;
        }
        if (!peeked) {
index 513cab0..1a9f372 100644 (file)
@@ -1501,6 +1501,8 @@ out:
        return err;
 }
 
+static struct lock_class_key l2tp_socket_class;
+
 int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp)
 {
        struct l2tp_tunnel *tunnel = NULL;
@@ -1605,6 +1607,8 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
        tunnel->old_sk_destruct = sk->sk_destruct;
        sk->sk_destruct = &l2tp_tunnel_destruct;
        tunnel->sock = sk;
+       lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, "l2tp_sock");
+
        sk->sk_allocation = GFP_ATOMIC;
 
        /* Add tunnel to our list */
index f9ee74d..3bfb34a 100644 (file)
@@ -153,7 +153,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
                print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, skb->data, length);
        }
 
-       if (!pskb_may_pull(skb, sizeof(ETH_HLEN)))
+       if (!pskb_may_pull(skb, ETH_HLEN))
                goto error;
 
        secpath_reset(skb);
index d41974a..a58c0b6 100644 (file)
@@ -1378,6 +1378,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
        else
                memset(next_hop, 0, ETH_ALEN);
 
+       memset(pinfo, 0, sizeof(*pinfo));
+
        pinfo->generation = mesh_paths_generation;
 
        pinfo->filled = MPATH_INFO_FRAME_QLEN |
@@ -1396,7 +1398,6 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
        pinfo->discovery_timeout =
                        jiffies_to_msecs(mpath->discovery_timeout);
        pinfo->discovery_retries = mpath->discovery_retries;
-       pinfo->flags = 0;
        if (mpath->flags & MESH_PATH_ACTIVE)
                pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
        if (mpath->flags & MESH_PATH_RESOLVING)
@@ -1405,10 +1406,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
                pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
        if (mpath->flags & MESH_PATH_FIXED)
                pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
-       if (mpath->flags & MESH_PATH_RESOLVING)
-               pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
-
-       pinfo->flags = mpath->flags;
+       if (mpath->flags & MESH_PATH_RESOLVED)
+               pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;
 }
 
 static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
index a4a5acd..f76b833 100644 (file)
@@ -3248,6 +3248,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
        goto out_unlock;
 
  err_clear:
+       memset(ifmgd->bssid, 0, ETH_ALEN);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
        ifmgd->auth_data = NULL;
  err_free:
        kfree(auth_data);
@@ -3439,6 +3441,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        err = 0;
        goto out;
  err_clear:
+       memset(ifmgd->bssid, 0, ETH_ALEN);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
        ifmgd->assoc_data = NULL;
  err_free:
        kfree(assoc_data);
index 06592d8..1b9024e 100644 (file)
@@ -1169,7 +1169,12 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
                msg->msg_flags |= MSG_TRUNC;
        }
 
-       skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       er = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       if (er < 0) {
+               skb_free_datagram(sk, skb);
+               release_sock(sk);
+               return er;
+       }
 
        if (sax != NULL) {
                sax->sax25_family = AF_NETROM;
index f3f96ba..954405c 100644 (file)
@@ -45,7 +45,7 @@ static int make_writable(struct sk_buff *skb, int write_len)
        return pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
 }
 
-/* remove VLAN header from packet and update csum accrodingly. */
+/* remove VLAN header from packet and update csum accordingly. */
 static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
 {
        struct vlan_hdr *vhdr;
index d8277d2..cf58ced 100644 (file)
@@ -425,10 +425,10 @@ static int validate_sample(const struct nlattr *attr,
 static int validate_tp_port(const struct sw_flow_key *flow_key)
 {
        if (flow_key->eth.type == htons(ETH_P_IP)) {
-               if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst)
+               if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst)
                        return 0;
        } else if (flow_key->eth.type == htons(ETH_P_IPV6)) {
-               if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst)
+               if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst)
                        return 0;
        }
 
@@ -460,7 +460,7 @@ static int validate_set(const struct nlattr *a,
                if (flow_key->eth.type != htons(ETH_P_IP))
                        return -EINVAL;
 
-               if (!flow_key->ipv4.addr.src || !flow_key->ipv4.addr.dst)
+               if (!flow_key->ip.proto)
                        return -EINVAL;
 
                ipv4_key = nla_data(ovs_key);
index 9b75617..c30df1a 100644 (file)
@@ -145,15 +145,17 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
  *  OVS_KEY_ATTR_PRIORITY      4    --     4      8
  *  OVS_KEY_ATTR_IN_PORT       4    --     4      8
  *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
+ *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (outer VLAN ethertype)
  *  OVS_KEY_ATTR_8021Q         4    --     4      8
- *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8
+ *  OVS_KEY_ATTR_ENCAP         0    --     4      4  (VLAN encapsulation)
+ *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (inner VLAN ethertype)
  *  OVS_KEY_ATTR_IPV6         40    --     4     44
  *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
  *  OVS_KEY_ATTR_ND           28    --     4     32
  *  -------------------------------------------------
- *  total                                       132
+ *  total                                       144
  */
-#define FLOW_BUFSIZE 132
+#define FLOW_BUFSIZE 144
 
 int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
 int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
index 6aabd77..564b9fc 100644 (file)
@@ -250,10 +250,11 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
                        else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL)
                                cl = defmap[TC_PRIO_BESTEFFORT];
 
-                       if (cl == NULL || cl->level >= head->level)
+                       if (cl == NULL)
                                goto fallback;
                }
-
+               if (cl->level >= head->level)
+                       goto fallback;
 #ifdef CONFIG_NET_CLS_ACT
                switch (result) {
                case TC_ACT_QUEUED:
index 9fc1c62..4e606fc 100644 (file)
@@ -191,7 +191,6 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
        if (list_empty(&flow->flowchain)) {
                list_add_tail(&flow->flowchain, &q->new_flows);
-               codel_vars_init(&flow->cvars);
                q->new_flow_count++;
                flow->deficit = q->quantum;
                flow->dropped = 0;
@@ -418,6 +417,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)
                        struct fq_codel_flow *flow = q->flows + i;
 
                        INIT_LIST_HEAD(&flow->flowchain);
+                       codel_vars_init(&flow->cvars);
                }
        }
        if (sch->limit >= 1)
index 838e18b..be50aa2 100644 (file)
@@ -364,6 +364,25 @@ finish:
        return retval;
 }
 
+static void sctp_packet_release_owner(struct sk_buff *skb)
+{
+       sk_free(skb->sk);
+}
+
+static void sctp_packet_set_owner_w(struct sk_buff *skb, struct sock *sk)
+{
+       skb_orphan(skb);
+       skb->sk = sk;
+       skb->destructor = sctp_packet_release_owner;
+
+       /*
+        * The data chunks have already been accounted for in sctp_sendmsg(),
+        * therefore only reserve a single byte to keep socket around until
+        * the packet has been transmitted.
+        */
+       atomic_inc(&sk->sk_wmem_alloc);
+}
+
 /* All packets are sent to the network through this function from
  * sctp_outq_tail().
  *
@@ -405,7 +424,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        /* Set the owning socket so that we know where to get the
         * destination IP address.
         */
-       skb_set_owner_w(nskb, sk);
+       sctp_packet_set_owner_w(nskb, sk);
 
        if (!sctp_transport_dst_check(tp)) {
                sctp_transport_route(tp, NULL, sctp_sk(sk));
index 97026f3..1e37dbf 100644 (file)
@@ -5633,8 +5633,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
                       sizeof(connect.ht_capa_mask));
 
        if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
-               if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
+               if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
+                       kfree(connkeys);
                        return -EINVAL;
+               }
                memcpy(&connect.ht_capa,
                       nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
                       sizeof(connect.ht_capa));
index 54a0dc2..ab2bb42 100644 (file)
@@ -212,7 +212,7 @@ resume:
                /* only the first xfrm gets the encap type */
                encap_type = 0;
 
-               if (async && x->repl->check(x, skb, seq)) {
+               if (async && x->repl->recheck(x, skb, seq)) {
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
                        goto drop_unlock;
                }
index 2f6d11d..3efb07d 100644 (file)
@@ -420,6 +420,18 @@ err:
        return -EINVAL;
 }
 
+static int xfrm_replay_recheck_esn(struct xfrm_state *x,
+                                  struct sk_buff *skb, __be32 net_seq)
+{
+       if (unlikely(XFRM_SKB_CB(skb)->seq.input.hi !=
+                    htonl(xfrm_replay_seqhi(x, net_seq)))) {
+                       x->stats.replay_window++;
+                       return -EINVAL;
+       }
+
+       return xfrm_replay_check_esn(x, skb, net_seq);
+}
+
 static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
 {
        unsigned int bitnr, nr, i;
@@ -479,6 +491,7 @@ static void xfrm_replay_advance_esn(struct xfrm_state *x, __be32 net_seq)
 static struct xfrm_replay xfrm_replay_legacy = {
        .advance        = xfrm_replay_advance,
        .check          = xfrm_replay_check,
+       .recheck        = xfrm_replay_check,
        .notify         = xfrm_replay_notify,
        .overflow       = xfrm_replay_overflow,
 };
@@ -486,6 +499,7 @@ static struct xfrm_replay xfrm_replay_legacy = {
 static struct xfrm_replay xfrm_replay_bmp = {
        .advance        = xfrm_replay_advance_bmp,
        .check          = xfrm_replay_check_bmp,
+       .recheck        = xfrm_replay_check_bmp,
        .notify         = xfrm_replay_notify_bmp,
        .overflow       = xfrm_replay_overflow_bmp,
 };
@@ -493,6 +507,7 @@ static struct xfrm_replay xfrm_replay_bmp = {
 static struct xfrm_replay xfrm_replay_esn = {
        .advance        = xfrm_replay_advance_esn,
        .check          = xfrm_replay_check_esn,
+       .recheck        = xfrm_replay_recheck_esn,
        .notify         = xfrm_replay_notify_bmp,
        .overflow       = xfrm_replay_overflow_esn,
 };