diff options
Diffstat (limited to 'drivers/net')
68 files changed, 1028 insertions, 588 deletions
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 | } |
