diff options
141 files changed, 1551 insertions, 916 deletions
diff --git a/Documentation/devicetree/bindings/net/davinci_emac.txt b/Documentation/devicetree/bindings/net/davinci_emac.txt index 48b259e29e87..bad381faf036 100644 --- a/Documentation/devicetree/bindings/net/davinci_emac.txt +++ b/Documentation/devicetree/bindings/net/davinci_emac.txt | |||
| @@ -4,7 +4,7 @@ This file provides information, what the device node | |||
| 4 | for the davinci_emac interface contains. | 4 | for the davinci_emac interface contains. |
| 5 | 5 | ||
| 6 | Required properties: | 6 | Required properties: |
| 7 | - compatible: "ti,davinci-dm6467-emac"; | 7 | - compatible: "ti,davinci-dm6467-emac" or "ti,am3517-emac" |
| 8 | - reg: Offset and length of the register set for the device | 8 | - reg: Offset and length of the register set for the device |
| 9 | - ti,davinci-ctrl-reg-offset: offset to control register | 9 | - ti,davinci-ctrl-reg-offset: offset to control register |
| 10 | - ti,davinci-ctrl-mod-reg-offset: offset to control module register | 10 | - ti,davinci-ctrl-mod-reg-offset: offset to control module register |
diff --git a/Documentation/devicetree/bindings/net/smsc-lan91c111.txt b/Documentation/devicetree/bindings/net/smsc-lan91c111.txt index 953049b4248a..5a41a8658daa 100644 --- a/Documentation/devicetree/bindings/net/smsc-lan91c111.txt +++ b/Documentation/devicetree/bindings/net/smsc-lan91c111.txt | |||
| @@ -8,3 +8,7 @@ Required properties: | |||
| 8 | Optional properties: | 8 | Optional properties: |
| 9 | - phy-device : phandle to Ethernet phy | 9 | - phy-device : phandle to Ethernet phy |
| 10 | - local-mac-address : Ethernet mac address to use | 10 | - local-mac-address : Ethernet mac address to use |
| 11 | - reg-io-width : Mask of sizes (in bytes) of the IO accesses that | ||
| 12 | are supported on the device. Valid value for SMSC LAN91c111 are | ||
| 13 | 1, 2 or 4. If it's omitted or invalid, the size would be 2 meaning | ||
| 14 | 16-bit access only. | ||
diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt index c01223628a87..8e48e3b14227 100644 --- a/Documentation/networking/packet_mmap.txt +++ b/Documentation/networking/packet_mmap.txt | |||
| @@ -123,6 +123,16 @@ Transmission process is similar to capture as shown below. | |||
| 123 | [shutdown] close() --------> destruction of the transmission socket and | 123 | [shutdown] close() --------> destruction of the transmission socket and |
| 124 | deallocation of all associated resources. | 124 | deallocation of all associated resources. |
| 125 | 125 | ||
| 126 | Socket creation and destruction is also straight forward, and is done | ||
| 127 | the same way as in capturing described in the previous paragraph: | ||
| 128 | |||
| 129 | int fd = socket(PF_PACKET, mode, 0); | ||
| 130 | |||
| 131 | The protocol can optionally be 0 in case we only want to transmit | ||
| 132 | via this socket, which avoids an expensive call to packet_rcv(). | ||
| 133 | In this case, you also need to bind(2) the TX_RING with sll_protocol = 0 | ||
| 134 | set. Otherwise, htons(ETH_P_ALL) or any other protocol, for example. | ||
| 135 | |||
| 126 | Binding the socket to your network interface is mandatory (with zero copy) to | 136 | Binding the socket to your network interface is mandatory (with zero copy) to |
| 127 | know the header size of frames used in the circular buffer. | 137 | know the header size of frames used in the circular buffer. |
| 128 | 138 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 94e3223b2bf4..1344816c4c06 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4466,10 +4466,8 @@ M: Bruce Allan <bruce.w.allan@intel.com> | |||
| 4466 | M: Carolyn Wyborny <carolyn.wyborny@intel.com> | 4466 | M: Carolyn Wyborny <carolyn.wyborny@intel.com> |
| 4467 | M: Don Skidmore <donald.c.skidmore@intel.com> | 4467 | M: Don Skidmore <donald.c.skidmore@intel.com> |
| 4468 | M: Greg Rose <gregory.v.rose@intel.com> | 4468 | M: Greg Rose <gregory.v.rose@intel.com> |
| 4469 | M: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> | ||
| 4470 | M: Alex Duyck <alexander.h.duyck@intel.com> | 4469 | M: Alex Duyck <alexander.h.duyck@intel.com> |
| 4471 | M: John Ronciak <john.ronciak@intel.com> | 4470 | M: John Ronciak <john.ronciak@intel.com> |
| 4472 | M: Tushar Dave <tushar.n.dave@intel.com> | ||
| 4473 | L: e1000-devel@lists.sourceforge.net | 4471 | L: e1000-devel@lists.sourceforge.net |
| 4474 | W: http://www.intel.com/support/feedback.htm | 4472 | W: http://www.intel.com/support/feedback.htm |
| 4475 | W: http://e1000.sourceforge.net/ | 4473 | W: http://e1000.sourceforge.net/ |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 36eab0c4fb33..398e299ee1bd 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -4199,9 +4199,9 @@ static int bond_check_params(struct bond_params *params) | |||
| 4199 | (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) { | 4199 | (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) { |
| 4200 | /* not complete check, but should be good enough to | 4200 | /* not complete check, but should be good enough to |
| 4201 | catch mistakes */ | 4201 | catch mistakes */ |
| 4202 | __be32 ip = in_aton(arp_ip_target[i]); | 4202 | __be32 ip; |
| 4203 | if (!isdigit(arp_ip_target[i][0]) || ip == 0 || | 4203 | if (!in4_pton(arp_ip_target[i], -1, (u8 *)&ip, -1, NULL) || |
| 4204 | ip == htonl(INADDR_BROADCAST)) { | 4204 | IS_IP_TARGET_UNUSABLE_ADDRESS(ip)) { |
| 4205 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", | 4205 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
| 4206 | arp_ip_target[i]); | 4206 | arp_ip_target[i]); |
| 4207 | arp_interval = 0; | 4207 | arp_interval = 0; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index abf5e106edc5..0ae580bbc5db 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -1635,12 +1635,12 @@ static ssize_t bonding_show_packets_per_slave(struct device *d, | |||
| 1635 | char *buf) | 1635 | char *buf) |
| 1636 | { | 1636 | { |
| 1637 | struct bonding *bond = to_bond(d); | 1637 | struct bonding *bond = to_bond(d); |
| 1638 | int packets_per_slave = bond->params.packets_per_slave; | 1638 | unsigned int packets_per_slave = bond->params.packets_per_slave; |
| 1639 | 1639 | ||
| 1640 | if (packets_per_slave > 1) | 1640 | if (packets_per_slave > 1) |
| 1641 | packets_per_slave = reciprocal_value(packets_per_slave); | 1641 | packets_per_slave = reciprocal_value(packets_per_slave); |
| 1642 | 1642 | ||
| 1643 | return sprintf(buf, "%d\n", packets_per_slave); | 1643 | return sprintf(buf, "%u\n", packets_per_slave); |
| 1644 | } | 1644 | } |
| 1645 | 1645 | ||
| 1646 | static ssize_t bonding_store_packets_per_slave(struct device *d, | 1646 | static ssize_t bonding_store_packets_per_slave(struct device *d, |
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 50b853a79d77..46dfb1378c17 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c | |||
| @@ -717,8 +717,7 @@ static int emac_open(struct net_device *dev) | |||
| 717 | if (netif_msg_ifup(db)) | 717 | if (netif_msg_ifup(db)) |
| 718 | dev_dbg(db->dev, "enabling %s\n", dev->name); | 718 | dev_dbg(db->dev, "enabling %s\n", dev->name); |
| 719 | 719 | ||
| 720 | if (devm_request_irq(db->dev, dev->irq, &emac_interrupt, | 720 | if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev)) |
| 721 | 0, dev->name, dev)) | ||
| 722 | return -EAGAIN; | 721 | return -EAGAIN; |
| 723 | 722 | ||
| 724 | /* Initialize EMAC board */ | 723 | /* Initialize EMAC board */ |
| @@ -774,6 +773,8 @@ static int emac_stop(struct net_device *ndev) | |||
| 774 | 773 | ||
| 775 | emac_shutdown(ndev); | 774 | emac_shutdown(ndev); |
| 776 | 775 | ||
| 776 | free_irq(ndev->irq, ndev); | ||
| 777 | |||
| 777 | return 0; | 778 | return 0; |
| 778 | } | 779 | } |
| 779 | 780 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 0216d592d0ce..2e46c28fc601 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
| @@ -3114,6 +3114,11 @@ int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs_param) | |||
| 3114 | { | 3114 | { |
| 3115 | struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev)); | 3115 | struct bnx2x *bp = netdev_priv(pci_get_drvdata(dev)); |
| 3116 | 3116 | ||
| 3117 | if (!IS_SRIOV(bp)) { | ||
| 3118 | BNX2X_ERR("failed to configure SR-IOV since vfdb was not allocated. Check dmesg for errors in probe stage\n"); | ||
| 3119 | return -EINVAL; | ||
| 3120 | } | ||
| 3121 | |||
| 3117 | DP(BNX2X_MSG_IOV, "bnx2x_sriov_configure called with %d, BNX2X_NR_VIRTFN(bp) was %d\n", | 3122 | DP(BNX2X_MSG_IOV, "bnx2x_sriov_configure called with %d, BNX2X_NR_VIRTFN(bp) was %d\n", |
| 3118 | num_vfs_param, BNX2X_NR_VIRTFN(bp)); | 3123 | num_vfs_param, BNX2X_NR_VIRTFN(bp)); |
| 3119 | 3124 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 369b736dde05..f3dd93b4aeaa 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
| @@ -8932,6 +8932,9 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
| 8932 | void (*write_op)(struct tg3 *, u32, u32); | 8932 | void (*write_op)(struct tg3 *, u32, u32); |
| 8933 | int i, err; | 8933 | int i, err; |
| 8934 | 8934 | ||
| 8935 | if (!pci_device_is_present(tp->pdev)) | ||
| 8936 | return -ENODEV; | ||
| 8937 | |||
| 8935 | tg3_nvram_lock(tp); | 8938 | tg3_nvram_lock(tp); |
| 8936 | 8939 | ||
| 8937 | tg3_ape_lock(tp, TG3_APE_LOCK_GRC); | 8940 | tg3_ape_lock(tp, TG3_APE_LOCK_GRC); |
| @@ -11581,10 +11584,11 @@ static int tg3_close(struct net_device *dev) | |||
| 11581 | memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev)); | 11584 | memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev)); |
| 11582 | memset(&tp->estats_prev, 0, sizeof(tp->estats_prev)); | 11585 | memset(&tp->estats_prev, 0, sizeof(tp->estats_prev)); |
| 11583 | 11586 | ||
| 11584 | tg3_power_down_prepare(tp); | 11587 | if (pci_device_is_present(tp->pdev)) { |
| 11585 | 11588 | tg3_power_down_prepare(tp); | |
| 11586 | tg3_carrier_off(tp); | ||
| 11587 | 11589 | ||
| 11590 | tg3_carrier_off(tp); | ||
| 11591 | } | ||
| 11588 | return 0; | 11592 | return 0; |
| 11589 | } | 11593 | } |
| 11590 | 11594 | ||
| @@ -16499,6 +16503,9 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) | |||
| 16499 | /* Clear this out for sanity. */ | 16503 | /* Clear this out for sanity. */ |
| 16500 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); | 16504 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
| 16501 | 16505 | ||
| 16506 | /* Clear TG3PCI_REG_BASE_ADDR to prevent hangs. */ | ||
| 16507 | tw32(TG3PCI_REG_BASE_ADDR, 0); | ||
| 16508 | |||
| 16502 | pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, | 16509 | pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, |
| 16503 | &pci_state_reg); | 16510 | &pci_state_reg); |
| 16504 | if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 && | 16511 | if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 && |
| @@ -17726,10 +17733,12 @@ static int tg3_suspend(struct device *device) | |||
| 17726 | struct pci_dev *pdev = to_pci_dev(device); | 17733 | struct pci_dev *pdev = to_pci_dev(device); |
| 17727 | struct net_device *dev = pci_get_drvdata(pdev); | 17734 | struct net_device *dev = pci_get_drvdata(pdev); |
| 17728 | struct tg3 *tp = netdev_priv(dev); | 17735 | struct tg3 *tp = netdev_priv(dev); |
| 17729 | int err; | 17736 | int err = 0; |
| 17737 | |||
| 17738 | rtnl_lock(); | ||
| 17730 | 17739 | ||
| 17731 | if (!netif_running(dev)) | 17740 | if (!netif_running(dev)) |
| 17732 | return 0; | 17741 | goto unlock; |
| 17733 | 17742 | ||
| 17734 | tg3_reset_task_cancel(tp); | 17743 | tg3_reset_task_cancel(tp); |
| 17735 | tg3_phy_stop(tp); | 17744 | tg3_phy_stop(tp); |
| @@ -17771,6 +17780,8 @@ out: | |||
| 17771 | tg3_phy_start(tp); | 17780 | tg3_phy_start(tp); |
| 17772 | } | 17781 | } |
| 17773 | 17782 | ||
| 17783 | unlock: | ||
| 17784 | rtnl_unlock(); | ||
| 17774 | return err; | 17785 | return err; |
| 17775 | } | 17786 | } |
| 17776 | 17787 | ||
| @@ -17779,10 +17790,12 @@ static int tg3_resume(struct device *device) | |||
| 17779 | struct pci_dev *pdev = to_pci_dev(device); | 17790 | struct pci_dev *pdev = to_pci_dev(device); |
| 17780 | struct net_device *dev = pci_get_drvdata(pdev); | 17791 | struct net_device *dev = pci_get_drvdata(pdev); |
| 17781 | struct tg3 *tp = netdev_priv(dev); | 17792 | struct tg3 *tp = netdev_priv(dev); |
| 17782 | int err; | 17793 | int err = 0; |
| 17794 | |||
| 17795 | rtnl_lock(); | ||
| 17783 | 17796 | ||
| 17784 | if (!netif_running(dev)) | 17797 | if (!netif_running(dev)) |
| 17785 | return 0; | 17798 | goto unlock; |
| 17786 | 17799 | ||
| 17787 | netif_device_attach(dev); | 17800 | netif_device_attach(dev); |
| 17788 | 17801 | ||
| @@ -17806,6 +17819,8 @@ out: | |||
| 17806 | if (!err) | 17819 | if (!err) |
| 17807 | tg3_phy_start(tp); | 17820 | tg3_phy_start(tp); |
| 17808 | 17821 | ||
| 17822 | unlock: | ||
| 17823 | rtnl_unlock(); | ||
| 17809 | return err; | 17824 | return err; |
| 17810 | } | 17825 | } |
| 17811 | #endif /* CONFIG_PM_SLEEP */ | 17826 | #endif /* CONFIG_PM_SLEEP */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index ecd2fb3ef695..6c9308850453 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | |||
| @@ -49,13 +49,15 @@ | |||
| 49 | #include <asm/io.h> | 49 | #include <asm/io.h> |
| 50 | #include "cxgb4_uld.h" | 50 | #include "cxgb4_uld.h" |
| 51 | 51 | ||
| 52 | #define FW_VERSION_MAJOR 1 | 52 | #define T4FW_VERSION_MAJOR 0x01 |
| 53 | #define FW_VERSION_MINOR 4 | 53 | #define T4FW_VERSION_MINOR 0x06 |
| 54 | #define FW_VERSION_MICRO 0 | 54 | #define T4FW_VERSION_MICRO 0x18 |
| 55 | #define T4FW_VERSION_BUILD 0x00 | ||
| 55 | 56 | ||
| 56 | #define FW_VERSION_MAJOR_T5 0 | 57 | #define T5FW_VERSION_MAJOR 0x01 |
| 57 | #define FW_VERSION_MINOR_T5 0 | 58 | #define T5FW_VERSION_MINOR 0x08 |
| 58 | #define FW_VERSION_MICRO_T5 0 | 59 | #define T5FW_VERSION_MICRO 0x1C |
| 60 | #define T5FW_VERSION_BUILD 0x00 | ||
| 59 | 61 | ||
| 60 | #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__) | 62 | #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__) |
| 61 | 63 | ||
| @@ -240,6 +242,26 @@ struct pci_params { | |||
| 240 | unsigned char width; | 242 | unsigned char width; |
| 241 | }; | 243 | }; |
| 242 | 244 | ||
| 245 | #define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) | ||
| 246 | #define CHELSIO_CHIP_FPGA 0x100 | ||
| 247 | #define CHELSIO_CHIP_VERSION(code) (((code) >> 4) & 0xf) | ||
| 248 | #define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) | ||
| 249 | |||
| 250 | #define CHELSIO_T4 0x4 | ||
| 251 | #define CHELSIO_T5 0x5 | ||
| 252 | |||
| 253 | enum chip_type { | ||
| 254 | T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), | ||
| 255 | T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), | ||
| 256 | T4_FIRST_REV = T4_A1, | ||
| 257 | T4_LAST_REV = T4_A2, | ||
| 258 | |||
| 259 | T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), | ||
| 260 | T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1), | ||
| 261 | T5_FIRST_REV = T5_A0, | ||
| 262 | T5_LAST_REV = T5_A1, | ||
| 263 | }; | ||
| 264 | |||
| 243 | struct adapter_params { | 265 | struct adapter_params { |
| 244 | struct tp_params tp; | 266 | struct tp_params tp; |
| 245 | struct vpd_params vpd; | 267 | struct vpd_params vpd; |
| @@ -259,7 +281,7 @@ struct adapter_params { | |||
| 259 | 281 | ||
| 260 | unsigned char nports; /* # of ethernet ports */ | 282 | unsigned char nports; /* # of ethernet ports */ |
| 261 | unsigned char portvec; | 283 | unsigned char portvec; |
| 262 | unsigned char rev; /* chip revision */ | 284 | enum chip_type chip; /* chip code */ |
| 263 | unsigned char offload; | 285 | unsigned char offload; |
| 264 | 286 | ||
| 265 | unsigned char bypass; | 287 | unsigned char bypass; |
| @@ -267,6 +289,23 @@ struct adapter_params { | |||
| 267 | unsigned int ofldq_wr_cred; | 289 | unsigned int ofldq_wr_cred; |
| 268 | }; | 290 | }; |
| 269 | 291 | ||
| 292 | #include "t4fw_api.h" | ||
| 293 | |||
| 294 | #define FW_VERSION(chip) ( \ | ||
| 295 | FW_HDR_FW_VER_MAJOR_GET(chip##FW_VERSION_MAJOR) | \ | ||
| 296 | FW_HDR_FW_VER_MINOR_GET(chip##FW_VERSION_MINOR) | \ | ||
| 297 | FW_HDR_FW_VER_MICRO_GET(chip##FW_VERSION_MICRO) | \ | ||
| 298 | FW_HDR_FW_VER_BUILD_GET(chip##FW_VERSION_BUILD)) | ||
| 299 | #define FW_INTFVER(chip, intf) (FW_HDR_INTFVER_##intf) | ||
| 300 | |||
| 301 | struct fw_info { | ||
| 302 | u8 chip; | ||
| 303 | char *fs_name; | ||
| 304 | char *fw_mod_name; | ||
| 305 | struct fw_hdr fw_hdr; | ||
| 306 | }; | ||
| 307 | |||
| 308 | |||
| 270 | struct trace_params { | 309 | struct trace_params { |
| 271 | u32 data[TRACE_LEN / 4]; | 310 | u32 data[TRACE_LEN / 4]; |
| 272 | u32 mask[TRACE_LEN / 4]; | 311 | u32 mask[TRACE_LEN / 4]; |
| @@ -512,25 +551,6 @@ struct sge { | |||
| 512 | 551 | ||
| 513 | struct l2t_data; | 552 | struct l2t_data; |
| 514 | 553 | ||
| 515 | #define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) | ||
| 516 | #define CHELSIO_CHIP_VERSION(code) ((code) >> 4) | ||
| 517 | #define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) | ||
| 518 | |||
| 519 | #define CHELSIO_T4 0x4 | ||
| 520 | #define CHELSIO_T5 0x5 | ||
| 521 | |||
| 522 | enum chip_type { | ||
| 523 | T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0), | ||
| 524 | T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), | ||
| 525 | T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), | ||
| 526 | T4_FIRST_REV = T4_A1, | ||
| 527 | T4_LAST_REV = T4_A3, | ||
| 528 | |||
| 529 | T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), | ||
| 530 | T5_FIRST_REV = T5_A1, | ||
| 531 | T5_LAST_REV = T5_A1, | ||
| 532 | }; | ||
| 533 | |||
| 534 | #ifdef CONFIG_PCI_IOV | 554 | #ifdef CONFIG_PCI_IOV |
| 535 | 555 | ||
| 536 | /* T4 supports SRIOV on PF0-3 and T5 on PF0-7. However, the Serial | 556 | /* T4 supports SRIOV on PF0-3 and T5 on PF0-7. However, the Serial |
| @@ -715,12 +735,12 @@ enum { | |||
| 715 | 735 | ||
| 716 | static inline int is_t5(enum chip_type chip) | 736 | static inline int is_t5(enum chip_type chip) |
| 717 | { | 737 | { |
| 718 | return (chip >= T5_FIRST_REV && chip <= T5_LAST_REV); | 738 | return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T5; |
| 719 | } | 739 | } |
| 720 | 740 | ||
| 721 | static inline int is_t4(enum chip_type chip) | 741 | static inline int is_t4(enum chip_type chip) |
| 722 | { | 742 | { |
| 723 | return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV); | 743 | return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T4; |
| 724 | } | 744 | } |
| 725 | 745 | ||
| 726 | static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) | 746 | static inline u32 t4_read_reg(struct adapter *adap, u32 reg_addr) |
| @@ -900,7 +920,11 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p); | |||
| 900 | int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); | 920 | int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size); |
| 901 | unsigned int t4_flash_cfg_addr(struct adapter *adapter); | 921 | unsigned int t4_flash_cfg_addr(struct adapter *adapter); |
| 902 | int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size); | 922 | int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size); |
| 903 | int t4_check_fw_version(struct adapter *adapter); | 923 | int t4_get_fw_version(struct adapter *adapter, u32 *vers); |
| 924 | int t4_get_tp_version(struct adapter *adapter, u32 *vers); | ||
| 925 | int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, | ||
| 926 | const u8 *fw_data, unsigned int fw_size, | ||
| 927 | struct fw_hdr *card_fw, enum dev_state state, int *reset); | ||
| 904 | int t4_prep_adapter(struct adapter *adapter); | 928 | int t4_prep_adapter(struct adapter *adapter); |
| 905 | int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); | 929 | int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); |
| 906 | void t4_fatal_err(struct adapter *adapter); | 930 | void t4_fatal_err(struct adapter *adapter); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 8b929eeecd2d..d6b12e035a7d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
| @@ -276,9 +276,9 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { | |||
| 276 | { 0, } | 276 | { 0, } |
| 277 | }; | 277 | }; |
| 278 | 278 | ||
| 279 | #define FW_FNAME "cxgb4/t4fw.bin" | 279 | #define FW4_FNAME "cxgb4/t4fw.bin" |
| 280 | #define FW5_FNAME "cxgb4/t5fw.bin" | 280 | #define FW5_FNAME "cxgb4/t5fw.bin" |
| 281 | #define FW_CFNAME "cxgb4/t4-config.txt" | 281 | #define FW4_CFNAME "cxgb4/t4-config.txt" |
| 282 | #define FW5_CFNAME "cxgb4/t5-config.txt" | 282 | #define FW5_CFNAME "cxgb4/t5-config.txt" |
| 283 | 283 | ||
| 284 | MODULE_DESCRIPTION(DRV_DESC); | 284 | MODULE_DESCRIPTION(DRV_DESC); |
| @@ -286,7 +286,7 @@ MODULE_AUTHOR("Chelsio Communications"); | |||
| 286 | MODULE_LICENSE("Dual BSD/GPL"); | 286 | MODULE_LICENSE("Dual BSD/GPL"); |
| 287 | MODULE_VERSION(DRV_VERSION); | 287 | MODULE_VERSION(DRV_VERSION); |
| 288 | MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); | 288 | MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); |
| 289 | MODULE_FIRMWARE(FW_FNAME); | 289 | MODULE_FIRMWARE(FW4_FNAME); |
| 290 | MODULE_FIRMWARE(FW5_FNAME); | 290 | MODULE_FIRMWARE(FW5_FNAME); |
| 291 | 291 | ||
| 292 | /* | 292 | /* |
| @@ -1071,72 +1071,6 @@ freeout: t4_free_sge_resources(adap); | |||
| 1071 | } | 1071 | } |
| 1072 | 1072 | ||
| 1073 | /* | 1073 | /* |
| 1074 | * Returns 0 if new FW was successfully loaded, a positive errno if a load was | ||
| 1075 | * started but failed, and a negative errno if flash load couldn't start. | ||
| 1076 | */ | ||
| 1077 | static int upgrade_fw(struct adapter *adap) | ||
| 1078 | { | ||
| 1079 | int ret; | ||
| 1080 | u32 vers, exp_major; | ||
| 1081 | const struct fw_hdr *hdr; | ||
| 1082 | const struct firmware *fw; | ||
| 1083 | struct device *dev = adap->pdev_dev; | ||
| 1084 | char *fw_file_name; | ||
| 1085 | |||
| 1086 | switch (CHELSIO_CHIP_VERSION(adap->chip)) { | ||
| 1087 | case CHELSIO_T4: | ||
| 1088 | fw_file_name = FW_FNAME; | ||
| 1089 | exp_major = FW_VERSION_MAJOR; | ||
| 1090 | break; | ||
| 1091 | case CHELSIO_T5: | ||
| 1092 | fw_file_name = FW5_FNAME; | ||
| 1093 | exp_major = FW_VERSION_MAJOR_T5; | ||
| 1094 | break; | ||
| 1095 | default: | ||
| 1096 | dev_err(dev, "Unsupported chip type, %x\n", adap->chip); | ||
| 1097 | return -EINVAL; | ||
| 1098 | } | ||
| 1099 | |||
| 1100 | ret = request_firmware(&fw, fw_file_name, dev); | ||
| 1101 | if (ret < 0) { | ||
| 1102 | dev_err(dev, "unable to load firmware image %s, error %d\n", | ||
| 1103 | fw_file_name, ret); | ||
| 1104 | return ret; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | hdr = (const struct fw_hdr *)fw->data; | ||
| 1108 | vers = ntohl(hdr->fw_ver); | ||
| 1109 | if (FW_HDR_FW_VER_MAJOR_GET(vers) != exp_major) { | ||
| 1110 | ret = -EINVAL; /* wrong major version, won't do */ | ||
| 1111 | goto out; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | /* | ||
| 1115 | * If the flash FW is unusable or we found something newer, load it. | ||
| 1116 | */ | ||
| 1117 | if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != exp_major || | ||
| 1118 | vers > adap->params.fw_vers) { | ||
| 1119 | dev_info(dev, "upgrading firmware ...\n"); | ||
| 1120 | ret = t4_fw_upgrade(adap, adap->mbox, fw->data, fw->size, | ||
| 1121 | /*force=*/false); | ||
| 1122 | if (!ret) | ||
| 1123 | dev_info(dev, | ||
| 1124 | "firmware upgraded to version %pI4 from %s\n", | ||
| 1125 | &hdr->fw_ver, fw_file_name); | ||
| 1126 | else | ||
| 1127 | dev_err(dev, "firmware upgrade failed! err=%d\n", -ret); | ||
| 1128 | } else { | ||
| 1129 | /* | ||
| 1130 | * Tell our caller that we didn't upgrade the firmware. | ||
| 1131 | */ | ||
| 1132 | ret = -EINVAL; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | out: release_firmware(fw); | ||
| 1136 | return ret; | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | /* | ||
| 1140 | * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. | 1074 | * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. |
| 1141 | * The allocated memory is cleared. | 1075 | * The allocated memory is cleared. |
| 1142 | */ | 1076 | */ |
| @@ -1415,7 +1349,7 @@ static int get_sset_count(struct net_device *dev, int sset) | |||
| 1415 | static int get_regs_len(struct net_device *dev) | 1349 | static int get_regs_len(struct net_device *dev) |
| 1416 | { | 1350 | { |
| 1417 | struct adapter *adap = netdev2adap(dev); | 1351 | struct adapter *adap = netdev2adap(dev); |
| 1418 | if (is_t4(adap->chip)) | 1352 | if (is_t4(adap->params.chip)) |
| 1419 | return T4_REGMAP_SIZE; | 1353 | return T4_REGMAP_SIZE; |
| 1420 | else | 1354 | else |
| 1421 | return T5_REGMAP_SIZE; | 1355 | return T5_REGMAP_SIZE; |
| @@ -1499,7 +1433,7 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | |||
| 1499 | data += sizeof(struct port_stats) / sizeof(u64); | 1433 | data += sizeof(struct port_stats) / sizeof(u64); |
| 1500 | collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); | 1434 | collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); |
| 1501 | data += sizeof(struct queue_port_stats) / sizeof(u64); | 1435 | data += sizeof(struct queue_port_stats) / sizeof(u64); |
| 1502 | if (!is_t4(adapter->chip)) { | 1436 | if (!is_t4(adapter->params.chip)) { |
| 1503 | t4_write_reg(adapter, SGE_STAT_CFG, STATSOURCE_T5(7)); | 1437 | t4_write_reg(adapter, SGE_STAT_CFG, STATSOURCE_T5(7)); |
| 1504 | val1 = t4_read_reg(adapter, SGE_STAT_TOTAL); | 1438 | val1 = t4_read_reg(adapter, SGE_STAT_TOTAL); |
| 1505 | val2 = t4_read_reg(adapter, SGE_STAT_MATCH); | 1439 | val2 = t4_read_reg(adapter, SGE_STAT_MATCH); |
| @@ -1521,8 +1455,8 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | |||
| 1521 | */ | 1455 | */ |
| 1522 | static inline unsigned int mk_adap_vers(const struct adapter *ap) | 1456 | static inline unsigned int mk_adap_vers(const struct adapter *ap) |
| 1523 | { | 1457 | { |
| 1524 | return CHELSIO_CHIP_VERSION(ap->chip) | | 1458 | return CHELSIO_CHIP_VERSION(ap->params.chip) | |
| 1525 | (CHELSIO_CHIP_RELEASE(ap->chip) << 10) | (1 << 16); | 1459 | (CHELSIO_CHIP_RELEASE(ap->params.chip) << 10) | (1 << 16); |
| 1526 | } | 1460 | } |
| 1527 | 1461 | ||
| 1528 | static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, | 1462 | static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, |
| @@ -2189,7 +2123,7 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
| 2189 | static const unsigned int *reg_ranges; | 2123 | static const unsigned int *reg_ranges; |
| 2190 | int arr_size = 0, buf_size = 0; | 2124 | int arr_size = 0, buf_size = 0; |
| 2191 | 2125 | ||
| 2192 | if (is_t4(ap->chip)) { | 2126 | if (is_t4(ap->params.chip)) { |
| 2193 | reg_ranges = &t4_reg_ranges[0]; | 2127 | reg_ranges = &t4_reg_ranges[0]; |
| 2194 | arr_size = ARRAY_SIZE(t4_reg_ranges); | 2128 | arr_size = ARRAY_SIZE(t4_reg_ranges); |
| 2195 | buf_size = T4_REGMAP_SIZE; | 2129 | buf_size = T4_REGMAP_SIZE; |
| @@ -2967,7 +2901,7 @@ static int setup_debugfs(struct adapter *adap) | |||
| 2967 | size = t4_read_reg(adap, MA_EDRAM1_BAR); | 2901 | size = t4_read_reg(adap, MA_EDRAM1_BAR); |
| 2968 | add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); | 2902 | add_debugfs_mem(adap, "edc1", MEM_EDC1, EDRAM_SIZE_GET(size)); |
| 2969 | } | 2903 | } |
| 2970 | if (is_t4(adap->chip)) { | 2904 | if (is_t4(adap->params.chip)) { |
| 2971 | size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); | 2905 | size = t4_read_reg(adap, MA_EXT_MEMORY_BAR); |
| 2972 | if (i & EXT_MEM_ENABLE) | 2906 | if (i & EXT_MEM_ENABLE) |
| 2973 | add_debugfs_mem(adap, "mc", MEM_MC, | 2907 | add_debugfs_mem(adap, "mc", MEM_MC, |
| @@ -3419,7 +3353,7 @@ unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo) | |||
| 3419 | 3353 | ||
| 3420 | v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); | 3354 | v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); |
| 3421 | v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); | 3355 | v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); |
| 3422 | if (is_t4(adap->chip)) { | 3356 | if (is_t4(adap->params.chip)) { |
| 3423 | lp_count = G_LP_COUNT(v1); | 3357 | lp_count = G_LP_COUNT(v1); |
| 3424 | hp_count = G_HP_COUNT(v1); | 3358 | hp_count = G_HP_COUNT(v1); |
| 3425 | } else { | 3359 | } else { |
| @@ -3588,7 +3522,7 @@ static void drain_db_fifo(struct adapter *adap, int usecs) | |||
| 3588 | do { | 3522 | do { |
| 3589 | v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); | 3523 | v1 = t4_read_reg(adap, A_SGE_DBFIFO_STATUS); |
| 3590 | v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); | 3524 | v2 = t4_read_reg(adap, SGE_DBFIFO_STATUS2); |
| 3591 | if (is_t4(adap->chip)) { | 3525 | if (is_t4(adap->params.chip)) { |
| 3592 | lp_count = G_LP_COUNT(v1); | 3526 | lp_count = G_LP_COUNT(v1); |
| 3593 | hp_count = G_HP_COUNT(v1); | 3527 | hp_count = G_HP_COUNT(v1); |
| 3594 | } else { | 3528 | } else { |
| @@ -3708,7 +3642,7 @@ static void process_db_drop(struct work_struct *work) | |||
| 3708 | 3642 | ||
| 3709 | adap = container_of(work, struct adapter, db_drop_task); | 3643 | adap = container_of(work, struct adapter, db_drop_task); |
| 3710 | 3644 | ||
| 3711 | if (is_t4(adap->chip)) { | 3645 | if (is_t4(adap->params.chip)) { |
| 3712 | disable_dbs(adap); | 3646 | disable_dbs(adap); |
| 3713 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP); | 3647 | notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP); |
| 3714 | drain_db_fifo(adap, 1); | 3648 | drain_db_fifo(adap, 1); |
| @@ -3753,7 +3687,7 @@ static void process_db_drop(struct work_struct *work) | |||
| 3753 | 3687 | ||
| 3754 | void t4_db_full(struct adapter *adap) | 3688 | void t4_db_full(struct adapter *adap) |
| 3755 | { | 3689 | { |
| 3756 | if (is_t4(adap->chip)) { | 3690 | if (is_t4(adap->params.chip)) { |
| 3757 | t4_set_reg_field(adap, SGE_INT_ENABLE3, | 3691 | t4_set_reg_field(adap, SGE_INT_ENABLE3, |
| 3758 | DBFIFO_HP_INT | DBFIFO_LP_INT, 0); | 3692 | DBFIFO_HP_INT | DBFIFO_LP_INT, 0); |
| 3759 | queue_work(workq, &adap->db_full_task); | 3693 | queue_work(workq, &adap->db_full_task); |
| @@ -3762,7 +3696,7 @@ void t4_db_full(struct adapter *adap) | |||
| 3762 | 3696 | ||
| 3763 | void t4_db_dropped(struct adapter *adap) | 3697 | void t4_db_dropped(struct adapter *adap) |
| 3764 | { | 3698 | { |
| 3765 | if (is_t4(adap->chip)) | 3699 | if (is_t4(adap->params.chip)) |
| 3766 | queue_work(workq, &adap->db_drop_task); | 3700 | queue_work(workq, &adap->db_drop_task); |
| 3767 | } | 3701 | } |
| 3768 | 3702 | ||
| @@ -3789,7 +3723,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld) | |||
| 3789 | lli.nchan = adap->params.nports; | 3723 | lli.nchan = adap->params.nports; |
| 3790 | lli.nports = adap->params.nports; | 3724 | lli.nports = adap->params.nports; |
| 3791 | lli.wr_cred = adap->params.ofldq_wr_cred; | 3725 | lli.wr_cred = adap->params.ofldq_wr_cred; |
| 3792 | lli.adapter_type = adap->params.rev; | 3726 | lli.adapter_type = adap->params.chip; |
| 3793 | lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2)); | 3727 | lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2)); |
| 3794 | lli.udb_density = 1 << QUEUESPERPAGEPF0_GET( | 3728 | lli.udb_density = 1 << QUEUESPERPAGEPF0_GET( |
| 3795 | t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >> | 3729 | t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >> |
| @@ -4483,7 +4417,7 @@ static void setup_memwin(struct adapter *adap) | |||
| 4483 | u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base; | 4417 | u32 bar0, mem_win0_base, mem_win1_base, mem_win2_base; |
| 4484 | 4418 | ||
| 4485 | bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */ | 4419 | bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */ |
| 4486 | if (is_t4(adap->chip)) { | 4420 | if (is_t4(adap->params.chip)) { |
| 4487 | mem_win0_base = bar0 + MEMWIN0_BASE; | 4421 | mem_win0_base = bar0 + MEMWIN0_BASE; |
| 4488 | mem_win1_base = bar0 + MEMWIN1_BASE; | 4422 | mem_win1_base = bar0 + MEMWIN1_BASE; |
| 4489 | mem_win2_base = bar0 + MEMWIN2_BASE; | 4423 | mem_win2_base = bar0 + MEMWIN2_BASE; |
| @@ -4668,8 +4602,10 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4668 | const struct firmware *cf; | 4602 | const struct firmware *cf; |
| 4669 | unsigned long mtype = 0, maddr = 0; | 4603 | unsigned long mtype = 0, maddr = 0; |
| 4670 | u32 finiver, finicsum, cfcsum; | 4604 | u32 finiver, finicsum, cfcsum; |
| 4671 | int ret, using_flash; | 4605 | int ret; |
| 4606 | int config_issued = 0; | ||
| 4672 | char *fw_config_file, fw_config_file_path[256]; | 4607 | char *fw_config_file, fw_config_file_path[256]; |
| 4608 | char *config_name = NULL; | ||
| 4673 | 4609 | ||
| 4674 | /* | 4610 | /* |
| 4675 | * Reset device if necessary. | 4611 | * Reset device if necessary. |
| @@ -4686,9 +4622,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4686 | * then use that. Otherwise, use the configuration file stored | 4622 | * then use that. Otherwise, use the configuration file stored |
| 4687 | * in the adapter flash ... | 4623 | * in the adapter flash ... |
| 4688 | */ | 4624 | */ |
| 4689 | switch (CHELSIO_CHIP_VERSION(adapter->chip)) { | 4625 | switch (CHELSIO_CHIP_VERSION(adapter->params.chip)) { |
| 4690 | case CHELSIO_T4: | 4626 | case CHELSIO_T4: |
| 4691 | fw_config_file = FW_CFNAME; | 4627 | fw_config_file = FW4_CFNAME; |
| 4692 | break; | 4628 | break; |
| 4693 | case CHELSIO_T5: | 4629 | case CHELSIO_T5: |
| 4694 | fw_config_file = FW5_CFNAME; | 4630 | fw_config_file = FW5_CFNAME; |
| @@ -4702,13 +4638,16 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4702 | 4638 | ||
| 4703 | ret = request_firmware(&cf, fw_config_file, adapter->pdev_dev); | 4639 | ret = request_firmware(&cf, fw_config_file, adapter->pdev_dev); |
| 4704 | if (ret < 0) { | 4640 | if (ret < 0) { |
| 4705 | using_flash = 1; | 4641 | config_name = "On FLASH"; |
| 4706 | mtype = FW_MEMTYPE_CF_FLASH; | 4642 | mtype = FW_MEMTYPE_CF_FLASH; |
| 4707 | maddr = t4_flash_cfg_addr(adapter); | 4643 | maddr = t4_flash_cfg_addr(adapter); |
| 4708 | } else { | 4644 | } else { |
| 4709 | u32 params[7], val[7]; | 4645 | u32 params[7], val[7]; |
| 4710 | 4646 | ||
| 4711 | using_flash = 0; | 4647 | sprintf(fw_config_file_path, |
| 4648 | "/lib/firmware/%s", fw_config_file); | ||
| 4649 | config_name = fw_config_file_path; | ||
| 4650 | |||
| 4712 | if (cf->size >= FLASH_CFG_MAX_SIZE) | 4651 | if (cf->size >= FLASH_CFG_MAX_SIZE) |
| 4713 | ret = -ENOMEM; | 4652 | ret = -ENOMEM; |
| 4714 | else { | 4653 | else { |
| @@ -4776,6 +4715,26 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4776 | FW_LEN16(caps_cmd)); | 4715 | FW_LEN16(caps_cmd)); |
| 4777 | ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), | 4716 | ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, sizeof(caps_cmd), |
| 4778 | &caps_cmd); | 4717 | &caps_cmd); |
| 4718 | |||
| 4719 | /* If the CAPS_CONFIG failed with an ENOENT (for a Firmware | ||
| 4720 | * Configuration File in FLASH), our last gasp effort is to use the | ||
| 4721 | * Firmware Configuration File which is embedded in the firmware. A | ||
| 4722 | * very few early versions of the firmware didn't have one embedded | ||
| 4723 | * but we can ignore those. | ||
| 4724 | */ | ||
| 4725 | if (ret == -ENOENT) { | ||
| 4726 | memset(&caps_cmd, 0, sizeof(caps_cmd)); | ||
| 4727 | caps_cmd.op_to_write = | ||
| 4728 | htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | ||
| 4729 | FW_CMD_REQUEST | | ||
| 4730 | FW_CMD_READ); | ||
| 4731 | caps_cmd.cfvalid_to_len16 = htonl(FW_LEN16(caps_cmd)); | ||
| 4732 | ret = t4_wr_mbox(adapter, adapter->mbox, &caps_cmd, | ||
| 4733 | sizeof(caps_cmd), &caps_cmd); | ||
| 4734 | config_name = "Firmware Default"; | ||
| 4735 | } | ||
| 4736 | |||
| 4737 | config_issued = 1; | ||
| 4779 | if (ret < 0) | 4738 | if (ret < 0) |
| 4780 | goto bye; | 4739 | goto bye; |
| 4781 | 4740 | ||
| @@ -4816,7 +4775,6 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4816 | if (ret < 0) | 4775 | if (ret < 0) |
| 4817 | goto bye; | 4776 | goto bye; |
| 4818 | 4777 | ||
| 4819 | sprintf(fw_config_file_path, "/lib/firmware/%s", fw_config_file); | ||
| 4820 | /* | 4778 | /* |
| 4821 | * Return successfully and note that we're operating with parameters | 4779 | * Return successfully and note that we're operating with parameters |
| 4822 | * not supplied by the driver, rather than from hard-wired | 4780 | * not supplied by the driver, rather than from hard-wired |
| @@ -4824,11 +4782,8 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4824 | */ | 4782 | */ |
| 4825 | adapter->flags |= USING_SOFT_PARAMS; | 4783 | adapter->flags |= USING_SOFT_PARAMS; |
| 4826 | dev_info(adapter->pdev_dev, "Successfully configured using Firmware "\ | 4784 | dev_info(adapter->pdev_dev, "Successfully configured using Firmware "\ |
| 4827 | "Configuration File %s, version %#x, computed checksum %#x\n", | 4785 | "Configuration File \"%s\", version %#x, computed checksum %#x\n", |
| 4828 | (using_flash | 4786 | config_name, finiver, cfcsum); |
| 4829 | ? "in device FLASH" | ||
| 4830 | : fw_config_file_path), | ||
| 4831 | finiver, cfcsum); | ||
| 4832 | return 0; | 4787 | return 0; |
| 4833 | 4788 | ||
| 4834 | /* | 4789 | /* |
| @@ -4837,9 +4792,9 @@ static int adap_init0_config(struct adapter *adapter, int reset) | |||
| 4837 | * want to issue a warning since this is fairly common.) | 4792 | * want to issue a warning since this is fairly common.) |
| 4838 | */ | 4793 | */ |
| 4839 | bye: | 4794 | bye: |
| 4840 | if (ret != -ENOENT) | 4795 | if (config_issued && ret != -ENOENT) |
| 4841 | dev_warn(adapter->pdev_dev, "Configuration file error %d\n", | 4796 | dev_warn(adapter->pdev_dev, "\"%s\" configuration file error %d\n", |
| 4842 | -ret); | 4797 | config_name, -ret); |
| 4843 | return ret; | 4798 | return ret; |
| 4844 | } | 4799 | } |
| 4845 | 4800 | ||
| @@ -5086,6 +5041,47 @@ bye: | |||
| 5086 | return ret; | 5041 | return ret; |
| 5087 | } | 5042 | } |
| 5088 | 5043 | ||
| 5044 | static struct fw_info fw_info_array[] = { | ||
| 5045 | { | ||
| 5046 | .chip = CHELSIO_T4, | ||
| 5047 | .fs_name = FW4_CFNAME, | ||
| 5048 | .fw_mod_name = FW4_FNAME, | ||
| 5049 | .fw_hdr = { | ||
| 5050 | .chip = FW_HDR_CHIP_T4, | ||
| 5051 | .fw_ver = __cpu_to_be32(FW_VERSION(T4)), | ||
| 5052 | .intfver_nic = FW_INTFVER(T4, NIC), | ||
| 5053 | .intfver_vnic = FW_INTFVER(T4, VNIC), | ||
| 5054 | .intfver_ri = FW_INTFVER(T4, RI), | ||
| 5055 | .intfver_iscsi = FW_INTFVER(T4, ISCSI), | ||
| 5056 | .intfver_fcoe = FW_INTFVER(T4, FCOE), | ||
| 5057 | }, | ||
| 5058 | }, { | ||
| 5059 | .chip = CHELSIO_T5, | ||
| 5060 | .fs_name = FW5_CFNAME, | ||
| 5061 | .fw_mod_name = FW5_FNAME, | ||
| 5062 | .fw_hdr = { | ||
| 5063 | .chip = FW_HDR_CHIP_T5, | ||
| 5064 | .fw_ver = __cpu_to_be32(FW_VERSION(T5)), | ||
| 5065 | .intfver_nic = FW_INTFVER(T5, NIC), | ||
| 5066 | .intfver_vnic = FW_INTFVER(T5, VNIC), | ||
| 5067 | .intfver_ri = FW_INTFVER(T5, RI), | ||
| 5068 | .intfver_iscsi = FW_INTFVER(T5, ISCSI), | ||
| 5069 | .intfver_fcoe = FW_INTFVER(T5, FCOE), | ||
| 5070 | }, | ||
| 5071 | } | ||
| 5072 | }; | ||
| 5073 | |||
| 5074 | static struct fw_info *find_fw_info(int chip) | ||
| 5075 | { | ||
| 5076 | int i; | ||
| 5077 | |||
| 5078 | for (i = 0; i < ARRAY_SIZE(fw_info_array); i++) { | ||
| 5079 | if (fw_info_array[i].chip == chip) | ||
| 5080 | return &fw_info_array[i]; | ||
| 5081 | } | ||
| 5082 | return NULL; | ||
| 5083 | } | ||
| 5084 | |||
| 5089 | /* | 5085 | /* |
| 5090 | * Phase 0 of initialization: contact FW, obtain config, perform basic init. | 5086 | * Phase 0 of initialization: contact FW, obtain config, perform basic init. |
| 5091 | */ | 5087 | */ |
| @@ -5123,44 +5119,54 @@ static int adap_init0(struct adapter *adap) | |||
| 5123 | * later reporting and B. to warn if the currently loaded firmware | 5119 | * later reporting and B. to warn if the currently loaded firmware |
| 5124 | * is excessively mismatched relative to the driver.) | 5120 | * is excessively mismatched relative to the driver.) |
| 5125 | */ | 5121 | */ |
| 5126 | ret = t4_check_fw_version(adap); | 5122 | t4_get_fw_version(adap, &adap->params.fw_vers); |
| 5127 | 5123 | t4_get_tp_version(adap, &adap->params.tp_vers); | |
| 5128 | /* The error code -EFAULT is returned by t4_check_fw_version() if | ||
| 5129 | * firmware on adapter < supported firmware. If firmware on adapter | ||
| 5130 | * is too old (not supported by driver) and we're the MASTER_PF set | ||
| 5131 | * adapter state to DEV_STATE_UNINIT to force firmware upgrade | ||
| 5132 | * and reinitialization. | ||
| 5133 | */ | ||
| 5134 | if ((adap->flags & MASTER_PF) && ret == -EFAULT) | ||
| 5135 | state = DEV_STATE_UNINIT; | ||
| 5136 | if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) { | 5124 | if ((adap->flags & MASTER_PF) && state != DEV_STATE_INIT) { |
| 5137 | if (ret == -EINVAL || ret == -EFAULT || ret > 0) { | 5125 | struct fw_info *fw_info; |
| 5138 | if (upgrade_fw(adap) >= 0) { | 5126 | struct fw_hdr *card_fw; |
| 5139 | /* | 5127 | const struct firmware *fw; |
| 5140 | * Note that the chip was reset as part of the | 5128 | const u8 *fw_data = NULL; |
| 5141 | * firmware upgrade so we don't reset it again | 5129 | unsigned int fw_size = 0; |
| 5142 | * below and grab the new firmware version. | 5130 | |
| 5143 | */ | 5131 | /* This is the firmware whose headers the driver was compiled |
| 5144 | reset = 0; | 5132 | * against |
| 5145 | ret = t4_check_fw_version(adap); | 5133 | */ |
| 5146 | } else | 5134 | fw_info = find_fw_info(CHELSIO_CHIP_VERSION(adap->params.chip)); |
| 5147 | if (ret == -EFAULT) { | 5135 | if (fw_info == NULL) { |
| 5148 | /* | 5136 | dev_err(adap->pdev_dev, |
| 5149 | * Firmware is old but still might | 5137 | "unable to get firmware info for chip %d.\n", |
| 5150 | * work if we force reinitialization | 5138 | CHELSIO_CHIP_VERSION(adap->params.chip)); |
| 5151 | * of the adapter. Ignoring FW upgrade | 5139 | return -EINVAL; |
| 5152 | * failure. | ||
| 5153 | */ | ||
| 5154 | dev_warn(adap->pdev_dev, | ||
| 5155 | "Ignoring firmware upgrade " | ||
| 5156 | "failure, and forcing driver " | ||
| 5157 | "to reinitialize the " | ||
| 5158 | "adapter.\n"); | ||
| 5159 | ret = 0; | ||
| 5160 | } | ||
| 5161 | } | 5140 | } |
| 5141 | |||
| 5142 | /* allocate memory to read the header of the firmware on the | ||
| 5143 | * card | ||
| 5144 | */ | ||
| 5145 | card_fw = t4_alloc_mem(sizeof(*card_fw)); | ||
| 5146 | |||
| 5147 | /* Get FW from from /lib/firmware/ */ | ||
| 5148 | ret = request_firmware(&fw, fw_info->fw_mod_name, | ||
| 5149 | adap->pdev_dev); | ||
| 5150 | if (ret < 0) { | ||
| 5151 | dev_err(adap->pdev_dev, | ||
| 5152 | "unable to load firmware image %s, error %d\n", | ||
| 5153 | fw_info->fw_mod_name, ret); | ||
| 5154 | } else { | ||
| 5155 | fw_data = fw->data; | ||
| 5156 | fw_size = fw->size; | ||
| 5157 | } | ||
| 5158 | |||
| 5159 | /* upgrade FW logic */ | ||
| 5160 | ret = t4_prep_fw(adap, fw_info, fw_data, fw_size, card_fw, | ||
| 5161 | state, &reset); | ||
| 5162 | |||
| 5163 | /* Cleaning up */ | ||
| 5164 | if (fw != NULL) | ||
| 5165 | release_firmware(fw); | ||
| 5166 | t4_free_mem(card_fw); | ||
| 5167 | |||
| 5162 | if (ret < 0) | 5168 | if (ret < 0) |
| 5163 | return ret; | 5169 | goto bye; |
| 5164 | } | 5170 | } |
| 5165 | 5171 | ||
| 5166 | /* | 5172 | /* |
| @@ -5245,7 +5251,7 @@ static int adap_init0(struct adapter *adap) | |||
| 5245 | if (ret == -ENOENT) { | 5251 | if (ret == -ENOENT) { |
| 5246 | dev_info(adap->pdev_dev, | 5252 | dev_info(adap->pdev_dev, |
| 5247 | "No Configuration File present " | 5253 | "No Configuration File present " |
| 5248 | "on adapter. Using hard-wired " | 5254 | "on adapter. Using hard-wired " |
| 5249 | "configuration parameters.\n"); | 5255 | "configuration parameters.\n"); |
| 5250 | ret = adap_init0_no_config(adap, reset); | 5256 | ret = adap_init0_no_config(adap, reset); |
| 5251 | } | 5257 | } |
| @@ -5787,7 +5793,7 @@ static void print_port_info(const struct net_device *dev) | |||
| 5787 | 5793 | ||
| 5788 | netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", | 5794 | netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", |
| 5789 | adap->params.vpd.id, | 5795 | adap->params.vpd.id, |
| 5790 | CHELSIO_CHIP_RELEASE(adap->params.rev), buf, | 5796 | CHELSIO_CHIP_RELEASE(adap->params.chip), buf, |
| 5791 | is_offload(adap) ? "R" : "", adap->params.pci.width, spd, | 5797 | is_offload(adap) ? "R" : "", adap->params.pci.width, spd, |
| 5792 | (adap->flags & USING_MSIX) ? " MSI-X" : | 5798 | (adap->flags & USING_MSIX) ? " MSI-X" : |
| 5793 | (adap->flags & USING_MSI) ? " MSI" : ""); | 5799 | (adap->flags & USING_MSI) ? " MSI" : ""); |
| @@ -5910,7 +5916,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 5910 | if (err) | 5916 | if (err) |
| 5911 | goto out_unmap_bar0; | 5917 | goto out_unmap_bar0; |
| 5912 | 5918 | ||
| 5913 | if (!is_t4(adapter->chip)) { | 5919 | if (!is_t4(adapter->params.chip)) { |
| 5914 | s_qpp = QUEUESPERPAGEPF1 * adapter->fn; | 5920 | s_qpp = QUEUESPERPAGEPF1 * adapter->fn; |
| 5915 | qpp = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adapter, | 5921 | qpp = 1 << QUEUESPERPAGEPF0_GET(t4_read_reg(adapter, |
| 5916 | SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp); | 5922 | SGE_EGRESS_QUEUES_PER_PAGE_PF) >> s_qpp); |
| @@ -6064,7 +6070,7 @@ sriov: | |||
| 6064 | out_free_dev: | 6070 | out_free_dev: |
| 6065 | free_some_resources(adapter); | 6071 | free_some_resources(adapter); |
| 6066 | out_unmap_bar: | 6072 | out_unmap_bar: |
| 6067 | if (!is_t4(adapter->chip)) | 6073 | if (!is_t4(adapter->params.chip)) |
| 6068 | iounmap(adapter->bar2); | 6074 | iounmap(adapter->bar2); |
| 6069 | out_unmap_bar0: | 6075 | out_unmap_bar0: |
| 6070 | iounmap(adapter->regs); | 6076 | iounmap(adapter->regs); |
| @@ -6116,7 +6122,7 @@ static void remove_one(struct pci_dev *pdev) | |||
| 6116 | 6122 | ||
| 6117 | free_some_resources(adapter); | 6123 | free_some_resources(adapter); |
| 6118 | iounmap(adapter->regs); | 6124 | iounmap(adapter->regs); |
| 6119 | if (!is_t4(adapter->chip)) | 6125 | if (!is_t4(adapter->params.chip)) |
| 6120 | iounmap(adapter->bar2); | 6126 | iounmap(adapter->bar2); |
| 6121 | kfree(adapter); | 6127 | kfree(adapter); |
| 6122 | pci_disable_pcie_error_reporting(pdev); | 6128 | pci_disable_pcie_error_reporting(pdev); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index ac311f5f3eb9..cc380c36e1a8 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
| @@ -509,7 +509,7 @@ static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q) | |||
| 509 | u32 val; | 509 | u32 val; |
| 510 | if (q->pend_cred >= 8) { | 510 | if (q->pend_cred >= 8) { |
| 511 | val = PIDX(q->pend_cred / 8); | 511 | val = PIDX(q->pend_cred / 8); |
| 512 | if (!is_t4(adap->chip)) | 512 | if (!is_t4(adap->params.chip)) |
| 513 | val |= DBTYPE(1); | 513 | val |= DBTYPE(1); |
| 514 | wmb(); | 514 | wmb(); |
| 515 | t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) | | 515 | t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) | |
| @@ -847,7 +847,7 @@ static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n) | |||
| 847 | wmb(); /* write descriptors before telling HW */ | 847 | wmb(); /* write descriptors before telling HW */ |
| 848 | spin_lock(&q->db_lock); | 848 | spin_lock(&q->db_lock); |
| 849 | if (!q->db_disabled) { | 849 | if (!q->db_disabled) { |
| 850 | if (is_t4(adap->chip)) { | 850 | if (is_t4(adap->params.chip)) { |
| 851 | t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), | 851 | t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), |
| 852 | QID(q->cntxt_id) | PIDX(n)); | 852 | QID(q->cntxt_id) | PIDX(n)); |
| 853 | } else { | 853 | } else { |
| @@ -1596,7 +1596,7 @@ static noinline int handle_trace_pkt(struct adapter *adap, | |||
| 1596 | return 0; | 1596 | return 0; |
| 1597 | } | 1597 | } |
| 1598 | 1598 | ||
| 1599 | if (is_t4(adap->chip)) | 1599 | if (is_t4(adap->params.chip)) |
| 1600 | __skb_pull(skb, sizeof(struct cpl_trace_pkt)); | 1600 | __skb_pull(skb, sizeof(struct cpl_trace_pkt)); |
| 1601 | else | 1601 | else |
| 1602 | __skb_pull(skb, sizeof(struct cpl_t5_trace_pkt)); | 1602 | __skb_pull(skb, sizeof(struct cpl_t5_trace_pkt)); |
| @@ -1661,7 +1661,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, | |||
| 1661 | const struct cpl_rx_pkt *pkt; | 1661 | const struct cpl_rx_pkt *pkt; |
| 1662 | struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); | 1662 | struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq); |
| 1663 | struct sge *s = &q->adap->sge; | 1663 | struct sge *s = &q->adap->sge; |
| 1664 | int cpl_trace_pkt = is_t4(q->adap->chip) ? | 1664 | int cpl_trace_pkt = is_t4(q->adap->params.chip) ? |
| 1665 | CPL_TRACE_PKT : CPL_TRACE_PKT_T5; | 1665 | CPL_TRACE_PKT : CPL_TRACE_PKT_T5; |
| 1666 | 1666 | ||
| 1667 | if (unlikely(*(u8 *)rsp == cpl_trace_pkt)) | 1667 | if (unlikely(*(u8 *)rsp == cpl_trace_pkt)) |
| @@ -2182,7 +2182,7 @@ err: | |||
| 2182 | static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) | 2182 | static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) |
| 2183 | { | 2183 | { |
| 2184 | q->cntxt_id = id; | 2184 | q->cntxt_id = id; |
| 2185 | if (!is_t4(adap->chip)) { | 2185 | if (!is_t4(adap->params.chip)) { |
| 2186 | unsigned int s_qpp; | 2186 | unsigned int s_qpp; |
| 2187 | unsigned short udb_density; | 2187 | unsigned short udb_density; |
| 2188 | unsigned long qpshift; | 2188 | unsigned long qpshift; |
| @@ -2641,7 +2641,7 @@ static int t4_sge_init_hard(struct adapter *adap) | |||
| 2641 | * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows | 2641 | * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows |
| 2642 | * and generate an interrupt when this occurs so we can recover. | 2642 | * and generate an interrupt when this occurs so we can recover. |
| 2643 | */ | 2643 | */ |
| 2644 | if (is_t4(adap->chip)) { | 2644 | if (is_t4(adap->params.chip)) { |
| 2645 | t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, | 2645 | t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS, |
| 2646 | V_HP_INT_THRESH(M_HP_INT_THRESH) | | 2646 | V_HP_INT_THRESH(M_HP_INT_THRESH) | |
| 2647 | V_LP_INT_THRESH(M_LP_INT_THRESH), | 2647 | V_LP_INT_THRESH(M_LP_INT_THRESH), |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 4cbb2f9850be..74a6fce5a15a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | |||
| @@ -296,7 +296,7 @@ int t4_mc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) | |||
| 296 | u32 mc_bist_cmd, mc_bist_cmd_addr, mc_bist_cmd_len; | 296 | u32 mc_bist_cmd, mc_bist_cmd_addr, mc_bist_cmd_len; |
| 297 | u32 mc_bist_status_rdata, mc_bist_data_pattern; | 297 | u32 mc_bist_status_rdata, mc_bist_data_pattern; |
| 298 | 298 | ||
| 299 | if (is_t4(adap->chip)) { | 299 | if (is_t4(adap->params.chip)) { |
| 300 | mc_bist_cmd = MC_BIST_CMD; | 300 | mc_bist_cmd = MC_BIST_CMD; |
| 301 | mc_bist_cmd_addr = MC_BIST_CMD_ADDR; | 301 | mc_bist_cmd_addr = MC_BIST_CMD_ADDR; |
| 302 | mc_bist_cmd_len = MC_BIST_CMD_LEN; | 302 | mc_bist_cmd_len = MC_BIST_CMD_LEN; |
| @@ -349,7 +349,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) | |||
| 349 | u32 edc_bist_cmd, edc_bist_cmd_addr, edc_bist_cmd_len; | 349 | u32 edc_bist_cmd, edc_bist_cmd_addr, edc_bist_cmd_len; |
| 350 | u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata; | 350 | u32 edc_bist_cmd_data_pattern, edc_bist_status_rdata; |
| 351 | 351 | ||
| 352 | if (is_t4(adap->chip)) { | 352 | if (is_t4(adap->params.chip)) { |
| 353 | edc_bist_cmd = EDC_REG(EDC_BIST_CMD, idx); | 353 | edc_bist_cmd = EDC_REG(EDC_BIST_CMD, idx); |
| 354 | edc_bist_cmd_addr = EDC_REG(EDC_BIST_CMD_ADDR, idx); | 354 | edc_bist_cmd_addr = EDC_REG(EDC_BIST_CMD_ADDR, idx); |
| 355 | edc_bist_cmd_len = EDC_REG(EDC_BIST_CMD_LEN, idx); | 355 | edc_bist_cmd_len = EDC_REG(EDC_BIST_CMD_LEN, idx); |
| @@ -402,7 +402,7 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc) | |||
| 402 | static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir) | 402 | static int t4_mem_win_rw(struct adapter *adap, u32 addr, __be32 *data, int dir) |
| 403 | { | 403 | { |
| 404 | int i; | 404 | int i; |
| 405 | u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn); | 405 | u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn); |
| 406 | 406 | ||
| 407 | /* | 407 | /* |
| 408 | * Setup offset into PCIE memory window. Address must be a | 408 | * Setup offset into PCIE memory window. Address must be a |
| @@ -863,104 +863,169 @@ unlock: | |||
| 863 | } | 863 | } |
| 864 | 864 | ||
| 865 | /** | 865 | /** |
| 866 | * get_fw_version - read the firmware version | 866 | * t4_get_fw_version - read the firmware version |
| 867 | * @adapter: the adapter | 867 | * @adapter: the adapter |
| 868 | * @vers: where to place the version | 868 | * @vers: where to place the version |
| 869 | * | 869 | * |
| 870 | * Reads the FW version from flash. | 870 | * Reads the FW version from flash. |
| 871 | */ | 871 | */ |
| 872 | static int get_fw_version(struct adapter *adapter, u32 *vers) | 872 | int t4_get_fw_version(struct adapter *adapter, u32 *vers) |
| 873 | { | 873 | { |
| 874 | return t4_read_flash(adapter, adapter->params.sf_fw_start + | 874 | return t4_read_flash(adapter, FLASH_FW_START + |
| 875 | offsetof(struct fw_hdr, fw_ver), 1, vers, 0); | 875 | offsetof(struct fw_hdr, fw_ver), 1, |
| 876 | vers, 0); | ||
| 876 | } | 877 | } |
| 877 | 878 | ||
| 878 | /** | 879 | /** |
| 879 | * get_tp_version - read the TP microcode version | 880 | * t4_get_tp_version - read the TP microcode version |
| 880 | * @adapter: the adapter | 881 | * @adapter: the adapter |
| 881 | * @vers: where to place the version | 882 | * @vers: where to place the version |
| 882 | * | 883 | * |
| 883 | * Reads the TP microcode version from flash. | 884 | * Reads the TP microcode version from flash. |
| 884 | */ | 885 | */ |
| 885 | static int get_tp_version(struct adapter *adapter, u32 *vers) | 886 | int t4_get_tp_version(struct adapter *adapter, u32 *vers) |
| 886 | { | 887 | { |
| 887 | return t4_read_flash(adapter, adapter->params.sf_fw_start + | 888 | return t4_read_flash(adapter, FLASH_FW_START + |
| 888 | offsetof(struct fw_hdr, tp_microcode_ver), | 889 | offsetof(struct fw_hdr, tp_microcode_ver), |
| 889 | 1, vers, 0); | 890 | 1, vers, 0); |
| 890 | } | 891 | } |
| 891 | 892 | ||
| 892 | /** | 893 | /* Is the given firmware API compatible with the one the driver was compiled |
| 893 | * t4_check_fw_version - check if the FW is compatible with this driver | 894 | * with? |
| 894 | * @adapter: the adapter | ||
| 895 | * | ||
| 896 | * Checks if an adapter's FW is compatible with the driver. Returns 0 | ||
| 897 | * if there's exact match, a negative error if the version could not be | ||
| 898 | * read or there's a major version mismatch, and a positive value if the | ||
| 899 | * expected major version is found but there's a minor version mismatch. | ||
| 900 | */ | 895 | */ |
| 901 | int t4_check_fw_version(struct adapter *adapter) | 896 | static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2) |
| 902 | { | 897 | { |
| 903 | u32 api_vers[2]; | ||
| 904 | int ret, major, minor, micro; | ||
| 905 | int exp_major, exp_minor, exp_micro; | ||
| 906 | 898 | ||
| 907 | ret = get_fw_version(adapter, &adapter->params.fw_vers); | 899 | /* short circuit if it's the exact same firmware version */ |
| 908 | if (!ret) | 900 | if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver) |
| 909 | ret = get_tp_version(adapter, &adapter->params.tp_vers); | 901 | return 1; |
| 910 | if (!ret) | ||
| 911 | ret = t4_read_flash(adapter, adapter->params.sf_fw_start + | ||
| 912 | offsetof(struct fw_hdr, intfver_nic), | ||
| 913 | 2, api_vers, 1); | ||
| 914 | if (ret) | ||
| 915 | return ret; | ||
| 916 | 902 | ||
| 917 | major = FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers); | 903 | #define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x) |
| 918 | minor = FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers); | 904 | if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) && |
| 919 | micro = FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers); | 905 | SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe)) |
| 906 | return 1; | ||
| 907 | #undef SAME_INTF | ||
| 920 | 908 | ||
| 921 | switch (CHELSIO_CHIP_VERSION(adapter->chip)) { | 909 | return 0; |
| 922 | case CHELSIO_T4: | 910 | } |
| 923 | exp_major = FW_VERSION_MAJOR; | ||
| 924 | exp_minor = FW_VERSION_MINOR; | ||
| 925 | exp_micro = FW_VERSION_MICRO; | ||
| 926 | break; | ||
| 927 | case CHELSIO_T5: | ||
| 928 | exp_major = FW_VERSION_MAJOR_T5; | ||
| 929 | exp_minor = FW_VERSION_MINOR_T5; | ||
| 930 | exp_micro = FW_VERSION_MICRO_T5; | ||
| 931 | break; | ||
| 932 | default: | ||
| 933 | dev_err(adapter->pdev_dev, "Unsupported chip type, %x\n", | ||
| 934 | adapter->chip); | ||
| 935 | return -EINVAL; | ||
| 936 | } | ||
| 937 | 911 | ||
| 938 | memcpy(adapter->params.api_vers, api_vers, | 912 | /* The firmware in the filesystem is usable, but should it be installed? |
| 939 | sizeof(adapter->params.api_vers)); | 913 | * This routine explains itself in detail if it indicates the filesystem |
| 914 | * firmware should be installed. | ||
| 915 | */ | ||
| 916 | static int should_install_fs_fw(struct adapter *adap, int card_fw_usable, | ||
| 917 | int k, int c) | ||
| 918 | { | ||
| 919 | const char *reason; | ||
| 940 | 920 | ||
| 941 | if (major < exp_major || (major == exp_major && minor < exp_minor) || | 921 | if (!card_fw_usable) { |
| 942 | (major == exp_major && minor == exp_minor && micro < exp_micro)) { | 922 | reason = "incompatible or unusable"; |
| 943 | dev_err(adapter->pdev_dev, | 923 | goto install; |
| 944 | "Card has firmware version %u.%u.%u, minimum " | ||
| 945 | "supported firmware is %u.%u.%u.\n", major, minor, | ||
| 946 | micro, exp_major, exp_minor, exp_micro); | ||
| 947 | return -EFAULT; | ||
| 948 | } | 924 | } |
| 949 | 925 | ||
| 950 | if (major != exp_major) { /* major mismatch - fail */ | 926 | if (k > c) { |
| 951 | dev_err(adapter->pdev_dev, | 927 | reason = "older than the version supported with this driver"; |
| 952 | "card FW has major version %u, driver wants %u\n", | 928 | goto install; |
| 953 | major, exp_major); | ||
| 954 | return -EINVAL; | ||
| 955 | } | 929 | } |
| 956 | 930 | ||
| 957 | if (minor == exp_minor && micro == exp_micro) | 931 | return 0; |
| 958 | return 0; /* perfect match */ | 932 | |
| 933 | install: | ||
| 934 | dev_err(adap->pdev_dev, "firmware on card (%u.%u.%u.%u) is %s, " | ||
| 935 | "installing firmware %u.%u.%u.%u on card.\n", | ||
| 936 | FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c), | ||
| 937 | FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), reason, | ||
| 938 | FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k), | ||
| 939 | FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k)); | ||
| 959 | 940 | ||
| 960 | /* Minor/micro version mismatch. Report it but often it's OK. */ | ||
| 961 | return 1; | 941 | return 1; |
| 962 | } | 942 | } |
| 963 | 943 | ||
| 944 | int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info, | ||
| 945 | const u8 *fw_data, unsigned int fw_size, | ||
| 946 | struct fw_hdr *card_fw, enum dev_state state, | ||
| 947 | int *reset) | ||
| 948 | { | ||
| 949 | int ret, card_fw_usable, fs_fw_usable; | ||
| 950 | const struct fw_hdr *fs_fw; | ||
| 951 | const struct fw_hdr *drv_fw; | ||
| 952 | |||
| 953 | drv_fw = &fw_info->fw_hdr; | ||
| 954 | |||
| 955 | /* Read the header of the firmware on the card */ | ||
| 956 | ret = -t4_read_flash(adap, FLASH_FW_START, | ||
| 957 | sizeof(*card_fw) / sizeof(uint32_t), | ||
| 958 | (uint32_t *)card_fw, 1); | ||
| 959 | if (ret == 0) { | ||
| 960 | card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw); | ||
| 961 | } else { | ||
| 962 | dev_err(adap->pdev_dev, | ||
| 963 | "Unable to read card's firmware header: %d\n", ret); | ||
| 964 | card_fw_usable = 0; | ||
| 965 | } | ||
| 966 | |||
| 967 | if (fw_data != NULL) { | ||
| 968 | fs_fw = (const void *)fw_data; | ||
| 969 | fs_fw_usable = fw_compatible(drv_fw, fs_fw); | ||
| 970 | } else { | ||
| 971 | fs_fw = NULL; | ||
| 972 | fs_fw_usable = 0; | ||
| 973 | } | ||
| 974 | |||
| 975 | if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver && | ||
| 976 | (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) { | ||
| 977 | /* Common case: the firmware on the card is an exact match and | ||
| 978 | * the filesystem one is an exact match too, or the filesystem | ||
| 979 | * one is absent/incompatible. | ||
| 980 | */ | ||
| 981 | } else if (fs_fw_usable && state == DEV_STATE_UNINIT && | ||
| 982 | should_install_fs_fw(adap, card_fw_usable, | ||
| 983 | be32_to_cpu(fs_fw->fw_ver), | ||
| 984 | be32_to_cpu(card_fw->fw_ver))) { | ||
| 985 | ret = -t4_fw_upgrade(adap, adap->mbox, fw_data, | ||
| 986 | fw_size, 0); | ||
| 987 | if (ret != 0) { | ||
| 988 | dev_err(adap->pdev_dev, | ||
| 989 | "failed to install firmware: %d\n", ret); | ||
| 990 | goto bye; | ||
| 991 | } | ||
| 992 | |||
| 993 | /* Installed successfully, update the cached header too. */ | ||
| 994 | memcpy(card_fw, fs_fw, sizeof(*card_fw)); | ||
| 995 | card_fw_usable = 1; | ||
| 996 | *reset = 0; /* already reset as part of load_fw */ | ||
| 997 | } | ||
| 998 | |||
| 999 | if (!card_fw_usable) { | ||
| 1000 | uint32_t d, c, k; | ||
| 1001 | |||
| 1002 | d = be32_to_cpu(drv_fw->fw_ver); | ||
| 1003 | c = be32_to_cpu(card_fw->fw_ver); | ||
| 1004 | k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0; | ||
| 1005 | |||
| 1006 | dev_err(adap->pdev_dev, "Cannot find a usable firmware: " | ||
| 1007 | "chip state %d, " | ||
| 1008 | "driver compiled with %d.%d.%d.%d, " | ||
| 1009 | "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n", | ||
| 1010 | state, | ||
| 1011 | FW_HDR_FW_VER_MAJOR_GET(d), FW_HDR_FW_VER_MINOR_GET(d), | ||
| 1012 | FW_HDR_FW_VER_MICRO_GET(d), FW_HDR_FW_VER_BUILD_GET(d), | ||
| 1013 | FW_HDR_FW_VER_MAJOR_GET(c), FW_HDR_FW_VER_MINOR_GET(c), | ||
| 1014 | FW_HDR_FW_VER_MICRO_GET(c), FW_HDR_FW_VER_BUILD_GET(c), | ||
| 1015 | FW_HDR_FW_VER_MAJOR_GET(k), FW_HDR_FW_VER_MINOR_GET(k), | ||
| 1016 | FW_HDR_FW_VER_MICRO_GET(k), FW_HDR_FW_VER_BUILD_GET(k)); | ||
| 1017 | ret = EINVAL; | ||
| 1018 | goto bye; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | /* We're using whatever's on the card and it's known to be good. */ | ||
| 1022 | adap->params.fw_vers = be32_to_cpu(card_fw->fw_ver); | ||
| 1023 | adap->params.tp_vers = be32_to_cpu(card_fw->tp_microcode_ver); | ||
| 1024 | |||
| 1025 | bye: | ||
| 1026 | return ret; | ||
| 1027 | } | ||
| 1028 | |||
| 964 | /** | 1029 | /** |
| 965 | * t4_flash_erase_sectors - erase a range of flash sectors | 1030 | * t4_flash_erase_sectors - erase a range of flash sectors |
| 966 | * @adapter: the adapter | 1031 | * @adapter: the adapter |
| @@ -1368,7 +1433,7 @@ static void pcie_intr_handler(struct adapter *adapter) | |||
| 1368 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, | 1433 | PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, |
| 1369 | pcie_port_intr_info) + | 1434 | pcie_port_intr_info) + |
| 1370 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, | 1435 | t4_handle_intr_status(adapter, PCIE_INT_CAUSE, |
| 1371 | is_t4(adapter->chip) ? | 1436 | is_t4(adapter->params.chip) ? |
| 1372 | pcie_intr_info : t5_pcie_intr_info); | 1437 | pcie_intr_info : t5_pcie_intr_info); |
| 1373 | 1438 | ||
| 1374 | if (fat) | 1439 | if (fat) |
| @@ -1782,7 +1847,7 @@ static void xgmac_intr_handler(struct adapter *adap, int port) | |||
| 1782 | { | 1847 | { |
| 1783 | u32 v, int_cause_reg; | 1848 | u32 v, int_cause_reg; |
| 1784 | 1849 | ||
| 1785 | if (is_t4(adap->chip)) | 1850 | if (is_t4(adap->params.chip)) |
| 1786 | int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE); | 1851 | int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE); |
| 1787 | else | 1852 | else |
| 1788 | int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE); | 1853 | int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE); |
| @@ -2250,7 +2315,7 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) | |||
| 2250 | 2315 | ||
| 2251 | #define GET_STAT(name) \ | 2316 | #define GET_STAT(name) \ |
| 2252 | t4_read_reg64(adap, \ | 2317 | t4_read_reg64(adap, \ |
| 2253 | (is_t4(adap->chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \ | 2318 | (is_t4(adap->params.chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \ |
| 2254 | T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L))) | 2319 | T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L))) |
| 2255 | #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) | 2320 | #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) |
| 2256 | 2321 | ||
| @@ -2332,7 +2397,7 @@ void t4_wol_magic_enable(struct adapter *adap, unsigned int port, | |||
| 2332 | { | 2397 | { |
| 2333 | u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg; | 2398 | u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg; |
| 2334 | 2399 | ||
| 2335 | if (is_t4(adap->chip)) { | 2400 | if (is_t4(adap->params.chip)) { |
| 2336 | mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO); | 2401 | mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO); |
| 2337 | mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI); | 2402 | mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI); |
| 2338 | port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); | 2403 | port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); |
| @@ -2374,7 +2439,7 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, | |||
| 2374 | int i; | 2439 | int i; |
| 2375 | u32 port_cfg_reg; | 2440 | u32 port_cfg_reg; |
| 2376 | 2441 | ||
| 2377 | if (is_t4(adap->chip)) | 2442 | if (is_t4(adap->params.chip)) |
| 2378 | port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); | 2443 | port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2); |
| 2379 | else | 2444 | else |
| 2380 | port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2); | 2445 | port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2); |
| @@ -2387,7 +2452,7 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map, | |||
| 2387 | return -EINVAL; | 2452 | return -EINVAL; |
| 2388 | 2453 | ||
| 2389 | #define EPIO_REG(name) \ | 2454 | #define EPIO_REG(name) \ |
| 2390 | (is_t4(adap->chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \ | 2455 | (is_t4(adap->params.chip) ? PORT_REG(port, XGMAC_PORT_EPIO_##name) : \ |
| 2391 | T5_PORT_REG(port, MAC_PORT_EPIO_##name)) | 2456 | T5_PORT_REG(port, MAC_PORT_EPIO_##name)) |
| 2392 | 2457 | ||
| 2393 | t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32); | 2458 | t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32); |
| @@ -2474,7 +2539,7 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, | |||
| 2474 | int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len) | 2539 | int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len) |
| 2475 | { | 2540 | { |
| 2476 | int i, off; | 2541 | int i, off; |
| 2477 | u32 win_pf = is_t4(adap->chip) ? 0 : V_PFNUM(adap->fn); | 2542 | u32 win_pf = is_t4(adap->params.chip) ? 0 : V_PFNUM(adap->fn); |
| 2478 | 2543 | ||
| 2479 | /* Align on a 2KB boundary. | 2544 | /* Align on a 2KB boundary. |
| 2480 | */ | 2545 | */ |
| @@ -3306,7 +3371,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, | |||
| 3306 | int i, ret; | 3371 | int i, ret; |
| 3307 | struct fw_vi_mac_cmd c; | 3372 | struct fw_vi_mac_cmd c; |
| 3308 | struct fw_vi_mac_exact *p; | 3373 | struct fw_vi_mac_exact *p; |
| 3309 | unsigned int max_naddr = is_t4(adap->chip) ? | 3374 | unsigned int max_naddr = is_t4(adap->params.chip) ? |
| 3310 | NUM_MPS_CLS_SRAM_L_INSTANCES : | 3375 | NUM_MPS_CLS_SRAM_L_INSTANCES : |
| 3311 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; | 3376 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; |
| 3312 | 3377 | ||
| @@ -3368,7 +3433,7 @@ int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid, | |||
| 3368 | int ret, mode; | 3433 | int ret, mode; |
| 3369 | struct fw_vi_mac_cmd c; | 3434 | struct fw_vi_mac_cmd c; |
| 3370 | struct fw_vi_mac_exact *p = c.u.exact; | 3435 | struct fw_vi_mac_exact *p = c.u.exact; |
| 3371 | unsigned int max_mac_addr = is_t4(adap->chip) ? | 3436 | unsigned int max_mac_addr = is_t4(adap->params.chip) ? |
| 3372 | NUM_MPS_CLS_SRAM_L_INSTANCES : | 3437 | NUM_MPS_CLS_SRAM_L_INSTANCES : |
| 3373 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; | 3438 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; |
| 3374 | 3439 | ||
| @@ -3699,13 +3764,14 @@ int t4_prep_adapter(struct adapter *adapter) | |||
| 3699 | { | 3764 | { |
| 3700 | int ret, ver; | 3765 | int ret, ver; |
| 3701 | uint16_t device_id; | 3766 | uint16_t device_id; |
| 3767 | u32 pl_rev; | ||
| 3702 | 3768 | ||
| 3703 | ret = t4_wait_dev_ready(adapter); | 3769 | ret = t4_wait_dev_ready(adapter); |
| 3704 | if (ret < 0) | 3770 | if (ret < 0) |
| 3705 | return ret; | 3771 | return ret; |
| 3706 | 3772 | ||
| 3707 | get_pci_mode(adapter, &adapter->params.pci); | 3773 | get_pci_mode(adapter, &adapter->params.pci); |
| 3708 | adapter->params.rev = t4_read_reg(adapter, PL_REV); | 3774 | pl_rev = G_REV(t4_read_reg(adapter, PL_REV)); |
| 3709 | 3775 | ||
| 3710 | ret = get_flash_params(adapter); | 3776 | ret = get_flash_params(adapter); |
| 3711 | if (ret < 0) { | 3777 | if (ret < 0) { |
| @@ -3717,14 +3783,13 @@ int t4_prep_adapter(struct adapter *adapter) | |||
| 3717 | */ | 3783 | */ |
| 3718 | pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id); | 3784 | pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id); |
| 3719 | ver = device_id >> 12; | 3785 | ver = device_id >> 12; |
| 3786 | adapter->params.chip = 0; | ||
| 3720 | switch (ver) { | 3787 | switch (ver) { |
| 3721 | case CHELSIO_T4: | 3788 | case CHELSIO_T4: |
| 3722 | adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, | 3789 | adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev); |
| 3723 | adapter->params.rev); | ||
| 3724 | break; | 3790 | break; |
| 3725 | case CHELSIO_T5: | 3791 | case CHELSIO_T5: |
| 3726 | adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, | 3792 | adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev); |
| 3727 | adapter->params.rev); | ||
| 3728 | break; | 3793 | break; |
| 3729 | default: | 3794 | default: |
| 3730 | dev_err(adapter->pdev_dev, "Device %d is not supported\n", | 3795 | dev_err(adapter->pdev_dev, "Device %d is not supported\n", |
| @@ -3732,9 +3797,6 @@ int t4_prep_adapter(struct adapter *adapter) | |||
| 3732 | return -EINVAL; | 3797 | return -EINVAL; |
| 3733 | } | 3798 | } |
| 3734 | 3799 | ||
| 3735 | /* Reassign the updated revision field */ | ||
| 3736 | adapter->params.rev = adapter->chip; | ||
| 3737 | |||
| 3738 | init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); | 3800 | init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd); |
| 3739 | 3801 | ||
| 3740 | /* | 3802 | /* |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index ef146c0ba481..0a8205d69d2c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | |||
| @@ -1092,6 +1092,11 @@ | |||
| 1092 | 1092 | ||
| 1093 | #define PL_REV 0x1943c | 1093 | #define PL_REV 0x1943c |
| 1094 | 1094 | ||
| 1095 | #define S_REV 0 | ||
| 1096 | #define M_REV 0xfU | ||
| 1097 | #define V_REV(x) ((x) << S_REV) | ||
| 1098 | #define G_REV(x) (((x) >> S_REV) & M_REV) | ||
| 1099 | |||
| 1095 | #define LE_DB_CONFIG 0x19c04 | 1100 | #define LE_DB_CONFIG 0x19c04 |
| 1096 | #define HASHEN 0x00100000U | 1101 | #define HASHEN 0x00100000U |
| 1097 | 1102 | ||
| @@ -1199,4 +1204,13 @@ | |||
| 1199 | #define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) | 1204 | #define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR) |
| 1200 | #define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) | 1205 | #define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx) |
| 1201 | 1206 | ||
| 1207 | #define A_PL_VF_REV 0x4 | ||
| 1208 | #define A_PL_VF_WHOAMI 0x0 | ||
| 1209 | #define A_PL_VF_REVISION 0x8 | ||
| 1210 | |||
| 1211 | #define S_CHIPID 4 | ||
| 1212 | #define M_CHIPID 0xfU | ||
| 1213 | #define V_CHIPID(x) ((x) << S_CHIPID) | ||
| 1214 | #define G_CHIPID(x) (((x) >> S_CHIPID) & M_CHIPID) | ||
| 1215 | |||
| 1202 | #endif /* __T4_REGS_H */ | 1216 | #endif /* __T4_REGS_H */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h index 6f77ac487743..74fea74ce0aa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | |||
| @@ -2157,7 +2157,7 @@ struct fw_debug_cmd { | |||
| 2157 | 2157 | ||
| 2158 | struct fw_hdr { | 2158 | struct fw_hdr { |
| 2159 | u8 ver; | 2159 | u8 ver; |
| 2160 | u8 reserved1; | 2160 | u8 chip; /* terminator chip type */ |
| 2161 | __be16 len512; /* bin length in units of 512-bytes */ | 2161 | __be16 len512; /* bin length in units of 512-bytes */ |
| 2162 | __be32 fw_ver; /* firmware version */ | 2162 | __be32 fw_ver; /* firmware version */ |
| 2163 | __be32 tp_microcode_ver; | 2163 | __be32 tp_microcode_ver; |
| @@ -2176,6 +2176,11 @@ struct fw_hdr { | |||
| 2176 | __be32 reserved6[23]; | 2176 | __be32 reserved6[23]; |
| 2177 | }; | 2177 | }; |
| 2178 | 2178 | ||
| 2179 | enum fw_hdr_chip { | ||
| 2180 | FW_HDR_CHIP_T4, | ||
| 2181 | FW_HDR_CHIP_T5 | ||
| 2182 | }; | ||
| 2183 | |||
| 2179 | #define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff) | 2184 | #define FW_HDR_FW_VER_MAJOR_GET(x) (((x) >> 24) & 0xff) |
| 2180 | #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff) | 2185 | #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff) |
| 2181 | #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) | 2186 | #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index be5c7ef6ca93..68eaa9c88c7d 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | |||
| @@ -344,7 +344,6 @@ struct adapter { | |||
| 344 | unsigned long registered_device_map; | 344 | unsigned long registered_device_map; |
| 345 | unsigned long open_device_map; | 345 | unsigned long open_device_map; |
| 346 | unsigned long flags; | 346 | unsigned long flags; |
| 347 | enum chip_type chip; | ||
| 348 | struct adapter_params params; | 347 | struct adapter_params params; |
| 349 | 348 | ||
| 350 | /* queue and interrupt resources */ | 349 | /* queue and interrupt resources */ |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 5f90ec5f7519..0899c0983594 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | |||
| @@ -1064,7 +1064,7 @@ static inline unsigned int mk_adap_vers(const struct adapter *adapter) | |||
| 1064 | /* | 1064 | /* |
| 1065 | * Chip version 4, revision 0x3f (cxgb4vf). | 1065 | * Chip version 4, revision 0x3f (cxgb4vf). |
| 1066 | */ | 1066 | */ |
| 1067 | return CHELSIO_CHIP_VERSION(adapter->chip) | (0x3f << 10); | 1067 | return CHELSIO_CHIP_VERSION(adapter->params.chip) | (0x3f << 10); |
| 1068 | } | 1068 | } |
| 1069 | 1069 | ||
| 1070 | /* | 1070 | /* |
| @@ -1551,9 +1551,13 @@ static void cxgb4vf_get_regs(struct net_device *dev, | |||
| 1551 | reg_block_dump(adapter, regbuf, | 1551 | reg_block_dump(adapter, regbuf, |
| 1552 | T4VF_MPS_BASE_ADDR + T4VF_MOD_MAP_MPS_FIRST, | 1552 | T4VF_MPS_BASE_ADDR + T4VF_MOD_MAP_MPS_FIRST, |
| 1553 | T4VF_MPS_BASE_ADDR + T4VF_MOD_MAP_MPS_LAST); | 1553 | T4VF_MPS_BASE_ADDR + T4VF_MOD_MAP_MPS_LAST); |
| 1554 | |||
| 1555 | /* T5 adds new registers in the PL Register map. | ||
| 1556 | */ | ||
| 1554 | reg_block_dump(adapter, regbuf, | 1557 | reg_block_dump(adapter, regbuf, |
| 1555 | T4VF_PL_BASE_ADDR + T4VF_MOD_MAP_PL_FIRST, | 1558 | T4VF_PL_BASE_ADDR + T4VF_MOD_MAP_PL_FIRST, |
| 1556 | T4VF_PL_BASE_ADDR + T4VF_MOD_MAP_PL_LAST); | 1559 | T4VF_PL_BASE_ADDR + (is_t4(adapter->params.chip) |
| 1560 | ? A_PL_VF_WHOAMI : A_PL_VF_REVISION)); | ||
| 1557 | reg_block_dump(adapter, regbuf, | 1561 | reg_block_dump(adapter, regbuf, |
| 1558 | T4VF_CIM_BASE_ADDR + T4VF_MOD_MAP_CIM_FIRST, | 1562 | T4VF_CIM_BASE_ADDR + T4VF_MOD_MAP_CIM_FIRST, |
| 1559 | T4VF_CIM_BASE_ADDR + T4VF_MOD_MAP_CIM_LAST); | 1563 | T4VF_CIM_BASE_ADDR + T4VF_MOD_MAP_CIM_LAST); |
| @@ -2087,6 +2091,7 @@ static int adap_init0(struct adapter *adapter) | |||
| 2087 | unsigned int ethqsets; | 2091 | unsigned int ethqsets; |
| 2088 | int err; | 2092 | int err; |
| 2089 | u32 param, val = 0; | 2093 | u32 param, val = 0; |
| 2094 | unsigned int chipid; | ||
| 2090 | 2095 | ||
| 2091 | /* | 2096 | /* |
| 2092 | * Wait for the device to become ready before proceeding ... | 2097 | * Wait for the device to become ready before proceeding ... |
| @@ -2114,12 +2119,14 @@ static int adap_init0(struct adapter *adapter) | |||
| 2114 | return err; | 2119 | return err; |
| 2115 | } | 2120 | } |
| 2116 | 2121 | ||
| 2122 | adapter->params.chip = 0; | ||
| 2117 | switch (adapter->pdev->device >> 12) { | 2123 | switch (adapter->pdev->device >> 12) { |
| 2118 | case CHELSIO_T4: | 2124 | case CHELSIO_T4: |
| 2119 | adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T4, 0); | 2125 | adapter->params.chip = CHELSIO_CHIP_CODE(CHELSIO_T4, 0); |
| 2120 | break; | 2126 | break; |
| 2121 | case CHELSIO_T5: | 2127 | case CHELSIO_T5: |
| 2122 | adapter->chip = CHELSIO_CHIP_CODE(CHELSIO_T5, 0); | 2128 | chipid = G_REV(t4_read_reg(adapter, A_PL_VF_REV)); |
| 2129 | adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, chipid); | ||
| 2123 | break; | 2130 | break; |
| 2124 | } | 2131 | } |
| 2125 | 2132 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 8475c4cda9e4..0a89963c48ce 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c | |||
| @@ -537,7 +537,7 @@ static inline void ring_fl_db(struct adapter *adapter, struct sge_fl *fl) | |||
| 537 | */ | 537 | */ |
| 538 | if (fl->pend_cred >= FL_PER_EQ_UNIT) { | 538 | if (fl->pend_cred >= FL_PER_EQ_UNIT) { |
| 539 | val = PIDX(fl->pend_cred / FL_PER_EQ_UNIT); | 539 | val = PIDX(fl->pend_cred / FL_PER_EQ_UNIT); |
| 540 | if (!is_t4(adapter->chip)) | 540 | if (!is_t4(adapter->params.chip)) |
| 541 | val |= DBTYPE(1); | 541 | val |= DBTYPE(1); |
| 542 | wmb(); | 542 | wmb(); |
| 543 | t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL, | 543 | t4_write_reg(adapter, T4VF_SGE_BASE_ADDR + SGE_VF_KDOORBELL, |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 53cbfed21d0b..61362450d05b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | |||
| @@ -39,21 +39,28 @@ | |||
| 39 | #include "../cxgb4/t4fw_api.h" | 39 | #include "../cxgb4/t4fw_api.h" |
| 40 | 40 | ||
| 41 | #define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) | 41 | #define CHELSIO_CHIP_CODE(version, revision) (((version) << 4) | (revision)) |
| 42 | #define CHELSIO_CHIP_VERSION(code) ((code) >> 4) | 42 | #define CHELSIO_CHIP_VERSION(code) (((code) >> 4) & 0xf) |
| 43 | #define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) | 43 | #define CHELSIO_CHIP_RELEASE(code) ((code) & 0xf) |
| 44 | 44 | ||
| 45 | /* All T4 and later chips have their PCI-E Device IDs encoded as 0xVFPP where: | ||
| 46 | * | ||
| 47 | * V = "4" for T4; "5" for T5, etc. or | ||
| 48 | * = "a" for T4 FPGA; "b" for T4 FPGA, etc. | ||
| 49 | * F = "0" for PF 0..3; "4".."7" for PF4..7; and "8" for VFs | ||
| 50 | * PP = adapter product designation | ||
| 51 | */ | ||
| 45 | #define CHELSIO_T4 0x4 | 52 | #define CHELSIO_T4 0x4 |
| 46 | #define CHELSIO_T5 0x5 | 53 | #define CHELSIO_T5 0x5 |
| 47 | 54 | ||
| 48 | enum chip_type { | 55 | enum chip_type { |
| 49 | T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 0), | 56 | T4_A1 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), |
| 50 | T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 1), | 57 | T4_A2 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), |
| 51 | T4_A3 = CHELSIO_CHIP_CODE(CHELSIO_T4, 2), | ||
| 52 | T4_FIRST_REV = T4_A1, | 58 | T4_FIRST_REV = T4_A1, |
| 53 | T4_LAST_REV = T4_A3, | 59 | T4_LAST_REV = T4_A2, |
| 54 | 60 | ||
| 55 | T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), | 61 | T5_A0 = CHELSIO_CHIP_CODE(CHELSIO_T5, 0), |
| 56 | T5_FIRST_REV = T5_A1, | 62 | T5_A1 = CHELSIO_CHIP_CODE(CHELSIO_T5, 1), |
| 63 | T5_FIRST_REV = T5_A0, | ||
| 57 | T5_LAST_REV = T5_A1, | 64 | T5_LAST_REV = T5_A1, |
| 58 | }; | 65 | }; |
| 59 | 66 | ||
| @@ -203,6 +210,7 @@ struct adapter_params { | |||
| 203 | struct vpd_params vpd; /* Vital Product Data */ | 210 | struct vpd_params vpd; /* Vital Product Data */ |
| 204 | struct rss_params rss; /* Receive Side Scaling */ | 211 | struct rss_params rss; /* Receive Side Scaling */ |
| 205 | struct vf_resources vfres; /* Virtual Function Resource limits */ | 212 | struct vf_resources vfres; /* Virtual Function Resource limits */ |
| 213 | enum chip_type chip; /* chip code */ | ||
| 206 | u8 nports; /* # of Ethernet "ports" */ | 214 | u8 nports; /* # of Ethernet "ports" */ |
| 207 | }; | 215 | }; |
| 208 | 216 | ||
| @@ -253,7 +261,7 @@ static inline int t4vf_wr_mbox_ns(struct adapter *adapter, const void *cmd, | |||
| 253 | 261 | ||
| 254 | static inline int is_t4(enum chip_type chip) | 262 | static inline int is_t4(enum chip_type chip) |
| 255 | { | 263 | { |
| 256 | return (chip >= T4_FIRST_REV && chip <= T4_LAST_REV); | 264 | return CHELSIO_CHIP_VERSION(chip) == CHELSIO_T4; |
| 257 | } | 265 | } |
| 258 | 266 | ||
| 259 | int t4vf_wait_dev_ready(struct adapter *); | 267 | int t4vf_wait_dev_ready(struct adapter *); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 9f96dc3bb112..d958c44341b5 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | |||
| @@ -1027,7 +1027,7 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, | |||
| 1027 | unsigned nfilters = 0; | 1027 | unsigned nfilters = 0; |
| 1028 | unsigned int rem = naddr; | 1028 | unsigned int rem = naddr; |
| 1029 | struct fw_vi_mac_cmd cmd, rpl; | 1029 | struct fw_vi_mac_cmd cmd, rpl; |
| 1030 | unsigned int max_naddr = is_t4(adapter->chip) ? | 1030 | unsigned int max_naddr = is_t4(adapter->params.chip) ? |
| 1031 | NUM_MPS_CLS_SRAM_L_INSTANCES : | 1031 | NUM_MPS_CLS_SRAM_L_INSTANCES : |
| 1032 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; | 1032 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; |
| 1033 | 1033 | ||
| @@ -1121,7 +1121,7 @@ int t4vf_change_mac(struct adapter *adapter, unsigned int viid, | |||
| 1121 | struct fw_vi_mac_exact *p = &cmd.u.exact[0]; | 1121 | struct fw_vi_mac_exact *p = &cmd.u.exact[0]; |
| 1122 | size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, | 1122 | size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, |
| 1123 | u.exact[1]), 16); | 1123 | u.exact[1]), 16); |
| 1124 | unsigned int max_naddr = is_t4(adapter->chip) ? | 1124 | unsigned int max_naddr = is_t4(adapter->params.chip) ? |
| 1125 | NUM_MPS_CLS_SRAM_L_INSTANCES : | 1125 | NUM_MPS_CLS_SRAM_L_INSTANCES : |
| 1126 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; | 1126 | NUM_MPS_T5_CLS_SRAM_L_INSTANCES; |
| 1127 | 1127 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 3e2162121601..dc88782185f2 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h | |||
| @@ -64,6 +64,9 @@ | |||
| 64 | #define SLIPORT_ERROR_NO_RESOURCE1 0x2 | 64 | #define SLIPORT_ERROR_NO_RESOURCE1 0x2 |
| 65 | #define SLIPORT_ERROR_NO_RESOURCE2 0x9 | 65 | #define SLIPORT_ERROR_NO_RESOURCE2 0x9 |
| 66 | 66 | ||
| 67 | #define SLIPORT_ERROR_FW_RESET1 0x2 | ||
| 68 | #define SLIPORT_ERROR_FW_RESET2 0x0 | ||
| 69 | |||
| 67 | /********* Memory BAR register ************/ | 70 | /********* Memory BAR register ************/ |
| 68 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc | 71 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc |
| 69 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt | 72 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fee64bf10446..0fde69d5cb6a 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
| @@ -2464,8 +2464,16 @@ void be_detect_error(struct be_adapter *adapter) | |||
| 2464 | */ | 2464 | */ |
| 2465 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { | 2465 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { |
| 2466 | adapter->hw_error = true; | 2466 | adapter->hw_error = true; |
| 2467 | dev_err(&adapter->pdev->dev, | 2467 | /* Do not log error messages if its a FW reset */ |
| 2468 | "Error detected in the card\n"); | 2468 | if (sliport_err1 == SLIPORT_ERROR_FW_RESET1 && |
| 2469 | sliport_err2 == SLIPORT_ERROR_FW_RESET2) { | ||
| 2470 | dev_info(&adapter->pdev->dev, | ||
| 2471 | "Firmware update in progress\n"); | ||
| 2472 | return; | ||
| 2473 | } else { | ||
| 2474 | dev_err(&adapter->pdev->dev, | ||
| 2475 | "Error detected in the card\n"); | ||
| 2476 | } | ||
| 2469 | } | 2477 | } |
| 2470 | 2478 | ||
| 2471 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { | 2479 | if (sliport_status & SLIPORT_STATUS_ERR_MASK) { |
| @@ -2932,28 +2940,35 @@ static void be_cancel_worker(struct be_adapter *adapter) | |||
| 2932 | } | 2940 | } |
| 2933 | } | 2941 | } |
| 2934 | 2942 | ||
| 2935 | static int be_clear(struct be_adapter *adapter) | 2943 | static void be_mac_clear(struct be_adapter *adapter) |
| 2936 | { | 2944 | { |
| 2937 | int i; | 2945 | int i; |
| 2938 | 2946 | ||
| 2947 | if (adapter->pmac_id) { | ||
| 2948 | for (i = 0; i < (adapter->uc_macs + 1); i++) | ||
| 2949 | be_cmd_pmac_del(adapter, adapter->if_handle, | ||
| 2950 | adapter->pmac_id[i], 0); | ||
| 2951 | adapter->uc_macs = 0; | ||
| 2952 | |||
| 2953 | kfree(adapter->pmac_id); | ||
| 2954 | adapter->pmac_id = NULL; | ||
| 2955 | } | ||
| 2956 | } | ||
| 2957 | |||
| 2958 | static int be_clear(struct be_adapter *adapter) | ||
| 2959 | { | ||
| 2939 | be_cancel_worker(adapter); | 2960 | be_cancel_worker(adapter); |
| 2940 | 2961 | ||
| 2941 | if (sriov_enabled(adapter)) | 2962 | if (sriov_enabled(adapter)) |
| 2942 | be_vf_clear(adapter); | 2963 | be_vf_clear(adapter); |
| 2943 | 2964 | ||
| 2944 | /* delete the primary mac along with the uc-mac list */ | 2965 | /* delete the primary mac along with the uc-mac list */ |
| 2945 | for (i = 0; i < (adapter->uc_macs + 1); i++) | 2966 | be_mac_clear(adapter); |
| 2946 | be_cmd_pmac_del(adapter, adapter->if_handle, | ||
| 2947 | adapter->pmac_id[i], 0); | ||
| 2948 | adapter->uc_macs = 0; | ||
| 2949 | 2967 | ||
| 2950 | be_cmd_if_destroy(adapter, adapter->if_handle, 0); | 2968 | be_cmd_if_destroy(adapter, adapter->if_handle, 0); |
| 2951 | 2969 | ||
| 2952 | be_clear_queues(adapter); | 2970 | be_clear_queues(adapter); |
| 2953 | 2971 | ||
| 2954 | kfree(adapter->pmac_id); | ||
| 2955 | adapter->pmac_id = NULL; | ||
| 2956 | |||
| 2957 | be_msix_disable(adapter); | 2972 | be_msix_disable(adapter); |
| 2958 | return 0; | 2973 | return 0; |
| 2959 | } | 2974 | } |
| @@ -3812,6 +3827,8 @@ static int lancer_fw_download(struct be_adapter *adapter, | |||
| 3812 | } | 3827 | } |
| 3813 | 3828 | ||
| 3814 | if (change_status == LANCER_FW_RESET_NEEDED) { | 3829 | if (change_status == LANCER_FW_RESET_NEEDED) { |
| 3830 | dev_info(&adapter->pdev->dev, | ||
| 3831 | "Resetting adapter to activate new FW\n"); | ||
| 3815 | status = lancer_physdev_ctrl(adapter, | 3832 | status = lancer_physdev_ctrl(adapter, |
| 3816 | PHYSDEV_CONTROL_FW_RESET_MASK); | 3833 | PHYSDEV_CONTROL_FW_RESET_MASK); |
| 3817 | if (status) { | 3834 | if (status) { |
| @@ -4363,13 +4380,13 @@ static int lancer_recover_func(struct be_adapter *adapter) | |||
| 4363 | goto err; | 4380 | goto err; |
| 4364 | } | 4381 | } |
| 4365 | 4382 | ||
| 4366 | dev_err(dev, "Error recovery successful\n"); | 4383 | dev_err(dev, "Adapter recovery successful\n"); |
| 4367 | return 0; | 4384 | return 0; |
| 4368 | err: | 4385 | err: |
| 4369 | if (status == -EAGAIN) | 4386 | if (status == -EAGAIN) |
| 4370 | dev_err(dev, "Waiting for resource provisioning\n"); | 4387 | dev_err(dev, "Waiting for resource provisioning\n"); |
| 4371 | else | 4388 | else |
| 4372 | dev_err(dev, "Error recovery failed\n"); | 4389 | dev_err(dev, "Adapter recovery failed\n"); |
| 4373 | 4390 | ||
| 4374 | return status; | 4391 | return status; |
| 4375 | } | 4392 | } |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 4cbebf3d80eb..e7c8b749c5a5 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
| @@ -98,10 +98,6 @@ static void set_multicast_list(struct net_device *ndev); | |||
| 98 | * detected as not set during a prior frame transmission, then the | 98 | * detected as not set during a prior frame transmission, then the |
| 99 | * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs | 99 | * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs |
| 100 | * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in | 100 | * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in |
| 101 | * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously | ||
| 102 | * detected as not set during a prior frame transmission, then the | ||
| 103 | * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs | ||
| 104 | * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in | ||
| 105 | * frames not being transmitted until there is a 0-to-1 transition on | 101 | * frames not being transmitted until there is a 0-to-1 transition on |
| 106 | * ENET_TDAR[TDAR]. | 102 | * ENET_TDAR[TDAR]. |
| 107 | */ | 103 | */ |
| @@ -385,7 +381,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
| 385 | * data. | 381 | * data. |
| 386 | */ | 382 | */ |
| 387 | bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr, | 383 | bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, bufaddr, |
| 388 | FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); | 384 | skb->len, DMA_TO_DEVICE); |
| 389 | if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) { | 385 | if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) { |
| 390 | bdp->cbd_bufaddr = 0; | 386 | bdp->cbd_bufaddr = 0; |
| 391 | fep->tx_skbuff[index] = NULL; | 387 | fep->tx_skbuff[index] = NULL; |
| @@ -779,11 +775,10 @@ fec_enet_tx(struct net_device *ndev) | |||
| 779 | else | 775 | else |
| 780 | index = bdp - fep->tx_bd_base; | 776 | index = bdp - fep->tx_bd_base; |
| 781 | 777 | ||
| 782 | dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, | ||
| 783 | FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); | ||
| 784 | bdp->cbd_bufaddr = 0; | ||
| 785 | |||
| 786 | skb = fep->tx_skbuff[index]; | 778 | skb = fep->tx_skbuff[index]; |
| 779 | dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, skb->len, | ||
| 780 | DMA_TO_DEVICE); | ||
| 781 | bdp->cbd_bufaddr = 0; | ||
| 787 | 782 | ||
| 788 | /* Check for errors. */ | 783 | /* Check for errors. */ |
| 789 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | | 784 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | |
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 2d1c6bdd3618..7628e0fd8455 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
| @@ -3033,7 +3033,7 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
| 3033 | 3033 | ||
| 3034 | dev->hw_features = NETIF_F_SG | NETIF_F_TSO | | 3034 | dev->hw_features = NETIF_F_SG | NETIF_F_TSO | |
| 3035 | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX; | 3035 | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_CTAG_TX; |
| 3036 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO | | 3036 | dev->features = NETIF_F_SG | NETIF_F_TSO | |
| 3037 | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | | 3037 | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | |
| 3038 | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | | 3038 | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | |
| 3039 | NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM; | 3039 | NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM; |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index be15938ba213..12b0932204ba 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
| @@ -354,6 +354,9 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( | |||
| 354 | struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi); | 354 | struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi); |
| 355 | int i; | 355 | int i; |
| 356 | 356 | ||
| 357 | if (!vsi->tx_rings) | ||
| 358 | return stats; | ||
| 359 | |||
| 357 | rcu_read_lock(); | 360 | rcu_read_lock(); |
| 358 | for (i = 0; i < vsi->num_queue_pairs; i++) { | 361 | for (i = 0; i < vsi->num_queue_pairs; i++) { |
| 359 | struct i40e_ring *tx_ring, *rx_ring; | 362 | struct i40e_ring *tx_ring, *rx_ring; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index c4c4fe332c7e..ad2b74d95138 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c | |||
| @@ -1728,7 +1728,10 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, | |||
| 1728 | * ownership of the resources, wait and try again to | 1728 | * ownership of the resources, wait and try again to |
| 1729 | * see if they have relinquished the resources yet. | 1729 | * see if they have relinquished the resources yet. |
| 1730 | */ | 1730 | */ |
| 1731 | udelay(usec_interval); | 1731 | if (usec_interval >= 1000) |
| 1732 | mdelay(usec_interval/1000); | ||
| 1733 | else | ||
| 1734 | udelay(usec_interval); | ||
| 1732 | } | 1735 | } |
| 1733 | ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); | 1736 | ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); |
| 1734 | if (ret_val) | 1737 | if (ret_val) |
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index b8e232b4ea2d..d5f0d72e5e33 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c | |||
| @@ -1378,7 +1378,7 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp, | |||
| 1378 | 1378 | ||
| 1379 | dev_kfree_skb_any(skb); | 1379 | dev_kfree_skb_any(skb); |
| 1380 | dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, | 1380 | dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, |
| 1381 | rx_desc->data_size, DMA_FROM_DEVICE); | 1381 | MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| 1384 | if (rx_done) | 1384 | if (rx_done) |
| @@ -1424,7 +1424,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, | |||
| 1424 | } | 1424 | } |
| 1425 | 1425 | ||
| 1426 | dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, | 1426 | dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr, |
| 1427 | rx_desc->data_size, DMA_FROM_DEVICE); | 1427 | MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE); |
| 1428 | 1428 | ||
| 1429 | rx_bytes = rx_desc->data_size - | 1429 | rx_bytes = rx_desc->data_size - |
| 1430 | (ETH_FCS_LEN + MVNETA_MH_SIZE); | 1430 | (ETH_FCS_LEN + MVNETA_MH_SIZE); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 5789ea2c934d..01fc6515384d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -2635,6 +2635,8 @@ static int __init mlx4_init(void) | |||
| 2635 | return -ENOMEM; | 2635 | return -ENOMEM; |
| 2636 | 2636 | ||
| 2637 | ret = pci_register_driver(&mlx4_driver); | 2637 | ret = pci_register_driver(&mlx4_driver); |
| 2638 | if (ret < 0) | ||
| 2639 | destroy_workqueue(mlx4_wq); | ||
| 2638 | return ret < 0 ? ret : 0; | 2640 | return ret < 0 ? ret : 0; |
| 2639 | } | 2641 | } |
| 2640 | 2642 | ||
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 2d045be4b5cf..1e8b9514718b 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c | |||
| @@ -5150,8 +5150,10 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 | |||
| 5150 | { | 5150 | { |
| 5151 | struct fe_priv *np = netdev_priv(dev); | 5151 | struct fe_priv *np = netdev_priv(dev); |
| 5152 | u8 __iomem *base = get_hwbase(dev); | 5152 | u8 __iomem *base = get_hwbase(dev); |
| 5153 | int result; | 5153 | int result, count; |
| 5154 | memset(buffer, 0, nv_get_sset_count(dev, ETH_SS_TEST)*sizeof(u64)); | 5154 | |
| 5155 | count = nv_get_sset_count(dev, ETH_SS_TEST); | ||
| 5156 | memset(buffer, 0, count * sizeof(u64)); | ||
| 5155 | 5157 | ||
| 5156 | if (!nv_link_test(dev)) { | 5158 | if (!nv_link_test(dev)) { |
| 5157 | test->flags |= ETH_TEST_FL_FAILED; | 5159 | test->flags |= ETH_TEST_FL_FAILED; |
| @@ -5195,7 +5197,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 | |||
| 5195 | return; | 5197 | return; |
| 5196 | } | 5198 | } |
| 5197 | 5199 | ||
| 5198 | if (!nv_loopback_test(dev)) { | 5200 | if (count > NV_TEST_COUNT_BASE && !nv_loopback_test(dev)) { |
| 5199 | test->flags |= ETH_TEST_FL_FAILED; | 5201 | test->flags |= ETH_TEST_FL_FAILED; |
| 5200 | buffer[3] = 1; | 5202 | buffer[3] = 1; |
| 5201 | } | 5203 | } |
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h index 0c9c4e895595..03517478e589 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/drivers/net/ethernet/qlogic/qlge/qlge.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | */ | 18 | */ |
| 19 | #define DRV_NAME "qlge" | 19 | #define DRV_NAME "qlge" |
| 20 | #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " | 20 | #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " |
| 21 | #define DRV_VERSION "1.00.00.33" | 21 | #define DRV_VERSION "1.00.00.34" |
| 22 | 22 | ||
| 23 | #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ | 23 | #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ |
| 24 | 24 | ||
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c b/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c index 0780e039b271..8dee1beb9854 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_ethtool.c | |||
| @@ -181,6 +181,7 @@ static const char ql_gstrings_test[][ETH_GSTRING_LEN] = { | |||
| 181 | }; | 181 | }; |
| 182 | #define QLGE_TEST_LEN (sizeof(ql_gstrings_test) / ETH_GSTRING_LEN) | 182 | #define QLGE_TEST_LEN (sizeof(ql_gstrings_test) / ETH_GSTRING_LEN) |
| 183 | #define QLGE_STATS_LEN ARRAY_SIZE(ql_gstrings_stats) | 183 | #define QLGE_STATS_LEN ARRAY_SIZE(ql_gstrings_stats) |
| 184 | #define QLGE_RCV_MAC_ERR_STATS 7 | ||
| 184 | 185 | ||
| 185 | static int ql_update_ring_coalescing(struct ql_adapter *qdev) | 186 | static int ql_update_ring_coalescing(struct ql_adapter *qdev) |
| 186 | { | 187 | { |
| @@ -280,6 +281,9 @@ static void ql_update_stats(struct ql_adapter *qdev) | |||
| 280 | iter++; | 281 | iter++; |
| 281 | } | 282 | } |
| 282 | 283 | ||
| 284 | /* Update receive mac error statistics */ | ||
| 285 | iter += QLGE_RCV_MAC_ERR_STATS; | ||
| 286 | |||
| 283 | /* | 287 | /* |
| 284 | * Get Per-priority TX pause frame counter statistics. | 288 | * Get Per-priority TX pause frame counter statistics. |
| 285 | */ | 289 | */ |
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index a245dc18d769..449f506d2e8f 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c | |||
| @@ -2376,14 +2376,6 @@ static netdev_features_t qlge_fix_features(struct net_device *ndev, | |||
| 2376 | netdev_features_t features) | 2376 | netdev_features_t features) |
| 2377 | { | 2377 | { |
| 2378 | int err; | 2378 | int err; |
| 2379 | /* | ||
| 2380 | * Since there is no support for separate rx/tx vlan accel | ||
| 2381 | * enable/disable make sure tx flag is always in same state as rx. | ||
| 2382 | */ | ||
| 2383 | if (features & NETIF_F_HW_VLAN_CTAG_RX) | ||
| 2384 | features |= NETIF_F_HW_VLAN_CTAG_TX; | ||
| 2385 | else | ||
| 2386 | features &= ~NETIF_F_HW_VLAN_CTAG_TX; | ||
| 2387 | 2379 | ||
| 2388 | /* Update the behavior of vlan accel in the adapter */ | 2380 | /* Update the behavior of vlan accel in the adapter */ |
| 2389 | err = qlge_update_hw_vlan_features(ndev, features); | 2381 | err = qlge_update_hw_vlan_features(ndev, features); |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 2e27837ce6a2..fd844b53e385 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
| @@ -585,7 +585,7 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
| 585 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + | 585 | EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + |
| 586 | efx->type->rx_buffer_padding); | 586 | efx->type->rx_buffer_padding); |
| 587 | rx_buf_len = (sizeof(struct efx_rx_page_state) + | 587 | rx_buf_len = (sizeof(struct efx_rx_page_state) + |
| 588 | NET_IP_ALIGN + efx->rx_dma_len); | 588 | efx->rx_ip_align + efx->rx_dma_len); |
| 589 | if (rx_buf_len <= PAGE_SIZE) { | 589 | if (rx_buf_len <= PAGE_SIZE) { |
| 590 | efx->rx_scatter = efx->type->always_rx_scatter; | 590 | efx->rx_scatter = efx->type->always_rx_scatter; |
| 591 | efx->rx_buffer_order = 0; | 591 | efx->rx_buffer_order = 0; |
| @@ -645,6 +645,8 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
| 645 | WARN_ON(channel->rx_pkt_n_frags); | 645 | WARN_ON(channel->rx_pkt_n_frags); |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | efx_ptp_start_datapath(efx); | ||
| 649 | |||
| 648 | if (netif_device_present(efx->net_dev)) | 650 | if (netif_device_present(efx->net_dev)) |
| 649 | netif_tx_wake_all_queues(efx->net_dev); | 651 | netif_tx_wake_all_queues(efx->net_dev); |
| 650 | } | 652 | } |
| @@ -659,6 +661,8 @@ static void efx_stop_datapath(struct efx_nic *efx) | |||
| 659 | EFX_ASSERT_RESET_SERIALISED(efx); | 661 | EFX_ASSERT_RESET_SERIALISED(efx); |
| 660 | BUG_ON(efx->port_enabled); | 662 | BUG_ON(efx->port_enabled); |
| 661 | 663 | ||
| 664 | efx_ptp_stop_datapath(efx); | ||
| 665 | |||
| 662 | /* Stop RX refill */ | 666 | /* Stop RX refill */ |
| 663 | efx_for_each_channel(channel, efx) { | 667 | efx_for_each_channel(channel, efx) { |
| 664 | efx_for_each_channel_rx_queue(rx_queue, channel) | 668 | efx_for_each_channel_rx_queue(rx_queue, channel) |
| @@ -2540,6 +2544,8 @@ static int efx_init_struct(struct efx_nic *efx, | |||
| 2540 | 2544 | ||
| 2541 | efx->net_dev = net_dev; | 2545 | efx->net_dev = net_dev; |
| 2542 | efx->rx_prefix_size = efx->type->rx_prefix_size; | 2546 | efx->rx_prefix_size = efx->type->rx_prefix_size; |
| 2547 | efx->rx_ip_align = | ||
| 2548 | NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0; | ||
| 2543 | efx->rx_packet_hash_offset = | 2549 | efx->rx_packet_hash_offset = |
| 2544 | efx->type->rx_hash_offset - efx->type->rx_prefix_size; | 2550 | efx->type->rx_hash_offset - efx->type->rx_prefix_size; |
| 2545 | spin_lock_init(&efx->stats_lock); | 2551 | spin_lock_init(&efx->stats_lock); |
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 366c8e3e3784..4b0bd8a1514d 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c | |||
| @@ -50,6 +50,7 @@ struct efx_mcdi_async_param { | |||
| 50 | static void efx_mcdi_timeout_async(unsigned long context); | 50 | static void efx_mcdi_timeout_async(unsigned long context); |
| 51 | static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, | 51 | static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, |
| 52 | bool *was_attached_out); | 52 | bool *was_attached_out); |
| 53 | static bool efx_mcdi_poll_once(struct efx_nic *efx); | ||
| 53 | 54 | ||
| 54 | static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) | 55 | static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) |
| 55 | { | 56 | { |
| @@ -237,6 +238,21 @@ static void efx_mcdi_read_response_header(struct efx_nic *efx) | |||
| 237 | } | 238 | } |
| 238 | } | 239 | } |
| 239 | 240 | ||
| 241 | static bool efx_mcdi_poll_once(struct efx_nic *efx) | ||
| 242 | { | ||
| 243 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | ||
| 244 | |||
| 245 | rmb(); | ||
| 246 | if (!efx->type->mcdi_poll_response(efx)) | ||
| 247 | return false; | ||
| 248 | |||
| 249 | spin_lock_bh(&mcdi->iface_lock); | ||
| 250 | efx_mcdi_read_response_header(efx); | ||
| 251 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 252 | |||
| 253 | return true; | ||
| 254 | } | ||
| 255 | |||
| 240 | static int efx_mcdi_poll(struct efx_nic *efx) | 256 | static int efx_mcdi_poll(struct efx_nic *efx) |
| 241 | { | 257 | { |
| 242 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); | 258 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
| @@ -272,18 +288,13 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
| 272 | 288 | ||
| 273 | time = jiffies; | 289 | time = jiffies; |
| 274 | 290 | ||
| 275 | rmb(); | 291 | if (efx_mcdi_poll_once(efx)) |
| 276 | if (efx->type->mcdi_poll_response(efx)) | ||
| 277 | break; | 292 | break; |
| 278 | 293 | ||
| 279 | if (time_after(time, finish)) | 294 | if (time_after(time, finish)) |
| 280 | return -ETIMEDOUT; | 295 | return -ETIMEDOUT; |
| 281 | } | 296 | } |
| 282 | 297 | ||
| 283 | spin_lock_bh(&mcdi->iface_lock); | ||
| 284 | efx_mcdi_read_response_header(efx); | ||
| 285 | spin_unlock_bh(&mcdi->iface_lock); | ||
| 286 | |||
| 287 | /* Return rc=0 like wait_event_timeout() */ | 298 | /* Return rc=0 like wait_event_timeout() */ |
| 288 | return 0; | 299 | return 0; |
| 289 | } | 300 | } |
| @@ -619,6 +630,16 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, | |||
| 619 | rc = efx_mcdi_await_completion(efx); | 630 | rc = efx_mcdi_await_completion(efx); |
| 620 | 631 | ||
| 621 | if (rc != 0) { | 632 | if (rc != 0) { |
| 633 | netif_err(efx, hw, efx->net_dev, | ||
| 634 | "MC command 0x%x inlen %d mode %d timed out\n", | ||
| 635 | cmd, (int)inlen, mcdi->mode); | ||
| 636 | |||
| 637 | if (mcdi->mode == MCDI_MODE_EVENTS && efx_mcdi_poll_once(efx)) { | ||
| 638 | netif_err(efx, hw, efx->net_dev, | ||
| 639 | "MCDI request was completed without an event\n"); | ||
| 640 | rc = 0; | ||
| 641 | } | ||
| 642 | |||
| 622 | /* Close the race with efx_mcdi_ev_cpl() executing just too late | 643 | /* Close the race with efx_mcdi_ev_cpl() executing just too late |
| 623 | * and completing a request we've just cancelled, by ensuring | 644 | * and completing a request we've just cancelled, by ensuring |
| 624 | * that the seqno check therein fails. | 645 | * that the seqno check therein fails. |
| @@ -627,11 +648,9 @@ int efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, | |||
| 627 | ++mcdi->seqno; | 648 | ++mcdi->seqno; |
| 628 | ++mcdi->credits; | 649 | ++mcdi->credits; |
| 629 | spin_unlock_bh(&mcdi->iface_lock); | 650 | spin_unlock_bh(&mcdi->iface_lock); |
| 651 | } | ||
| 630 | 652 | ||
| 631 | netif_err(efx, hw, efx->net_dev, | 653 | if (rc == 0) { |
| 632 | "MC command 0x%x inlen %d mode %d timed out\n", | ||
| 633 | cmd, (int)inlen, mcdi->mode); | ||
| 634 | } else { | ||
| 635 | size_t hdr_len, data_len; | 654 | size_t hdr_len, data_len; |
| 636 | 655 | ||
| 637 | /* At the very least we need a memory barrier here to ensure | 656 | /* At the very least we need a memory barrier here to ensure |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b14a717ac3e8..542a0d252ae0 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
| @@ -683,6 +683,8 @@ struct vfdi_status; | |||
| 683 | * @n_channels: Number of channels in use | 683 | * @n_channels: Number of channels in use |
| 684 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) | 684 | * @n_rx_channels: Number of channels used for RX (= number of RX queues) |
| 685 | * @n_tx_channels: Number of channels used for TX | 685 | * @n_tx_channels: Number of channels used for TX |
| 686 | * @rx_ip_align: RX DMA address offset to have IP header aligned in | ||
| 687 | * in accordance with NET_IP_ALIGN | ||
| 686 | * @rx_dma_len: Current maximum RX DMA length | 688 | * @rx_dma_len: Current maximum RX DMA length |
| 687 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer | 689 | * @rx_buffer_order: Order (log2) of number of pages for each RX buffer |
| 688 | * @rx_buffer_truesize: Amortised allocation size of an RX buffer, | 690 | * @rx_buffer_truesize: Amortised allocation size of an RX buffer, |
| @@ -816,6 +818,7 @@ struct efx_nic { | |||
| 816 | unsigned rss_spread; | 818 | unsigned rss_spread; |
| 817 | unsigned tx_channel_offset; | 819 | unsigned tx_channel_offset; |
| 818 | unsigned n_tx_channels; | 820 | unsigned n_tx_channels; |
| 821 | unsigned int rx_ip_align; | ||
| 819 | unsigned int rx_dma_len; | 822 | unsigned int rx_dma_len; |
| 820 | unsigned int rx_buffer_order; | 823 | unsigned int rx_buffer_order; |
| 821 | unsigned int rx_buffer_truesize; | 824 | unsigned int rx_buffer_truesize; |
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 11b6112d9249..91c63ec79c5f 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h | |||
| @@ -560,6 +560,8 @@ void efx_ptp_get_ts_info(struct efx_nic *efx, struct ethtool_ts_info *ts_info); | |||
| 560 | bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 560 | bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
| 561 | int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); | 561 | int efx_ptp_tx(struct efx_nic *efx, struct sk_buff *skb); |
| 562 | void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); | 562 | void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev); |
| 563 | void efx_ptp_start_datapath(struct efx_nic *efx); | ||
| 564 | void efx_ptp_stop_datapath(struct efx_nic *efx); | ||
| 563 | 565 | ||
| 564 | extern const struct efx_nic_type falcon_a1_nic_type; | 566 | extern const struct efx_nic_type falcon_a1_nic_type; |
| 565 | extern const struct efx_nic_type falcon_b0_nic_type; | 567 | extern const struct efx_nic_type falcon_b0_nic_type; |
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 03acf57df045..3dd39dcfe36b 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c | |||
| @@ -220,6 +220,7 @@ struct efx_ptp_timeset { | |||
| 220 | * @evt_list: List of MC receive events awaiting packets | 220 | * @evt_list: List of MC receive events awaiting packets |
| 221 | * @evt_free_list: List of free events | 221 | * @evt_free_list: List of free events |
| 222 | * @evt_lock: Lock for manipulating evt_list and evt_free_list | 222 | * @evt_lock: Lock for manipulating evt_list and evt_free_list |
| 223 | * @evt_overflow: Boolean indicating that event list has overflowed | ||
| 223 | * @rx_evts: Instantiated events (on evt_list and evt_free_list) | 224 | * @rx_evts: Instantiated events (on evt_list and evt_free_list) |
| 224 | * @workwq: Work queue for processing pending PTP operations | 225 | * @workwq: Work queue for processing pending PTP operations |
| 225 | * @work: Work task | 226 | * @work: Work task |
| @@ -270,6 +271,7 @@ struct efx_ptp_data { | |||
| 270 | struct list_head evt_list; | 271 | struct list_head evt_list; |
| 271 | struct list_head evt_free_list; | 272 | struct list_head evt_free_list; |
| 272 | spinlock_t evt_lock; | 273 | spinlock_t evt_lock; |
| 274 | bool evt_overflow; | ||
| 273 | struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS]; | 275 | struct efx_ptp_event_rx rx_evts[MAX_RECEIVE_EVENTS]; |
| 274 | struct workqueue_struct *workwq; | 276 | struct workqueue_struct *workwq; |
| 275 | struct work_struct work; | 277 | struct work_struct work; |
| @@ -635,6 +637,11 @@ static void efx_ptp_drop_time_expired_events(struct efx_nic *efx) | |||
| 635 | } | 637 | } |
| 636 | } | 638 | } |
| 637 | } | 639 | } |
| 640 | /* If the event overflow flag is set and the event list is now empty | ||
| 641 | * clear the flag to re-enable the overflow warning message. | ||
| 642 | */ | ||
| 643 | if (ptp->evt_overflow && list_empty(&ptp->evt_list)) | ||
| 644 | ptp->evt_overflow = false; | ||
| 638 | spin_unlock_bh(&ptp->evt_lock); | 645 | spin_unlock_bh(&ptp->evt_lock); |
| 639 | } | 646 | } |
| 640 | 647 | ||
| @@ -676,6 +683,11 @@ static enum ptp_packet_state efx_ptp_match_rx(struct efx_nic *efx, | |||
| 676 | break; | 683 | break; |
| 677 | } | 684 | } |
| 678 | } | 685 | } |
| 686 | /* If the event overflow flag is set and the event list is now empty | ||
| 687 | * clear the flag to re-enable the overflow warning message. | ||
| 688 | */ | ||
| 689 | if (ptp->evt_overflow && list_empty(&ptp->evt_list)) | ||
| 690 | ptp->evt_overflow = false; | ||
| 679 | spin_unlock_bh(&ptp->evt_lock); | 691 | spin_unlock_bh(&ptp->evt_lock); |
| 680 | 692 | ||
| 681 | return rc; | 693 | return rc; |
| @@ -705,8 +717,9 @@ static bool efx_ptp_process_events(struct efx_nic *efx, struct sk_buff_head *q) | |||
| 705 | __skb_queue_tail(q, skb); | 717 | __skb_queue_tail(q, skb); |
| 706 | } else if (time_after(jiffies, match->expiry)) { | 718 | } else if (time_after(jiffies, match->expiry)) { |
| 707 | match->state = PTP_PACKET_STATE_TIMED_OUT; | 719 | match->state = PTP_PACKET_STATE_TIMED_OUT; |
| 708 | netif_warn(efx, rx_err, efx->net_dev, | 720 | if (net_ratelimit()) |
| 709 | "PTP packet - no timestamp seen\n"); | 721 | netif_warn(efx, rx_err, efx->net_dev, |
| 722 | "PTP packet - no timestamp seen\n"); | ||
| 710 | __skb_queue_tail(q, skb); | 723 | __skb_queue_tail(q, skb); |
| 711 | } else { | 724 | } else { |
| 712 | /* Replace unprocessed entry and stop */ | 725 | /* Replace unprocessed entry and stop */ |
| @@ -788,9 +801,14 @@ fail: | |||
| 788 | static int efx_ptp_stop(struct efx_nic *efx) | 801 | static int efx_ptp_stop(struct efx_nic *efx) |
| 789 | { | 802 | { |
| 790 | struct efx_ptp_data *ptp = efx->ptp_data; | 803 | struct efx_ptp_data *ptp = efx->ptp_data; |
| 791 | int rc = efx_ptp_disable(efx); | ||
| 792 | struct list_head *cursor; | 804 | struct list_head *cursor; |
| 793 | struct list_head *next; | 805 | struct list_head *next; |
| 806 | int rc; | ||
| 807 | |||
| 808 | if (ptp == NULL) | ||
| 809 | return 0; | ||
| 810 | |||
| 811 | rc = efx_ptp_disable(efx); | ||
| 794 | 812 | ||
| 795 | if (ptp->rxfilter_installed) { | 813 | if (ptp->rxfilter_installed) { |
| 796 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, | 814 | efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, |
| @@ -809,11 +827,19 @@ static int efx_ptp_stop(struct efx_nic *efx) | |||
| 809 | list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) { | 827 | list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) { |
| 810 | list_move(cursor, &efx->ptp_data->evt_free_list); | 828 | list_move(cursor, &efx->ptp_data->evt_free_list); |
| 811 | } | 829 | } |
| 830 | ptp->evt_overflow = false; | ||
| 812 | spin_unlock_bh(&efx->ptp_data->evt_lock); | 831 | spin_unlock_bh(&efx->ptp_data->evt_lock); |
| 813 | 832 | ||
| 814 | return rc; | 833 | return rc; |
| 815 | } | 834 | } |
| 816 | 835 | ||
| 836 | static int efx_ptp_restart(struct efx_nic *efx) | ||
| 837 | { | ||
| 838 | if (efx->ptp_data && efx->ptp_data->enabled) | ||
| 839 | return efx_ptp_start(efx); | ||
| 840 | return 0; | ||
| 841 | } | ||
| 842 | |||
| 817 | static void efx_ptp_pps_worker(struct work_struct *work) | 843 | static void efx_ptp_pps_worker(struct work_struct *work) |
| 818 | { | 844 | { |
| 819 | struct efx_ptp_data *ptp = | 845 | struct efx_ptp_data *ptp = |
| @@ -901,6 +927,7 @@ static int efx_ptp_probe_channel(struct efx_channel *channel) | |||
| 901 | spin_lock_init(&ptp->evt_lock); | 927 | spin_lock_init(&ptp->evt_lock); |
| 902 | for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) | 928 | for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++) |
| 903 | list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); | 929 | list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list); |
| 930 | ptp->evt_overflow = false; | ||
| 904 | 931 | ||
| 905 | ptp->phc_clock_info.owner = THIS_MODULE; | 932 | ptp->phc_clock_info.owner = THIS_MODULE; |
| 906 | snprintf(ptp->phc_clock_info.name, | 933 | snprintf(ptp->phc_clock_info.name, |
| @@ -989,7 +1016,11 @@ bool efx_ptp_is_ptp_tx(struct efx_nic *efx, struct sk_buff *skb) | |||
| 989 | skb->len >= PTP_MIN_LENGTH && | 1016 | skb->len >= PTP_MIN_LENGTH && |
| 990 | skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM && | 1017 | skb->len <= MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM && |
| 991 | likely(skb->protocol == htons(ETH_P_IP)) && | 1018 | likely(skb->protocol == htons(ETH_P_IP)) && |
| 1019 | skb_transport_header_was_set(skb) && | ||
| 1020 | skb_network_header_len(skb) >= sizeof(struct iphdr) && | ||
| 992 | ip_hdr(skb)->protocol == IPPROTO_UDP && | 1021 | ip_hdr(skb)->protocol == IPPROTO_UDP && |
| 1022 | skb_headlen(skb) >= | ||
| 1023 | skb_transport_offset(skb) + sizeof(struct udphdr) && | ||
| 993 | udp_hdr(skb)->dest == htons(PTP_EVENT_PORT); | 1024 | udp_hdr(skb)->dest == htons(PTP_EVENT_PORT); |
| 994 | } | 1025 | } |
| 995 | 1026 | ||
| @@ -1106,7 +1137,7 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | |||
| 1106 | { | 1137 | { |
| 1107 | if ((enable_wanted != efx->ptp_data->enabled) || | 1138 | if ((enable_wanted != efx->ptp_data->enabled) || |
| 1108 | (enable_wanted && (efx->ptp_data->mode != new_mode))) { | 1139 | (enable_wanted && (efx->ptp_data->mode != new_mode))) { |
| 1109 | int rc; | 1140 | int rc = 0; |
| 1110 | 1141 | ||
| 1111 | if (enable_wanted) { | 1142 | if (enable_wanted) { |
| 1112 | /* Change of mode requires disable */ | 1143 | /* Change of mode requires disable */ |
| @@ -1123,7 +1154,8 @@ static int efx_ptp_change_mode(struct efx_nic *efx, bool enable_wanted, | |||
| 1123 | * succeed. | 1154 | * succeed. |
| 1124 | */ | 1155 | */ |
| 1125 | efx->ptp_data->mode = new_mode; | 1156 | efx->ptp_data->mode = new_mode; |
| 1126 | rc = efx_ptp_start(efx); | 1157 | if (netif_running(efx->net_dev)) |
| 1158 | rc = efx_ptp_start(efx); | ||
| 1127 | if (rc == 0) { | 1159 | if (rc == 0) { |
| 1128 | rc = efx_ptp_synchronize(efx, | 1160 | rc = efx_ptp_synchronize(efx, |
| 1129 | PTP_SYNC_ATTEMPTS * 2); | 1161 | PTP_SYNC_ATTEMPTS * 2); |
| @@ -1295,8 +1327,13 @@ static void ptp_event_rx(struct efx_nic *efx, struct efx_ptp_data *ptp) | |||
| 1295 | list_add_tail(&evt->link, &ptp->evt_list); | 1327 | list_add_tail(&evt->link, &ptp->evt_list); |
| 1296 | 1328 | ||
| 1297 | queue_work(ptp->workwq, &ptp->work); | 1329 | queue_work(ptp->workwq, &ptp->work); |
| 1298 | } else { | 1330 | } else if (!ptp->evt_overflow) { |
| 1299 | netif_err(efx, rx_err, efx->net_dev, "No free PTP event"); | 1331 | /* Log a warning message and set the event overflow flag. |
| 1332 | * The message won't be logged again until the event queue | ||
| 1333 | * becomes empty. | ||
| 1334 | */ | ||
| 1335 | netif_err(efx, rx_err, efx->net_dev, "PTP event queue overflow\n"); | ||
| 1336 | ptp->evt_overflow = true; | ||
| 1300 | } | 1337 | } |
| 1301 | spin_unlock_bh(&ptp->evt_lock); | 1338 | spin_unlock_bh(&ptp->evt_lock); |
| 1302 | } | 1339 | } |
| @@ -1389,7 +1426,7 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) | |||
| 1389 | if (rc != 0) | 1426 | if (rc != 0) |
| 1390 | return rc; | 1427 | return rc; |
| 1391 | 1428 | ||
| 1392 | ptp_data->current_adjfreq = delta; | 1429 | ptp_data->current_adjfreq = adjustment_ns; |
| 1393 | return 0; | 1430 | return 0; |
| 1394 | } | 1431 | } |
| 1395 | 1432 | ||
| @@ -1404,7 +1441,7 @@ static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta) | |||
| 1404 | 1441 | ||
| 1405 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST); | 1442 | MCDI_SET_DWORD(inbuf, PTP_IN_OP, MC_CMD_PTP_OP_ADJUST); |
| 1406 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); | 1443 | MCDI_SET_DWORD(inbuf, PTP_IN_PERIPH_ID, 0); |
| 1407 | MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, 0); | 1444 | MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq); |
| 1408 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec); | 1445 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_SECONDS, (u32)delta_ts.tv_sec); |
| 1409 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec); | 1446 | MCDI_SET_DWORD(inbuf, PTP_IN_ADJUST_NANOSECONDS, (u32)delta_ts.tv_nsec); |
| 1410 | return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), | 1447 | return efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf), |
| @@ -1491,3 +1528,14 @@ void efx_ptp_probe(struct efx_nic *efx) | |||
| 1491 | efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] = | 1528 | efx->extra_channel_type[EFX_EXTRA_CHANNEL_PTP] = |
| 1492 | &efx_ptp_channel_type; | 1529 | &efx_ptp_channel_type; |
| 1493 | } | 1530 | } |
| 1531 | |||
| 1532 | void efx_ptp_start_datapath(struct efx_nic *efx) | ||
| 1533 | { | ||
| 1534 | if (efx_ptp_restart(efx)) | ||
| 1535 | netif_err(efx, drv, efx->net_dev, "Failed to restart PTP.\n"); | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | void efx_ptp_stop_datapath(struct efx_nic *efx) | ||
| 1539 | { | ||
| 1540 | efx_ptp_stop(efx); | ||
| 1541 | } | ||
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 8f09e686fc23..42488df1f4ec 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
| @@ -94,7 +94,7 @@ static inline void efx_sync_rx_buffer(struct efx_nic *efx, | |||
| 94 | 94 | ||
| 95 | void efx_rx_config_page_split(struct efx_nic *efx) | 95 | void efx_rx_config_page_split(struct efx_nic *efx) |
| 96 | { | 96 | { |
| 97 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + NET_IP_ALIGN, | 97 | efx->rx_page_buf_step = ALIGN(efx->rx_dma_len + efx->rx_ip_align, |
| 98 | EFX_RX_BUF_ALIGNMENT); | 98 | EFX_RX_BUF_ALIGNMENT); |
| 99 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : | 99 | efx->rx_bufs_per_page = efx->rx_buffer_order ? 1 : |
| 100 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / | 100 | ((PAGE_SIZE - sizeof(struct efx_rx_page_state)) / |
| @@ -189,9 +189,9 @@ static int efx_init_rx_buffers(struct efx_rx_queue *rx_queue) | |||
| 189 | do { | 189 | do { |
| 190 | index = rx_queue->added_count & rx_queue->ptr_mask; | 190 | index = rx_queue->added_count & rx_queue->ptr_mask; |
| 191 | rx_buf = efx_rx_buffer(rx_queue, index); | 191 | rx_buf = efx_rx_buffer(rx_queue, index); |
| 192 | rx_buf->dma_addr = dma_addr + NET_IP_ALIGN; | 192 | rx_buf->dma_addr = dma_addr + efx->rx_ip_align; |
| 193 | rx_buf->page = page; | 193 | rx_buf->page = page; |
| 194 | rx_buf->page_offset = page_offset + NET_IP_ALIGN; | 194 | rx_buf->page_offset = page_offset + efx->rx_ip_align; |
| 195 | rx_buf->len = efx->rx_dma_len; | 195 | rx_buf->len = efx->rx_dma_len; |
| 196 | rx_buf->flags = 0; | 196 | rx_buf->flags = 0; |
| 197 | ++rx_queue->added_count; | 197 | ++rx_queue->added_count; |
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 0c9b5d94154f..8bf29eb4a5a0 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
| @@ -82,6 +82,7 @@ static const char version[] = | |||
| 82 | #include <linux/mii.h> | 82 | #include <linux/mii.h> |
| 83 | #include <linux/workqueue.h> | 83 | #include <linux/workqueue.h> |
| 84 | #include <linux/of.h> | 84 | #include <linux/of.h> |
| 85 | #include <linux/of_device.h> | ||
| 85 | 86 | ||
| 86 | #include <linux/netdevice.h> | 87 | #include <linux/netdevice.h> |
| 87 | #include <linux/etherdevice.h> | 88 | #include <linux/etherdevice.h> |
| @@ -2184,6 +2185,15 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * | |||
| 2184 | } | 2185 | } |
| 2185 | } | 2186 | } |
| 2186 | 2187 | ||
| 2188 | #if IS_BUILTIN(CONFIG_OF) | ||
| 2189 | static const struct of_device_id smc91x_match[] = { | ||
| 2190 | { .compatible = "smsc,lan91c94", }, | ||
| 2191 | { .compatible = "smsc,lan91c111", }, | ||
| 2192 | {}, | ||
| 2193 | }; | ||
| 2194 | MODULE_DEVICE_TABLE(of, smc91x_match); | ||
| 2195 | #endif | ||
| 2196 | |||
| 2187 | /* | 2197 | /* |
| 2188 | * smc_init(void) | 2198 | * smc_init(void) |
| 2189 | * Input parameters: | 2199 | * Input parameters: |
| @@ -2198,6 +2208,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * | |||
| 2198 | static int smc_drv_probe(struct platform_device *pdev) | 2208 | static int smc_drv_probe(struct platform_device *pdev) |
| 2199 | { | 2209 | { |
| 2200 | struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev); | 2210 | struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev); |
| 2211 | const struct of_device_id *match = NULL; | ||
| 2201 | struct smc_local *lp; | 2212 | struct smc_local *lp; |
| 2202 | struct net_device *ndev; | 2213 | struct net_device *ndev; |
| 2203 | struct resource *res, *ires; | 2214 | struct resource *res, *ires; |
| @@ -2217,11 +2228,34 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
| 2217 | */ | 2228 | */ |
| 2218 | 2229 | ||
| 2219 | lp = netdev_priv(ndev); | 2230 | lp = netdev_priv(ndev); |
| 2231 | lp->cfg.flags = 0; | ||
| 2220 | 2232 | ||
| 2221 | if (pd) { | 2233 | if (pd) { |
| 2222 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); | 2234 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); |
| 2223 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); | 2235 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); |
| 2224 | } else { | 2236 | } |
| 2237 | |||
| 2238 | #if IS_BUILTIN(CONFIG_OF) | ||
| 2239 | match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev); | ||
| 2240 | if (match) { | ||
| 2241 | struct device_node *np = pdev->dev.of_node; | ||
| 2242 | u32 val; | ||
| 2243 | |||
| 2244 | /* Combination of IO widths supported, default to 16-bit */ | ||
| 2245 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | ||
| 2246 | if (val & 1) | ||
| 2247 | lp->cfg.flags |= SMC91X_USE_8BIT; | ||
| 2248 | if ((val == 0) || (val & 2)) | ||
| 2249 | lp->cfg.flags |= SMC91X_USE_16BIT; | ||
| 2250 | if (val & 4) | ||
| 2251 | lp->cfg.flags |= SMC91X_USE_32BIT; | ||
| 2252 | } else { | ||
| 2253 | lp->cfg.flags |= SMC91X_USE_16BIT; | ||
| 2254 | } | ||
| 2255 | } | ||
| 2256 | #endif | ||
| 2257 | |||
| 2258 | if (!pd && !match) { | ||
| 2225 | lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; | 2259 | lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; |
| 2226 | lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; | 2260 | lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; |
| 2227 | lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; | 2261 | lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; |
| @@ -2370,15 +2404,6 @@ static int smc_drv_resume(struct device *dev) | |||
| 2370 | return 0; | 2404 | return 0; |
| 2371 | } | 2405 | } |
| 2372 | 2406 | ||
| 2373 | #ifdef CONFIG_OF | ||
| 2374 | static const struct of_device_id smc91x_match[] = { | ||
| 2375 | { .compatible = "smsc,lan91c94", }, | ||
| 2376 | { .compatible = "smsc,lan91c111", }, | ||
| 2377 | {}, | ||
| 2378 | }; | ||
| 2379 | MODULE_DEVICE_TABLE(of, smc91x_match); | ||
| 2380 | #endif | ||
| 2381 | |||
| 2382 | static struct dev_pm_ops smc_drv_pm_ops = { | 2407 | static struct dev_pm_ops smc_drv_pm_ops = { |
| 2383 | .suspend = smc_drv_suspend, | 2408 | .suspend = smc_drv_suspend, |
| 2384 | .resume = smc_drv_resume, | 2409 | .resume = smc_drv_resume, |
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index dd0dd6279b4e..4f1d2549130e 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c | |||
| @@ -2019,7 +2019,6 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2019 | ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO | 2019 | ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO |
| 2020 | | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | | 2020 | | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | |
| 2021 | NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM | 2021 | NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXCSUM |
| 2022 | /*| NETIF_F_FRAGLIST */ | ||
| 2023 | ; | 2022 | ; |
| 2024 | ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | | 2023 | ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | |
| 2025 | NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX; | 2024 | NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX; |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 7536a4c01293..5120d9ce1dd4 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
| @@ -1151,6 +1151,12 @@ static int cpsw_ndo_open(struct net_device *ndev) | |||
| 1151 | * receive descs | 1151 | * receive descs |
| 1152 | */ | 1152 | */ |
| 1153 | cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); | 1153 | cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); |
| 1154 | |||
| 1155 | if (cpts_register(&priv->pdev->dev, priv->cpts, | ||
| 1156 | priv->data.cpts_clock_mult, | ||
| 1157 | priv->data.cpts_clock_shift)) | ||
| 1158 | dev_err(priv->dev, "error registering cpts device\n"); | ||
| 1159 | |||
| 1154 | } | 1160 | } |
| 1155 | 1161 | ||
| 1156 | /* Enable Interrupt pacing if configured */ | 1162 | /* Enable Interrupt pacing if configured */ |
| @@ -1197,6 +1203,7 @@ static int cpsw_ndo_stop(struct net_device *ndev) | |||
| 1197 | netif_carrier_off(priv->ndev); | 1203 | netif_carrier_off(priv->ndev); |
| 1198 | 1204 | ||
| 1199 | if (cpsw_common_res_usage_state(priv) <= 1) { | 1205 | if (cpsw_common_res_usage_state(priv) <= 1) { |
| 1206 | cpts_unregister(priv->cpts); | ||
| 1200 | cpsw_intr_disable(priv); | 1207 | cpsw_intr_disable(priv); |
| 1201 | cpdma_ctlr_int_ctrl(priv->dma, false); | 1208 | cpdma_ctlr_int_ctrl(priv->dma, false); |
| 1202 | cpdma_ctlr_stop(priv->dma); | 1209 | cpdma_ctlr_stop(priv->dma); |
| @@ -1816,6 +1823,8 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
| 1816 | } | 1823 | } |
| 1817 | 1824 | ||
| 1818 | i++; | 1825 | i++; |
| 1826 | if (i == data->slaves) | ||
| 1827 | break; | ||
| 1819 | } | 1828 | } |
| 1820 | 1829 | ||
| 1821 | return 0; | 1830 | return 0; |
| @@ -1983,9 +1992,15 @@ static int cpsw_probe(struct platform_device *pdev) | |||
| 1983 | goto clean_runtime_disable_ret; | 1992 | goto clean_runtime_disable_ret; |
| 1984 | } | 1993 | } |
| 1985 | priv->regs = ss_regs; | 1994 | priv->regs = ss_regs; |
| 1986 | priv->version = __raw_readl(&priv->regs->id_ver); | ||
| 1987 | priv->host_port = HOST_PORT_NUM; | 1995 | priv->host_port = HOST_PORT_NUM; |
| 1988 | 1996 | ||
| 1997 | /* Need to enable clocks with runtime PM api to access module | ||
| 1998 | * registers | ||
| 1999 | */ | ||
| 2000 | pm_runtime_get_sync(&pdev->dev); | ||
| 2001 | priv->version = readl(&priv->regs->id_ver); | ||
| 2002 | pm_runtime_put_sync(&pdev->dev); | ||
| 2003 | |||
| 1989 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 2004 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 1990 | priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); | 2005 | priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); |
| 1991 | if (IS_ERR(priv->wr_regs)) { | 2006 | if (IS_ERR(priv->wr_regs)) { |
| @@ -2155,8 +2170,6 @@ static int cpsw_remove(struct platform_device *pdev) | |||
| 2155 | unregister_netdev(cpsw_get_slave_ndev(priv, 1)); | 2170 | unregister_netdev(cpsw_get_slave_ndev(priv, 1)); |
| 2156 | unregister_netdev(ndev); | 2171 | unregister_netdev(ndev); |
| 2157 | 2172 | ||
| 2158 | cpts_unregister(priv->cpts); | ||
| 2159 | |||
| 2160 | cpsw_ale_destroy(priv->ale); | 2173 | cpsw_ale_destroy(priv->ale); |
| 2161 | cpdma_chan_destroy(priv->txch); | 2174 | cpdma_chan_destroy(priv->txch); |
| 2162 | cpdma_chan_destroy(priv->rxch); | 2175 | cpdma_chan_destroy(priv->rxch); |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 41ba974bf37c..cd9b164a0434 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
| @@ -61,6 +61,7 @@ | |||
| 61 | #include <linux/davinci_emac.h> | 61 | #include <linux/davinci_emac.h> |
| 62 | #include <linux/of.h> | 62 | #include <linux/of.h> |
| 63 | #include <linux/of_address.h> | 63 | #include <linux/of_address.h> |
| 64 | #include <linux/of_device.h> | ||
| 64 | #include <linux/of_irq.h> | 65 | #include <linux/of_irq.h> |
| 65 | #include <linux/of_net.h> | 66 | #include <linux/of_net.h> |
| 66 | 67 | ||
| @@ -1752,10 +1753,14 @@ static const struct net_device_ops emac_netdev_ops = { | |||
| 1752 | #endif | 1753 | #endif |
| 1753 | }; | 1754 | }; |
| 1754 | 1755 | ||
| 1756 | static const struct of_device_id davinci_emac_of_match[]; | ||
| 1757 | |||
| 1755 | static struct emac_platform_data * | 1758 | static struct emac_platform_data * |
| 1756 | davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) | 1759 | davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) |
| 1757 | { | 1760 | { |
| 1758 | struct device_node *np; | 1761 | struct device_node *np; |
| 1762 | const struct of_device_id *match; | ||
| 1763 | const struct emac_platform_data *auxdata; | ||
| 1759 | struct emac_platform_data *pdata = NULL; | 1764 | struct emac_platform_data *pdata = NULL; |
| 1760 | const u8 *mac_addr; | 1765 | const u8 *mac_addr; |
| 1761 | 1766 | ||
| @@ -1793,7 +1798,20 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) | |||
| 1793 | 1798 | ||
| 1794 | priv->phy_node = of_parse_phandle(np, "phy-handle", 0); | 1799 | priv->phy_node = of_parse_phandle(np, "phy-handle", 0); |
| 1795 | if (!priv->phy_node) | 1800 | if (!priv->phy_node) |
| 1796 | pdata->phy_id = ""; | 1801 | pdata->phy_id = NULL; |
| 1802 | |||
| 1803 | auxdata = pdev->dev.platform_data; | ||
| 1804 | if (auxdata) { | ||
| 1805 | pdata->interrupt_enable = auxdata->interrupt_enable; | ||
| 1806 | pdata->interrupt_disable = auxdata->interrupt_disable; | ||
| 1807 | } | ||
| 1808 | |||
| 1809 | match = of_match_device(davinci_emac_of_match, &pdev->dev); | ||
| 1810 | if (match && match->data) { | ||
| 1811 | auxdata = match->data; | ||
| 1812 | pdata->version = auxdata->version; | ||
| 1813 | pdata->hw_ram_addr = auxdata->hw_ram_addr; | ||
| 1814 | } | ||
| 1797 | 1815 | ||
| 1798 | pdev->dev.platform_data = pdata; | 1816 | pdev->dev.platform_data = pdata; |
| 1799 | 1817 | ||
| @@ -2020,8 +2038,14 @@ static const struct dev_pm_ops davinci_emac_pm_ops = { | |||
| 2020 | }; | 2038 | }; |
| 2021 | 2039 | ||
| 2022 | #if IS_ENABLED(CONFIG_OF) | 2040 | #if IS_ENABLED(CONFIG_OF) |
| 2041 | static const struct emac_platform_data am3517_emac_data = { | ||
| 2042 | .version = EMAC_VERSION_2, | ||
| 2043 | .hw_ram_addr = 0x01e20000, | ||
| 2044 | }; | ||
| 2045 | |||
| 2023 | static const struct of_device_id davinci_emac_of_match[] = { | 2046 | static const struct of_device_id davinci_emac_of_match[] = { |
| 2024 | {.compatible = "ti,davinci-dm6467-emac", }, | 2047 | {.compatible = "ti,davinci-dm6467-emac", }, |
| 2048 | {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, }, | ||
| 2025 | {}, | 2049 | {}, |
| 2026 | }; | 2050 | }; |
| 2027 | MODULE_DEVICE_TABLE(of, davinci_emac_of_match); | 2051 | MODULE_DEVICE_TABLE(of, davinci_emac_of_match); |
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 1f2364126323..2166e879a096 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c | |||
| @@ -1017,7 +1017,7 @@ static int temac_of_probe(struct platform_device *op) | |||
| 1017 | platform_set_drvdata(op, ndev); | 1017 | platform_set_drvdata(op, ndev); |
| 1018 | SET_NETDEV_DEV(ndev, &op->dev); | 1018 | SET_NETDEV_DEV(ndev, &op->dev); |
| 1019 | ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ | 1019 | ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ |
| 1020 | ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; | 1020 | ndev->features = NETIF_F_SG; |
| 1021 | ndev->netdev_ops = &temac_netdev_ops; | 1021 | ndev->netdev_ops = &temac_netdev_ops; |
| 1022 | ndev->ethtool_ops = &temac_ethtool_ops; | 1022 | ndev->ethtool_ops = &temac_ethtool_ops; |
| 1023 | #if 0 | 1023 | #if 0 |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index b2ff038d6d20..f9293da19e26 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
| @@ -1486,7 +1486,7 @@ static int axienet_of_probe(struct platform_device *op) | |||
| 1486 | 1486 | ||
| 1487 | SET_NETDEV_DEV(ndev, &op->dev); | 1487 | SET_NETDEV_DEV(ndev, &op->dev); |
| 1488 | ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ | 1488 | ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ |
| 1489 | ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; | 1489 | ndev->features = NETIF_F_SG; |
| 1490 | ndev->netdev_ops = &axienet_netdev_ops; | 1490 | ndev->netdev_ops = &axienet_netdev_ops; |
| 1491 | ndev->ethtool_ops = &axienet_ethtool_ops; | 1491 | ndev->ethtool_ops = &axienet_ethtool_ops; |
| 1492 | 1492 | ||
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 74234a51c851..fefb8cd5eb65 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c | |||
| @@ -163,26 +163,9 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata) | |||
| 163 | __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, | 163 | __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, |
| 164 | drvdata->base_addr + XEL_TSR_OFFSET); | 164 | drvdata->base_addr + XEL_TSR_OFFSET); |
| 165 | 165 | ||
| 166 | /* Enable the Tx interrupts for the second Buffer if | ||
| 167 | * configured in HW */ | ||
| 168 | if (drvdata->tx_ping_pong != 0) { | ||
| 169 | reg_data = __raw_readl(drvdata->base_addr + | ||
| 170 | XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); | ||
| 171 | __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, | ||
| 172 | drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
| 173 | XEL_TSR_OFFSET); | ||
| 174 | } | ||
| 175 | |||
| 176 | /* Enable the Rx interrupts for the first buffer */ | 166 | /* Enable the Rx interrupts for the first buffer */ |
| 177 | __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); | 167 | __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); |
| 178 | 168 | ||
| 179 | /* Enable the Rx interrupts for the second Buffer if | ||
| 180 | * configured in HW */ | ||
| 181 | if (drvdata->rx_ping_pong != 0) { | ||
| 182 | __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + | ||
| 183 | XEL_BUFFER_OFFSET + XEL_RSR_OFFSET); | ||
| 184 | } | ||
| 185 | |||
| 186 | /* Enable the Global Interrupt Enable */ | 169 | /* Enable the Global Interrupt Enable */ |
| 187 | __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); | 170 | __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); |
| 188 | } | 171 | } |
| @@ -206,31 +189,10 @@ static void xemaclite_disable_interrupts(struct net_local *drvdata) | |||
| 206 | __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), | 189 | __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), |
| 207 | drvdata->base_addr + XEL_TSR_OFFSET); | 190 | drvdata->base_addr + XEL_TSR_OFFSET); |
| 208 | 191 | ||
| 209 | /* Disable the Tx interrupts for the second Buffer | ||
| 210 | * if configured in HW */ | ||
| 211 | if (drvdata->tx_ping_pong != 0) { | ||
| 212 | reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
| 213 | XEL_TSR_OFFSET); | ||
| 214 | __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), | ||
| 215 | drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
| 216 | XEL_TSR_OFFSET); | ||
| 217 | } | ||
| 218 | |||
| 219 | /* Disable the Rx interrupts for the first buffer */ | 192 | /* Disable the Rx interrupts for the first buffer */ |
| 220 | reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); | 193 | reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); |
| 221 | __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), | 194 | __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), |
| 222 | drvdata->base_addr + XEL_RSR_OFFSET); | 195 | drvdata->base_addr + XEL_RSR_OFFSET); |
| 223 | |||
| 224 | /* Disable the Rx interrupts for the second buffer | ||
| 225 | * if configured in HW */ | ||
| 226 | if (drvdata->rx_ping_pong != 0) { | ||
| 227 | |||
| 228 | reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
| 229 | XEL_RSR_OFFSET); | ||
| 230 | __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), | ||
| 231 | drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
| 232 | XEL_RSR_OFFSET); | ||
| 233 | } | ||
| 234 | } | 196 | } |
| 235 | 197 | ||
| 236 | /** | 198 | /** |
| @@ -258,6 +220,13 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, | |||
| 258 | *to_u16_ptr++ = *from_u16_ptr++; | 220 | *to_u16_ptr++ = *from_u16_ptr++; |
| 259 | *to_u16_ptr++ = *from_u16_ptr++; | 221 | *to_u16_ptr++ = *from_u16_ptr++; |
| 260 | 222 | ||
| 223 | /* This barrier resolves occasional issues seen around | ||
| 224 | * cases where the data is not properly flushed out | ||
| 225 | * from the processor store buffers to the destination | ||
| 226 | * memory locations. | ||
| 227 | */ | ||
| 228 | wmb(); | ||
| 229 | |||
| 261 | /* Output a word */ | 230 | /* Output a word */ |
| 262 | *to_u32_ptr++ = align_buffer; | 231 | *to_u32_ptr++ = align_buffer; |
| 263 | } | 232 | } |
| @@ -273,6 +242,12 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, | |||
| 273 | for (; length > 0; length--) | 242 | for (; length > 0; length--) |
| 274 | *to_u8_ptr++ = *from_u8_ptr++; | 243 | *to_u8_ptr++ = *from_u8_ptr++; |
| 275 | 244 | ||
| 245 | /* This barrier resolves occasional issues seen around | ||
| 246 | * cases where the data is not properly flushed out | ||
| 247 | * from the processor store buffers to the destination | ||
| 248 | * memory locations. | ||
| 249 | */ | ||
| 250 | wmb(); | ||
| 276 | *to_u32_ptr = align_buffer; | 251 | *to_u32_ptr = align_buffer; |
| 277 | } | 252 | } |
| 278 | } | 253 | } |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 9093004f9b63..2a89da080317 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
| @@ -770,7 +770,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
| 770 | int ret; | 770 | int ret; |
| 771 | int vnet_hdr_len = 0; | 771 | int vnet_hdr_len = 0; |
| 772 | int vlan_offset = 0; | 772 | int vlan_offset = 0; |
| 773 | int copied; | 773 | int copied, total; |
| 774 | 774 | ||
| 775 | if (q->flags & IFF_VNET_HDR) { | 775 | if (q->flags & IFF_VNET_HDR) { |
| 776 | struct virtio_net_hdr vnet_hdr; | 776 | struct virtio_net_hdr vnet_hdr; |
| @@ -785,7 +785,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
| 785 | if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) | 785 | if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) |
| 786 | return -EFAULT; | 786 | return -EFAULT; |
| 787 | } | 787 | } |
| 788 | copied = vnet_hdr_len; | 788 | total = copied = vnet_hdr_len; |
| 789 | total += skb->len; | ||
| 789 | 790 | ||
| 790 | if (!vlan_tx_tag_present(skb)) | 791 | if (!vlan_tx_tag_present(skb)) |
| 791 | len = min_t(int, skb->len, len); | 792 | len = min_t(int, skb->len, len); |
| @@ -800,6 +801,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
| 800 | 801 | ||
| 801 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 802 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); |
| 802 | len = min_t(int, skb->len + VLAN_HLEN, len); | 803 | len = min_t(int, skb->len + VLAN_HLEN, len); |
| 804 | total += VLAN_HLEN; | ||
| 803 | 805 | ||
| 804 | copy = min_t(int, vlan_offset, len); | 806 | copy = min_t(int, vlan_offset, len); |
| 805 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); | 807 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); |
| @@ -817,10 +819,9 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
| 817 | } | 819 | } |
| 818 | 820 | ||
| 819 | ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); | 821 | ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); |
| 820 | copied += len; | ||
| 821 | 822 | ||
| 822 | done: | 823 | done: |
| 823 | return ret ? ret : copied; | 824 | return ret ? ret : total; |
| 824 | } | 825 | } |
| 825 | 826 | ||
| 826 | static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, | 827 | static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, |
| @@ -875,7 +876,9 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
| 875 | } | 876 | } |
| 876 | 877 | ||
| 877 | ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); | 878 | ret = macvtap_do_read(q, iocb, iv, len, file->f_flags & O_NONBLOCK); |
| 878 | ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ | 879 | ret = min_t(ssize_t, ret, len); |
| 880 | if (ret > 0) | ||
| 881 | iocb->ki_pos = ret; | ||
| 879 | out: | 882 | out: |
| 880 | return ret; | 883 | return ret; |
| 881 | } | 884 | } |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 3ae28f420868..26fa05a472b4 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
| @@ -336,6 +336,21 @@ static struct phy_driver ksphy_driver[] = { | |||
| 336 | .resume = genphy_resume, | 336 | .resume = genphy_resume, |
| 337 | .driver = { .owner = THIS_MODULE,}, | 337 | .driver = { .owner = THIS_MODULE,}, |
| 338 | }, { | 338 | }, { |
| 339 | .phy_id = PHY_ID_KSZ8041RNLI, | ||
| 340 | .phy_id_mask = 0x00fffff0, | ||
| 341 | .name = "Micrel KSZ8041RNLI", | ||
| 342 | .features = PHY_BASIC_FEATURES | | ||
| 343 | SUPPORTED_Pause | SUPPORTED_Asym_Pause, | ||
| 344 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | ||
| 345 | .config_init = kszphy_config_init, | ||
| 346 | .config_aneg = genphy_config_aneg, | ||
| 347 | .read_status = genphy_read_status, | ||
| 348 | .ack_interrupt = kszphy_ack_interrupt, | ||
| 349 | .config_intr = kszphy_config_intr, | ||
| 350 | .suspend = genphy_suspend, | ||
| 351 | .resume = genphy_resume, | ||
| 352 | .driver = { .owner = THIS_MODULE,}, | ||
| 353 | }, { | ||
| 339 | .phy_id = PHY_ID_KSZ8051, | 354 | .phy_id = PHY_ID_KSZ8051, |
| 340 | .phy_id_mask = 0x00fffff0, | 355 | .phy_id_mask = 0x00fffff0, |
| 341 | .name = "Micrel KSZ8051", | 356 | .name = "Micrel KSZ8051", |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 782e38bfc1ee..7c8343a4f918 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -1184,7 +1184,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
| 1184 | { | 1184 | { |
| 1185 | struct tun_pi pi = { 0, skb->protocol }; | 1185 | struct tun_pi pi = { 0, skb->protocol }; |
| 1186 | ssize_t total = 0; | 1186 | ssize_t total = 0; |
| 1187 | int vlan_offset = 0; | 1187 | int vlan_offset = 0, copied; |
| 1188 | 1188 | ||
| 1189 | if (!(tun->flags & TUN_NO_PI)) { | 1189 | if (!(tun->flags & TUN_NO_PI)) { |
| 1190 | if ((len -= sizeof(pi)) < 0) | 1190 | if ((len -= sizeof(pi)) < 0) |
| @@ -1248,6 +1248,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
| 1248 | total += tun->vnet_hdr_sz; | 1248 | total += tun->vnet_hdr_sz; |
| 1249 | } | 1249 | } |
| 1250 | 1250 | ||
| 1251 | copied = total; | ||
| 1252 | total += skb->len; | ||
| 1251 | if (!vlan_tx_tag_present(skb)) { | 1253 | if (!vlan_tx_tag_present(skb)) { |
| 1252 | len = min_t(int, skb->len, len); | 1254 | len = min_t(int, skb->len, len); |
| 1253 | } else { | 1255 | } else { |
| @@ -1262,24 +1264,24 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
| 1262 | 1264 | ||
| 1263 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 1265 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); |
| 1264 | len = min_t(int, skb->len + VLAN_HLEN, len); | 1266 | len = min_t(int, skb->len + VLAN_HLEN, len); |
| 1267 | total += VLAN_HLEN; | ||
| 1265 | 1268 | ||
| 1266 | copy = min_t(int, vlan_offset, len); | 1269 | copy = min_t(int, vlan_offset, len); |
| 1267 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy); | 1270 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); |
| 1268 | len -= copy; | 1271 | len -= copy; |
| 1269 | total += copy; | 1272 | copied += copy; |
| 1270 | if (ret || !len) | 1273 | if (ret || !len) |
| 1271 | goto done; | 1274 | goto done; |
| 1272 | 1275 | ||
| 1273 | copy = min_t(int, sizeof(veth), len); | 1276 | copy = min_t(int, sizeof(veth), len); |
| 1274 | ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); | 1277 | ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); |
| 1275 | len -= copy; | 1278 | len -= copy; |
| 1276 | total += copy; | 1279 | copied += copy; |
| 1277 | if (ret || !len) | 1280 | if (ret || !len) |
| 1278 | goto done; | 1281 | goto done; |
| 1279 | } | 1282 | } |
| 1280 | 1283 | ||
| 1281 | skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); | 1284 | skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); |
| 1282 | total += len; | ||
| 1283 | 1285 | ||
| 1284 | done: | 1286 | done: |
| 1285 | tun->dev->stats.tx_packets++; | 1287 | tun->dev->stats.tx_packets++; |
| @@ -1356,6 +1358,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
| 1356 | ret = tun_do_read(tun, tfile, iocb, iv, len, | 1358 | ret = tun_do_read(tun, tfile, iocb, iv, len, |
| 1357 | file->f_flags & O_NONBLOCK); | 1359 | file->f_flags & O_NONBLOCK); |
| 1358 | ret = min_t(ssize_t, ret, len); | 1360 | ret = min_t(ssize_t, ret, len); |
| 1361 | if (ret > 0) | ||
| 1362 | iocb->ki_pos = ret; | ||
| 1359 | out: | 1363 | out: |
| 1360 | tun_put(tun); | 1364 | tun_put(tun); |
| 1361 | return ret; | 1365 | return ret; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 916241d16c67..d208f8604981 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -426,10 +426,10 @@ static void receive_buf(struct receive_queue *rq, void *buf, unsigned int len) | |||
| 426 | if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { | 426 | if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { |
| 427 | pr_debug("%s: short packet %i\n", dev->name, len); | 427 | pr_debug("%s: short packet %i\n", dev->name, len); |
| 428 | dev->stats.rx_length_errors++; | 428 | dev->stats.rx_length_errors++; |
| 429 | if (vi->big_packets) | 429 | if (vi->mergeable_rx_bufs) |
| 430 | give_pages(rq, buf); | ||
| 431 | else if (vi->mergeable_rx_bufs) | ||
| 432 | put_page(virt_to_head_page(buf)); | 430 | put_page(virt_to_head_page(buf)); |
| 431 | else if (vi->big_packets) | ||
| 432 | give_pages(rq, buf); | ||
| 433 | else | 433 | else |
| 434 | dev_kfree_skb(buf); | 434 | dev_kfree_skb(buf); |
| 435 | return; | 435 | return; |
| @@ -1367,6 +1367,11 @@ static void virtnet_config_changed(struct virtio_device *vdev) | |||
| 1367 | 1367 | ||
| 1368 | static void virtnet_free_queues(struct virtnet_info *vi) | 1368 | static void virtnet_free_queues(struct virtnet_info *vi) |
| 1369 | { | 1369 | { |
| 1370 | int i; | ||
| 1371 | |||
| 1372 | for (i = 0; i < vi->max_queue_pairs; i++) | ||
| 1373 | netif_napi_del(&vi->rq[i].napi); | ||
| 1374 | |||
| 1370 | kfree(vi->rq); | 1375 | kfree(vi->rq); |
| 1371 | kfree(vi->sq); | 1376 | kfree(vi->sq); |
| 1372 | } | 1377 | } |
| @@ -1396,10 +1401,10 @@ static void free_unused_bufs(struct virtnet_info *vi) | |||
| 1396 | struct virtqueue *vq = vi->rq[i].vq; | 1401 | struct virtqueue *vq = vi->rq[i].vq; |
| 1397 | 1402 | ||
| 1398 | while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { | 1403 | while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { |
| 1399 | if (vi->big_packets) | 1404 | if (vi->mergeable_rx_bufs) |
| 1400 | give_pages(&vi->rq[i], buf); | ||
| 1401 | else if (vi->mergeable_rx_bufs) | ||
| 1402 | put_page(virt_to_head_page(buf)); | 1405 | put_page(virt_to_head_page(buf)); |
| 1406 | else if (vi->big_packets) | ||
| 1407 | give_pages(&vi->rq[i], buf); | ||
| 1403 | else | 1408 | else |
| 1404 | dev_kfree_skb(buf); | 1409 | dev_kfree_skb(buf); |
| 1405 | --vi->rq[i].num; | 1410 | --vi->rq[i].num; |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 0358c07f7669..249e01c5600c 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -1668,7 +1668,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
| 1668 | netdev_dbg(dev, "circular route to %pI4\n", | 1668 | netdev_dbg(dev, "circular route to %pI4\n", |
| 1669 | &dst->sin.sin_addr.s_addr); | 1669 | &dst->sin.sin_addr.s_addr); |
| 1670 | dev->stats.collisions++; | 1670 | dev->stats.collisions++; |
| 1671 | goto tx_error; | 1671 | goto rt_tx_error; |
| 1672 | } | 1672 | } |
| 1673 | 1673 | ||
| 1674 | /* Bypass encapsulation if the destination is local */ | 1674 | /* Bypass encapsulation if the destination is local */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 1ec52356b5a1..130657db5c43 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
| @@ -3984,18 +3984,20 @@ static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq) | |||
| 3984 | int quick_drop; | 3984 | int quick_drop; |
| 3985 | s32 t[3], f[3] = {5180, 5500, 5785}; | 3985 | s32 t[3], f[3] = {5180, 5500, 5785}; |
| 3986 | 3986 | ||
| 3987 | if (!(pBase->miscConfiguration & BIT(1))) | 3987 | if (!(pBase->miscConfiguration & BIT(4))) |
| 3988 | return; | 3988 | return; |
| 3989 | 3989 | ||
| 3990 | if (freq < 4000) | 3990 | if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) { |
| 3991 | quick_drop = eep->modalHeader2G.quick_drop; | 3991 | if (freq < 4000) { |
| 3992 | else { | 3992 | quick_drop = eep->modalHeader2G.quick_drop; |
| 3993 | t[0] = eep->base_ext1.quick_drop_low; | 3993 | } else { |
| 3994 | t[1] = eep->modalHeader5G.quick_drop; | 3994 | t[0] = eep->base_ext1.quick_drop_low; |
| 3995 | t[2] = eep->base_ext1.quick_drop_high; | 3995 | t[1] = eep->modalHeader5G.quick_drop; |
| 3996 | quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3); | 3996 | t[2] = eep->base_ext1.quick_drop_high; |
| 3997 | quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3); | ||
| 3998 | } | ||
| 3999 | REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); | ||
| 3997 | } | 4000 | } |
| 3998 | REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); | ||
| 3999 | } | 4001 | } |
| 4000 | 4002 | ||
| 4001 | static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz) | 4003 | static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz) |
| @@ -4035,7 +4037,7 @@ static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz) | |||
| 4035 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 4037 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
| 4036 | u8 bias; | 4038 | u8 bias; |
| 4037 | 4039 | ||
| 4038 | if (!(eep->baseEepHeader.featureEnable & 0x40)) | 4040 | if (!(eep->baseEepHeader.miscConfiguration & 0x40)) |
| 4039 | return; | 4041 | return; |
| 4040 | 4042 | ||
| 4041 | if (!AR_SREV_9300(ah)) | 4043 | if (!AR_SREV_9300(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 54b04155e43b..8918035da3a3 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -146,10 +146,9 @@ static void ath9k_hw_set_clockrate(struct ath_hw *ah) | |||
| 146 | else | 146 | else |
| 147 | clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; | 147 | clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; |
| 148 | 148 | ||
| 149 | if (IS_CHAN_HT40(chan)) | 149 | if (chan) { |
| 150 | clockrate *= 2; | 150 | if (IS_CHAN_HT40(chan)) |
| 151 | 151 | clockrate *= 2; | |
| 152 | if (ah->curchan) { | ||
| 153 | if (IS_CHAN_HALF_RATE(chan)) | 152 | if (IS_CHAN_HALF_RATE(chan)) |
| 154 | clockrate /= 2; | 153 | clockrate /= 2; |
| 155 | if (IS_CHAN_QUARTER_RATE(chan)) | 154 | if (IS_CHAN_QUARTER_RATE(chan)) |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 09cdbcd09739..b5a19e098f2d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1276,6 +1276,10 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1276 | if (!rts_thresh || (len > rts_thresh)) | 1276 | if (!rts_thresh || (len > rts_thresh)) |
| 1277 | rts = true; | 1277 | rts = true; |
| 1278 | } | 1278 | } |
| 1279 | |||
| 1280 | if (!aggr) | ||
| 1281 | len = fi->framelen; | ||
| 1282 | |||
| 1279 | ath_buf_set_rate(sc, bf, &info, len, rts); | 1283 | ath_buf_set_rate(sc, bf, &info, len, rts); |
| 1280 | } | 1284 | } |
| 1281 | 1285 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index de9eb2cfbf4b..366339421d4f 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c | |||
| @@ -2041,13 +2041,20 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) | |||
| 2041 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: | 2041 | case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: |
| 2042 | mutex_lock(&wcn->hal_ind_mutex); | 2042 | mutex_lock(&wcn->hal_ind_mutex); |
| 2043 | msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL); | 2043 | msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL); |
| 2044 | msg_ind->msg_len = len; | 2044 | if (msg_ind) { |
| 2045 | msg_ind->msg = kmalloc(len, GFP_KERNEL); | 2045 | msg_ind->msg_len = len; |
| 2046 | memcpy(msg_ind->msg, buf, len); | 2046 | msg_ind->msg = kmalloc(len, GFP_KERNEL); |
| 2047 | list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); | 2047 | memcpy(msg_ind->msg, buf, len); |
| 2048 | queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); | 2048 | list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); |
| 2049 | wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); | 2049 | queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); |
| 2050 | wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); | ||
| 2051 | } | ||
| 2050 | mutex_unlock(&wcn->hal_ind_mutex); | 2052 | mutex_unlock(&wcn->hal_ind_mutex); |
| 2053 | if (msg_ind) | ||
| 2054 | break; | ||
| 2055 | /* FIXME: Do something smarter then just printing an error. */ | ||
| 2056 | wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n", | ||
| 2057 | msg_header->msg_type); | ||
| 2051 | break; | 2058 | break; |
| 2052 | default: | 2059 | default: |
| 2053 | wcn36xx_err("SMD_EVENT (%d) not supported\n", | 2060 | wcn36xx_err("SMD_EVENT (%d) not supported\n", |
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index b00a7e92225f..54e36fcb3954 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig | |||
| @@ -5,6 +5,8 @@ config BRCMSMAC | |||
| 5 | tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" | 5 | tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" |
| 6 | depends on MAC80211 | 6 | depends on MAC80211 |
| 7 | depends on BCMA | 7 | depends on BCMA |
| 8 | select NEW_LEDS if BCMA_DRIVER_GPIO | ||
| 9 | select LEDS_CLASS if BCMA_DRIVER_GPIO | ||
| 8 | select BRCMUTIL | 10 | select BRCMUTIL |
| 9 | select FW_LOADER | 11 | select FW_LOADER |
| 10 | select CRC_CCITT | 12 | select CRC_CCITT |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 905704e335d7..abc9ceca70f3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
| @@ -109,6 +109,8 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, | |||
| 109 | brcmf_err("Disable F2 failed:%d\n", | 109 | brcmf_err("Disable F2 failed:%d\n", |
| 110 | err_ret); | 110 | err_ret); |
| 111 | } | 111 | } |
| 112 | } else { | ||
| 113 | err_ret = -ENOENT; | ||
| 112 | } | 114 | } |
| 113 | } else if ((regaddr == SDIO_CCCR_ABORT) || | 115 | } else if ((regaddr == SDIO_CCCR_ABORT) || |
| 114 | (regaddr == SDIO_CCCR_IENx)) { | 116 | (regaddr == SDIO_CCCR_IENx)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 85879dbaa402..3c34a72a5d64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
| @@ -67,8 +67,8 @@ | |||
| 67 | #include "iwl-agn-hw.h" | 67 | #include "iwl-agn-hw.h" |
| 68 | 68 | ||
| 69 | /* Highest firmware API version supported */ | 69 | /* Highest firmware API version supported */ |
| 70 | #define IWL7260_UCODE_API_MAX 7 | 70 | #define IWL7260_UCODE_API_MAX 8 |
| 71 | #define IWL3160_UCODE_API_MAX 7 | 71 | #define IWL3160_UCODE_API_MAX 8 |
| 72 | 72 | ||
| 73 | /* Oldest version we won't warn about */ | 73 | /* Oldest version we won't warn about */ |
| 74 | #define IWL7260_UCODE_API_OK 7 | 74 | #define IWL7260_UCODE_API_OK 7 |
| @@ -130,6 +130,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = { | |||
| 130 | .ht_params = &iwl7000_ht_params, | 130 | .ht_params = &iwl7000_ht_params, |
| 131 | .nvm_ver = IWL7260_NVM_VERSION, | 131 | .nvm_ver = IWL7260_NVM_VERSION, |
| 132 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, | 132 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, |
| 133 | .host_interrupt_operation_mode = true, | ||
| 133 | }; | 134 | }; |
| 134 | 135 | ||
| 135 | const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { | 136 | const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { |
| @@ -140,6 +141,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { | |||
| 140 | .nvm_ver = IWL7260_NVM_VERSION, | 141 | .nvm_ver = IWL7260_NVM_VERSION, |
| 141 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, | 142 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, |
| 142 | .high_temp = true, | 143 | .high_temp = true, |
| 144 | .host_interrupt_operation_mode = true, | ||
| 143 | }; | 145 | }; |
| 144 | 146 | ||
| 145 | const struct iwl_cfg iwl7260_2n_cfg = { | 147 | const struct iwl_cfg iwl7260_2n_cfg = { |
| @@ -149,6 +151,7 @@ const struct iwl_cfg iwl7260_2n_cfg = { | |||
| 149 | .ht_params = &iwl7000_ht_params, | 151 | .ht_params = &iwl7000_ht_params, |
| 150 | .nvm_ver = IWL7260_NVM_VERSION, | 152 | .nvm_ver = IWL7260_NVM_VERSION, |
| 151 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, | 153 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, |
| 154 | .host_interrupt_operation_mode = true, | ||
| 152 | }; | 155 | }; |
| 153 | 156 | ||
| 154 | const struct iwl_cfg iwl7260_n_cfg = { | 157 | const struct iwl_cfg iwl7260_n_cfg = { |
| @@ -158,6 +161,7 @@ const struct iwl_cfg iwl7260_n_cfg = { | |||
| 158 | .ht_params = &iwl7000_ht_params, | 161 | .ht_params = &iwl7000_ht_params, |
| 159 | .nvm_ver = IWL7260_NVM_VERSION, | 162 | .nvm_ver = IWL7260_NVM_VERSION, |
| 160 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, | 163 | .nvm_calib_ver = IWL7260_TX_POWER_VERSION, |
| 164 | .host_interrupt_operation_mode = true, | ||
| 161 | }; | 165 | }; |
| 162 | 166 | ||
| 163 | const struct iwl_cfg iwl3160_2ac_cfg = { | 167 | const struct iwl_cfg iwl3160_2ac_cfg = { |
| @@ -167,6 +171,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = { | |||
| 167 | .ht_params = &iwl7000_ht_params, | 171 | .ht_params = &iwl7000_ht_params, |
| 168 | .nvm_ver = IWL3160_NVM_VERSION, | 172 | .nvm_ver = IWL3160_NVM_VERSION, |
| 169 | .nvm_calib_ver = IWL3160_TX_POWER_VERSION, | 173 | .nvm_calib_ver = IWL3160_TX_POWER_VERSION, |
| 174 | .host_interrupt_operation_mode = true, | ||
| 170 | }; | 175 | }; |
| 171 | 176 | ||
| 172 | const struct iwl_cfg iwl3160_2n_cfg = { | 177 | const struct iwl_cfg iwl3160_2n_cfg = { |
| @@ -176,6 +181,7 @@ const struct iwl_cfg iwl3160_2n_cfg = { | |||
| 176 | .ht_params = &iwl7000_ht_params, | 181 | .ht_params = &iwl7000_ht_params, |
| 177 | .nvm_ver = IWL3160_NVM_VERSION, | 182 | .nvm_ver = IWL3160_NVM_VERSION, |
| 178 | .nvm_calib_ver = IWL3160_TX_POWER_VERSION, | 183 | .nvm_calib_ver = IWL3160_TX_POWER_VERSION, |
| 184 | .host_interrupt_operation_mode = true, | ||
| 179 | }; | 185 | }; |
| 180 | 186 | ||
| 181 | const struct iwl_cfg iwl3160_n_cfg = { | 187 | const struct iwl_cfg iwl3160_n_cfg = { |
| @@ -185,6 +191,7 @@ const struct iwl_cfg iwl3160_n_cfg = { | |||
| 185 | .ht_params = &iwl7000_ht_params, | 191 | .ht_params = &iwl7000_ht_params, |
| 186 | .nvm_ver = IWL3160_NVM_VERSION, | 192 | .nvm_ver = IWL3160_NVM_VERSION, |
| 187 | .nvm_calib_ver = IWL3160_TX_POWER_VERSION, | 193 | .nvm_calib_ver = IWL3160_TX_POWER_VERSION, |
| 194 | .host_interrupt_operation_mode = true, | ||
| 188 | }; | 195 | }; |
| 189 | 196 | ||
| 190 | const struct iwl_cfg iwl7265_2ac_cfg = { | 197 | const struct iwl_cfg iwl7265_2ac_cfg = { |
| @@ -196,5 +203,23 @@ const struct iwl_cfg iwl7265_2ac_cfg = { | |||
| 196 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 203 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
| 197 | }; | 204 | }; |
| 198 | 205 | ||
| 206 | const struct iwl_cfg iwl7265_2n_cfg = { | ||
| 207 | .name = "Intel(R) Dual Band Wireless N 7265", | ||
| 208 | .fw_name_pre = IWL7265_FW_PRE, | ||
| 209 | IWL_DEVICE_7000, | ||
| 210 | .ht_params = &iwl7000_ht_params, | ||
| 211 | .nvm_ver = IWL7265_NVM_VERSION, | ||
| 212 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | ||
| 213 | }; | ||
| 214 | |||
| 215 | const struct iwl_cfg iwl7265_n_cfg = { | ||
| 216 | .name = "Intel(R) Wireless N 7265", | ||
| 217 | .fw_name_pre = IWL7265_FW_PRE, | ||
| 218 | IWL_DEVICE_7000, | ||
| 219 | .ht_params = &iwl7000_ht_params, | ||
| 220 | .nvm_ver = IWL7265_NVM_VERSION, | ||
| 221 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | ||
| 222 | }; | ||
| 223 | |||
| 199 | MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); | 224 | MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); |
| 200 | MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); | 225 | MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 18f232e8e812..03fd9aa8bfda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
| @@ -207,6 +207,8 @@ struct iwl_eeprom_params { | |||
| 207 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | 207 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity |
| 208 | * @internal_wimax_coex: internal wifi/wimax combo device | 208 | * @internal_wimax_coex: internal wifi/wimax combo device |
| 209 | * @high_temp: Is this NIC is designated to be in high temperature. | 209 | * @high_temp: Is this NIC is designated to be in high temperature. |
| 210 | * @host_interrupt_operation_mode: device needs host interrupt operation | ||
| 211 | * mode set | ||
| 210 | * | 212 | * |
| 211 | * We enable the driver to be backward compatible wrt. hardware features. | 213 | * We enable the driver to be backward compatible wrt. hardware features. |
| 212 | * API differences in uCode shouldn't be handled here but through TLVs | 214 | * API differences in uCode shouldn't be handled here but through TLVs |
| @@ -235,6 +237,7 @@ struct iwl_cfg { | |||
| 235 | enum iwl_led_mode led_mode; | 237 | enum iwl_led_mode led_mode; |
| 236 | const bool rx_with_siso_diversity; | 238 | const bool rx_with_siso_diversity; |
| 237 | const bool internal_wimax_coex; | 239 | const bool internal_wimax_coex; |
| 240 | const bool host_interrupt_operation_mode; | ||
| 238 | bool high_temp; | 241 | bool high_temp; |
| 239 | }; | 242 | }; |
| 240 | 243 | ||
| @@ -294,6 +297,8 @@ extern const struct iwl_cfg iwl3160_2ac_cfg; | |||
| 294 | extern const struct iwl_cfg iwl3160_2n_cfg; | 297 | extern const struct iwl_cfg iwl3160_2n_cfg; |
| 295 | extern const struct iwl_cfg iwl3160_n_cfg; | 298 | extern const struct iwl_cfg iwl3160_n_cfg; |
| 296 | extern const struct iwl_cfg iwl7265_2ac_cfg; | 299 | extern const struct iwl_cfg iwl7265_2ac_cfg; |
| 300 | extern const struct iwl_cfg iwl7265_2n_cfg; | ||
| 301 | extern const struct iwl_cfg iwl7265_n_cfg; | ||
| 297 | #endif /* CONFIG_IWLMVM */ | 302 | #endif /* CONFIG_IWLMVM */ |
| 298 | 303 | ||
| 299 | #endif /* __IWL_CONFIG_H__ */ | 304 | #endif /* __IWL_CONFIG_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 54a4fdc631b7..da4eca8b3007 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
| @@ -495,14 +495,11 @@ enum secure_load_status_reg { | |||
| 495 | * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit | 495 | * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit |
| 496 | * | 496 | * |
| 497 | * default interrupt coalescing timer is 64 x 32 = 2048 usecs | 497 | * default interrupt coalescing timer is 64 x 32 = 2048 usecs |
| 498 | * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs | ||
| 499 | */ | 498 | */ |
| 500 | #define IWL_HOST_INT_TIMEOUT_MAX (0xFF) | 499 | #define IWL_HOST_INT_TIMEOUT_MAX (0xFF) |
| 501 | #define IWL_HOST_INT_TIMEOUT_DEF (0x40) | 500 | #define IWL_HOST_INT_TIMEOUT_DEF (0x40) |
| 502 | #define IWL_HOST_INT_TIMEOUT_MIN (0x0) | 501 | #define IWL_HOST_INT_TIMEOUT_MIN (0x0) |
| 503 | #define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) | 502 | #define IWL_HOST_INT_OPER_MODE BIT(31) |
| 504 | #define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) | ||
| 505 | #define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) | ||
| 506 | 503 | ||
| 507 | /***************************************************************************** | 504 | /***************************************************************************** |
| 508 | * 7000/3000 series SHR DTS addresses * | 505 | * 7000/3000 series SHR DTS addresses * |
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 5d066cbc5ac7..75b72a956552 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
| @@ -391,7 +391,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) | |||
| 391 | BT_VALID_LUT | | 391 | BT_VALID_LUT | |
| 392 | BT_VALID_WIFI_RX_SW_PRIO_BOOST | | 392 | BT_VALID_WIFI_RX_SW_PRIO_BOOST | |
| 393 | BT_VALID_WIFI_TX_SW_PRIO_BOOST | | 393 | BT_VALID_WIFI_TX_SW_PRIO_BOOST | |
| 394 | BT_VALID_MULTI_PRIO_LUT | | ||
| 395 | BT_VALID_CORUN_LUT_20 | | 394 | BT_VALID_CORUN_LUT_20 | |
| 396 | BT_VALID_CORUN_LUT_40 | | 395 | BT_VALID_CORUN_LUT_40 | |
| 397 | BT_VALID_ANT_ISOLATION | | 396 | BT_VALID_ANT_ISOLATION | |
| @@ -842,6 +841,11 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, | |||
| 842 | 841 | ||
| 843 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], | 842 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], |
| 844 | lockdep_is_held(&mvm->mutex)); | 843 | lockdep_is_held(&mvm->mutex)); |
| 844 | |||
| 845 | /* This can happen if the station has been removed right now */ | ||
| 846 | if (IS_ERR_OR_NULL(sta)) | ||
| 847 | return; | ||
| 848 | |||
| 845 | mvmsta = (void *)sta->drv_priv; | 849 | mvmsta = (void *)sta->drv_priv; |
| 846 | 850 | ||
| 847 | data->num_bss_ifaces++; | 851 | data->num_bss_ifaces++; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 6f45966817bb..b9b81e881dd0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c | |||
| @@ -895,7 +895,7 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm, | |||
| 895 | /* new API returns next, not last-used seqno */ | 895 | /* new API returns next, not last-used seqno */ |
| 896 | if (mvm->fw->ucode_capa.flags & | 896 | if (mvm->fw->ucode_capa.flags & |
| 897 | IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) | 897 | IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) |
| 898 | err -= 0x10; | 898 | err = (u16) (err - 0x10); |
| 899 | } | 899 | } |
| 900 | 900 | ||
| 901 | iwl_free_resp(&cmd); | 901 | iwl_free_resp(&cmd); |
| @@ -1549,7 +1549,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, | |||
| 1549 | if (gtkdata.unhandled_cipher) | 1549 | if (gtkdata.unhandled_cipher) |
| 1550 | return false; | 1550 | return false; |
| 1551 | if (!gtkdata.num_keys) | 1551 | if (!gtkdata.num_keys) |
| 1552 | return true; | 1552 | goto out; |
| 1553 | if (!gtkdata.last_gtk) | 1553 | if (!gtkdata.last_gtk) |
| 1554 | return false; | 1554 | return false; |
| 1555 | 1555 | ||
| @@ -1600,6 +1600,7 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, | |||
| 1600 | (void *)&replay_ctr, GFP_KERNEL); | 1600 | (void *)&replay_ctr, GFP_KERNEL); |
| 1601 | } | 1601 | } |
| 1602 | 1602 | ||
| 1603 | out: | ||
| 1603 | mvmvif->seqno_valid = true; | 1604 | mvmvif->seqno_valid = true; |
| 1604 | /* +0x10 because the set API expects next-to-use, not last-used */ | 1605 | /* +0x10 because the set API expects next-to-use, not last-used */ |
| 1605 | mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10; | 1606 | mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 9864d713eb2c..a8fe6b41f9a3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
| @@ -119,6 +119,10 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, | |||
| 119 | 119 | ||
| 120 | if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) | 120 | if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) |
| 121 | return -EINVAL; | 121 | return -EINVAL; |
| 122 | if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT) | ||
| 123 | return -EINVAL; | ||
| 124 | if (drain < 0 || drain > 1) | ||
| 125 | return -EINVAL; | ||
| 122 | 126 | ||
| 123 | mutex_lock(&mvm->mutex); | 127 | mutex_lock(&mvm->mutex); |
| 124 | 128 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 33cf56fdfc41..95ce4b601fef 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
| @@ -176,8 +176,11 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, | |||
| 176 | * P2P Device discoveribility, while there are other higher priority | 176 | * P2P Device discoveribility, while there are other higher priority |
| 177 | * events in the system). | 177 | * events in the system). |
| 178 | */ | 178 | */ |
| 179 | if (WARN_ONCE(!le32_to_cpu(notif->status), | 179 | if (!le32_to_cpu(notif->status)) { |
| 180 | "Failed to schedule time event\n")) { | 180 | bool start = le32_to_cpu(notif->action) & |
| 181 | TE_V2_NOTIF_HOST_EVENT_START; | ||
| 182 | IWL_WARN(mvm, "Time Event %s notification failure\n", | ||
| 183 | start ? "start" : "end"); | ||
| 181 | if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) { | 184 | if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, NULL)) { |
| 182 | iwl_mvm_te_clear_data(mvm, te_data); | 185 | iwl_mvm_te_clear_data(mvm, te_data); |
| 183 | return; | 186 | return; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 941c0c88f982..86605027c41d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
| @@ -353,6 +353,27 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 353 | 353 | ||
| 354 | /* 7265 Series */ | 354 | /* 7265 Series */ |
| 355 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 355 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
| 356 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, | ||
| 357 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, | ||
| 358 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, | ||
| 359 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, | ||
| 360 | {IWL_PCI_DEVICE(0x095B, 0x5012, iwl7265_2ac_cfg)}, | ||
| 361 | {IWL_PCI_DEVICE(0x095B, 0x500A, iwl7265_2ac_cfg)}, | ||
| 362 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, | ||
| 363 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, | ||
| 364 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, | ||
| 365 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, | ||
| 366 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, | ||
| 367 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, | ||
| 368 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, | ||
| 369 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, | ||
| 370 | {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)}, | ||
| 371 | {IWL_PCI_DEVICE(0x095A, 0x5020, iwl7265_2n_cfg)}, | ||
| 372 | {IWL_PCI_DEVICE(0x095A, 0x502A, iwl7265_2n_cfg)}, | ||
| 373 | {IWL_PCI_DEVICE(0x095A, 0x5420, iwl7265_2n_cfg)}, | ||
| 374 | {IWL_PCI_DEVICE(0x095A, 0x5090, iwl7265_2ac_cfg)}, | ||
| 375 | {IWL_PCI_DEVICE(0x095B, 0x5290, iwl7265_2ac_cfg)}, | ||
| 376 | {IWL_PCI_DEVICE(0x095A, 0x5490, iwl7265_2ac_cfg)}, | ||
| 356 | #endif /* CONFIG_IWLMVM */ | 377 | #endif /* CONFIG_IWLMVM */ |
| 357 | 378 | ||
| 358 | {0} | 379 | {0} |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index fa22639b63c9..051268c037b1 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
| @@ -477,4 +477,12 @@ static inline bool iwl_is_rfkill_set(struct iwl_trans *trans) | |||
| 477 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); | 477 | CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); |
| 478 | } | 478 | } |
| 479 | 479 | ||
| 480 | static inline void iwl_nic_error(struct iwl_trans *trans) | ||
| 481 | { | ||
| 482 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 483 | |||
| 484 | set_bit(STATUS_FW_ERROR, &trans_pcie->status); | ||
| 485 | iwl_op_mode_nic_error(trans->op_mode); | ||
| 486 | } | ||
| 487 | |||
| 480 | #endif /* __iwl_trans_int_pcie_h__ */ | 488 | #endif /* __iwl_trans_int_pcie_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 3f237b42eb36..be3995afa9d0 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
| @@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | |||
| 489 | 489 | ||
| 490 | /* Set interrupt coalescing timer to default (2048 usecs) */ | 490 | /* Set interrupt coalescing timer to default (2048 usecs) */ |
| 491 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | 491 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); |
| 492 | |||
| 493 | /* W/A for interrupt coalescing bug in 7260 and 3160 */ | ||
| 494 | if (trans->cfg->host_interrupt_operation_mode) | ||
| 495 | iwl_set_bit(trans, CSR_INT_COALESCING, IWL_HOST_INT_OPER_MODE); | ||
| 492 | } | 496 | } |
| 493 | 497 | ||
| 494 | static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq) | 498 | static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq) |
| @@ -796,12 +800,13 @@ static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) | |||
| 796 | iwl_pcie_dump_csr(trans); | 800 | iwl_pcie_dump_csr(trans); |
| 797 | iwl_dump_fh(trans, NULL); | 801 | iwl_dump_fh(trans, NULL); |
| 798 | 802 | ||
| 803 | /* set the ERROR bit before we wake up the caller */ | ||
| 799 | set_bit(STATUS_FW_ERROR, &trans_pcie->status); | 804 | set_bit(STATUS_FW_ERROR, &trans_pcie->status); |
| 800 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 805 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
| 801 | wake_up(&trans_pcie->wait_command_queue); | 806 | wake_up(&trans_pcie->wait_command_queue); |
| 802 | 807 | ||
| 803 | local_bh_disable(); | 808 | local_bh_disable(); |
| 804 | iwl_op_mode_nic_error(trans->op_mode); | 809 | iwl_nic_error(trans); |
| 805 | local_bh_enable(); | 810 | local_bh_enable(); |
| 806 | } | 811 | } |
| 807 | 812 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 5d9337bec67a..cde9c16f6e4f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
| @@ -279,9 +279,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) | |||
| 279 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 279 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
| 280 | iwl_pcie_apm_init(trans); | 280 | iwl_pcie_apm_init(trans); |
| 281 | 281 | ||
| 282 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ | ||
| 283 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); | ||
| 284 | |||
| 285 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 282 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
| 286 | 283 | ||
| 287 | iwl_pcie_set_pwr(trans, false); | 284 | iwl_pcie_set_pwr(trans, false); |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 059c5acad3a0..0adde919a258 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
| @@ -207,7 +207,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) | |||
| 207 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, | 207 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, |
| 208 | le32_to_cpu(txq->scratchbufs[i].scratch)); | 208 | le32_to_cpu(txq->scratchbufs[i].scratch)); |
| 209 | 209 | ||
| 210 | iwl_op_mode_nic_error(trans->op_mode); | 210 | iwl_nic_error(trans); |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /* | 213 | /* |
| @@ -1023,7 +1023,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) | |||
| 1023 | if (nfreed++ > 0) { | 1023 | if (nfreed++ > 0) { |
| 1024 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", | 1024 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", |
| 1025 | idx, q->write_ptr, q->read_ptr); | 1025 | idx, q->write_ptr, q->read_ptr); |
| 1026 | iwl_op_mode_nic_error(trans->op_mode); | 1026 | iwl_nic_error(trans); |
| 1027 | } | 1027 | } |
| 1028 | } | 1028 | } |
| 1029 | 1029 | ||
| @@ -1562,7 +1562,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, | |||
| 1562 | get_cmd_string(trans_pcie, cmd->id)); | 1562 | get_cmd_string(trans_pcie, cmd->id)); |
| 1563 | ret = -ETIMEDOUT; | 1563 | ret = -ETIMEDOUT; |
| 1564 | 1564 | ||
| 1565 | iwl_op_mode_nic_error(trans->op_mode); | 1565 | iwl_nic_error(trans); |
| 1566 | 1566 | ||
| 1567 | goto cancel; | 1567 | goto cancel; |
| 1568 | } | 1568 | } |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 9df7bc91a26f..c72438bb2faf 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -383,6 +383,14 @@ struct hwsim_radiotap_hdr { | |||
| 383 | __le16 rt_chbitmask; | 383 | __le16 rt_chbitmask; |
| 384 | } __packed; | 384 | } __packed; |
| 385 | 385 | ||
| 386 | struct hwsim_radiotap_ack_hdr { | ||
| 387 | struct ieee80211_radiotap_header hdr; | ||
| 388 | u8 rt_flags; | ||
| 389 | u8 pad; | ||
| 390 | __le16 rt_channel; | ||
| 391 | __le16 rt_chbitmask; | ||
| 392 | } __packed; | ||
| 393 | |||
| 386 | /* MAC80211_HWSIM netlinf family */ | 394 | /* MAC80211_HWSIM netlinf family */ |
| 387 | static struct genl_family hwsim_genl_family = { | 395 | static struct genl_family hwsim_genl_family = { |
| 388 | .id = GENL_ID_GENERATE, | 396 | .id = GENL_ID_GENERATE, |
| @@ -500,7 +508,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan, | |||
| 500 | const u8 *addr) | 508 | const u8 *addr) |
| 501 | { | 509 | { |
| 502 | struct sk_buff *skb; | 510 | struct sk_buff *skb; |
| 503 | struct hwsim_radiotap_hdr *hdr; | 511 | struct hwsim_radiotap_ack_hdr *hdr; |
| 504 | u16 flags; | 512 | u16 flags; |
| 505 | struct ieee80211_hdr *hdr11; | 513 | struct ieee80211_hdr *hdr11; |
| 506 | 514 | ||
| @@ -511,14 +519,14 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan, | |||
| 511 | if (skb == NULL) | 519 | if (skb == NULL) |
| 512 | return; | 520 | return; |
| 513 | 521 | ||
| 514 | hdr = (struct hwsim_radiotap_hdr *) skb_put(skb, sizeof(*hdr)); | 522 | hdr = (struct hwsim_radiotap_ack_hdr *) skb_put(skb, sizeof(*hdr)); |
| 515 | hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; | 523 | hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; |
| 516 | hdr->hdr.it_pad = 0; | 524 | hdr->hdr.it_pad = 0; |
| 517 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); | 525 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); |
| 518 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | 526 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | |
| 519 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 527 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
| 520 | hdr->rt_flags = 0; | 528 | hdr->rt_flags = 0; |
| 521 | hdr->rt_rate = 0; | 529 | hdr->pad = 0; |
| 522 | hdr->rt_channel = cpu_to_le16(chan->center_freq); | 530 | hdr->rt_channel = cpu_to_le16(chan->center_freq); |
| 523 | flags = IEEE80211_CHAN_2GHZ; | 531 | flags = IEEE80211_CHAN_2GHZ; |
| 524 | hdr->rt_chbitmask = cpu_to_le16(flags); | 532 | hdr->rt_chbitmask = cpu_to_le16(flags); |
| @@ -1230,7 +1238,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1230 | HRTIMER_MODE_REL); | 1238 | HRTIMER_MODE_REL); |
| 1231 | } else if (!info->enable_beacon) { | 1239 | } else if (!info->enable_beacon) { |
| 1232 | unsigned int count = 0; | 1240 | unsigned int count = 0; |
| 1233 | ieee80211_iterate_active_interfaces( | 1241 | ieee80211_iterate_active_interfaces_atomic( |
| 1234 | data->hw, IEEE80211_IFACE_ITER_NORMAL, | 1242 | data->hw, IEEE80211_IFACE_ITER_NORMAL, |
| 1235 | mac80211_hwsim_bcn_en_iter, &count); | 1243 | mac80211_hwsim_bcn_en_iter, &count); |
| 1236 | wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", | 1244 | wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index c8e029df770e..a09398fe9e2a 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
| @@ -319,8 +319,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
| 319 | if (bss_desc && bss_desc->ssid.ssid_len && | 319 | if (bss_desc && bss_desc->ssid.ssid_len && |
| 320 | (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. | 320 | (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. |
| 321 | ssid, &bss_desc->ssid))) { | 321 | ssid, &bss_desc->ssid))) { |
| 322 | kfree(bss_desc); | 322 | ret = 0; |
| 323 | return 0; | 323 | goto done; |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | /* Exit Adhoc mode first */ | 326 | /* Exit Adhoc mode first */ |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 2329cccf1fa6..870f1fa58370 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -368,11 +368,11 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
| 368 | unsigned long rx_ring_ref, unsigned int tx_evtchn, | 368 | unsigned long rx_ring_ref, unsigned int tx_evtchn, |
| 369 | unsigned int rx_evtchn) | 369 | unsigned int rx_evtchn) |
| 370 | { | 370 | { |
| 371 | struct task_struct *task; | ||
| 371 | int err = -ENOMEM; | 372 | int err = -ENOMEM; |
| 372 | 373 | ||
| 373 | /* Already connected through? */ | 374 | BUG_ON(vif->tx_irq); |
| 374 | if (vif->tx_irq) | 375 | BUG_ON(vif->task); |
| 375 | return 0; | ||
| 376 | 376 | ||
| 377 | err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); | 377 | err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); |
| 378 | if (err < 0) | 378 | if (err < 0) |
| @@ -411,14 +411,16 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | init_waitqueue_head(&vif->wq); | 413 | init_waitqueue_head(&vif->wq); |
| 414 | vif->task = kthread_create(xenvif_kthread, | 414 | task = kthread_create(xenvif_kthread, |
| 415 | (void *)vif, "%s", vif->dev->name); | 415 | (void *)vif, "%s", vif->dev->name); |
| 416 | if (IS_ERR(vif->task)) { | 416 | if (IS_ERR(task)) { |
| 417 | pr_warn("Could not allocate kthread for %s\n", vif->dev->name); | 417 | pr_warn("Could not allocate kthread for %s\n", vif->dev->name); |
| 418 | err = PTR_ERR(vif->task); | 418 | err = PTR_ERR(task); |
| 419 | goto err_rx_unbind; | 419 | goto err_rx_unbind; |
| 420 | } | 420 | } |
| 421 | 421 | ||
| 422 | vif->task = task; | ||
| 423 | |||
| 422 | rtnl_lock(); | 424 | rtnl_lock(); |
| 423 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) | 425 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) |
| 424 | dev_set_mtu(vif->dev, ETH_DATA_LEN); | 426 | dev_set_mtu(vif->dev, ETH_DATA_LEN); |
| @@ -461,8 +463,10 @@ void xenvif_disconnect(struct xenvif *vif) | |||
| 461 | if (netif_carrier_ok(vif->dev)) | 463 | if (netif_carrier_ok(vif->dev)) |
| 462 | xenvif_carrier_off(vif); | 464 | xenvif_carrier_off(vif); |
| 463 | 465 | ||
| 464 | if (vif->task) | 466 | if (vif->task) { |
| 465 | kthread_stop(vif->task); | 467 | kthread_stop(vif->task); |
| 468 | vif->task = NULL; | ||
| 469 | } | ||
| 466 | 470 | ||
| 467 | if (vif->tx_irq) { | 471 | if (vif->tx_irq) { |
| 468 | if (vif->tx_irq == vif->rx_irq) | 472 | if (vif->tx_irq == vif->rx_irq) |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 64f0e0d18b81..e884ee1fe7ed 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -452,7 +452,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | /* Set up a GSO prefix descriptor, if necessary */ | 454 | /* Set up a GSO prefix descriptor, if necessary */ |
| 455 | if ((1 << skb_shinfo(skb)->gso_type) & vif->gso_prefix_mask) { | 455 | if ((1 << gso_type) & vif->gso_prefix_mask) { |
| 456 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); | 456 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); |
| 457 | meta = npo->meta + npo->meta_prod++; | 457 | meta = npo->meta + npo->meta_prod++; |
| 458 | meta->gso_type = gso_type; | 458 | meta->gso_type = gso_type; |
| @@ -1149,75 +1149,92 @@ static int xenvif_set_skb_gso(struct xenvif *vif, | |||
| 1149 | return 0; | 1149 | return 0; |
| 1150 | } | 1150 | } |
| 1151 | 1151 | ||
| 1152 | static inline void maybe_pull_tail(struct sk_buff *skb, unsigned int len) | 1152 | static inline int maybe_pull_tail(struct sk_buff *skb, unsigned int len, |
| 1153 | unsigned int max) | ||
| 1153 | { | 1154 | { |
| 1154 | if (skb_is_nonlinear(skb) && skb_headlen(skb) < len) { | 1155 | if (skb_headlen(skb) >= len) |
| 1155 | /* If we need to pullup then pullup to the max, so we | 1156 | return 0; |
| 1156 | * won't need to do it again. | 1157 | |
| 1157 | */ | 1158 | /* If we need to pullup then pullup to the max, so we |
| 1158 | int target = min_t(int, skb->len, MAX_TCP_HEADER); | 1159 | * won't need to do it again. |
| 1159 | __pskb_pull_tail(skb, target - skb_headlen(skb)); | 1160 | */ |
| 1160 | } | 1161 | if (max > skb->len) |
| 1162 | max = skb->len; | ||
| 1163 | |||
| 1164 | if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL) | ||
| 1165 | return -ENOMEM; | ||
| 1166 | |||
| 1167 | if (skb_headlen(skb) < len) | ||
| 1168 | return -EPROTO; | ||
| 1169 | |||
| 1170 | return 0; | ||
| 1161 | } | 1171 | } |
| 1162 | 1172 | ||
| 1173 | /* This value should be large enough to cover a tagged ethernet header plus | ||
| 1174 | * maximally sized IP and TCP or UDP headers. | ||
| 1175 | */ | ||
| 1176 | #define MAX_IP_HDR_LEN 128 | ||
| 1177 | |||
| 1163 | static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, | 1178 | static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, |
| 1164 | int recalculate_partial_csum) | 1179 | int recalculate_partial_csum) |
| 1165 | { | 1180 | { |
| 1166 | struct iphdr *iph = (void *)skb->data; | ||
| 1167 | unsigned int header_size; | ||
| 1168 | unsigned int off; | 1181 | unsigned int off; |
| 1169 | int err = -EPROTO; | 1182 | bool fragment; |
| 1183 | int err; | ||
| 1170 | 1184 | ||
| 1171 | off = sizeof(struct iphdr); | 1185 | fragment = false; |
| 1172 | 1186 | ||
| 1173 | header_size = skb->network_header + off + MAX_IPOPTLEN; | 1187 | err = maybe_pull_tail(skb, |
| 1174 | maybe_pull_tail(skb, header_size); | 1188 | sizeof(struct iphdr), |
| 1189 | MAX_IP_HDR_LEN); | ||
| 1190 | if (err < 0) | ||
| 1191 | goto out; | ||
| 1175 | 1192 | ||
| 1176 | off = iph->ihl * 4; | 1193 | if (ip_hdr(skb)->frag_off & htons(IP_OFFSET | IP_MF)) |
| 1194 | fragment = true; | ||
| 1177 | 1195 | ||
| 1178 | switch (iph->protocol) { | 1196 | off = ip_hdrlen(skb); |
| 1197 | |||
| 1198 | err = -EPROTO; | ||
| 1199 | |||
| 1200 | switch (ip_hdr(skb)->protocol) { | ||
| 1179 | case IPPROTO_TCP: | 1201 | case IPPROTO_TCP: |
| 1202 | err = maybe_pull_tail(skb, | ||
| 1203 | off + sizeof(struct tcphdr), | ||
| 1204 | MAX_IP_HDR_LEN); | ||
| 1205 | if (err < 0) | ||
| 1206 | goto out; | ||
| 1207 | |||
| 1180 | if (!skb_partial_csum_set(skb, off, | 1208 | if (!skb_partial_csum_set(skb, off, |
| 1181 | offsetof(struct tcphdr, check))) | 1209 | offsetof(struct tcphdr, check))) |
| 1182 | goto out; | 1210 | goto out; |
| 1183 | 1211 | ||
| 1184 | if (recalculate_partial_csum) { | 1212 | if (recalculate_partial_csum) |
| 1185 | struct tcphdr *tcph = tcp_hdr(skb); | 1213 | tcp_hdr(skb)->check = |
| 1186 | 1214 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, | |
| 1187 | header_size = skb->network_header + | 1215 | ip_hdr(skb)->daddr, |
| 1188 | off + | 1216 | skb->len - off, |
| 1189 | sizeof(struct tcphdr); | 1217 | IPPROTO_TCP, 0); |
| 1190 | maybe_pull_tail(skb, header_size); | ||
| 1191 | |||
| 1192 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
| 1193 | skb->len - off, | ||
| 1194 | IPPROTO_TCP, 0); | ||
| 1195 | } | ||
| 1196 | break; | 1218 | break; |
| 1197 | case IPPROTO_UDP: | 1219 | case IPPROTO_UDP: |
| 1220 | err = maybe_pull_tail(skb, | ||
| 1221 | off + sizeof(struct udphdr), | ||
| 1222 | MAX_IP_HDR_LEN); | ||
| 1223 | if (err < 0) | ||
| 1224 | goto out; | ||
| 1225 | |||
| 1198 | if (!skb_partial_csum_set(skb, off, | 1226 | if (!skb_partial_csum_set(skb, off, |
| 1199 | offsetof(struct udphdr, check))) | 1227 | offsetof(struct udphdr, check))) |
| 1200 | goto out; | 1228 | goto out; |
| 1201 | 1229 | ||
| 1202 | if (recalculate_partial_csum) { | 1230 | if (recalculate_partial_csum) |
| 1203 | struct udphdr *udph = udp_hdr(skb); | 1231 | udp_hdr(skb)->check = |
| 1204 | 1232 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, | |
| 1205 | header_size = skb->network_header + | 1233 | ip_hdr(skb)->daddr, |
| 1206 | off + | 1234 | skb->len - off, |
| 1207 | sizeof(struct udphdr); | 1235 | IPPROTO_UDP, 0); |
| 1208 | maybe_pull_tail(skb, header_size); | ||
| 1209 | |||
| 1210 | udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
| 1211 | skb->len - off, | ||
| 1212 | IPPROTO_UDP, 0); | ||
| 1213 | } | ||
| 1214 | break; | 1236 | break; |
| 1215 | default: | 1237 | default: |
| 1216 | if (net_ratelimit()) | ||
| 1217 | netdev_err(vif->dev, | ||
| 1218 | "Attempting to checksum a non-TCP/UDP packet, " | ||
| 1219 | "dropping a protocol %d packet\n", | ||
| 1220 | iph->protocol); | ||
| 1221 | goto out; | 1238 | goto out; |
| 1222 | } | 1239 | } |
| 1223 | 1240 | ||
| @@ -1227,121 +1244,138 @@ out: | |||
| 1227 | return err; | 1244 | return err; |
| 1228 | } | 1245 | } |
| 1229 | 1246 | ||
| 1247 | /* This value should be large enough to cover a tagged ethernet header plus | ||
| 1248 | * an IPv6 header, all options, and a maximal TCP or UDP header. | ||
| 1249 | */ | ||
| 1250 | #define MAX_IPV6_HDR_LEN 256 | ||
| 1251 | |||
| 1252 | #define OPT_HDR(type, skb, off) \ | ||
| 1253 | (type *)(skb_network_header(skb) + (off)) | ||
| 1254 | |||
| 1230 | static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb, | 1255 | static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb, |
| 1231 | int recalculate_partial_csum) | 1256 | int recalculate_partial_csum) |
| 1232 | { | 1257 | { |
| 1233 | int err = -EPROTO; | 1258 | int err; |
| 1234 | struct ipv6hdr *ipv6h = (void *)skb->data; | ||
| 1235 | u8 nexthdr; | 1259 | u8 nexthdr; |
| 1236 | unsigned int header_size; | ||
| 1237 | unsigned int off; | 1260 | unsigned int off; |
| 1261 | unsigned int len; | ||
| 1238 | bool fragment; | 1262 | bool fragment; |
| 1239 | bool done; | 1263 | bool done; |
| 1240 | 1264 | ||
| 1265 | fragment = false; | ||
| 1241 | done = false; | 1266 | done = false; |
| 1242 | 1267 | ||
| 1243 | off = sizeof(struct ipv6hdr); | 1268 | off = sizeof(struct ipv6hdr); |
| 1244 | 1269 | ||
| 1245 | header_size = skb->network_header + off; | 1270 | err = maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN); |
| 1246 | maybe_pull_tail(skb, header_size); | 1271 | if (err < 0) |
| 1272 | goto out; | ||
| 1247 | 1273 | ||
| 1248 | nexthdr = ipv6h->nexthdr; | 1274 | nexthdr = ipv6_hdr(skb)->nexthdr; |
| 1249 | 1275 | ||
| 1250 | while ((off <= sizeof(struct ipv6hdr) + ntohs(ipv6h->payload_len)) && | 1276 | len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len); |
| 1251 | !done) { | 1277 | while (off <= len && !done) { |
| 1252 | switch (nexthdr) { | 1278 | switch (nexthdr) { |
| 1253 | case IPPROTO_DSTOPTS: | 1279 | case IPPROTO_DSTOPTS: |
| 1254 | case IPPROTO_HOPOPTS: | 1280 | case IPPROTO_HOPOPTS: |
| 1255 | case IPPROTO_ROUTING: { | 1281 | case IPPROTO_ROUTING: { |
| 1256 | struct ipv6_opt_hdr *hp = (void *)(skb->data + off); | 1282 | struct ipv6_opt_hdr *hp; |
| 1257 | 1283 | ||
| 1258 | header_size = skb->network_header + | 1284 | err = maybe_pull_tail(skb, |
| 1259 | off + | 1285 | off + |
| 1260 | sizeof(struct ipv6_opt_hdr); | 1286 | sizeof(struct ipv6_opt_hdr), |
| 1261 | maybe_pull_tail(skb, header_size); | 1287 | MAX_IPV6_HDR_LEN); |
| 1288 | if (err < 0) | ||
| 1289 | goto out; | ||
| 1262 | 1290 | ||
| 1291 | hp = OPT_HDR(struct ipv6_opt_hdr, skb, off); | ||
| 1263 | nexthdr = hp->nexthdr; | 1292 | nexthdr = hp->nexthdr; |
| 1264 | off += ipv6_optlen(hp); | 1293 | off += ipv6_optlen(hp); |
| 1265 | break; | 1294 | break; |
| 1266 | } | 1295 | } |
| 1267 | case IPPROTO_AH: { | 1296 | case IPPROTO_AH: { |
| 1268 | struct ip_auth_hdr *hp = (void *)(skb->data + off); | 1297 | struct ip_auth_hdr *hp; |
| 1269 | 1298 | ||
| 1270 | header_size = skb->network_header + | 1299 | err = maybe_pull_tail(skb, |
| 1271 | off + | 1300 | off + |
| 1272 | sizeof(struct ip_auth_hdr); | 1301 | sizeof(struct ip_auth_hdr), |
| 1273 | maybe_pull_tail(skb, header_size); | 1302 | MAX_IPV6_HDR_LEN); |
| 1303 | if (err < 0) | ||
| 1304 | goto out; | ||
| 1274 | 1305 | ||
| 1306 | hp = OPT_HDR(struct ip_auth_hdr, skb, off); | ||
| 1275 | nexthdr = hp->nexthdr; | 1307 | nexthdr = hp->nexthdr; |
| 1276 | off += (hp->hdrlen+2)<<2; | 1308 | off += ipv6_authlen(hp); |
| 1309 | break; | ||
| 1310 | } | ||
| 1311 | case IPPROTO_FRAGMENT: { | ||
| 1312 | struct frag_hdr *hp; | ||
| 1313 | |||
| 1314 | err = maybe_pull_tail(skb, | ||
| 1315 | off + | ||
| 1316 | sizeof(struct frag_hdr), | ||
| 1317 | MAX_IPV6_HDR_LEN); | ||
| 1318 | if (err < 0) | ||
| 1319 | goto out; | ||
| 1320 | |||
| 1321 | hp = OPT_HDR(struct frag_hdr, skb, off); | ||
| 1322 | |||
| 1323 | if (hp->frag_off & htons(IP6_OFFSET | IP6_MF)) | ||
| 1324 | fragment = true; | ||
| 1325 | |||
| 1326 | nexthdr = hp->nexthdr; | ||
| 1327 | off += sizeof(struct frag_hdr); | ||
| 1277 | break; | 1328 | break; |
| 1278 | } | 1329 | } |
| 1279 | case IPPROTO_FRAGMENT: | ||
| 1280 | fragment = true; | ||
| 1281 | /* fall through */ | ||
| 1282 | default: | 1330 | default: |
| 1283 | done = true; | 1331 | done = true; |
| 1284 | break; | 1332 | break; |
| 1285 | } | 1333 | } |
| 1286 | } | 1334 | } |
| 1287 | 1335 | ||
| 1288 | if (!done) { | 1336 | err = -EPROTO; |
| 1289 | if (net_ratelimit()) | ||
| 1290 | netdev_err(vif->dev, "Failed to parse packet header\n"); | ||
| 1291 | goto out; | ||
| 1292 | } | ||
| 1293 | 1337 | ||
| 1294 | if (fragment) { | 1338 | if (!done || fragment) |
| 1295 | if (net_ratelimit()) | ||
| 1296 | netdev_err(vif->dev, "Packet is a fragment!\n"); | ||
| 1297 | goto out; | 1339 | goto out; |
| 1298 | } | ||
| 1299 | 1340 | ||
| 1300 | switch (nexthdr) { | 1341 | switch (nexthdr) { |
| 1301 | case IPPROTO_TCP: | 1342 | case IPPROTO_TCP: |
| 1343 | err = maybe_pull_tail(skb, | ||
| 1344 | off + sizeof(struct tcphdr), | ||
| 1345 | MAX_IPV6_HDR_LEN); | ||
| 1346 | if (err < 0) | ||
| 1347 | goto out; | ||
| 1348 | |||
| 1302 | if (!skb_partial_csum_set(skb, off, | 1349 | if (!skb_partial_csum_set(skb, off, |
| 1303 | offsetof(struct tcphdr, check))) | 1350 | offsetof(struct tcphdr, check))) |
| 1304 | goto out; | 1351 | goto out; |
| 1305 | 1352 | ||
| 1306 | if (recalculate_partial_csum) { | 1353 | if (recalculate_partial_csum) |
| 1307 | struct tcphdr *tcph = tcp_hdr(skb); | 1354 | tcp_hdr(skb)->check = |
| 1308 | 1355 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | |
| 1309 | header_size = skb->network_header + | 1356 | &ipv6_hdr(skb)->daddr, |
| 1310 | off + | 1357 | skb->len - off, |
| 1311 | sizeof(struct tcphdr); | 1358 | IPPROTO_TCP, 0); |
| 1312 | maybe_pull_tail(skb, header_size); | ||
| 1313 | |||
| 1314 | tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, | ||
| 1315 | &ipv6h->daddr, | ||
| 1316 | skb->len - off, | ||
| 1317 | IPPROTO_TCP, 0); | ||
| 1318 | } | ||
| 1319 | break; | 1359 | break; |
| 1320 | case IPPROTO_UDP: | 1360 | case IPPROTO_UDP: |
| 1361 | err = maybe_pull_tail(skb, | ||
| 1362 | off + sizeof(struct udphdr), | ||
| 1363 | MAX_IPV6_HDR_LEN); | ||
| 1364 | if (err < 0) | ||
| 1365 | goto out; | ||
| 1366 | |||
| 1321 | if (!skb_partial_csum_set(skb, off, | 1367 | if (!skb_partial_csum_set(skb, off, |
| 1322 | offsetof(struct udphdr, check))) | 1368 | offsetof(struct udphdr, check))) |
| 1323 | goto out; | 1369 | goto out; |
| 1324 | 1370 | ||
| 1325 | if (recalculate_partial_csum) { | 1371 | if (recalculate_partial_csum) |
| 1326 | struct udphdr *udph = udp_hdr(skb); | 1372 | udp_hdr(skb)->check = |
| 1327 | 1373 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | |
| 1328 | header_size = skb->network_header + | 1374 | &ipv6_hdr(skb)->daddr, |
| 1329 | off + | 1375 | skb->len - off, |
| 1330 | sizeof(struct udphdr); | 1376 | IPPROTO_UDP, 0); |
| 1331 | maybe_pull_tail(skb, header_size); | ||
| 1332 | |||
| 1333 | udph->check = ~csum_ipv6_magic(&ipv6h->saddr, | ||
| 1334 | &ipv6h->daddr, | ||
| 1335 | skb->len - off, | ||
| 1336 | IPPROTO_UDP, 0); | ||
| 1337 | } | ||
| 1338 | break; | 1377 | break; |
| 1339 | default: | 1378 | default: |
| 1340 | if (net_ratelimit()) | ||
| 1341 | netdev_err(vif->dev, | ||
| 1342 | "Attempting to checksum a non-TCP/UDP packet, " | ||
| 1343 | "dropping a protocol %d packet\n", | ||
| 1344 | nexthdr); | ||
| 1345 | goto out; | 1379 | goto out; |
| 1346 | } | 1380 | } |
| 1347 | 1381 | ||
| @@ -1411,14 +1445,15 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) | |||
| 1411 | return false; | 1445 | return false; |
| 1412 | } | 1446 | } |
| 1413 | 1447 | ||
| 1414 | static unsigned xenvif_tx_build_gops(struct xenvif *vif) | 1448 | static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget) |
| 1415 | { | 1449 | { |
| 1416 | struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop; | 1450 | struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop; |
| 1417 | struct sk_buff *skb; | 1451 | struct sk_buff *skb; |
| 1418 | int ret; | 1452 | int ret; |
| 1419 | 1453 | ||
| 1420 | while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX | 1454 | while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX |
| 1421 | < MAX_PENDING_REQS)) { | 1455 | < MAX_PENDING_REQS) && |
| 1456 | (skb_queue_len(&vif->tx_queue) < budget)) { | ||
| 1422 | struct xen_netif_tx_request txreq; | 1457 | struct xen_netif_tx_request txreq; |
| 1423 | struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX]; | 1458 | struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX]; |
| 1424 | struct page *page; | 1459 | struct page *page; |
| @@ -1440,7 +1475,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif) | |||
| 1440 | continue; | 1475 | continue; |
| 1441 | } | 1476 | } |
| 1442 | 1477 | ||
| 1443 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); | 1478 | work_to_do = RING_HAS_UNCONSUMED_REQUESTS(&vif->tx); |
| 1444 | if (!work_to_do) | 1479 | if (!work_to_do) |
| 1445 | break; | 1480 | break; |
| 1446 | 1481 | ||
| @@ -1580,14 +1615,13 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif) | |||
| 1580 | } | 1615 | } |
| 1581 | 1616 | ||
| 1582 | 1617 | ||
| 1583 | static int xenvif_tx_submit(struct xenvif *vif, int budget) | 1618 | static int xenvif_tx_submit(struct xenvif *vif) |
| 1584 | { | 1619 | { |
| 1585 | struct gnttab_copy *gop = vif->tx_copy_ops; | 1620 | struct gnttab_copy *gop = vif->tx_copy_ops; |
| 1586 | struct sk_buff *skb; | 1621 | struct sk_buff *skb; |
| 1587 | int work_done = 0; | 1622 | int work_done = 0; |
| 1588 | 1623 | ||
| 1589 | while (work_done < budget && | 1624 | while ((skb = __skb_dequeue(&vif->tx_queue)) != NULL) { |
| 1590 | (skb = __skb_dequeue(&vif->tx_queue)) != NULL) { | ||
| 1591 | struct xen_netif_tx_request *txp; | 1625 | struct xen_netif_tx_request *txp; |
| 1592 | u16 pending_idx; | 1626 | u16 pending_idx; |
| 1593 | unsigned data_len; | 1627 | unsigned data_len; |
| @@ -1662,14 +1696,14 @@ int xenvif_tx_action(struct xenvif *vif, int budget) | |||
| 1662 | if (unlikely(!tx_work_todo(vif))) | 1696 | if (unlikely(!tx_work_todo(vif))) |
| 1663 | return 0; | 1697 | return 0; |
| 1664 | 1698 | ||
| 1665 | nr_gops = xenvif_tx_build_gops(vif); | 1699 | nr_gops = xenvif_tx_build_gops(vif, budget); |
| 1666 | 1700 | ||
| 1667 | if (nr_gops == 0) | 1701 | if (nr_gops == 0) |
| 1668 | return 0; | 1702 | return 0; |
| 1669 | 1703 | ||
| 1670 | gnttab_batch_copy(vif->tx_copy_ops, nr_gops); | 1704 | gnttab_batch_copy(vif->tx_copy_ops, nr_gops); |
| 1671 | 1705 | ||
| 1672 | work_done = xenvif_tx_submit(vif, nr_gops); | 1706 | work_done = xenvif_tx_submit(vif); |
| 1673 | 1707 | ||
| 1674 | return work_done; | 1708 | return work_done; |
| 1675 | } | 1709 | } |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 33120d156668..07369f32e8bb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -4165,6 +4165,14 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, | |||
| 4165 | return 0; | 4165 | return 0; |
| 4166 | } | 4166 | } |
| 4167 | 4167 | ||
| 4168 | bool pci_device_is_present(struct pci_dev *pdev) | ||
| 4169 | { | ||
| 4170 | u32 v; | ||
| 4171 | |||
| 4172 | return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0); | ||
| 4173 | } | ||
| 4174 | EXPORT_SYMBOL_GPL(pci_device_is_present); | ||
| 4175 | |||
| 4168 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE | 4176 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE |
| 4169 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; | 4177 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; |
| 4170 | static DEFINE_SPINLOCK(resource_alignment_lock); | 4178 | static DEFINE_SPINLOCK(resource_alignment_lock); |
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 5d89d1b808a6..c56c350324e4 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <uapi/linux/ipv6.h> | 4 | #include <uapi/linux/ipv6.h> |
| 5 | 5 | ||
| 6 | #define ipv6_optlen(p) (((p)->hdrlen+1) << 3) | 6 | #define ipv6_optlen(p) (((p)->hdrlen+1) << 3) |
| 7 | #define ipv6_authlen(p) (((p)->hdrlen+2) << 2) | ||
| 7 | /* | 8 | /* |
| 8 | * This structure contains configuration options per IPv6 link. | 9 | * This structure contains configuration options per IPv6 link. |
| 9 | */ | 10 | */ |
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index ad05ce60c1c9..2e5b194b9b19 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #define PHY_ID_KSZ8021 0x00221555 | 22 | #define PHY_ID_KSZ8021 0x00221555 |
| 23 | #define PHY_ID_KSZ8031 0x00221556 | 23 | #define PHY_ID_KSZ8031 0x00221556 |
| 24 | #define PHY_ID_KSZ8041 0x00221510 | 24 | #define PHY_ID_KSZ8041 0x00221510 |
| 25 | /* undocumented */ | ||
| 26 | #define PHY_ID_KSZ8041RNLI 0x00221537 | ||
| 25 | #define PHY_ID_KSZ8051 0x00221550 | 27 | #define PHY_ID_KSZ8051 0x00221550 |
| 26 | /* same id: ks8001 Rev. A/B, and ks8721 Rev 3. */ | 28 | /* same id: ks8001 Rev. A/B, and ks8721 Rev 3. */ |
| 27 | #define PHY_ID_KSZ8001 0x0022161A | 29 | #define PHY_ID_KSZ8001 0x0022161A |
diff --git a/include/linux/net.h b/include/linux/net.h index 4bcee94cef93..69be3e6079c8 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
| @@ -181,7 +181,7 @@ struct proto_ops { | |||
| 181 | int offset, size_t size, int flags); | 181 | int offset, size_t size, int flags); |
| 182 | ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, | 182 | ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, |
| 183 | struct pipe_inode_info *pipe, size_t len, unsigned int flags); | 183 | struct pipe_inode_info *pipe, size_t len, unsigned int flags); |
| 184 | void (*set_peek_off)(struct sock *sk, int val); | 184 | int (*set_peek_off)(struct sock *sk, int val); |
| 185 | }; | 185 | }; |
| 186 | 186 | ||
| 187 | #define DECLARE_SOCKADDR(type, dst, src) \ | 187 | #define DECLARE_SOCKADDR(type, dst, src) \ |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7f0ed423a360..d9a550bf3e8e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -1255,7 +1255,7 @@ struct net_device { | |||
| 1255 | unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ | 1255 | unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ |
| 1256 | unsigned char addr_assign_type; /* hw address assignment type */ | 1256 | unsigned char addr_assign_type; /* hw address assignment type */ |
| 1257 | unsigned char addr_len; /* hardware address length */ | 1257 | unsigned char addr_len; /* hardware address length */ |
| 1258 | unsigned char neigh_priv_len; | 1258 | unsigned short neigh_priv_len; |
| 1259 | unsigned short dev_id; /* Used to differentiate devices | 1259 | unsigned short dev_id; /* Used to differentiate devices |
| 1260 | * that share the same link | 1260 | * that share the same link |
| 1261 | * layer address | 1261 | * layer address |
diff --git a/include/linux/pci.h b/include/linux/pci.h index eb8078aeadc8..a13d6825e586 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -960,6 +960,7 @@ void pci_update_resource(struct pci_dev *dev, int resno); | |||
| 960 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); | 960 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); |
| 961 | int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align); | 961 | int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align); |
| 962 | int pci_select_bars(struct pci_dev *dev, unsigned long flags); | 962 | int pci_select_bars(struct pci_dev *dev, unsigned long flags); |
| 963 | bool pci_device_is_present(struct pci_dev *pdev); | ||
| 963 | 964 | ||
| 964 | /* ROM control related routines */ | 965 | /* ROM control related routines */ |
| 965 | int pci_enable_rom(struct pci_dev *pdev); | 966 | int pci_enable_rom(struct pci_dev *pdev); |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index bec1cc7d5e3c..215b5ea1cb30 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -2263,6 +2263,24 @@ static inline void skb_postpull_rcsum(struct sk_buff *skb, | |||
| 2263 | 2263 | ||
| 2264 | unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len); | 2264 | unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len); |
| 2265 | 2265 | ||
| 2266 | /** | ||
| 2267 | * pskb_trim_rcsum - trim received skb and update checksum | ||
| 2268 | * @skb: buffer to trim | ||
| 2269 | * @len: new length | ||
| 2270 | * | ||
| 2271 | * This is exactly the same as pskb_trim except that it ensures the | ||
| 2272 | * checksum of received packets are still valid after the operation. | ||
| 2273 | */ | ||
| 2274 | |||
| 2275 | static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) | ||
| 2276 | { | ||
| 2277 | if (likely(len >= skb->len)) | ||
| 2278 | return 0; | ||
| 2279 | if (skb->ip_summed == CHECKSUM_COMPLETE) | ||
| 2280 | skb->ip_summed = CHECKSUM_NONE; | ||
| 2281 | return __pskb_trim(skb, len); | ||
| 2282 | } | ||
| 2283 | |||
| 2266 | #define skb_queue_walk(queue, skb) \ | 2284 | #define skb_queue_walk(queue, skb) \ |
| 2267 | for (skb = (queue)->next; \ | 2285 | for (skb = (queue)->next; \ |
| 2268 | skb != (struct sk_buff *)(queue); \ | 2286 | skb != (struct sk_buff *)(queue); \ |
| @@ -2360,27 +2378,6 @@ __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len, | |||
| 2360 | __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, | 2378 | __wsum skb_checksum(const struct sk_buff *skb, int offset, int len, |
| 2361 | __wsum csum); | 2379 | __wsum csum); |
| 2362 | 2380 | ||
| 2363 | /** | ||
| 2364 | * pskb_trim_rcsum - trim received skb and update checksum | ||
| 2365 | * @skb: buffer to trim | ||
| 2366 | * @len: new length | ||
| 2367 | * | ||
| 2368 | * This is exactly the same as pskb_trim except that it ensures the | ||
| 2369 | * checksum of received packets are still valid after the operation. | ||
| 2370 | */ | ||
| 2371 | |||
| 2372 | static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) | ||
| 2373 | { | ||
| 2374 | if (likely(len >= skb->len)) | ||
| 2375 | return 0; | ||
| 2376 | if (skb->ip_summed == CHECKSUM_COMPLETE) { | ||
| 2377 | __wsum adj = skb_checksum(skb, len, skb->len - len, 0); | ||
| 2378 | |||
| 2379 | skb->csum = csum_sub(skb->csum, adj); | ||
| 2380 | } | ||
| 2381 | return __pskb_trim(skb, len); | ||
| 2382 | } | ||
| 2383 | |||
| 2384 | static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, | 2381 | static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, |
| 2385 | int len, void *buffer) | 2382 | int len, void *buffer) |
| 2386 | { | 2383 | { |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index eb198acaac1d..488316e339a1 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
| @@ -110,7 +110,8 @@ struct frag_hdr { | |||
| 110 | __be32 identification; | 110 | __be32 identification; |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | #define IP6_MF 0x0001 | 113 | #define IP6_MF 0x0001 |
| 114 | #define IP6_OFFSET 0xFFF8 | ||
| 114 | 115 | ||
| 115 | #include <net/sock.h> | 116 | #include <net/sock.h> |
| 116 | 117 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index ea0ca5f6e629..67b5d0068273 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -1726,12 +1726,6 @@ struct sctp_association { | |||
| 1726 | /* How many duplicated TSNs have we seen? */ | 1726 | /* How many duplicated TSNs have we seen? */ |
| 1727 | int numduptsns; | 1727 | int numduptsns; |
| 1728 | 1728 | ||
| 1729 | /* Number of seconds of idle time before an association is closed. | ||
| 1730 | * In the association context, this is really used as a boolean | ||
| 1731 | * since the real timeout is stored in the timeouts array | ||
| 1732 | */ | ||
| 1733 | __u32 autoclose; | ||
| 1734 | |||
| 1735 | /* These are to support | 1729 | /* These are to support |
| 1736 | * "SCTP Extensions for Dynamic Reconfiguration of IP Addresses | 1730 | * "SCTP Extensions for Dynamic Reconfiguration of IP Addresses |
| 1737 | * and Enforcement of Flow and Message Limits" | 1731 | * and Enforcement of Flow and Message Limits" |
diff --git a/include/net/sock.h b/include/net/sock.h index e3a18ff0c38b..2ef3c3eca47a 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -1035,7 +1035,6 @@ enum cg_proto_flags { | |||
| 1035 | }; | 1035 | }; |
| 1036 | 1036 | ||
| 1037 | struct cg_proto { | 1037 | struct cg_proto { |
| 1038 | void (*enter_memory_pressure)(struct sock *sk); | ||
| 1039 | struct res_counter memory_allocated; /* Current allocated memory. */ | 1038 | struct res_counter memory_allocated; /* Current allocated memory. */ |
| 1040 | struct percpu_counter sockets_allocated; /* Current number of sockets. */ | 1039 | struct percpu_counter sockets_allocated; /* Current number of sockets. */ |
| 1041 | int memory_pressure; | 1040 | int memory_pressure; |
| @@ -1155,8 +1154,7 @@ static inline void sk_leave_memory_pressure(struct sock *sk) | |||
| 1155 | struct proto *prot = sk->sk_prot; | 1154 | struct proto *prot = sk->sk_prot; |
| 1156 | 1155 | ||
| 1157 | for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) | 1156 | for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) |
| 1158 | if (cg_proto->memory_pressure) | 1157 | cg_proto->memory_pressure = 0; |
| 1159 | cg_proto->memory_pressure = 0; | ||
| 1160 | } | 1158 | } |
| 1161 | 1159 | ||
| 1162 | } | 1160 | } |
| @@ -1171,7 +1169,7 @@ static inline void sk_enter_memory_pressure(struct sock *sk) | |||
| 1171 | struct proto *prot = sk->sk_prot; | 1169 | struct proto *prot = sk->sk_prot; |
| 1172 | 1170 | ||
| 1173 | for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) | 1171 | for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) |
| 1174 | cg_proto->enter_memory_pressure(sk); | 1172 | cg_proto->memory_pressure = 1; |
| 1175 | } | 1173 | } |
| 1176 | 1174 | ||
| 1177 | sk->sk_prot->enter_memory_pressure(sk); | 1175 | sk->sk_prot->enter_memory_pressure(sk); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 229d820bdf0b..045d56eaeca2 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -426,6 +426,16 @@ netdev_features_t br_features_recompute(struct net_bridge *br, | |||
| 426 | int br_handle_frame_finish(struct sk_buff *skb); | 426 | int br_handle_frame_finish(struct sk_buff *skb); |
| 427 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb); | 427 | rx_handler_result_t br_handle_frame(struct sk_buff **pskb); |
| 428 | 428 | ||
| 429 | static inline bool br_rx_handler_check_rcu(const struct net_device *dev) | ||
| 430 | { | ||
| 431 | return rcu_dereference(dev->rx_handler) == br_handle_frame; | ||
| 432 | } | ||
| 433 | |||
| 434 | static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) | ||
| 435 | { | ||
| 436 | return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL; | ||
| 437 | } | ||
| 438 | |||
| 429 | /* br_ioctl.c */ | 439 | /* br_ioctl.c */ |
| 430 | int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 440 | int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
| 431 | int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, | 441 | int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 8660ea3be705..bdb459d21ad8 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
| @@ -153,7 +153,7 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
| 153 | if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) | 153 | if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0) |
| 154 | goto err; | 154 | goto err; |
| 155 | 155 | ||
| 156 | p = br_port_get_rcu(dev); | 156 | p = br_port_get_check_rcu(dev); |
| 157 | if (!p) | 157 | if (!p) |
| 158 | goto err; | 158 | goto err; |
| 159 | 159 | ||
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 95897183226e..e70301eb7a4a 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -64,7 +64,6 @@ static struct genl_family net_drop_monitor_family = { | |||
| 64 | .hdrsize = 0, | 64 | .hdrsize = 0, |
| 65 | .name = "NET_DM", | 65 | .name = "NET_DM", |
| 66 | .version = 2, | 66 | .version = 2, |
| 67 | .maxattr = NET_DM_CMD_MAX, | ||
| 68 | }; | 67 | }; |
| 69 | 68 | ||
| 70 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); | 69 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2718fed53d8c..06e72d3cdf60 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -3584,6 +3584,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
| 3584 | skb->tstamp.tv64 = 0; | 3584 | skb->tstamp.tv64 = 0; |
| 3585 | skb->pkt_type = PACKET_HOST; | 3585 | skb->pkt_type = PACKET_HOST; |
| 3586 | skb->skb_iif = 0; | 3586 | skb->skb_iif = 0; |
| 3587 | skb->local_df = 0; | ||
| 3587 | skb_dst_drop(skb); | 3588 | skb_dst_drop(skb); |
| 3588 | skb->mark = 0; | 3589 | skb->mark = 0; |
| 3589 | secpath_reset(skb); | 3590 | secpath_reset(skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index ab20ed9b0f31..5393b4b719d7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -882,7 +882,7 @@ set_rcvbuf: | |||
| 882 | 882 | ||
| 883 | case SO_PEEK_OFF: | 883 | case SO_PEEK_OFF: |
| 884 | if (sock->ops->set_peek_off) | 884 | if (sock->ops->set_peek_off) |
| 885 | sock->ops->set_peek_off(sk, val); | 885 | ret = sock->ops->set_peek_off(sk, val); |
| 886 | else | 886 | else |
| 887 | ret = -EOPNOTSUPP; | 887 | ret = -EOPNOTSUPP; |
| 888 | break; | 888 | break; |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 4ac71ff7c2e4..2b90a786e475 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
| @@ -851,7 +851,6 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 851 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 851 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 852 | if (flowlabel == NULL) | 852 | if (flowlabel == NULL) |
| 853 | return -EINVAL; | 853 | return -EINVAL; |
| 854 | usin->sin6_addr = flowlabel->dst; | ||
| 855 | fl6_sock_release(flowlabel); | 854 | fl6_sock_release(flowlabel); |
| 856 | } | 855 | } |
| 857 | } | 856 | } |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 523be38e37de..f2e15738534d 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
| @@ -104,7 +104,10 @@ errout: | |||
| 104 | static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 104 | static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) |
| 105 | { | 105 | { |
| 106 | struct fib_result *result = (struct fib_result *) arg->result; | 106 | struct fib_result *result = (struct fib_result *) arg->result; |
| 107 | struct net_device *dev = result->fi->fib_dev; | 107 | struct net_device *dev = NULL; |
| 108 | |||
| 109 | if (result->fi) | ||
| 110 | dev = result->fi->fib_dev; | ||
| 108 | 111 | ||
| 109 | /* do not accept result if the route does | 112 | /* do not accept result if the route does |
| 110 | * not meet the required prefix length | 113 | * not meet the required prefix length |
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index 269a89ecd2f4..f7e522c558ba 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c | |||
| @@ -6,13 +6,6 @@ | |||
| 6 | #include <linux/memcontrol.h> | 6 | #include <linux/memcontrol.h> |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | 8 | ||
| 9 | static void memcg_tcp_enter_memory_pressure(struct sock *sk) | ||
| 10 | { | ||
| 11 | if (sk->sk_cgrp->memory_pressure) | ||
| 12 | sk->sk_cgrp->memory_pressure = 1; | ||
| 13 | } | ||
| 14 | EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure); | ||
| 15 | |||
| 16 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) | 9 | int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) |
| 17 | { | 10 | { |
| 18 | /* | 11 | /* |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 44f6a20fa29d..62c19fdd102d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -560,15 +560,11 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb, | |||
| 560 | __be16 sport, __be16 dport, | 560 | __be16 sport, __be16 dport, |
| 561 | struct udp_table *udptable) | 561 | struct udp_table *udptable) |
| 562 | { | 562 | { |
| 563 | struct sock *sk; | ||
| 564 | const struct iphdr *iph = ip_hdr(skb); | 563 | const struct iphdr *iph = ip_hdr(skb); |
| 565 | 564 | ||
| 566 | if (unlikely(sk = skb_steal_sock(skb))) | 565 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, |
| 567 | return sk; | 566 | iph->daddr, dport, inet_iif(skb), |
| 568 | else | 567 | udptable); |
| 569 | return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport, | ||
| 570 | iph->daddr, dport, inet_iif(skb), | ||
| 571 | udptable); | ||
| 572 | } | 568 | } |
| 573 | 569 | ||
| 574 | struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, | 570 | struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, |
| @@ -1603,12 +1599,21 @@ static void flush_stack(struct sock **stack, unsigned int count, | |||
| 1603 | kfree_skb(skb1); | 1599 | kfree_skb(skb1); |
| 1604 | } | 1600 | } |
| 1605 | 1601 | ||
| 1606 | static void udp_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | 1602 | /* For TCP sockets, sk_rx_dst is protected by socket lock |
| 1603 | * For UDP, we use sk_dst_lock to guard against concurrent changes. | ||
| 1604 | */ | ||
| 1605 | static void udp_sk_rx_dst_set(struct sock *sk, struct dst_entry *dst) | ||
| 1607 | { | 1606 | { |
| 1608 | struct dst_entry *dst = skb_dst(skb); | 1607 | struct dst_entry *old; |
| 1609 | 1608 | ||
| 1610 | dst_hold(dst); | 1609 | spin_lock(&sk->sk_dst_lock); |
| 1611 | sk->sk_rx_dst = dst; | 1610 | old = sk->sk_rx_dst; |
| 1611 | if (likely(old != dst)) { | ||
| 1612 | dst_hold(dst); | ||
| 1613 | sk->sk_rx_dst = dst; | ||
| 1614 | dst_release(old); | ||
| 1615 | } | ||
| 1616 | spin_unlock(&sk->sk_dst_lock); | ||
| 1612 | } | 1617 | } |
| 1613 | 1618 | ||
| 1614 | /* | 1619 | /* |
| @@ -1739,15 +1744,16 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
| 1739 | if (udp4_csum_init(skb, uh, proto)) | 1744 | if (udp4_csum_init(skb, uh, proto)) |
| 1740 | goto csum_error; | 1745 | goto csum_error; |
| 1741 | 1746 | ||
| 1742 | if (skb->sk) { | 1747 | sk = skb_steal_sock(skb); |
| 1748 | if (sk) { | ||
| 1749 | struct dst_entry *dst = skb_dst(skb); | ||
| 1743 | int ret; | 1750 | int ret; |
| 1744 | sk = skb->sk; | ||
| 1745 | 1751 | ||
| 1746 | if (unlikely(sk->sk_rx_dst == NULL)) | 1752 | if (unlikely(sk->sk_rx_dst != dst)) |
| 1747 | udp_sk_rx_dst_set(sk, skb); | 1753 | udp_sk_rx_dst_set(sk, dst); |
| 1748 | 1754 | ||
| 1749 | ret = udp_queue_rcv_skb(sk, skb); | 1755 | ret = udp_queue_rcv_skb(sk, skb); |
| 1750 | 1756 | sock_put(sk); | |
| 1751 | /* a return value > 0 means to resubmit the input, but | 1757 | /* a return value > 0 means to resubmit the input, but |
| 1752 | * it wants the return to be -protocol, or 0 | 1758 | * it wants the return to be -protocol, or 0 |
| 1753 | */ | 1759 | */ |
| @@ -1913,17 +1919,20 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net, | |||
| 1913 | 1919 | ||
| 1914 | void udp_v4_early_demux(struct sk_buff *skb) | 1920 | void udp_v4_early_demux(struct sk_buff *skb) |
| 1915 | { | 1921 | { |
| 1916 | const struct iphdr *iph = ip_hdr(skb); | 1922 | struct net *net = dev_net(skb->dev); |
| 1917 | const struct udphdr *uh = udp_hdr(skb); | 1923 | const struct iphdr *iph; |
| 1924 | const struct udphdr *uh; | ||
| 1918 | struct sock *sk; | 1925 | struct sock *sk; |
| 1919 | struct dst_entry *dst; | 1926 | struct dst_entry *dst; |
| 1920 | struct net *net = dev_net(skb->dev); | ||
| 1921 | int dif = skb->dev->ifindex; | 1927 | int dif = skb->dev->ifindex; |
| 1922 | 1928 | ||
| 1923 | /* validate the packet */ | 1929 | /* validate the packet */ |
| 1924 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) | 1930 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) |
| 1925 | return; | 1931 | return; |
| 1926 | 1932 | ||
| 1933 | iph = ip_hdr(skb); | ||
| 1934 | uh = udp_hdr(skb); | ||
| 1935 | |||
| 1927 | if (skb->pkt_type == PACKET_BROADCAST || | 1936 | if (skb->pkt_type == PACKET_BROADCAST || |
| 1928 | skb->pkt_type == PACKET_MULTICAST) | 1937 | skb->pkt_type == PACKET_MULTICAST) |
| 1929 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 1938 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 12c97d8aa6bb..d5fa5b8c443e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2613,7 +2613,7 @@ static void init_loopback(struct net_device *dev) | |||
| 2613 | if (sp_ifa->rt) | 2613 | if (sp_ifa->rt) |
| 2614 | continue; | 2614 | continue; |
| 2615 | 2615 | ||
| 2616 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | 2616 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, false); |
| 2617 | 2617 | ||
| 2618 | /* Failure cases are ignored */ | 2618 | /* Failure cases are ignored */ |
| 2619 | if (!IS_ERR(sp_rt)) { | 2619 | if (!IS_ERR(sp_rt)) { |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 8dfe1f4d3c1a..93b1aa34c432 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -73,7 +73,6 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
| 73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 73 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 74 | if (flowlabel == NULL) | 74 | if (flowlabel == NULL) |
| 75 | return -EINVAL; | 75 | return -EINVAL; |
| 76 | usin->sin6_addr = flowlabel->dst; | ||
| 77 | } | 76 | } |
| 78 | } | 77 | } |
| 79 | 78 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index e27591635f92..3fd0a578329e 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
| @@ -122,7 +122,11 @@ out: | |||
| 122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) | 122 | static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg) |
| 123 | { | 123 | { |
| 124 | struct rt6_info *rt = (struct rt6_info *) arg->result; | 124 | struct rt6_info *rt = (struct rt6_info *) arg->result; |
| 125 | struct net_device *dev = rt->rt6i_idev->dev; | 125 | struct net_device *dev = NULL; |
| 126 | |||
| 127 | if (rt->rt6i_idev) | ||
| 128 | dev = rt->rt6i_idev->dev; | ||
| 129 | |||
| 126 | /* do not accept result if the route does | 130 | /* do not accept result if the route does |
| 127 | * not meet the required prefix length | 131 | * not meet the required prefix length |
| 128 | */ | 132 | */ |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 3512177deb4d..300865171394 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1277,6 +1277,9 @@ skip_linkparms: | |||
| 1277 | ri->prefix_len == 0) | 1277 | ri->prefix_len == 0) |
| 1278 | continue; | 1278 | continue; |
| 1279 | #endif | 1279 | #endif |
| 1280 | if (ri->prefix_len == 0 && | ||
| 1281 | !in6_dev->cnf.accept_ra_defrtr) | ||
| 1282 | continue; | ||
| 1280 | if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) | 1283 | if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) |
| 1281 | continue; | 1284 | continue; |
| 1282 | rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, | 1285 | rt6_route_rcv(skb->dev, (u8*)p, (p->nd_opt_len) << 3, |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 7fb4e14c467f..b6bb87e55805 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -792,7 +792,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 792 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 792 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 793 | if (flowlabel == NULL) | 793 | if (flowlabel == NULL) |
| 794 | return -EINVAL; | 794 | return -EINVAL; |
| 795 | daddr = &flowlabel->dst; | ||
| 796 | } | 795 | } |
| 797 | } | 796 | } |
| 798 | 797 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7faa9d5e1503..a0a48ac3403f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -84,6 +84,8 @@ static int ip6_dst_gc(struct dst_ops *ops); | |||
| 84 | 84 | ||
| 85 | static int ip6_pkt_discard(struct sk_buff *skb); | 85 | static int ip6_pkt_discard(struct sk_buff *skb); |
| 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); | 86 | static int ip6_pkt_discard_out(struct sk_buff *skb); |
| 87 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
| 88 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
| 87 | static void ip6_link_failure(struct sk_buff *skb); | 89 | static void ip6_link_failure(struct sk_buff *skb); |
| 88 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 90 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 89 | struct sk_buff *skb, u32 mtu); | 91 | struct sk_buff *skb, u32 mtu); |
| @@ -234,9 +236,6 @@ static const struct rt6_info ip6_null_entry_template = { | |||
| 234 | 236 | ||
| 235 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 237 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 236 | 238 | ||
| 237 | static int ip6_pkt_prohibit(struct sk_buff *skb); | ||
| 238 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | ||
| 239 | |||
| 240 | static const struct rt6_info ip6_prohibit_entry_template = { | 239 | static const struct rt6_info ip6_prohibit_entry_template = { |
| 241 | .dst = { | 240 | .dst = { |
| 242 | .__refcnt = ATOMIC_INIT(1), | 241 | .__refcnt = ATOMIC_INIT(1), |
| @@ -1565,21 +1564,24 @@ int ip6_route_add(struct fib6_config *cfg) | |||
| 1565 | goto out; | 1564 | goto out; |
| 1566 | } | 1565 | } |
| 1567 | } | 1566 | } |
| 1568 | rt->dst.output = ip6_pkt_discard_out; | ||
| 1569 | rt->dst.input = ip6_pkt_discard; | ||
| 1570 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; | 1567 | rt->rt6i_flags = RTF_REJECT|RTF_NONEXTHOP; |
| 1571 | switch (cfg->fc_type) { | 1568 | switch (cfg->fc_type) { |
| 1572 | case RTN_BLACKHOLE: | 1569 | case RTN_BLACKHOLE: |
| 1573 | rt->dst.error = -EINVAL; | 1570 | rt->dst.error = -EINVAL; |
| 1571 | rt->dst.output = dst_discard; | ||
| 1572 | rt->dst.input = dst_discard; | ||
| 1574 | break; | 1573 | break; |
| 1575 | case RTN_PROHIBIT: | 1574 | case RTN_PROHIBIT: |
| 1576 | rt->dst.error = -EACCES; | 1575 | rt->dst.error = -EACCES; |
| 1576 | rt->dst.output = ip6_pkt_prohibit_out; | ||
| 1577 | rt->dst.input = ip6_pkt_prohibit; | ||
| 1577 | break; | 1578 | break; |
| 1578 | case RTN_THROW: | 1579 | case RTN_THROW: |
| 1579 | rt->dst.error = -EAGAIN; | ||
| 1580 | break; | ||
| 1581 | default: | 1580 | default: |
| 1582 | rt->dst.error = -ENETUNREACH; | 1581 | rt->dst.error = (cfg->fc_type == RTN_THROW) ? -EAGAIN |
| 1582 | : -ENETUNREACH; | ||
| 1583 | rt->dst.output = ip6_pkt_discard_out; | ||
| 1584 | rt->dst.input = ip6_pkt_discard; | ||
| 1583 | break; | 1585 | break; |
| 1584 | } | 1586 | } |
| 1585 | goto install_route; | 1587 | goto install_route; |
| @@ -2144,8 +2146,6 @@ static int ip6_pkt_discard_out(struct sk_buff *skb) | |||
| 2144 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); | 2146 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); |
| 2145 | } | 2147 | } |
| 2146 | 2148 | ||
| 2147 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||
| 2148 | |||
| 2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) | 2149 | static int ip6_pkt_prohibit(struct sk_buff *skb) |
| 2150 | { | 2150 | { |
| 2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); | 2151 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); |
| @@ -2157,8 +2157,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb) | |||
| 2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); | 2157 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
| 2158 | } | 2158 | } |
| 2159 | 2159 | ||
| 2160 | #endif | ||
| 2161 | |||
| 2162 | /* | 2160 | /* |
| 2163 | * Allocate a dst for local (unicast / anycast) address. | 2161 | * Allocate a dst for local (unicast / anycast) address. |
| 2164 | */ | 2162 | */ |
| @@ -2168,12 +2166,10 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
| 2168 | bool anycast) | 2166 | bool anycast) |
| 2169 | { | 2167 | { |
| 2170 | struct net *net = dev_net(idev->dev); | 2168 | struct net *net = dev_net(idev->dev); |
| 2171 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, 0, NULL); | 2169 | struct rt6_info *rt = ip6_dst_alloc(net, net->loopback_dev, |
| 2172 | 2170 | DST_NOCOUNT, NULL); | |
| 2173 | if (!rt) { | 2171 | if (!rt) |
| 2174 | net_warn_ratelimited("Maximum number of routes reached, consider increasing route/max_size\n"); | ||
| 2175 | return ERR_PTR(-ENOMEM); | 2172 | return ERR_PTR(-ENOMEM); |
| 2176 | } | ||
| 2177 | 2173 | ||
| 2178 | in6_dev_hold(idev); | 2174 | in6_dev_hold(idev); |
| 2179 | 2175 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 0740f93a114a..f67033b4bb66 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -156,7 +156,6 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
| 156 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 156 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 157 | if (flowlabel == NULL) | 157 | if (flowlabel == NULL) |
| 158 | return -EINVAL; | 158 | return -EINVAL; |
| 159 | usin->sin6_addr = flowlabel->dst; | ||
| 160 | fl6_sock_release(flowlabel); | 159 | fl6_sock_release(flowlabel); |
| 161 | } | 160 | } |
| 162 | } | 161 | } |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index bcd5699313c3..089c741a3992 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -1140,7 +1140,6 @@ do_udp_sendmsg: | |||
| 1140 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 1140 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 1141 | if (flowlabel == NULL) | 1141 | if (flowlabel == NULL) |
| 1142 | return -EINVAL; | 1142 | return -EINVAL; |
| 1143 | daddr = &flowlabel->dst; | ||
| 1144 | } | 1143 | } |
| 1145 | } | 1144 | } |
| 1146 | 1145 | ||
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index d9b437e55007..bb6e206ea70b 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
| @@ -528,7 +528,6 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 528 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 528 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
| 529 | if (flowlabel == NULL) | 529 | if (flowlabel == NULL) |
| 530 | return -EINVAL; | 530 | return -EINVAL; |
| 531 | daddr = &flowlabel->dst; | ||
| 532 | } | 531 | } |
| 533 | } | 532 | } |
| 534 | 533 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 95667b088c5b..364ce0c5962f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1368,7 +1368,7 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
| 1368 | changed |= | 1368 | changed |= |
| 1369 | ieee80211_mps_set_sta_local_pm(sta, | 1369 | ieee80211_mps_set_sta_local_pm(sta, |
| 1370 | params->local_pm); | 1370 | params->local_pm); |
| 1371 | ieee80211_bss_info_change_notify(sdata, changed); | 1371 | ieee80211_mbss_info_change_notify(sdata, changed); |
| 1372 | #endif | 1372 | #endif |
| 1373 | } | 1373 | } |
| 1374 | 1374 | ||
| @@ -2488,8 +2488,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
| 2488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2489 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2489 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 2490 | 2490 | ||
| 2491 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 2491 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
| 2492 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) | ||
| 2493 | return -EOPNOTSUPP; | 2492 | return -EOPNOTSUPP; |
| 2494 | 2493 | ||
| 2495 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | 2494 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) |
| @@ -3120,9 +3119,17 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, | |||
| 3120 | params->chandef.chan->band) | 3119 | params->chandef.chan->band) |
| 3121 | return -EINVAL; | 3120 | return -EINVAL; |
| 3122 | 3121 | ||
| 3122 | ifmsh->chsw_init = true; | ||
| 3123 | if (!ifmsh->pre_value) | ||
| 3124 | ifmsh->pre_value = 1; | ||
| 3125 | else | ||
| 3126 | ifmsh->pre_value++; | ||
| 3127 | |||
| 3123 | err = ieee80211_mesh_csa_beacon(sdata, params, true); | 3128 | err = ieee80211_mesh_csa_beacon(sdata, params, true); |
| 3124 | if (err < 0) | 3129 | if (err < 0) { |
| 3130 | ifmsh->chsw_init = false; | ||
| 3125 | return err; | 3131 | return err; |
| 3132 | } | ||
| 3126 | break; | 3133 | break; |
| 3127 | #endif | 3134 | #endif |
| 3128 | default: | 3135 | default: |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 531be040b9ae..27a39de89679 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -823,6 +823,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
| 823 | if (err) | 823 | if (err) |
| 824 | return false; | 824 | return false; |
| 825 | 825 | ||
| 826 | /* channel switch is not supported, disconnect */ | ||
| 827 | if (!(sdata->local->hw.wiphy->flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) | ||
| 828 | goto disconnect; | ||
| 829 | |||
| 826 | params.count = csa_ie.count; | 830 | params.count = csa_ie.count; |
| 827 | params.chandef = csa_ie.chandef; | 831 | params.chandef = csa_ie.chandef; |
| 828 | 832 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 29dc505be125..4aea4e791113 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1228,6 +1228,7 @@ struct ieee80211_csa_ie { | |||
| 1228 | u8 mode; | 1228 | u8 mode; |
| 1229 | u8 count; | 1229 | u8 count; |
| 1230 | u8 ttl; | 1230 | u8 ttl; |
| 1231 | u16 pre_value; | ||
| 1231 | }; | 1232 | }; |
| 1232 | 1233 | ||
| 1233 | /* Parsed Information Elements */ | 1234 | /* Parsed Information Elements */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ff101ea1d9ae..36c3a4cbcabf 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1325,7 +1325,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
| 1325 | sdata->vif.bss_conf.bssid = NULL; | 1325 | sdata->vif.bss_conf.bssid = NULL; |
| 1326 | break; | 1326 | break; |
| 1327 | case NL80211_IFTYPE_AP_VLAN: | 1327 | case NL80211_IFTYPE_AP_VLAN: |
| 1328 | break; | ||
| 1329 | case NL80211_IFTYPE_P2P_DEVICE: | 1328 | case NL80211_IFTYPE_P2P_DEVICE: |
| 1330 | sdata->vif.bss_conf.bssid = sdata->vif.addr; | 1329 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
| 1331 | break; | 1330 | break; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 21d5d44444d0..7d1c3ac48ed9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -940,6 +940,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 940 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", | 940 | wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", |
| 941 | result); | 941 | result); |
| 942 | 942 | ||
| 943 | local->hw.conf.flags = IEEE80211_CONF_IDLE; | ||
| 944 | |||
| 943 | ieee80211_led_init(local); | 945 | ieee80211_led_init(local); |
| 944 | 946 | ||
| 945 | rtnl_lock(); | 947 | rtnl_lock(); |
| @@ -1047,6 +1049,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
| 1047 | 1049 | ||
| 1048 | cancel_work_sync(&local->restart_work); | 1050 | cancel_work_sync(&local->restart_work); |
| 1049 | cancel_work_sync(&local->reconfig_filter); | 1051 | cancel_work_sync(&local->reconfig_filter); |
| 1052 | flush_work(&local->sched_scan_stopped_work); | ||
| 1050 | 1053 | ||
| 1051 | ieee80211_clear_tx_pending(local); | 1054 | ieee80211_clear_tx_pending(local); |
| 1052 | rate_control_deinitialize(local); | 1055 | rate_control_deinitialize(local); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 896fe3bd599e..ba105257d03f 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
| @@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata, | |||
| 943 | params.chandef.chan->center_freq); | 943 | params.chandef.chan->center_freq); |
| 944 | 944 | ||
| 945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; | 945 | params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; |
| 946 | if (beacon) | 946 | if (beacon) { |
| 947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; | 947 | ifmsh->chsw_ttl = csa_ie.ttl - 1; |
| 948 | else | 948 | if (ifmsh->pre_value >= csa_ie.pre_value) |
| 949 | ifmsh->chsw_ttl = 0; | 949 | return false; |
| 950 | ifmsh->pre_value = csa_ie.pre_value; | ||
| 951 | } | ||
| 950 | 952 | ||
| 951 | if (ifmsh->chsw_ttl > 0) | 953 | if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) { |
| 952 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) | 954 | if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) |
| 953 | return false; | 955 | return false; |
| 956 | } else { | ||
| 957 | return false; | ||
| 958 | } | ||
| 954 | 959 | ||
| 955 | sdata->csa_radar_required = params.radar_required; | 960 | sdata->csa_radar_required = params.radar_required; |
| 956 | 961 | ||
| @@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
| 1163 | offset_ttl = (len < 42) ? 7 : 10; | 1168 | offset_ttl = (len < 42) ? 7 : 10; |
| 1164 | *(pos + offset_ttl) -= 1; | 1169 | *(pos + offset_ttl) -= 1; |
| 1165 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; | 1170 | *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; |
| 1166 | sdata->u.mesh.chsw_ttl = *(pos + offset_ttl); | ||
| 1167 | 1171 | ||
| 1168 | memcpy(mgmt_fwd, mgmt, len); | 1172 | memcpy(mgmt_fwd, mgmt, len); |
| 1169 | eth_broadcast_addr(mgmt_fwd->da); | 1173 | eth_broadcast_addr(mgmt_fwd->da); |
| @@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
| 1182 | u16 pre_value; | 1186 | u16 pre_value; |
| 1183 | bool fwd_csa = true; | 1187 | bool fwd_csa = true; |
| 1184 | size_t baselen; | 1188 | size_t baselen; |
| 1185 | u8 *pos, ttl; | 1189 | u8 *pos; |
| 1186 | 1190 | ||
| 1187 | if (mgmt->u.action.u.measurement.action_code != | 1191 | if (mgmt->u.action.u.measurement.action_code != |
| 1188 | WLAN_ACTION_SPCT_CHL_SWITCH) | 1192 | WLAN_ACTION_SPCT_CHL_SWITCH) |
| @@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, | |||
| 1193 | u.action.u.chan_switch.variable); | 1197 | u.action.u.chan_switch.variable); |
| 1194 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); | 1198 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); |
| 1195 | 1199 | ||
| 1196 | ttl = elems.mesh_chansw_params_ie->mesh_ttl; | 1200 | ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; |
| 1197 | if (!--ttl) | 1201 | if (!--ifmsh->chsw_ttl) |
| 1198 | fwd_csa = false; | 1202 | fwd_csa = false; |
| 1199 | 1203 | ||
| 1200 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); | 1204 | pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7504ab61a34..b3a3ce316656 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1910,6 +1910,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
| 1910 | if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) | 1910 | if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) |
| 1911 | already = true; | 1911 | already = true; |
| 1912 | 1912 | ||
| 1913 | ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL; | ||
| 1914 | |||
| 1913 | mutex_unlock(&sdata->local->mtx); | 1915 | mutex_unlock(&sdata->local->mtx); |
| 1914 | 1916 | ||
| 1915 | if (already) | 1917 | if (already) |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 5d60779a0c1b..4096ff6cc24f 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
| @@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) | |||
| 226 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); | 226 | nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); |
| 227 | 227 | ||
| 228 | nsecs += minstrel_mcs_groups[group].duration[rate]; | 228 | nsecs += minstrel_mcs_groups[group].duration[rate]; |
| 229 | tp = 1000000 * ((mr->probability * 1000) / nsecs); | 229 | tp = 1000000 * ((prob * 1000) / nsecs); |
| 230 | 230 | ||
| 231 | mr->cur_tp = MINSTREL_TRUNC(tp); | 231 | mr->cur_tp = MINSTREL_TRUNC(tp); |
| 232 | } | 232 | } |
| @@ -277,13 +277,15 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 277 | if (!(mg->supported & BIT(i))) | 277 | if (!(mg->supported & BIT(i))) |
| 278 | continue; | 278 | continue; |
| 279 | 279 | ||
| 280 | index = MCS_GROUP_RATES * group + i; | ||
| 281 | |||
| 280 | /* initialize rates selections starting indexes */ | 282 | /* initialize rates selections starting indexes */ |
| 281 | if (!mg_rates_valid) { | 283 | if (!mg_rates_valid) { |
| 282 | mg->max_tp_rate = mg->max_tp_rate2 = | 284 | mg->max_tp_rate = mg->max_tp_rate2 = |
| 283 | mg->max_prob_rate = i; | 285 | mg->max_prob_rate = i; |
| 284 | if (!mi_rates_valid) { | 286 | if (!mi_rates_valid) { |
| 285 | mi->max_tp_rate = mi->max_tp_rate2 = | 287 | mi->max_tp_rate = mi->max_tp_rate2 = |
| 286 | mi->max_prob_rate = i; | 288 | mi->max_prob_rate = index; |
| 287 | mi_rates_valid = true; | 289 | mi_rates_valid = true; |
| 288 | } | 290 | } |
| 289 | mg_rates_valid = true; | 291 | mg_rates_valid = true; |
| @@ -291,7 +293,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
| 291 | 293 | ||
| 292 | mr = &mg->rates[i]; | 294 | mr = &mg->rates[i]; |
| 293 | mr->retry_updated = false; | 295 | mr->retry_updated = false; |
| 294 | index = MCS_GROUP_RATES * group + i; | ||
| 295 | minstrel_calc_rate_ewma(mr); | 296 | minstrel_calc_rate_ewma(mr); |
| 296 | minstrel_ht_calc_tp(mi, group, i); | 297 | minstrel_ht_calc_tp(mi, group, i); |
| 297 | 298 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index caecef870c0e..2b0debb0422b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -911,7 +911,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx, | |||
| 911 | u16 sc; | 911 | u16 sc; |
| 912 | u8 tid, ack_policy; | 912 | u8 tid, ack_policy; |
| 913 | 913 | ||
| 914 | if (!ieee80211_is_data_qos(hdr->frame_control)) | 914 | if (!ieee80211_is_data_qos(hdr->frame_control) || |
| 915 | is_multicast_ether_addr(hdr->addr1)) | ||
| 915 | goto dont_reorder; | 916 | goto dont_reorder; |
| 916 | 917 | ||
| 917 | /* | 918 | /* |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 5ad66a83ef7f..bcc4833d7542 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -1088,6 +1088,6 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw) | |||
| 1088 | 1088 | ||
| 1089 | trace_api_sched_scan_stopped(local); | 1089 | trace_api_sched_scan_stopped(local); |
| 1090 | 1090 | ||
| 1091 | ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work); | 1091 | schedule_work(&local->sched_scan_stopped_work); |
| 1092 | } | 1092 | } |
| 1093 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); | 1093 | EXPORT_SYMBOL(ieee80211_sched_scan_stopped); |
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index a40da20b32e0..6ab009070084 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c | |||
| @@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata, | |||
| 78 | if (elems->mesh_chansw_params_ie) { | 78 | if (elems->mesh_chansw_params_ie) { |
| 79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; | 79 | csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; |
| 80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; | 80 | csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; |
| 81 | csa_ie->pre_value = le16_to_cpu( | ||
| 82 | elems->mesh_chansw_params_ie->mesh_pre_value); | ||
| 81 | } | 83 | } |
| 82 | 84 | ||
| 83 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); | 85 | new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 592a18171f95..9f9b9bd3fd44 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -2278,17 +2278,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work) | |||
| 2278 | { | 2278 | { |
| 2279 | struct ieee80211_local *local = | 2279 | struct ieee80211_local *local = |
| 2280 | container_of(work, struct ieee80211_local, radar_detected_work); | 2280 | container_of(work, struct ieee80211_local, radar_detected_work); |
| 2281 | struct cfg80211_chan_def chandef; | 2281 | struct cfg80211_chan_def chandef = local->hw.conf.chandef; |
| 2282 | 2282 | ||
| 2283 | ieee80211_dfs_cac_cancel(local); | 2283 | ieee80211_dfs_cac_cancel(local); |
| 2284 | 2284 | ||
| 2285 | if (local->use_chanctx) | 2285 | if (local->use_chanctx) |
| 2286 | /* currently not handled */ | 2286 | /* currently not handled */ |
| 2287 | WARN_ON(1); | 2287 | WARN_ON(1); |
| 2288 | else { | 2288 | else |
| 2289 | chandef = local->hw.conf.chandef; | ||
| 2290 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); | 2289 | cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL); |
| 2291 | } | ||
| 2292 | } | 2290 | } |
| 2293 | 2291 | ||
| 2294 | void ieee80211_radar_detected(struct ieee80211_hw *hw) | 2292 | void ieee80211_radar_detected(struct ieee80211_hw *hw) |
| @@ -2459,14 +2457,9 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | |||
| 2459 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; | 2457 | WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; |
| 2460 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ | 2458 | put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ |
| 2461 | pos += 2; | 2459 | pos += 2; |
| 2462 | if (!ifmsh->pre_value) | ||
| 2463 | ifmsh->pre_value = 1; | ||
| 2464 | else | ||
| 2465 | ifmsh->pre_value++; | ||
| 2466 | pre_value = cpu_to_le16(ifmsh->pre_value); | 2460 | pre_value = cpu_to_le16(ifmsh->pre_value); |
| 2467 | memcpy(pos, &pre_value, 2); /* Precedence Value */ | 2461 | memcpy(pos, &pre_value, 2); /* Precedence Value */ |
| 2468 | pos += 2; | 2462 | pos += 2; |
| 2469 | ifmsh->chsw_init = true; | ||
| 2470 | } | 2463 | } |
| 2471 | 2464 | ||
| 2472 | ieee80211_tx_skb(sdata, skb); | 2465 | ieee80211_tx_skb(sdata, skb); |
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c index 2bc2dec20b00..6226803fc490 100644 --- a/net/netfilter/ipset/ip_set_hash_netnet.c +++ b/net/netfilter/ipset/ip_set_hash_netnet.c | |||
| @@ -59,7 +59,7 @@ hash_netnet4_data_equal(const struct hash_netnet4_elem *ip1, | |||
| 59 | u32 *multi) | 59 | u32 *multi) |
| 60 | { | 60 | { |
| 61 | return ip1->ipcmp == ip2->ipcmp && | 61 | return ip1->ipcmp == ip2->ipcmp && |
| 62 | ip2->ccmp == ip2->ccmp; | 62 | ip1->ccmp == ip2->ccmp; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static inline int | 65 | static inline int |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index dcddc49c0e08..f93b7d06f4be 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -1717,6 +1717,19 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule) | |||
| 1717 | return -ENOENT; | 1717 | return -ENOENT; |
| 1718 | } | 1718 | } |
| 1719 | 1719 | ||
| 1720 | static int nf_table_delrule_by_chain(struct nft_ctx *ctx) | ||
| 1721 | { | ||
| 1722 | struct nft_rule *rule; | ||
| 1723 | int err; | ||
| 1724 | |||
| 1725 | list_for_each_entry(rule, &ctx->chain->rules, list) { | ||
| 1726 | err = nf_tables_delrule_one(ctx, rule); | ||
| 1727 | if (err < 0) | ||
| 1728 | return err; | ||
| 1729 | } | ||
| 1730 | return 0; | ||
| 1731 | } | ||
| 1732 | |||
| 1720 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | 1733 | static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, |
| 1721 | const struct nlmsghdr *nlh, | 1734 | const struct nlmsghdr *nlh, |
| 1722 | const struct nlattr * const nla[]) | 1735 | const struct nlattr * const nla[]) |
| @@ -1725,8 +1738,8 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1725 | const struct nft_af_info *afi; | 1738 | const struct nft_af_info *afi; |
| 1726 | struct net *net = sock_net(skb->sk); | 1739 | struct net *net = sock_net(skb->sk); |
| 1727 | const struct nft_table *table; | 1740 | const struct nft_table *table; |
| 1728 | struct nft_chain *chain; | 1741 | struct nft_chain *chain = NULL; |
| 1729 | struct nft_rule *rule, *tmp; | 1742 | struct nft_rule *rule; |
| 1730 | int family = nfmsg->nfgen_family, err = 0; | 1743 | int family = nfmsg->nfgen_family, err = 0; |
| 1731 | struct nft_ctx ctx; | 1744 | struct nft_ctx ctx; |
| 1732 | 1745 | ||
| @@ -1738,22 +1751,29 @@ static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1738 | if (IS_ERR(table)) | 1751 | if (IS_ERR(table)) |
| 1739 | return PTR_ERR(table); | 1752 | return PTR_ERR(table); |
| 1740 | 1753 | ||
| 1741 | chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); | 1754 | if (nla[NFTA_RULE_CHAIN]) { |
| 1742 | if (IS_ERR(chain)) | 1755 | chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); |
| 1743 | return PTR_ERR(chain); | 1756 | if (IS_ERR(chain)) |
| 1757 | return PTR_ERR(chain); | ||
| 1758 | } | ||
| 1744 | 1759 | ||
| 1745 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); | 1760 | nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla); |
| 1746 | 1761 | ||
| 1747 | if (nla[NFTA_RULE_HANDLE]) { | 1762 | if (chain) { |
| 1748 | rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]); | 1763 | if (nla[NFTA_RULE_HANDLE]) { |
| 1749 | if (IS_ERR(rule)) | 1764 | rule = nf_tables_rule_lookup(chain, |
| 1750 | return PTR_ERR(rule); | 1765 | nla[NFTA_RULE_HANDLE]); |
| 1766 | if (IS_ERR(rule)) | ||
| 1767 | return PTR_ERR(rule); | ||
| 1751 | 1768 | ||
| 1752 | err = nf_tables_delrule_one(&ctx, rule); | ||
| 1753 | } else { | ||
| 1754 | /* Remove all rules in this chain */ | ||
| 1755 | list_for_each_entry_safe(rule, tmp, &chain->rules, list) { | ||
| 1756 | err = nf_tables_delrule_one(&ctx, rule); | 1769 | err = nf_tables_delrule_one(&ctx, rule); |
| 1770 | } else { | ||
| 1771 | err = nf_table_delrule_by_chain(&ctx); | ||
| 1772 | } | ||
| 1773 | } else { | ||
| 1774 | list_for_each_entry(chain, &table->chains, list) { | ||
| 1775 | ctx.chain = chain; | ||
| 1776 | err = nf_table_delrule_by_chain(&ctx); | ||
| 1757 | if (err < 0) | 1777 | if (err < 0) |
| 1758 | break; | 1778 | break; |
| 1759 | } | 1779 | } |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 9ff035c71403..a3910fc2122b 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
| @@ -325,21 +325,24 @@ static void htable_gc(unsigned long htlong) | |||
| 325 | add_timer(&ht->timer); | 325 | add_timer(&ht->timer); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | 328 | static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo) |
| 329 | { | 329 | { |
| 330 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net); | 330 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(hinfo->net); |
| 331 | struct proc_dir_entry *parent; | 331 | struct proc_dir_entry *parent; |
| 332 | 332 | ||
| 333 | del_timer_sync(&hinfo->timer); | ||
| 334 | |||
| 335 | if (hinfo->family == NFPROTO_IPV4) | 333 | if (hinfo->family == NFPROTO_IPV4) |
| 336 | parent = hashlimit_net->ipt_hashlimit; | 334 | parent = hashlimit_net->ipt_hashlimit; |
| 337 | else | 335 | else |
| 338 | parent = hashlimit_net->ip6t_hashlimit; | 336 | parent = hashlimit_net->ip6t_hashlimit; |
| 339 | 337 | ||
| 340 | if(parent != NULL) | 338 | if (parent != NULL) |
| 341 | remove_proc_entry(hinfo->name, parent); | 339 | remove_proc_entry(hinfo->name, parent); |
| 340 | } | ||
| 342 | 341 | ||
| 342 | static void htable_destroy(struct xt_hashlimit_htable *hinfo) | ||
| 343 | { | ||
| 344 | del_timer_sync(&hinfo->timer); | ||
| 345 | htable_remove_proc_entry(hinfo); | ||
| 343 | htable_selective_cleanup(hinfo, select_all); | 346 | htable_selective_cleanup(hinfo, select_all); |
| 344 | kfree(hinfo->name); | 347 | kfree(hinfo->name); |
| 345 | vfree(hinfo); | 348 | vfree(hinfo); |
| @@ -883,21 +886,15 @@ static int __net_init hashlimit_proc_net_init(struct net *net) | |||
| 883 | static void __net_exit hashlimit_proc_net_exit(struct net *net) | 886 | static void __net_exit hashlimit_proc_net_exit(struct net *net) |
| 884 | { | 887 | { |
| 885 | struct xt_hashlimit_htable *hinfo; | 888 | struct xt_hashlimit_htable *hinfo; |
| 886 | struct proc_dir_entry *pde; | ||
| 887 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); | 889 | struct hashlimit_net *hashlimit_net = hashlimit_pernet(net); |
| 888 | 890 | ||
| 889 | /* recent_net_exit() is called before recent_mt_destroy(). Make sure | 891 | /* hashlimit_net_exit() is called before hashlimit_mt_destroy(). |
| 890 | * that the parent xt_recent proc entry is is empty before trying to | 892 | * Make sure that the parent ipt_hashlimit and ip6t_hashlimit proc |
| 891 | * remove it. | 893 | * entries is empty before trying to remove it. |
| 892 | */ | 894 | */ |
| 893 | mutex_lock(&hashlimit_mutex); | 895 | mutex_lock(&hashlimit_mutex); |
| 894 | pde = hashlimit_net->ipt_hashlimit; | ||
| 895 | if (pde == NULL) | ||
| 896 | pde = hashlimit_net->ip6t_hashlimit; | ||
| 897 | |||
| 898 | hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) | 896 | hlist_for_each_entry(hinfo, &hashlimit_net->htables, node) |
| 899 | remove_proc_entry(hinfo->name, pde); | 897 | htable_remove_proc_entry(hinfo); |
| 900 | |||
| 901 | hashlimit_net->ipt_hashlimit = NULL; | 898 | hashlimit_net->ipt_hashlimit = NULL; |
| 902 | hashlimit_net->ip6t_hashlimit = NULL; | 899 | hashlimit_net->ip6t_hashlimit = NULL; |
| 903 | mutex_unlock(&hashlimit_mutex); | 900 | mutex_unlock(&hashlimit_mutex); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ba2548bd85bf..88cfbc189558 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -237,6 +237,30 @@ struct packet_skb_cb { | |||
| 237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); | 237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); |
| 238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); | 238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); |
| 239 | 239 | ||
| 240 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
| 241 | { | ||
| 242 | struct net_device *dev; | ||
| 243 | |||
| 244 | rcu_read_lock(); | ||
| 245 | dev = rcu_dereference(po->cached_dev); | ||
| 246 | if (likely(dev)) | ||
| 247 | dev_hold(dev); | ||
| 248 | rcu_read_unlock(); | ||
| 249 | |||
| 250 | return dev; | ||
| 251 | } | ||
| 252 | |||
| 253 | static void packet_cached_dev_assign(struct packet_sock *po, | ||
| 254 | struct net_device *dev) | ||
| 255 | { | ||
| 256 | rcu_assign_pointer(po->cached_dev, dev); | ||
| 257 | } | ||
| 258 | |||
| 259 | static void packet_cached_dev_reset(struct packet_sock *po) | ||
| 260 | { | ||
| 261 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
| 262 | } | ||
| 263 | |||
| 240 | /* register_prot_hook must be invoked with the po->bind_lock held, | 264 | /* register_prot_hook must be invoked with the po->bind_lock held, |
| 241 | * or from a context in which asynchronous accesses to the packet | 265 | * or from a context in which asynchronous accesses to the packet |
| 242 | * socket is not possible (packet_create()). | 266 | * socket is not possible (packet_create()). |
| @@ -246,12 +270,10 @@ static void register_prot_hook(struct sock *sk) | |||
| 246 | struct packet_sock *po = pkt_sk(sk); | 270 | struct packet_sock *po = pkt_sk(sk); |
| 247 | 271 | ||
| 248 | if (!po->running) { | 272 | if (!po->running) { |
| 249 | if (po->fanout) { | 273 | if (po->fanout) |
| 250 | __fanout_link(sk, po); | 274 | __fanout_link(sk, po); |
| 251 | } else { | 275 | else |
| 252 | dev_add_pack(&po->prot_hook); | 276 | dev_add_pack(&po->prot_hook); |
| 253 | rcu_assign_pointer(po->cached_dev, po->prot_hook.dev); | ||
| 254 | } | ||
| 255 | 277 | ||
| 256 | sock_hold(sk); | 278 | sock_hold(sk); |
| 257 | po->running = 1; | 279 | po->running = 1; |
| @@ -270,12 +292,11 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) | |||
| 270 | struct packet_sock *po = pkt_sk(sk); | 292 | struct packet_sock *po = pkt_sk(sk); |
| 271 | 293 | ||
| 272 | po->running = 0; | 294 | po->running = 0; |
| 273 | if (po->fanout) { | 295 | |
| 296 | if (po->fanout) | ||
| 274 | __fanout_unlink(sk, po); | 297 | __fanout_unlink(sk, po); |
| 275 | } else { | 298 | else |
| 276 | __dev_remove_pack(&po->prot_hook); | 299 | __dev_remove_pack(&po->prot_hook); |
| 277 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
| 278 | } | ||
| 279 | 300 | ||
| 280 | __sock_put(sk); | 301 | __sock_put(sk); |
| 281 | 302 | ||
| @@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
| 2059 | return tp_len; | 2080 | return tp_len; |
| 2060 | } | 2081 | } |
| 2061 | 2082 | ||
| 2062 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
| 2063 | { | ||
| 2064 | struct net_device *dev; | ||
| 2065 | |||
| 2066 | rcu_read_lock(); | ||
| 2067 | dev = rcu_dereference(po->cached_dev); | ||
| 2068 | if (dev) | ||
| 2069 | dev_hold(dev); | ||
| 2070 | rcu_read_unlock(); | ||
| 2071 | |||
| 2072 | return dev; | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | 2083 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
| 2076 | { | 2084 | { |
| 2077 | struct sk_buff *skb; | 2085 | struct sk_buff *skb; |
| @@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2088 | 2096 | ||
| 2089 | mutex_lock(&po->pg_vec_lock); | 2097 | mutex_lock(&po->pg_vec_lock); |
| 2090 | 2098 | ||
| 2091 | if (saddr == NULL) { | 2099 | if (likely(saddr == NULL)) { |
| 2092 | dev = packet_cached_dev_get(po); | 2100 | dev = packet_cached_dev_get(po); |
| 2093 | proto = po->num; | 2101 | proto = po->num; |
| 2094 | addr = NULL; | 2102 | addr = NULL; |
| @@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *sock, | |||
| 2242 | * Get and verify the address. | 2250 | * Get and verify the address. |
| 2243 | */ | 2251 | */ |
| 2244 | 2252 | ||
| 2245 | if (saddr == NULL) { | 2253 | if (likely(saddr == NULL)) { |
| 2246 | dev = packet_cached_dev_get(po); | 2254 | dev = packet_cached_dev_get(po); |
| 2247 | proto = po->num; | 2255 | proto = po->num; |
| 2248 | addr = NULL; | 2256 | addr = NULL; |
| @@ -2451,6 +2459,8 @@ static int packet_release(struct socket *sock) | |||
| 2451 | 2459 | ||
| 2452 | spin_lock(&po->bind_lock); | 2460 | spin_lock(&po->bind_lock); |
| 2453 | unregister_prot_hook(sk, false); | 2461 | unregister_prot_hook(sk, false); |
| 2462 | packet_cached_dev_reset(po); | ||
| 2463 | |||
| 2454 | if (po->prot_hook.dev) { | 2464 | if (po->prot_hook.dev) { |
| 2455 | dev_put(po->prot_hook.dev); | 2465 | dev_put(po->prot_hook.dev); |
| 2456 | po->prot_hook.dev = NULL; | 2466 | po->prot_hook.dev = NULL; |
| @@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc | |||
| 2506 | 2516 | ||
| 2507 | spin_lock(&po->bind_lock); | 2517 | spin_lock(&po->bind_lock); |
| 2508 | unregister_prot_hook(sk, true); | 2518 | unregister_prot_hook(sk, true); |
| 2519 | |||
| 2509 | po->num = protocol; | 2520 | po->num = protocol; |
| 2510 | po->prot_hook.type = protocol; | 2521 | po->prot_hook.type = protocol; |
| 2511 | if (po->prot_hook.dev) | 2522 | if (po->prot_hook.dev) |
| 2512 | dev_put(po->prot_hook.dev); | 2523 | dev_put(po->prot_hook.dev); |
| 2513 | po->prot_hook.dev = dev; | ||
| 2514 | 2524 | ||
| 2525 | po->prot_hook.dev = dev; | ||
| 2515 | po->ifindex = dev ? dev->ifindex : 0; | 2526 | po->ifindex = dev ? dev->ifindex : 0; |
| 2516 | 2527 | ||
| 2528 | packet_cached_dev_assign(po, dev); | ||
| 2529 | |||
| 2517 | if (protocol == 0) | 2530 | if (protocol == 0) |
| 2518 | goto out_unlock; | 2531 | goto out_unlock; |
| 2519 | 2532 | ||
| @@ -2626,7 +2639,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, | |||
| 2626 | po = pkt_sk(sk); | 2639 | po = pkt_sk(sk); |
| 2627 | sk->sk_family = PF_PACKET; | 2640 | sk->sk_family = PF_PACKET; |
| 2628 | po->num = proto; | 2641 | po->num = proto; |
| 2629 | RCU_INIT_POINTER(po->cached_dev, NULL); | 2642 | |
| 2643 | packet_cached_dev_reset(po); | ||
| 2630 | 2644 | ||
| 2631 | sk->sk_destruct = packet_sock_destruct; | 2645 | sk->sk_destruct = packet_sock_destruct; |
| 2632 | sk_refcnt_debug_inc(sk); | 2646 | sk_refcnt_debug_inc(sk); |
| @@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifier_block *this, | |||
| 3337 | sk->sk_error_report(sk); | 3351 | sk->sk_error_report(sk); |
| 3338 | } | 3352 | } |
| 3339 | if (msg == NETDEV_UNREGISTER) { | 3353 | if (msg == NETDEV_UNREGISTER) { |
| 3354 | packet_cached_dev_reset(po); | ||
| 3340 | po->ifindex = -1; | 3355 | po->ifindex = -1; |
| 3341 | if (po->prot_hook.dev) | 3356 | if (po->prot_hook.dev) |
| 3342 | dev_put(po->prot_hook.dev); | 3357 | dev_put(po->prot_hook.dev); |
diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index e59094981175..37be6e226d1b 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c | |||
| @@ -552,9 +552,8 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
| 552 | && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { | 552 | && rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { |
| 553 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); | 553 | rds_cong_map_updated(conn->c_fcong, ~(u64) 0); |
| 554 | scat = &rm->data.op_sg[sg]; | 554 | scat = &rm->data.op_sg[sg]; |
| 555 | ret = sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; | 555 | ret = max_t(int, RDS_CONG_MAP_BYTES, scat->length); |
| 556 | ret = min_t(int, ret, scat->length - conn->c_xmit_data_off); | 556 | return sizeof(struct rds_header) + ret; |
| 557 | return ret; | ||
| 558 | } | 557 | } |
| 559 | 558 | ||
| 560 | /* FIXME we may overallocate here */ | 559 | /* FIXME we may overallocate here */ |
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index fd7072827a40..69cb848e8345 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
| @@ -270,6 +270,16 @@ int tcf_register_action(struct tc_action_ops *act) | |||
| 270 | { | 270 | { |
| 271 | struct tc_action_ops *a, **ap; | 271 | struct tc_action_ops *a, **ap; |
| 272 | 272 | ||
| 273 | /* Must supply act, dump, cleanup and init */ | ||
| 274 | if (!act->act || !act->dump || !act->cleanup || !act->init) | ||
| 275 | return -EINVAL; | ||
| 276 | |||
| 277 | /* Supply defaults */ | ||
| 278 | if (!act->lookup) | ||
| 279 | act->lookup = tcf_hash_search; | ||
| 280 | if (!act->walk) | ||
| 281 | act->walk = tcf_generic_walker; | ||
| 282 | |||
| 273 | write_lock(&act_mod_lock); | 283 | write_lock(&act_mod_lock); |
| 274 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { | 284 | for (ap = &act_base; (a = *ap) != NULL; ap = &a->next) { |
| 275 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { | 285 | if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { |
| @@ -381,7 +391,7 @@ int tcf_action_exec(struct sk_buff *skb, const struct tc_action *act, | |||
| 381 | } | 391 | } |
| 382 | while ((a = act) != NULL) { | 392 | while ((a = act) != NULL) { |
| 383 | repeat: | 393 | repeat: |
| 384 | if (a->ops && a->ops->act) { | 394 | if (a->ops) { |
| 385 | ret = a->ops->act(skb, a, res); | 395 | ret = a->ops->act(skb, a, res); |
| 386 | if (TC_MUNGED & skb->tc_verd) { | 396 | if (TC_MUNGED & skb->tc_verd) { |
| 387 | /* copied already, allow trampling */ | 397 | /* copied already, allow trampling */ |
| @@ -405,7 +415,7 @@ void tcf_action_destroy(struct tc_action *act, int bind) | |||
| 405 | struct tc_action *a; | 415 | struct tc_action *a; |
| 406 | 416 | ||
| 407 | for (a = act; a; a = act) { | 417 | for (a = act; a; a = act) { |
| 408 | if (a->ops && a->ops->cleanup) { | 418 | if (a->ops) { |
| 409 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) | 419 | if (a->ops->cleanup(a, bind) == ACT_P_DELETED) |
| 410 | module_put(a->ops->owner); | 420 | module_put(a->ops->owner); |
| 411 | act = act->next; | 421 | act = act->next; |
| @@ -424,7 +434,7 @@ tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
| 424 | { | 434 | { |
| 425 | int err = -EINVAL; | 435 | int err = -EINVAL; |
| 426 | 436 | ||
| 427 | if (a->ops == NULL || a->ops->dump == NULL) | 437 | if (a->ops == NULL) |
| 428 | return err; | 438 | return err; |
| 429 | return a->ops->dump(skb, a, bind, ref); | 439 | return a->ops->dump(skb, a, bind, ref); |
| 430 | } | 440 | } |
| @@ -436,7 +446,7 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
| 436 | unsigned char *b = skb_tail_pointer(skb); | 446 | unsigned char *b = skb_tail_pointer(skb); |
| 437 | struct nlattr *nest; | 447 | struct nlattr *nest; |
| 438 | 448 | ||
| 439 | if (a->ops == NULL || a->ops->dump == NULL) | 449 | if (a->ops == NULL) |
| 440 | return err; | 450 | return err; |
| 441 | 451 | ||
| 442 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) | 452 | if (nla_put_string(skb, TCA_KIND, a->ops->kind)) |
| @@ -723,8 +733,6 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) | |||
| 723 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); | 733 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); |
| 724 | if (a->ops == NULL) | 734 | if (a->ops == NULL) |
| 725 | goto err_free; | 735 | goto err_free; |
| 726 | if (a->ops->lookup == NULL) | ||
| 727 | goto err_mod; | ||
| 728 | err = -ENOENT; | 736 | err = -ENOENT; |
| 729 | if (a->ops->lookup(a, index) == 0) | 737 | if (a->ops->lookup(a, index) == 0) |
| 730 | goto err_mod; | 738 | goto err_mod; |
| @@ -1084,12 +1092,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1084 | memset(&a, 0, sizeof(struct tc_action)); | 1092 | memset(&a, 0, sizeof(struct tc_action)); |
| 1085 | a.ops = a_o; | 1093 | a.ops = a_o; |
| 1086 | 1094 | ||
| 1087 | if (a_o->walk == NULL) { | ||
| 1088 | WARN(1, "tc_dump_action: %s !capable of dumping table\n", | ||
| 1089 | a_o->kind); | ||
| 1090 | goto out_module_put; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, | 1095 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
| 1094 | cb->nlh->nlmsg_type, sizeof(*t), 0); | 1096 | cb->nlh->nlmsg_type, sizeof(*t), 0); |
| 1095 | if (!nlh) | 1097 | if (!nlh) |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 3a4c0caa1f7d..5c5edf56adbd 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
| @@ -585,9 +585,7 @@ static struct tc_action_ops act_csum_ops = { | |||
| 585 | .act = tcf_csum, | 585 | .act = tcf_csum, |
| 586 | .dump = tcf_csum_dump, | 586 | .dump = tcf_csum_dump, |
| 587 | .cleanup = tcf_csum_cleanup, | 587 | .cleanup = tcf_csum_cleanup, |
| 588 | .lookup = tcf_hash_search, | ||
| 589 | .init = tcf_csum_init, | 588 | .init = tcf_csum_init, |
| 590 | .walk = tcf_generic_walker | ||
| 591 | }; | 589 | }; |
| 592 | 590 | ||
| 593 | MODULE_DESCRIPTION("Checksum updating actions"); | 591 | MODULE_DESCRIPTION("Checksum updating actions"); |
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index fd2b3cff5fa2..5645a4d32abd 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
| @@ -206,9 +206,7 @@ static struct tc_action_ops act_gact_ops = { | |||
| 206 | .act = tcf_gact, | 206 | .act = tcf_gact, |
| 207 | .dump = tcf_gact_dump, | 207 | .dump = tcf_gact_dump, |
| 208 | .cleanup = tcf_gact_cleanup, | 208 | .cleanup = tcf_gact_cleanup, |
| 209 | .lookup = tcf_hash_search, | ||
| 210 | .init = tcf_gact_init, | 209 | .init = tcf_gact_init, |
| 211 | .walk = tcf_generic_walker | ||
| 212 | }; | 210 | }; |
| 213 | 211 | ||
| 214 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 212 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 60d88b6b9560..882a89762f77 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
| @@ -298,9 +298,7 @@ static struct tc_action_ops act_ipt_ops = { | |||
| 298 | .act = tcf_ipt, | 298 | .act = tcf_ipt, |
| 299 | .dump = tcf_ipt_dump, | 299 | .dump = tcf_ipt_dump, |
| 300 | .cleanup = tcf_ipt_cleanup, | 300 | .cleanup = tcf_ipt_cleanup, |
| 301 | .lookup = tcf_hash_search, | ||
| 302 | .init = tcf_ipt_init, | 301 | .init = tcf_ipt_init, |
| 303 | .walk = tcf_generic_walker | ||
| 304 | }; | 302 | }; |
| 305 | 303 | ||
| 306 | static struct tc_action_ops act_xt_ops = { | 304 | static struct tc_action_ops act_xt_ops = { |
| @@ -312,9 +310,7 @@ static struct tc_action_ops act_xt_ops = { | |||
| 312 | .act = tcf_ipt, | 310 | .act = tcf_ipt, |
| 313 | .dump = tcf_ipt_dump, | 311 | .dump = tcf_ipt_dump, |
| 314 | .cleanup = tcf_ipt_cleanup, | 312 | .cleanup = tcf_ipt_cleanup, |
| 315 | .lookup = tcf_hash_search, | ||
| 316 | .init = tcf_ipt_init, | 313 | .init = tcf_ipt_init, |
| 317 | .walk = tcf_generic_walker | ||
| 318 | }; | 314 | }; |
| 319 | 315 | ||
| 320 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); | 316 | MODULE_AUTHOR("Jamal Hadi Salim(2002-13)"); |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 977c10e0631b..252378121ce7 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
| @@ -271,9 +271,7 @@ static struct tc_action_ops act_mirred_ops = { | |||
| 271 | .act = tcf_mirred, | 271 | .act = tcf_mirred, |
| 272 | .dump = tcf_mirred_dump, | 272 | .dump = tcf_mirred_dump, |
| 273 | .cleanup = tcf_mirred_cleanup, | 273 | .cleanup = tcf_mirred_cleanup, |
| 274 | .lookup = tcf_hash_search, | ||
| 275 | .init = tcf_mirred_init, | 274 | .init = tcf_mirred_init, |
| 276 | .walk = tcf_generic_walker | ||
| 277 | }; | 275 | }; |
| 278 | 276 | ||
| 279 | MODULE_AUTHOR("Jamal Hadi Salim(2002)"); | 277 | MODULE_AUTHOR("Jamal Hadi Salim(2002)"); |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 876f0ef29694..6a15ace00241 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
| @@ -308,9 +308,7 @@ static struct tc_action_ops act_nat_ops = { | |||
| 308 | .act = tcf_nat, | 308 | .act = tcf_nat, |
| 309 | .dump = tcf_nat_dump, | 309 | .dump = tcf_nat_dump, |
| 310 | .cleanup = tcf_nat_cleanup, | 310 | .cleanup = tcf_nat_cleanup, |
| 311 | .lookup = tcf_hash_search, | ||
| 312 | .init = tcf_nat_init, | 311 | .init = tcf_nat_init, |
| 313 | .walk = tcf_generic_walker | ||
| 314 | }; | 312 | }; |
| 315 | 313 | ||
| 316 | MODULE_DESCRIPTION("Stateless NAT actions"); | 314 | MODULE_DESCRIPTION("Stateless NAT actions"); |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 7ed78c9e505c..03b67674169c 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
| @@ -243,9 +243,7 @@ static struct tc_action_ops act_pedit_ops = { | |||
| 243 | .act = tcf_pedit, | 243 | .act = tcf_pedit, |
| 244 | .dump = tcf_pedit_dump, | 244 | .dump = tcf_pedit_dump, |
| 245 | .cleanup = tcf_pedit_cleanup, | 245 | .cleanup = tcf_pedit_cleanup, |
| 246 | .lookup = tcf_hash_search, | ||
| 247 | .init = tcf_pedit_init, | 246 | .init = tcf_pedit_init, |
| 248 | .walk = tcf_generic_walker | ||
| 249 | }; | 247 | }; |
| 250 | 248 | ||
| 251 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); | 249 | MODULE_AUTHOR("Jamal Hadi Salim(2002-4)"); |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 272d8e924cf6..16a62c36928a 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
| @@ -407,7 +407,6 @@ static struct tc_action_ops act_police_ops = { | |||
| 407 | .act = tcf_act_police, | 407 | .act = tcf_act_police, |
| 408 | .dump = tcf_act_police_dump, | 408 | .dump = tcf_act_police_dump, |
| 409 | .cleanup = tcf_act_police_cleanup, | 409 | .cleanup = tcf_act_police_cleanup, |
| 410 | .lookup = tcf_hash_search, | ||
| 411 | .init = tcf_act_police_locate, | 410 | .init = tcf_act_police_locate, |
| 412 | .walk = tcf_act_police_walker | 411 | .walk = tcf_act_police_walker |
| 413 | }; | 412 | }; |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 7725eb4ab756..31157d3e729c 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
| @@ -201,7 +201,6 @@ static struct tc_action_ops act_simp_ops = { | |||
| 201 | .dump = tcf_simp_dump, | 201 | .dump = tcf_simp_dump, |
| 202 | .cleanup = tcf_simp_cleanup, | 202 | .cleanup = tcf_simp_cleanup, |
| 203 | .init = tcf_simp_init, | 203 | .init = tcf_simp_init, |
| 204 | .walk = tcf_generic_walker, | ||
| 205 | }; | 204 | }; |
| 206 | 205 | ||
| 207 | MODULE_AUTHOR("Jamal Hadi Salim(2005)"); | 206 | MODULE_AUTHOR("Jamal Hadi Salim(2005)"); |
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index cb4221171f93..35ea643b4325 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
| @@ -203,7 +203,6 @@ static struct tc_action_ops act_skbedit_ops = { | |||
| 203 | .dump = tcf_skbedit_dump, | 203 | .dump = tcf_skbedit_dump, |
| 204 | .cleanup = tcf_skbedit_cleanup, | 204 | .cleanup = tcf_skbedit_cleanup, |
| 205 | .init = tcf_skbedit_init, | 205 | .init = tcf_skbedit_init, |
| 206 | .walk = tcf_generic_walker, | ||
| 207 | }; | 206 | }; |
| 208 | 207 | ||
| 209 | MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); | 208 | MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>"); |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 0e1e38b40025..717b2108f852 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
| @@ -1477,11 +1477,22 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1477 | sch_tree_lock(sch); | 1477 | sch_tree_lock(sch); |
| 1478 | } | 1478 | } |
| 1479 | 1479 | ||
| 1480 | rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0; | ||
| 1481 | |||
| 1482 | ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0; | ||
| 1483 | |||
| 1484 | psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64); | ||
| 1485 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64); | ||
| 1486 | |||
| 1480 | /* it used to be a nasty bug here, we have to check that node | 1487 | /* it used to be a nasty bug here, we have to check that node |
| 1481 | * is really leaf before changing cl->un.leaf ! | 1488 | * is really leaf before changing cl->un.leaf ! |
| 1482 | */ | 1489 | */ |
| 1483 | if (!cl->level) { | 1490 | if (!cl->level) { |
| 1484 | cl->quantum = hopt->rate.rate / q->rate2quantum; | 1491 | u64 quantum = cl->rate.rate_bytes_ps; |
| 1492 | |||
| 1493 | do_div(quantum, q->rate2quantum); | ||
| 1494 | cl->quantum = min_t(u64, quantum, INT_MAX); | ||
| 1495 | |||
| 1485 | if (!hopt->quantum && cl->quantum < 1000) { | 1496 | if (!hopt->quantum && cl->quantum < 1000) { |
| 1486 | pr_warning( | 1497 | pr_warning( |
| 1487 | "HTB: quantum of class %X is small. Consider r2q change.\n", | 1498 | "HTB: quantum of class %X is small. Consider r2q change.\n", |
| @@ -1500,13 +1511,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
| 1500 | cl->prio = TC_HTB_NUMPRIO - 1; | 1511 | cl->prio = TC_HTB_NUMPRIO - 1; |
| 1501 | } | 1512 | } |
| 1502 | 1513 | ||
| 1503 | rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0; | ||
| 1504 | |||
| 1505 | ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0; | ||
| 1506 | |||
| 1507 | psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64); | ||
| 1508 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64); | ||
| 1509 | |||
| 1510 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); | 1514 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); |
| 1511 | cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); | 1515 | cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); |
| 1512 | 1516 | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index a6090051c5db..887e672f9d7d 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
| @@ -118,6 +118,32 @@ struct tbf_sched_data { | |||
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | 120 | ||
| 121 | /* Time to Length, convert time in ns to length in bytes | ||
| 122 | * to determinate how many bytes can be sent in given time. | ||
| 123 | */ | ||
| 124 | static u64 psched_ns_t2l(const struct psched_ratecfg *r, | ||
| 125 | u64 time_in_ns) | ||
| 126 | { | ||
| 127 | /* The formula is : | ||
| 128 | * len = (time_in_ns * r->rate_bytes_ps) / NSEC_PER_SEC | ||
| 129 | */ | ||
| 130 | u64 len = time_in_ns * r->rate_bytes_ps; | ||
| 131 | |||
| 132 | do_div(len, NSEC_PER_SEC); | ||
| 133 | |||
| 134 | if (unlikely(r->linklayer == TC_LINKLAYER_ATM)) { | ||
| 135 | do_div(len, 53); | ||
| 136 | len = len * 48; | ||
| 137 | } | ||
| 138 | |||
| 139 | if (len > r->overhead) | ||
| 140 | len -= r->overhead; | ||
| 141 | else | ||
| 142 | len = 0; | ||
| 143 | |||
| 144 | return len; | ||
| 145 | } | ||
| 146 | |||
| 121 | /* | 147 | /* |
| 122 | * Return length of individual segments of a gso packet, | 148 | * Return length of individual segments of a gso packet, |
| 123 | * including all headers (MAC, IP, TCP/UDP) | 149 | * including all headers (MAC, IP, TCP/UDP) |
| @@ -289,10 +315,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 289 | struct tbf_sched_data *q = qdisc_priv(sch); | 315 | struct tbf_sched_data *q = qdisc_priv(sch); |
| 290 | struct nlattr *tb[TCA_TBF_MAX + 1]; | 316 | struct nlattr *tb[TCA_TBF_MAX + 1]; |
| 291 | struct tc_tbf_qopt *qopt; | 317 | struct tc_tbf_qopt *qopt; |
| 292 | struct qdisc_rate_table *rtab = NULL; | ||
| 293 | struct qdisc_rate_table *ptab = NULL; | ||
| 294 | struct Qdisc *child = NULL; | 318 | struct Qdisc *child = NULL; |
| 295 | int max_size, n; | 319 | struct psched_ratecfg rate; |
| 320 | struct psched_ratecfg peak; | ||
| 321 | u64 max_size; | ||
| 322 | s64 buffer, mtu; | ||
| 296 | u64 rate64 = 0, prate64 = 0; | 323 | u64 rate64 = 0, prate64 = 0; |
| 297 | 324 | ||
| 298 | err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy); | 325 | err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy); |
| @@ -304,38 +331,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 304 | goto done; | 331 | goto done; |
| 305 | 332 | ||
| 306 | qopt = nla_data(tb[TCA_TBF_PARMS]); | 333 | qopt = nla_data(tb[TCA_TBF_PARMS]); |
| 307 | rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]); | 334 | if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE) |
| 308 | if (rtab == NULL) | 335 | qdisc_put_rtab(qdisc_get_rtab(&qopt->rate, |
| 309 | goto done; | 336 | tb[TCA_TBF_RTAB])); |
| 310 | |||
| 311 | if (qopt->peakrate.rate) { | ||
| 312 | if (qopt->peakrate.rate > qopt->rate.rate) | ||
| 313 | ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]); | ||
| 314 | if (ptab == NULL) | ||
| 315 | goto done; | ||
| 316 | } | ||
| 317 | |||
| 318 | for (n = 0; n < 256; n++) | ||
| 319 | if (rtab->data[n] > qopt->buffer) | ||
| 320 | break; | ||
| 321 | max_size = (n << qopt->rate.cell_log) - 1; | ||
| 322 | if (ptab) { | ||
| 323 | int size; | ||
| 324 | |||
| 325 | for (n = 0; n < 256; n++) | ||
| 326 | if (ptab->data[n] > qopt->mtu) | ||
| 327 | break; | ||
| 328 | size = (n << qopt->peakrate.cell_log) - 1; | ||
| 329 | if (size < max_size) | ||
| 330 | max_size = size; | ||
| 331 | } | ||
| 332 | if (max_size < 0) | ||
| 333 | goto done; | ||
| 334 | 337 | ||
| 335 | if (max_size < psched_mtu(qdisc_dev(sch))) | 338 | if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE) |
| 336 | pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n", | 339 | qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate, |
| 337 | max_size, qdisc_dev(sch)->name, | 340 | tb[TCA_TBF_PTAB])); |
| 338 | psched_mtu(qdisc_dev(sch))); | ||
| 339 | 341 | ||
| 340 | if (q->qdisc != &noop_qdisc) { | 342 | if (q->qdisc != &noop_qdisc) { |
| 341 | err = fifo_set_limit(q->qdisc, qopt->limit); | 343 | err = fifo_set_limit(q->qdisc, qopt->limit); |
| @@ -349,6 +351,39 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 349 | } | 351 | } |
| 350 | } | 352 | } |
| 351 | 353 | ||
| 354 | buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U); | ||
| 355 | mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); | ||
| 356 | |||
| 357 | if (tb[TCA_TBF_RATE64]) | ||
| 358 | rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); | ||
| 359 | psched_ratecfg_precompute(&rate, &qopt->rate, rate64); | ||
| 360 | |||
| 361 | max_size = min_t(u64, psched_ns_t2l(&rate, buffer), ~0U); | ||
| 362 | |||
| 363 | if (qopt->peakrate.rate) { | ||
| 364 | if (tb[TCA_TBF_PRATE64]) | ||
| 365 | prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]); | ||
| 366 | psched_ratecfg_precompute(&peak, &qopt->peakrate, prate64); | ||
| 367 | if (peak.rate_bytes_ps <= rate.rate_bytes_ps) { | ||
| 368 | pr_warn_ratelimited("sch_tbf: peakrate %llu is lower than or equals to rate %llu !\n", | ||
| 369 | peak.rate_bytes_ps, rate.rate_bytes_ps); | ||
| 370 | err = -EINVAL; | ||
| 371 | goto done; | ||
| 372 | } | ||
| 373 | |||
| 374 | max_size = min_t(u64, max_size, psched_ns_t2l(&peak, mtu)); | ||
| 375 | } | ||
| 376 | |||
| 377 | if (max_size < psched_mtu(qdisc_dev(sch))) | ||
| 378 | pr_warn_ratelimited("sch_tbf: burst %llu is lower than device %s mtu (%u) !\n", | ||
| 379 | max_size, qdisc_dev(sch)->name, | ||
| 380 | psched_mtu(qdisc_dev(sch))); | ||
| 381 | |||
| 382 | if (!max_size) { | ||
| 383 | err = -EINVAL; | ||
| 384 | goto done; | ||
| 385 | } | ||
| 386 | |||
| 352 | sch_tree_lock(sch); | 387 | sch_tree_lock(sch); |
| 353 | if (child) { | 388 | if (child) { |
| 354 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | 389 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); |
| @@ -362,13 +397,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 362 | q->tokens = q->buffer; | 397 | q->tokens = q->buffer; |
| 363 | q->ptokens = q->mtu; | 398 | q->ptokens = q->mtu; |
| 364 | 399 | ||
| 365 | if (tb[TCA_TBF_RATE64]) | 400 | memcpy(&q->rate, &rate, sizeof(struct psched_ratecfg)); |
| 366 | rate64 = nla_get_u64(tb[TCA_TBF_RATE64]); | 401 | if (qopt->peakrate.rate) { |
| 367 | psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64); | 402 | memcpy(&q->peak, &peak, sizeof(struct psched_ratecfg)); |
| 368 | if (ptab) { | ||
| 369 | if (tb[TCA_TBF_PRATE64]) | ||
| 370 | prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]); | ||
| 371 | psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64); | ||
| 372 | q->peak_present = true; | 403 | q->peak_present = true; |
| 373 | } else { | 404 | } else { |
| 374 | q->peak_present = false; | 405 | q->peak_present = false; |
| @@ -377,10 +408,6 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 377 | sch_tree_unlock(sch); | 408 | sch_tree_unlock(sch); |
| 378 | err = 0; | 409 | err = 0; |
| 379 | done: | 410 | done: |
| 380 | if (rtab) | ||
| 381 | qdisc_put_rtab(rtab); | ||
| 382 | if (ptab) | ||
| 383 | qdisc_put_rtab(ptab); | ||
| 384 | return err; | 411 | return err; |
| 385 | } | 412 | } |
| 386 | 413 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 68a27f9796d2..31ed008c8e13 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -154,8 +154,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 154 | 154 | ||
| 155 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; | 155 | asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
| 156 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; | 156 | asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay; |
| 157 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | 157 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; |
| 158 | min_t(unsigned long, sp->autoclose, net->sctp.max_autoclose) * HZ; | ||
| 159 | 158 | ||
| 160 | /* Initializes the timers */ | 159 | /* Initializes the timers */ |
| 161 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) | 160 | for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) |
| @@ -291,8 +290,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 291 | asoc->peer.ipv6_address = 1; | 290 | asoc->peer.ipv6_address = 1; |
| 292 | INIT_LIST_HEAD(&asoc->asocs); | 291 | INIT_LIST_HEAD(&asoc->asocs); |
| 293 | 292 | ||
| 294 | asoc->autoclose = sp->autoclose; | ||
| 295 | |||
| 296 | asoc->default_stream = sp->default_stream; | 293 | asoc->default_stream = sp->default_stream; |
| 297 | asoc->default_ppid = sp->default_ppid; | 294 | asoc->default_ppid = sp->default_ppid; |
| 298 | asoc->default_flags = sp->default_flags; | 295 | asoc->default_flags = sp->default_flags; |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 0e2644d0a773..0fb140f8f088 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -581,7 +581,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 581 | unsigned long timeout; | 581 | unsigned long timeout; |
| 582 | 582 | ||
| 583 | /* Restart the AUTOCLOSE timer when sending data. */ | 583 | /* Restart the AUTOCLOSE timer when sending data. */ |
| 584 | if (sctp_state(asoc, ESTABLISHED) && asoc->autoclose) { | 584 | if (sctp_state(asoc, ESTABLISHED) && |
| 585 | asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { | ||
| 585 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 586 | timer = &asoc->timers[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
| 586 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; | 587 | timeout = asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]; |
| 587 | 588 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index dfe3f36ff2aa..a26065be7289 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -820,7 +820,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
| 820 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); | 820 | SCTP_INC_STATS(net, SCTP_MIB_PASSIVEESTABS); |
| 821 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 821 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
| 822 | 822 | ||
| 823 | if (new_asoc->autoclose) | 823 | if (new_asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 824 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 824 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
| 825 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 825 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 826 | 826 | ||
| @@ -908,7 +908,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(struct net *net, | |||
| 908 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); | 908 | SCTP_INC_STATS(net, SCTP_MIB_CURRESTAB); |
| 909 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); | 909 | SCTP_INC_STATS(net, SCTP_MIB_ACTIVEESTABS); |
| 910 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); | 910 | sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START, SCTP_NULL()); |
| 911 | if (asoc->autoclose) | 911 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 912 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 912 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, |
| 913 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 913 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 914 | 914 | ||
| @@ -2970,7 +2970,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, | |||
| 2970 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) | 2970 | if (chunk->chunk_hdr->flags & SCTP_DATA_SACK_IMM) |
| 2971 | force = SCTP_FORCE(); | 2971 | force = SCTP_FORCE(); |
| 2972 | 2972 | ||
| 2973 | if (asoc->autoclose) { | 2973 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
| 2974 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 2974 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 2975 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 2975 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 2976 | } | 2976 | } |
| @@ -3878,7 +3878,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(struct net *net, | |||
| 3878 | SCTP_CHUNK(chunk)); | 3878 | SCTP_CHUNK(chunk)); |
| 3879 | 3879 | ||
| 3880 | /* Count this as receiving DATA. */ | 3880 | /* Count this as receiving DATA. */ |
| 3881 | if (asoc->autoclose) { | 3881 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) { |
| 3882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 3882 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 3883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 3883 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 3884 | } | 3884 | } |
| @@ -5267,7 +5267,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
| 5267 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5267 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 5268 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5268 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
| 5269 | 5269 | ||
| 5270 | if (asoc->autoclose) | 5270 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 5271 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5271 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
| 5272 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5272 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 5273 | 5273 | ||
| @@ -5346,7 +5346,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown_ack( | |||
| 5346 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 5346 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 5347 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); | 5347 | SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); |
| 5348 | 5348 | ||
| 5349 | if (asoc->autoclose) | 5349 | if (asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE]) |
| 5350 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, | 5350 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, |
| 5351 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); | 5351 | SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); |
| 5352 | 5352 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 72046b9729a8..42b709c95cf3 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -2196,6 +2196,7 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
| 2196 | unsigned int optlen) | 2196 | unsigned int optlen) |
| 2197 | { | 2197 | { |
| 2198 | struct sctp_sock *sp = sctp_sk(sk); | 2198 | struct sctp_sock *sp = sctp_sk(sk); |
| 2199 | struct net *net = sock_net(sk); | ||
| 2199 | 2200 | ||
| 2200 | /* Applicable to UDP-style socket only */ | 2201 | /* Applicable to UDP-style socket only */ |
| 2201 | if (sctp_style(sk, TCP)) | 2202 | if (sctp_style(sk, TCP)) |
| @@ -2205,6 +2206,9 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
| 2205 | if (copy_from_user(&sp->autoclose, optval, optlen)) | 2206 | if (copy_from_user(&sp->autoclose, optval, optlen)) |
| 2206 | return -EFAULT; | 2207 | return -EFAULT; |
| 2207 | 2208 | ||
| 2209 | if (sp->autoclose > net->sctp.max_autoclose) | ||
| 2210 | sp->autoclose = net->sctp.max_autoclose; | ||
| 2211 | |||
| 2208 | return 0; | 2212 | return 0; |
| 2209 | } | 2213 | } |
| 2210 | 2214 | ||
| @@ -2811,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
| 2811 | { | 2815 | { |
| 2812 | struct sctp_rtoinfo rtoinfo; | 2816 | struct sctp_rtoinfo rtoinfo; |
| 2813 | struct sctp_association *asoc; | 2817 | struct sctp_association *asoc; |
| 2818 | unsigned long rto_min, rto_max; | ||
| 2819 | struct sctp_sock *sp = sctp_sk(sk); | ||
| 2814 | 2820 | ||
| 2815 | if (optlen != sizeof (struct sctp_rtoinfo)) | 2821 | if (optlen != sizeof (struct sctp_rtoinfo)) |
| 2816 | return -EINVAL; | 2822 | return -EINVAL; |
| @@ -2824,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne | |||
| 2824 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) | 2830 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) |
| 2825 | return -EINVAL; | 2831 | return -EINVAL; |
| 2826 | 2832 | ||
| 2833 | rto_max = rtoinfo.srto_max; | ||
| 2834 | rto_min = rtoinfo.srto_min; | ||
| 2835 | |||
| 2836 | if (rto_max) | ||
| 2837 | rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max; | ||
| 2838 | else | ||
| 2839 | rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max; | ||
| 2840 | |||
| 2841 | if (rto_min) | ||
| 2842 | rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min; | ||
| 2843 | else | ||
| 2844 | rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min; | ||
| 2845 | |||
| 2846 | if (rto_min > rto_max) | ||
| 2847 | return -EINVAL; | ||
| 2848 | |||
| 2827 | if (asoc) { | 2849 | if (asoc) { |
| 2828 | if (rtoinfo.srto_initial != 0) | 2850 | if (rtoinfo.srto_initial != 0) |
| 2829 | asoc->rto_initial = | 2851 | asoc->rto_initial = |
| 2830 | msecs_to_jiffies(rtoinfo.srto_initial); | 2852 | msecs_to_jiffies(rtoinfo.srto_initial); |
| 2831 | if (rtoinfo.srto_max != 0) | 2853 | asoc->rto_max = rto_max; |
| 2832 | asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max); | 2854 | asoc->rto_min = rto_min; |
| 2833 | if (rtoinfo.srto_min != 0) | ||
| 2834 | asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min); | ||
| 2835 | } else { | 2855 | } else { |
| 2836 | /* If there is no association or the association-id = 0 | 2856 | /* If there is no association or the association-id = 0 |
| 2837 | * set the values to the endpoint. | 2857 | * set the values to the endpoint. |
| 2838 | */ | 2858 | */ |
| 2839 | struct sctp_sock *sp = sctp_sk(sk); | ||
| 2840 | |||
| 2841 | if (rtoinfo.srto_initial != 0) | 2859 | if (rtoinfo.srto_initial != 0) |
| 2842 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; | 2860 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; |
| 2843 | if (rtoinfo.srto_max != 0) | 2861 | sp->rtoinfo.srto_max = rto_max; |
| 2844 | sp->rtoinfo.srto_max = rtoinfo.srto_max; | 2862 | sp->rtoinfo.srto_min = rto_min; |
| 2845 | if (rtoinfo.srto_min != 0) | ||
| 2846 | sp->rtoinfo.srto_min = rtoinfo.srto_min; | ||
| 2847 | } | 2863 | } |
| 2848 | 2864 | ||
| 2849 | return 0; | 2865 | return 0; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 6b36561a1b3b..b0565afb61c7 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
| @@ -56,11 +56,16 @@ extern long sysctl_sctp_mem[3]; | |||
| 56 | extern int sysctl_sctp_rmem[3]; | 56 | extern int sysctl_sctp_rmem[3]; |
| 57 | extern int sysctl_sctp_wmem[3]; | 57 | extern int sysctl_sctp_wmem[3]; |
| 58 | 58 | ||
| 59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 59 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
| 60 | int write, | 60 | void __user *buffer, size_t *lenp, |
| 61 | loff_t *ppos); | ||
| 62 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
| 63 | void __user *buffer, size_t *lenp, | ||
| 64 | loff_t *ppos); | ||
| 65 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
| 61 | void __user *buffer, size_t *lenp, | 66 | void __user *buffer, size_t *lenp, |
| 62 | |||
| 63 | loff_t *ppos); | 67 | loff_t *ppos); |
| 68 | |||
| 64 | static struct ctl_table sctp_table[] = { | 69 | static struct ctl_table sctp_table[] = { |
| 65 | { | 70 | { |
| 66 | .procname = "sctp_mem", | 71 | .procname = "sctp_mem", |
| @@ -102,17 +107,17 @@ static struct ctl_table sctp_net_table[] = { | |||
| 102 | .data = &init_net.sctp.rto_min, | 107 | .data = &init_net.sctp.rto_min, |
| 103 | .maxlen = sizeof(unsigned int), | 108 | .maxlen = sizeof(unsigned int), |
| 104 | .mode = 0644, | 109 | .mode = 0644, |
| 105 | .proc_handler = proc_dointvec_minmax, | 110 | .proc_handler = proc_sctp_do_rto_min, |
| 106 | .extra1 = &one, | 111 | .extra1 = &one, |
| 107 | .extra2 = &timer_max | 112 | .extra2 = &init_net.sctp.rto_max |
| 108 | }, | 113 | }, |
| 109 | { | 114 | { |
| 110 | .procname = "rto_max", | 115 | .procname = "rto_max", |
| 111 | .data = &init_net.sctp.rto_max, | 116 | .data = &init_net.sctp.rto_max, |
| 112 | .maxlen = sizeof(unsigned int), | 117 | .maxlen = sizeof(unsigned int), |
| 113 | .mode = 0644, | 118 | .mode = 0644, |
| 114 | .proc_handler = proc_dointvec_minmax, | 119 | .proc_handler = proc_sctp_do_rto_max, |
| 115 | .extra1 = &one, | 120 | .extra1 = &init_net.sctp.rto_min, |
| 116 | .extra2 = &timer_max | 121 | .extra2 = &timer_max |
| 117 | }, | 122 | }, |
| 118 | { | 123 | { |
| @@ -294,8 +299,7 @@ static struct ctl_table sctp_net_table[] = { | |||
| 294 | { /* sentinel */ } | 299 | { /* sentinel */ } |
| 295 | }; | 300 | }; |
| 296 | 301 | ||
| 297 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | 302 | static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, |
| 298 | int write, | ||
| 299 | void __user *buffer, size_t *lenp, | 303 | void __user *buffer, size_t *lenp, |
| 300 | loff_t *ppos) | 304 | loff_t *ppos) |
| 301 | { | 305 | { |
| @@ -342,6 +346,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, | |||
| 342 | return ret; | 346 | return ret; |
| 343 | } | 347 | } |
| 344 | 348 | ||
| 349 | static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | ||
| 350 | void __user *buffer, size_t *lenp, | ||
| 351 | loff_t *ppos) | ||
| 352 | { | ||
| 353 | struct net *net = current->nsproxy->net_ns; | ||
| 354 | int new_value; | ||
| 355 | struct ctl_table tbl; | ||
| 356 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
| 357 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
| 358 | int ret; | ||
| 359 | |||
| 360 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
| 361 | tbl.maxlen = sizeof(unsigned int); | ||
| 362 | |||
| 363 | if (write) | ||
| 364 | tbl.data = &new_value; | ||
| 365 | else | ||
| 366 | tbl.data = &net->sctp.rto_min; | ||
| 367 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
| 368 | if (write) { | ||
| 369 | if (ret || new_value > max || new_value < min) | ||
| 370 | return -EINVAL; | ||
| 371 | net->sctp.rto_min = new_value; | ||
| 372 | } | ||
| 373 | return ret; | ||
| 374 | } | ||
| 375 | |||
| 376 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | ||
| 377 | void __user *buffer, size_t *lenp, | ||
| 378 | loff_t *ppos) | ||
| 379 | { | ||
| 380 | struct net *net = current->nsproxy->net_ns; | ||
| 381 | int new_value; | ||
| 382 | struct ctl_table tbl; | ||
| 383 | unsigned int min = *(unsigned int *) ctl->extra1; | ||
| 384 | unsigned int max = *(unsigned int *) ctl->extra2; | ||
| 385 | int ret; | ||
| 386 | |||
| 387 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
| 388 | tbl.maxlen = sizeof(unsigned int); | ||
| 389 | |||
| 390 | if (write) | ||
| 391 | tbl.data = &new_value; | ||
| 392 | else | ||
| 393 | tbl.data = &net->sctp.rto_max; | ||
| 394 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
| 395 | if (write) { | ||
| 396 | if (ret || new_value > max || new_value < min) | ||
| 397 | return -EINVAL; | ||
| 398 | net->sctp.rto_max = new_value; | ||
| 399 | } | ||
| 400 | return ret; | ||
| 401 | } | ||
| 402 | |||
| 345 | int sctp_sysctl_net_register(struct net *net) | 403 | int sctp_sysctl_net_register(struct net *net) |
| 346 | { | 404 | { |
| 347 | struct ctl_table *table; | 405 | struct ctl_table *table; |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index e332efb124cc..efc46ffed1fd 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -573,7 +573,7 @@ void sctp_transport_burst_limited(struct sctp_transport *t) | |||
| 573 | u32 old_cwnd = t->cwnd; | 573 | u32 old_cwnd = t->cwnd; |
| 574 | u32 max_burst_bytes; | 574 | u32 max_burst_bytes; |
| 575 | 575 | ||
| 576 | if (t->burst_limited) | 576 | if (t->burst_limited || asoc->max_burst == 0) |
| 577 | return; | 577 | return; |
| 578 | 578 | ||
| 579 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); | 579 | max_burst_bytes = t->flight_size + (asoc->max_burst * asoc->pathmtu); |
diff --git a/net/tipc/core.c b/net/tipc/core.c index fd4eeeaa972a..c6d3f75a9e1b 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
| @@ -113,7 +113,6 @@ err: | |||
| 113 | static void tipc_core_stop(void) | 113 | static void tipc_core_stop(void) |
| 114 | { | 114 | { |
| 115 | tipc_netlink_stop(); | 115 | tipc_netlink_stop(); |
| 116 | tipc_handler_stop(); | ||
| 117 | tipc_cfg_stop(); | 116 | tipc_cfg_stop(); |
| 118 | tipc_subscr_stop(); | 117 | tipc_subscr_stop(); |
| 119 | tipc_nametbl_stop(); | 118 | tipc_nametbl_stop(); |
| @@ -146,9 +145,10 @@ static int tipc_core_start(void) | |||
| 146 | res = tipc_subscr_start(); | 145 | res = tipc_subscr_start(); |
| 147 | if (!res) | 146 | if (!res) |
| 148 | res = tipc_cfg_init(); | 147 | res = tipc_cfg_init(); |
| 149 | if (res) | 148 | if (res) { |
| 149 | tipc_handler_stop(); | ||
| 150 | tipc_core_stop(); | 150 | tipc_core_stop(); |
| 151 | 151 | } | |
| 152 | return res; | 152 | return res; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| @@ -178,6 +178,7 @@ static int __init tipc_init(void) | |||
| 178 | 178 | ||
| 179 | static void __exit tipc_exit(void) | 179 | static void __exit tipc_exit(void) |
| 180 | { | 180 | { |
| 181 | tipc_handler_stop(); | ||
| 181 | tipc_core_stop_net(); | 182 | tipc_core_stop_net(); |
| 182 | tipc_core_stop(); | 183 | tipc_core_stop(); |
| 183 | pr_info("Deactivated\n"); | 184 | pr_info("Deactivated\n"); |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index b36f0fcd9bdf..e4bc8a296744 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
| @@ -56,12 +56,13 @@ unsigned int tipc_k_signal(Handler routine, unsigned long argument) | |||
| 56 | { | 56 | { |
| 57 | struct queue_item *item; | 57 | struct queue_item *item; |
| 58 | 58 | ||
| 59 | spin_lock_bh(&qitem_lock); | ||
| 59 | if (!handler_enabled) { | 60 | if (!handler_enabled) { |
| 60 | pr_err("Signal request ignored by handler\n"); | 61 | pr_err("Signal request ignored by handler\n"); |
| 62 | spin_unlock_bh(&qitem_lock); | ||
| 61 | return -ENOPROTOOPT; | 63 | return -ENOPROTOOPT; |
| 62 | } | 64 | } |
| 63 | 65 | ||
| 64 | spin_lock_bh(&qitem_lock); | ||
| 65 | item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); | 66 | item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); |
| 66 | if (!item) { | 67 | if (!item) { |
| 67 | pr_err("Signal queue out of memory\n"); | 68 | pr_err("Signal queue out of memory\n"); |
| @@ -112,10 +113,14 @@ void tipc_handler_stop(void) | |||
| 112 | struct list_head *l, *n; | 113 | struct list_head *l, *n; |
| 113 | struct queue_item *item; | 114 | struct queue_item *item; |
| 114 | 115 | ||
| 115 | if (!handler_enabled) | 116 | spin_lock_bh(&qitem_lock); |
| 117 | if (!handler_enabled) { | ||
| 118 | spin_unlock_bh(&qitem_lock); | ||
| 116 | return; | 119 | return; |
| 117 | 120 | } | |
| 118 | handler_enabled = 0; | 121 | handler_enabled = 0; |
| 122 | spin_unlock_bh(&qitem_lock); | ||
| 123 | |||
| 119 | tasklet_kill(&tipc_tasklet); | 124 | tasklet_kill(&tipc_tasklet); |
| 120 | 125 | ||
| 121 | spin_lock_bh(&qitem_lock); | 126 | spin_lock_bh(&qitem_lock); |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 01625ccc3ae6..a0ca162e5bd5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -530,13 +530,17 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, | |||
| 530 | static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, | 530 | static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, |
| 531 | struct msghdr *, size_t, int); | 531 | struct msghdr *, size_t, int); |
| 532 | 532 | ||
| 533 | static void unix_set_peek_off(struct sock *sk, int val) | 533 | static int unix_set_peek_off(struct sock *sk, int val) |
| 534 | { | 534 | { |
| 535 | struct unix_sock *u = unix_sk(sk); | 535 | struct unix_sock *u = unix_sk(sk); |
| 536 | 536 | ||
| 537 | mutex_lock(&u->readlock); | 537 | if (mutex_lock_interruptible(&u->readlock)) |
| 538 | return -EINTR; | ||
| 539 | |||
| 538 | sk->sk_peek_off = val; | 540 | sk->sk_peek_off = val; |
| 539 | mutex_unlock(&u->readlock); | 541 | mutex_unlock(&u->readlock); |
| 542 | |||
| 543 | return 0; | ||
| 540 | } | 544 | } |
| 541 | 545 | ||
| 542 | 546 | ||
diff --git a/net/wireless/core.c b/net/wireless/core.c index aff959e5a1b3..52b865fb7351 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -451,6 +451,15 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 451 | int i; | 451 | int i; |
| 452 | u16 ifmodes = wiphy->interface_modes; | 452 | u16 ifmodes = wiphy->interface_modes; |
| 453 | 453 | ||
| 454 | /* support for 5/10 MHz is broken due to nl80211 API mess - disable */ | ||
| 455 | wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ; | ||
| 456 | |||
| 457 | /* | ||
| 458 | * There are major locking problems in nl80211/mac80211 for CSA, | ||
| 459 | * disable for all drivers until this has been reworked. | ||
| 460 | */ | ||
| 461 | wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH; | ||
| 462 | |||
| 454 | #ifdef CONFIG_PM | 463 | #ifdef CONFIG_PM |
| 455 | if (WARN_ON(wiphy->wowlan && | 464 | if (WARN_ON(wiphy->wowlan && |
| 456 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | 465 | (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 9d797df56649..89737ee2669a 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
| @@ -262,7 +262,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
| 262 | 262 | ||
| 263 | /* try to find an IBSS channel if none requested ... */ | 263 | /* try to find an IBSS channel if none requested ... */ |
| 264 | if (!wdev->wext.ibss.chandef.chan) { | 264 | if (!wdev->wext.ibss.chandef.chan) { |
| 265 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 265 | struct ieee80211_channel *new_chan = NULL; |
| 266 | 266 | ||
| 267 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 267 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
| 268 | struct ieee80211_supported_band *sband; | 268 | struct ieee80211_supported_band *sband; |
| @@ -278,18 +278,19 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
| 278 | continue; | 278 | continue; |
| 279 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 279 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
| 280 | continue; | 280 | continue; |
| 281 | wdev->wext.ibss.chandef.chan = chan; | 281 | new_chan = chan; |
| 282 | wdev->wext.ibss.chandef.center_freq1 = | ||
| 283 | chan->center_freq; | ||
| 284 | break; | 282 | break; |
| 285 | } | 283 | } |
| 286 | 284 | ||
| 287 | if (wdev->wext.ibss.chandef.chan) | 285 | if (new_chan) |
| 288 | break; | 286 | break; |
| 289 | } | 287 | } |
| 290 | 288 | ||
| 291 | if (!wdev->wext.ibss.chandef.chan) | 289 | if (!new_chan) |
| 292 | return -EINVAL; | 290 | return -EINVAL; |
| 291 | |||
| 292 | cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan, | ||
| 293 | NL80211_CHAN_NO_HT); | ||
| 293 | } | 294 | } |
| 294 | 295 | ||
| 295 | /* don't join -- SSID is not there */ | 296 | /* don't join -- SSID is not there */ |
| @@ -363,9 +364,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
| 363 | return err; | 364 | return err; |
| 364 | 365 | ||
| 365 | if (chan) { | 366 | if (chan) { |
| 366 | wdev->wext.ibss.chandef.chan = chan; | 367 | cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan, |
| 367 | wdev->wext.ibss.chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 368 | NL80211_CHAN_NO_HT); |
| 368 | wdev->wext.ibss.chandef.center_freq1 = freq; | ||
| 369 | wdev->wext.ibss.channel_fixed = true; | 369 | wdev->wext.ibss.channel_fixed = true; |
| 370 | } else { | 370 | } else { |
| 371 | /* cfg80211_ibss_wext_join will pick one if needed */ | 371 | /* cfg80211_ibss_wext_join will pick one if needed */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a1eb21073176..138dc3bb8b67 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -2687,7 +2687,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | |||
| 2687 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 2687 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
| 2688 | NL80211_CMD_NEW_KEY); | 2688 | NL80211_CMD_NEW_KEY); |
| 2689 | if (!hdr) | 2689 | if (!hdr) |
| 2690 | return -ENOBUFS; | 2690 | goto nla_put_failure; |
| 2691 | 2691 | ||
| 2692 | cookie.msg = msg; | 2692 | cookie.msg = msg; |
| 2693 | cookie.idx = key_idx; | 2693 | cookie.idx = key_idx; |
| @@ -5349,6 +5349,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
| 5349 | err = -EINVAL; | 5349 | err = -EINVAL; |
| 5350 | goto out_free; | 5350 | goto out_free; |
| 5351 | } | 5351 | } |
| 5352 | |||
| 5353 | if (!wiphy->bands[band]) | ||
| 5354 | continue; | ||
| 5355 | |||
| 5352 | err = ieee80211_get_ratemask(wiphy->bands[band], | 5356 | err = ieee80211_get_ratemask(wiphy->bands[band], |
| 5353 | nla_data(attr), | 5357 | nla_data(attr), |
| 5354 | nla_len(attr), | 5358 | nla_len(attr), |
| @@ -9633,8 +9637,9 @@ static int nl80211_add_scan_req(struct sk_buff *msg, | |||
| 9633 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) | 9637 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) |
| 9634 | goto nla_put_failure; | 9638 | goto nla_put_failure; |
| 9635 | 9639 | ||
| 9636 | if (req->flags) | 9640 | if (req->flags && |
| 9637 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); | 9641 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags)) |
| 9642 | goto nla_put_failure; | ||
| 9638 | 9643 | ||
| 9639 | return 0; | 9644 | return 0; |
| 9640 | nla_put_failure: | 9645 | nla_put_failure: |
| @@ -11093,6 +11098,8 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
| 11093 | struct nlattr *reasons; | 11098 | struct nlattr *reasons; |
| 11094 | 11099 | ||
| 11095 | reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); | 11100 | reasons = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); |
| 11101 | if (!reasons) | ||
| 11102 | goto free_msg; | ||
| 11096 | 11103 | ||
| 11097 | if (wakeup->disconnect && | 11104 | if (wakeup->disconnect && |
| 11098 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) | 11105 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) |
| @@ -11118,16 +11125,18 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, | |||
| 11118 | wakeup->pattern_idx)) | 11125 | wakeup->pattern_idx)) |
| 11119 | goto free_msg; | 11126 | goto free_msg; |
| 11120 | 11127 | ||
| 11121 | if (wakeup->tcp_match) | 11128 | if (wakeup->tcp_match && |
| 11122 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH); | 11129 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH)) |
| 11130 | goto free_msg; | ||
| 11123 | 11131 | ||
| 11124 | if (wakeup->tcp_connlost) | 11132 | if (wakeup->tcp_connlost && |
| 11125 | nla_put_flag(msg, | 11133 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST)) |
| 11126 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST); | 11134 | goto free_msg; |
| 11127 | 11135 | ||
| 11128 | if (wakeup->tcp_nomoretokens) | 11136 | if (wakeup->tcp_nomoretokens && |
| 11129 | nla_put_flag(msg, | 11137 | nla_put_flag(msg, |
| 11130 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS); | 11138 | NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS)) |
| 11139 | goto free_msg; | ||
| 11131 | 11140 | ||
| 11132 | if (wakeup->packet) { | 11141 | if (wakeup->packet) { |
| 11133 | u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; | 11142 | u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211; |
| @@ -11263,24 +11272,29 @@ void cfg80211_ft_event(struct net_device *netdev, | |||
| 11263 | return; | 11272 | return; |
| 11264 | 11273 | ||
| 11265 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); | 11274 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT); |
| 11266 | if (!hdr) { | 11275 | if (!hdr) |
| 11267 | nlmsg_free(msg); | 11276 | goto out; |
| 11268 | return; | ||
| 11269 | } | ||
| 11270 | 11277 | ||
| 11271 | nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); | 11278 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
| 11272 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); | 11279 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
| 11273 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap); | 11280 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap)) |
| 11274 | if (ft_event->ies) | 11281 | goto out; |
| 11275 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies); | 11282 | |
| 11276 | if (ft_event->ric_ies) | 11283 | if (ft_event->ies && |
| 11277 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | 11284 | nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies)) |
| 11278 | ft_event->ric_ies); | 11285 | goto out; |
| 11286 | if (ft_event->ric_ies && | ||
| 11287 | nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, | ||
| 11288 | ft_event->ric_ies)) | ||
| 11289 | goto out; | ||
| 11279 | 11290 | ||
| 11280 | genlmsg_end(msg, hdr); | 11291 | genlmsg_end(msg, hdr); |
| 11281 | 11292 | ||
| 11282 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 11293 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
| 11283 | NL80211_MCGRP_MLME, GFP_KERNEL); | 11294 | NL80211_MCGRP_MLME, GFP_KERNEL); |
| 11295 | return; | ||
| 11296 | out: | ||
| 11297 | nlmsg_free(msg); | ||
| 11284 | } | 11298 | } |
| 11285 | EXPORT_SYMBOL(cfg80211_ft_event); | 11299 | EXPORT_SYMBOL(cfg80211_ft_event); |
| 11286 | 11300 | ||
