diff options
Diffstat (limited to 'drivers/net')
108 files changed, 3475 insertions, 772 deletions
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 62d6f88cbab5..aa07657744c3 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
| @@ -1644,7 +1644,7 @@ ks8695_cleanup(void) | |||
| 1644 | module_init(ks8695_init); | 1644 | module_init(ks8695_init); |
| 1645 | module_exit(ks8695_cleanup); | 1645 | module_exit(ks8695_cleanup); |
| 1646 | 1646 | ||
| 1647 | MODULE_AUTHOR("Simtec Electronics") | 1647 | MODULE_AUTHOR("Simtec Electronics"); |
| 1648 | MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); | 1648 | MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); |
| 1649 | MODULE_LICENSE("GPL"); | 1649 | MODULE_LICENSE("GPL"); |
| 1650 | MODULE_ALIAS("platform:" MODULENAME); | 1650 | MODULE_ALIAS("platform:" MODULENAME); |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index a699bbf20eb5..3824382faecc 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
| @@ -48,6 +48,7 @@ static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = { | |||
| 48 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)}, | 48 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B)}, |
| 49 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)}, | 49 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L2C_B2)}, |
| 50 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)}, | 50 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)}, |
| 51 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D_2_0)}, | ||
| 51 | /* required last entry */ | 52 | /* required last entry */ |
| 52 | { 0 } | 53 | { 0 } |
| 53 | }; | 54 | }; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 0c7811faf72c..a179cc6d79f2 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
| @@ -1786,6 +1786,10 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
| 1786 | spin_lock_bh(&adapter->mcc_lock); | 1786 | spin_lock_bh(&adapter->mcc_lock); |
| 1787 | 1787 | ||
| 1788 | wrb = wrb_from_mccq(adapter); | 1788 | wrb = wrb_from_mccq(adapter); |
| 1789 | if (!wrb) { | ||
| 1790 | status = -EBUSY; | ||
| 1791 | goto err; | ||
| 1792 | } | ||
| 1789 | req = nonemb_cmd->va; | 1793 | req = nonemb_cmd->va; |
| 1790 | sge = nonembedded_sgl(wrb); | 1794 | sge = nonembedded_sgl(wrb); |
| 1791 | 1795 | ||
| @@ -1801,6 +1805,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, | |||
| 1801 | 1805 | ||
| 1802 | status = be_mcc_notify_wait(adapter); | 1806 | status = be_mcc_notify_wait(adapter); |
| 1803 | 1807 | ||
| 1808 | err: | ||
| 1804 | spin_unlock_bh(&adapter->mcc_lock); | 1809 | spin_unlock_bh(&adapter->mcc_lock); |
| 1805 | return status; | 1810 | return status; |
| 1806 | } | 1811 | } |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index de40d3b7152f..28a32a6c8bf1 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
| @@ -312,11 +312,9 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) | |||
| 312 | if (adapter->link_up != link_up) { | 312 | if (adapter->link_up != link_up) { |
| 313 | adapter->link_speed = -1; | 313 | adapter->link_speed = -1; |
| 314 | if (link_up) { | 314 | if (link_up) { |
| 315 | netif_start_queue(netdev); | ||
| 316 | netif_carrier_on(netdev); | 315 | netif_carrier_on(netdev); |
| 317 | printk(KERN_INFO "%s: Link up\n", netdev->name); | 316 | printk(KERN_INFO "%s: Link up\n", netdev->name); |
| 318 | } else { | 317 | } else { |
| 319 | netif_stop_queue(netdev); | ||
| 320 | netif_carrier_off(netdev); | 318 | netif_carrier_off(netdev); |
| 321 | printk(KERN_INFO "%s: Link down\n", netdev->name); | 319 | printk(KERN_INFO "%s: Link down\n", netdev->name); |
| 322 | } | 320 | } |
| @@ -2628,8 +2626,6 @@ static void be_netdev_init(struct net_device *netdev) | |||
| 2628 | 2626 | ||
| 2629 | netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, | 2627 | netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, |
| 2630 | BE_NAPI_WEIGHT); | 2628 | BE_NAPI_WEIGHT); |
| 2631 | |||
| 2632 | netif_stop_queue(netdev); | ||
| 2633 | } | 2629 | } |
| 2634 | 2630 | ||
| 2635 | static void be_unmap_pci_bars(struct be_adapter *adapter) | 2631 | static void be_unmap_pci_bars(struct be_adapter *adapter) |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index df99edf3464a..0ba59d5aeb7f 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
| @@ -7553,6 +7553,10 @@ bnx2_set_flags(struct net_device *dev, u32 data) | |||
| 7553 | !(data & ETH_FLAG_RXVLAN)) | 7553 | !(data & ETH_FLAG_RXVLAN)) |
| 7554 | return -EINVAL; | 7554 | return -EINVAL; |
| 7555 | 7555 | ||
| 7556 | /* TSO with VLAN tag won't work with current firmware */ | ||
| 7557 | if (!(data & ETH_FLAG_TXVLAN)) | ||
| 7558 | return -EINVAL; | ||
| 7559 | |||
| 7556 | rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | | 7560 | rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | |
| 7557 | ETH_FLAG_TXVLAN); | 7561 | ETH_FLAG_TXVLAN); |
| 7558 | if (rc) | 7562 | if (rc) |
| @@ -7962,11 +7966,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
| 7962 | 7966 | ||
| 7963 | /* AER (Advanced Error Reporting) hooks */ | 7967 | /* AER (Advanced Error Reporting) hooks */ |
| 7964 | err = pci_enable_pcie_error_reporting(pdev); | 7968 | err = pci_enable_pcie_error_reporting(pdev); |
| 7965 | if (err) { | 7969 | if (!err) |
| 7966 | dev_err(&pdev->dev, "pci_enable_pcie_error_reporting " | 7970 | bp->flags |= BNX2_FLAG_AER_ENABLED; |
| 7967 | "failed 0x%x\n", err); | ||
| 7968 | /* non-fatal, continue */ | ||
| 7969 | } | ||
| 7970 | 7971 | ||
| 7971 | } else { | 7972 | } else { |
| 7972 | bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); | 7973 | bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); |
| @@ -8229,8 +8230,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
| 8229 | return 0; | 8230 | return 0; |
| 8230 | 8231 | ||
| 8231 | err_out_unmap: | 8232 | err_out_unmap: |
| 8232 | if (bp->flags & BNX2_FLAG_PCIE) | 8233 | if (bp->flags & BNX2_FLAG_AER_ENABLED) { |
| 8233 | pci_disable_pcie_error_reporting(pdev); | 8234 | pci_disable_pcie_error_reporting(pdev); |
| 8235 | bp->flags &= ~BNX2_FLAG_AER_ENABLED; | ||
| 8236 | } | ||
| 8234 | 8237 | ||
| 8235 | if (bp->regview) { | 8238 | if (bp->regview) { |
| 8236 | iounmap(bp->regview); | 8239 | iounmap(bp->regview); |
| @@ -8418,8 +8421,10 @@ bnx2_remove_one(struct pci_dev *pdev) | |||
| 8418 | 8421 | ||
| 8419 | kfree(bp->temp_stats_blk); | 8422 | kfree(bp->temp_stats_blk); |
| 8420 | 8423 | ||
| 8421 | if (bp->flags & BNX2_FLAG_PCIE) | 8424 | if (bp->flags & BNX2_FLAG_AER_ENABLED) { |
| 8422 | pci_disable_pcie_error_reporting(pdev); | 8425 | pci_disable_pcie_error_reporting(pdev); |
| 8426 | bp->flags &= ~BNX2_FLAG_AER_ENABLED; | ||
| 8427 | } | ||
| 8423 | 8428 | ||
| 8424 | free_netdev(dev); | 8429 | free_netdev(dev); |
| 8425 | 8430 | ||
| @@ -8535,7 +8540,7 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev) | |||
| 8535 | } | 8540 | } |
| 8536 | rtnl_unlock(); | 8541 | rtnl_unlock(); |
| 8537 | 8542 | ||
| 8538 | if (!(bp->flags & BNX2_FLAG_PCIE)) | 8543 | if (!(bp->flags & BNX2_FLAG_AER_ENABLED)) |
| 8539 | return result; | 8544 | return result; |
| 8540 | 8545 | ||
| 8541 | err = pci_cleanup_aer_uncorrect_error_status(pdev); | 8546 | err = pci_cleanup_aer_uncorrect_error_status(pdev); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 5488a2e82fe9..f459fb2f9add 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
| @@ -6741,6 +6741,7 @@ struct bnx2 { | |||
| 6741 | #define BNX2_FLAG_JUMBO_BROKEN 0x00000800 | 6741 | #define BNX2_FLAG_JUMBO_BROKEN 0x00000800 |
| 6742 | #define BNX2_FLAG_CAN_KEEP_VLAN 0x00001000 | 6742 | #define BNX2_FLAG_CAN_KEEP_VLAN 0x00001000 |
| 6743 | #define BNX2_FLAG_BROKEN_STATS 0x00002000 | 6743 | #define BNX2_FLAG_BROKEN_STATS 0x00002000 |
| 6744 | #define BNX2_FLAG_AER_ENABLED 0x00004000 | ||
| 6744 | 6745 | ||
| 6745 | struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC]; | 6746 | struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC]; |
| 6746 | 6747 | ||
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 8e4183717d91..7897d114b290 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | * (you will need to reboot afterwards) */ | 22 | * (you will need to reboot afterwards) */ |
| 23 | /* #define BNX2X_STOP_ON_ERROR */ | 23 | /* #define BNX2X_STOP_ON_ERROR */ |
| 24 | 24 | ||
| 25 | #define DRV_MODULE_VERSION "1.62.00-4" | 25 | #define DRV_MODULE_VERSION "1.62.00-6" |
| 26 | #define DRV_MODULE_RELDATE "2011/01/18" | 26 | #define DRV_MODULE_RELDATE "2011/01/30" |
| 27 | #define BNX2X_BC_VER 0x040200 | 27 | #define BNX2X_BC_VER 0x040200 |
| 28 | 28 | ||
| 29 | #define BNX2X_MULTI_QUEUE | 29 | #define BNX2X_MULTI_QUEUE |
| @@ -1613,19 +1613,23 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | |||
| 1613 | #define BNX2X_BTR 4 | 1613 | #define BNX2X_BTR 4 |
| 1614 | #define MAX_SPQ_PENDING 8 | 1614 | #define MAX_SPQ_PENDING 8 |
| 1615 | 1615 | ||
| 1616 | 1616 | /* CMNG constants, as derived from system spec calculations */ | |
| 1617 | /* CMNG constants | 1617 | /* default MIN rate in case VNIC min rate is configured to zero - 100Mbps */ |
| 1618 | derived from lab experiments, and not from system spec calculations !!! */ | 1618 | #define DEF_MIN_RATE 100 |
| 1619 | #define DEF_MIN_RATE 100 | ||
| 1620 | /* resolution of the rate shaping timer - 100 usec */ | 1619 | /* resolution of the rate shaping timer - 100 usec */ |
| 1621 | #define RS_PERIODIC_TIMEOUT_USEC 100 | 1620 | #define RS_PERIODIC_TIMEOUT_USEC 100 |
| 1622 | /* resolution of fairness algorithm in usecs - | ||
| 1623 | coefficient for calculating the actual t fair */ | ||
| 1624 | #define T_FAIR_COEF 10000000 | ||
| 1625 | /* number of bytes in single QM arbitration cycle - | 1621 | /* number of bytes in single QM arbitration cycle - |
| 1626 | coefficient for calculating the fairness timer */ | 1622 | * coefficient for calculating the fairness timer */ |
| 1627 | #define QM_ARB_BYTES 40000 | 1623 | #define QM_ARB_BYTES 160000 |
| 1628 | #define FAIR_MEM 2 | 1624 | /* resolution of Min algorithm 1:100 */ |
| 1625 | #define MIN_RES 100 | ||
| 1626 | /* how many bytes above threshold for the minimal credit of Min algorithm*/ | ||
| 1627 | #define MIN_ABOVE_THRESH 32768 | ||
| 1628 | /* Fairness algorithm integration time coefficient - | ||
| 1629 | * for calculating the actual Tfair */ | ||
| 1630 | #define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES) | ||
| 1631 | /* Memory of fairness algorithm . 2 cycles */ | ||
| 1632 | #define FAIR_MEM 2 | ||
| 1629 | 1633 | ||
| 1630 | 1634 | ||
| 1631 | #define ATTN_NIG_FOR_FUNC (1L << 8) | 1635 | #define ATTN_NIG_FOR_FUNC (1L << 8) |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 710ce5d04c53..93798129061b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
| @@ -259,10 +259,44 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue, | |||
| 259 | #endif | 259 | #endif |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | /* Timestamp option length allowed for TPA aggregation: | ||
| 263 | * | ||
| 264 | * nop nop kind length echo val | ||
| 265 | */ | ||
| 266 | #define TPA_TSTAMP_OPT_LEN 12 | ||
| 267 | /** | ||
| 268 | * Calculate the approximate value of the MSS for this | ||
| 269 | * aggregation using the first packet of it. | ||
| 270 | * | ||
| 271 | * @param bp | ||
| 272 | * @param parsing_flags Parsing flags from the START CQE | ||
| 273 | * @param len_on_bd Total length of the first packet for the | ||
| 274 | * aggregation. | ||
| 275 | */ | ||
| 276 | static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags, | ||
| 277 | u16 len_on_bd) | ||
| 278 | { | ||
| 279 | /* TPA arrgregation won't have an IP options and TCP options | ||
| 280 | * other than timestamp. | ||
| 281 | */ | ||
| 282 | u16 hdrs_len = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct tcphdr); | ||
| 283 | |||
| 284 | |||
| 285 | /* Check if there was a TCP timestamp, if there is it's will | ||
| 286 | * always be 12 bytes length: nop nop kind length echo val. | ||
| 287 | * | ||
| 288 | * Otherwise FW would close the aggregation. | ||
| 289 | */ | ||
| 290 | if (parsing_flags & PARSING_FLAGS_TIME_STAMP_EXIST_FLAG) | ||
| 291 | hdrs_len += TPA_TSTAMP_OPT_LEN; | ||
| 292 | |||
| 293 | return len_on_bd - hdrs_len; | ||
| 294 | } | ||
| 295 | |||
| 262 | static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, | 296 | static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, |
| 263 | struct sk_buff *skb, | 297 | struct sk_buff *skb, |
| 264 | struct eth_fast_path_rx_cqe *fp_cqe, | 298 | struct eth_fast_path_rx_cqe *fp_cqe, |
| 265 | u16 cqe_idx) | 299 | u16 cqe_idx, u16 parsing_flags) |
| 266 | { | 300 | { |
| 267 | struct sw_rx_page *rx_pg, old_rx_pg; | 301 | struct sw_rx_page *rx_pg, old_rx_pg; |
| 268 | u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); | 302 | u16 len_on_bd = le16_to_cpu(fp_cqe->len_on_bd); |
| @@ -275,8 +309,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
| 275 | 309 | ||
| 276 | /* This is needed in order to enable forwarding support */ | 310 | /* This is needed in order to enable forwarding support */ |
| 277 | if (frag_size) | 311 | if (frag_size) |
| 278 | skb_shinfo(skb)->gso_size = min((u32)SGE_PAGE_SIZE, | 312 | skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp, parsing_flags, |
| 279 | max(frag_size, (u32)len_on_bd)); | 313 | len_on_bd); |
| 280 | 314 | ||
| 281 | #ifdef BNX2X_STOP_ON_ERROR | 315 | #ifdef BNX2X_STOP_ON_ERROR |
| 282 | if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { | 316 | if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) { |
| @@ -344,6 +378,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
| 344 | if (likely(new_skb)) { | 378 | if (likely(new_skb)) { |
| 345 | /* fix ip xsum and give it to the stack */ | 379 | /* fix ip xsum and give it to the stack */ |
| 346 | /* (no need to map the new skb) */ | 380 | /* (no need to map the new skb) */ |
| 381 | u16 parsing_flags = | ||
| 382 | le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags); | ||
| 347 | 383 | ||
| 348 | prefetch(skb); | 384 | prefetch(skb); |
| 349 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); | 385 | prefetch(((char *)(skb)) + L1_CACHE_BYTES); |
| @@ -373,9 +409,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, | |||
| 373 | } | 409 | } |
| 374 | 410 | ||
| 375 | if (!bnx2x_fill_frag_skb(bp, fp, skb, | 411 | if (!bnx2x_fill_frag_skb(bp, fp, skb, |
| 376 | &cqe->fast_path_cqe, cqe_idx)) { | 412 | &cqe->fast_path_cqe, cqe_idx, |
| 377 | if ((le16_to_cpu(cqe->fast_path_cqe. | 413 | parsing_flags)) { |
| 378 | pars_flags.flags) & PARSING_FLAGS_VLAN)) | 414 | if (parsing_flags & PARSING_FLAGS_VLAN) |
| 379 | __vlan_hwaccel_put_tag(skb, | 415 | __vlan_hwaccel_put_tag(skb, |
| 380 | le16_to_cpu(cqe->fast_path_cqe. | 416 | le16_to_cpu(cqe->fast_path_cqe. |
| 381 | vlan_tag)); | 417 | vlan_tag)); |
| @@ -703,19 +739,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp) | |||
| 703 | { | 739 | { |
| 704 | u16 line_speed = bp->link_vars.line_speed; | 740 | u16 line_speed = bp->link_vars.line_speed; |
| 705 | if (IS_MF(bp)) { | 741 | if (IS_MF(bp)) { |
| 706 | u16 maxCfg = (bp->mf_config[BP_VN(bp)] & | 742 | u16 maxCfg = bnx2x_extract_max_cfg(bp, |
| 707 | FUNC_MF_CFG_MAX_BW_MASK) >> | 743 | bp->mf_config[BP_VN(bp)]); |
| 708 | FUNC_MF_CFG_MAX_BW_SHIFT; | 744 | |
| 709 | /* Calculate the current MAX line speed limit for the DCC | 745 | /* Calculate the current MAX line speed limit for the MF |
| 710 | * capable devices | 746 | * devices |
| 711 | */ | 747 | */ |
| 712 | if (IS_MF_SD(bp)) { | 748 | if (IS_MF_SI(bp)) |
| 749 | line_speed = (line_speed * maxCfg) / 100; | ||
| 750 | else { /* SD mode */ | ||
| 713 | u16 vn_max_rate = maxCfg * 100; | 751 | u16 vn_max_rate = maxCfg * 100; |
| 714 | 752 | ||
| 715 | if (vn_max_rate < line_speed) | 753 | if (vn_max_rate < line_speed) |
| 716 | line_speed = vn_max_rate; | 754 | line_speed = vn_max_rate; |
| 717 | } else /* IS_MF_SI(bp)) */ | 755 | } |
| 718 | line_speed = (line_speed * maxCfg) / 100; | ||
| 719 | } | 756 | } |
| 720 | 757 | ||
| 721 | return line_speed; | 758 | return line_speed; |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 03eb4d68e6bb..326ba44b3ded 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h | |||
| @@ -1044,4 +1044,24 @@ static inline void storm_memset_cmng(struct bnx2x *bp, | |||
| 1044 | void bnx2x_acquire_phy_lock(struct bnx2x *bp); | 1044 | void bnx2x_acquire_phy_lock(struct bnx2x *bp); |
| 1045 | void bnx2x_release_phy_lock(struct bnx2x *bp); | 1045 | void bnx2x_release_phy_lock(struct bnx2x *bp); |
| 1046 | 1046 | ||
| 1047 | /** | ||
| 1048 | * Extracts MAX BW part from MF configuration. | ||
| 1049 | * | ||
| 1050 | * @param bp | ||
| 1051 | * @param mf_cfg | ||
| 1052 | * | ||
| 1053 | * @return u16 | ||
| 1054 | */ | ||
| 1055 | static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg) | ||
| 1056 | { | ||
| 1057 | u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> | ||
| 1058 | FUNC_MF_CFG_MAX_BW_SHIFT; | ||
| 1059 | if (!max_cfg) { | ||
| 1060 | BNX2X_ERR("Illegal configuration detected for Max BW - " | ||
| 1061 | "using 100 instead\n"); | ||
| 1062 | max_cfg = 100; | ||
| 1063 | } | ||
| 1064 | return max_cfg; | ||
| 1065 | } | ||
| 1066 | |||
| 1047 | #endif /* BNX2X_CMN_H */ | 1067 | #endif /* BNX2X_CMN_H */ |
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 5b44a8b48509..ef2919987a10 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c | |||
| @@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
| 238 | speed |= (cmd->speed_hi << 16); | 238 | speed |= (cmd->speed_hi << 16); |
| 239 | 239 | ||
| 240 | if (IS_MF_SI(bp)) { | 240 | if (IS_MF_SI(bp)) { |
| 241 | u32 param = 0; | 241 | u32 param = 0, part; |
| 242 | u32 line_speed = bp->link_vars.line_speed; | 242 | u32 line_speed = bp->link_vars.line_speed; |
| 243 | 243 | ||
| 244 | /* use 10G if no link detected */ | 244 | /* use 10G if no link detected */ |
| @@ -251,9 +251,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
| 251 | REQ_BC_VER_4_SET_MF_BW); | 251 | REQ_BC_VER_4_SET_MF_BW); |
| 252 | return -EINVAL; | 252 | return -EINVAL; |
| 253 | } | 253 | } |
| 254 | if (line_speed < speed) { | 254 | part = (speed * 100) / line_speed; |
| 255 | BNX2X_DEV_INFO("New speed should be less or equal " | 255 | if (line_speed < speed || !part) { |
| 256 | "to actual line speed\n"); | 256 | BNX2X_DEV_INFO("Speed setting should be in a range " |
| 257 | "from 1%% to 100%% " | ||
| 258 | "of actual line speed\n"); | ||
| 257 | return -EINVAL; | 259 | return -EINVAL; |
| 258 | } | 260 | } |
| 259 | /* load old values */ | 261 | /* load old values */ |
| @@ -263,8 +265,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
| 263 | param &= FUNC_MF_CFG_MIN_BW_MASK; | 265 | param &= FUNC_MF_CFG_MIN_BW_MASK; |
| 264 | 266 | ||
| 265 | /* set new MAX value */ | 267 | /* set new MAX value */ |
| 266 | param |= (((speed * 100) / line_speed) | 268 | param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT) |
| 267 | << FUNC_MF_CFG_MAX_BW_SHIFT) | ||
| 268 | & FUNC_MF_CFG_MAX_BW_MASK; | 269 | & FUNC_MF_CFG_MAX_BW_MASK; |
| 269 | 270 | ||
| 270 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); | 271 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); |
| @@ -1781,9 +1782,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp) | |||
| 1781 | { 0x100, 0x350 }, /* manuf_info */ | 1782 | { 0x100, 0x350 }, /* manuf_info */ |
| 1782 | { 0x450, 0xf0 }, /* feature_info */ | 1783 | { 0x450, 0xf0 }, /* feature_info */ |
| 1783 | { 0x640, 0x64 }, /* upgrade_key_info */ | 1784 | { 0x640, 0x64 }, /* upgrade_key_info */ |
| 1784 | { 0x6a4, 0x64 }, | ||
| 1785 | { 0x708, 0x70 }, /* manuf_key_info */ | 1785 | { 0x708, 0x70 }, /* manuf_key_info */ |
| 1786 | { 0x778, 0x70 }, | ||
| 1787 | { 0, 0 } | 1786 | { 0, 0 } |
| 1788 | }; | 1787 | }; |
| 1789 | __be32 buf[0x350 / 4]; | 1788 | __be32 buf[0x350 / 4]; |
| @@ -1933,11 +1932,11 @@ static void bnx2x_self_test(struct net_device *dev, | |||
| 1933 | buf[4] = 1; | 1932 | buf[4] = 1; |
| 1934 | etest->flags |= ETH_TEST_FL_FAILED; | 1933 | etest->flags |= ETH_TEST_FL_FAILED; |
| 1935 | } | 1934 | } |
| 1936 | if (bp->port.pmf) | 1935 | |
| 1937 | if (bnx2x_link_test(bp, is_serdes) != 0) { | 1936 | if (bnx2x_link_test(bp, is_serdes) != 0) { |
| 1938 | buf[5] = 1; | 1937 | buf[5] = 1; |
| 1939 | etest->flags |= ETH_TEST_FL_FAILED; | 1938 | etest->flags |= ETH_TEST_FL_FAILED; |
| 1940 | } | 1939 | } |
| 1941 | 1940 | ||
| 1942 | #ifdef BNX2X_EXTRA_DEBUG | 1941 | #ifdef BNX2X_EXTRA_DEBUG |
| 1943 | bnx2x_panic_dump(bp); | 1942 | bnx2x_panic_dump(bp); |
diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 5a268e9a0895..fa6dbe3f2058 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h | |||
| @@ -241,7 +241,7 @@ static const struct { | |||
| 241 | /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't | 241 | /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't |
| 242 | * want to handle "system kill" flow at the moment. | 242 | * want to handle "system kill" flow at the moment. |
| 243 | */ | 243 | */ |
| 244 | BLOCK_PRTY_INFO(PXP, 0x3ffffff, 0x3ffffff, 0x3ffffff, 0x3ffffff), | 244 | BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff), |
| 245 | BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), | 245 | BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), |
| 246 | BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), | 246 | BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), |
| 247 | BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), | 247 | BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), |
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7160ec51093e..dd1210fddfff 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
| @@ -3948,48 +3948,6 @@ static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | |||
| 3948 | return rc; | 3948 | return rc; |
| 3949 | } | 3949 | } |
| 3950 | 3950 | ||
| 3951 | static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, | ||
| 3952 | struct bnx2x_phy *phy) | ||
| 3953 | { | ||
| 3954 | u16 val; | ||
| 3955 | bnx2x_cl45_read(bp, phy, | ||
| 3956 | MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); | ||
| 3957 | |||
| 3958 | if (val == 0) { | ||
| 3959 | /* Mustn't set low power mode in 8073 A0 */ | ||
| 3960 | return; | ||
| 3961 | } | ||
| 3962 | |||
| 3963 | /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ | ||
| 3964 | bnx2x_cl45_read(bp, phy, | ||
| 3965 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); | ||
| 3966 | val &= ~(1<<13); | ||
| 3967 | bnx2x_cl45_write(bp, phy, | ||
| 3968 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); | ||
| 3969 | |||
| 3970 | /* PLL controls */ | ||
| 3971 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077); | ||
| 3972 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000); | ||
| 3973 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B); | ||
| 3974 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240); | ||
| 3975 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490); | ||
| 3976 | |||
| 3977 | /* Tx Controls */ | ||
| 3978 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74); | ||
| 3979 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041); | ||
| 3980 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640); | ||
| 3981 | |||
| 3982 | /* Rx Controls */ | ||
| 3983 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4); | ||
| 3984 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249); | ||
| 3985 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015); | ||
| 3986 | |||
| 3987 | /* Enable PLL sequencer (use read-modify-write to set bit 13) */ | ||
| 3988 | bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); | ||
| 3989 | val |= (1<<13); | ||
| 3990 | bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); | ||
| 3991 | } | ||
| 3992 | |||
| 3993 | /******************************************************************/ | 3951 | /******************************************************************/ |
| 3994 | /* BCM8073 PHY SECTION */ | 3952 | /* BCM8073 PHY SECTION */ |
| 3995 | /******************************************************************/ | 3953 | /******************************************************************/ |
| @@ -4148,8 +4106,6 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, | |||
| 4148 | 4106 | ||
| 4149 | bnx2x_8073_set_pause_cl37(params, phy, vars); | 4107 | bnx2x_8073_set_pause_cl37(params, phy, vars); |
| 4150 | 4108 | ||
| 4151 | bnx2x_8073_set_xaui_low_power_mode(bp, phy); | ||
| 4152 | |||
| 4153 | bnx2x_cl45_read(bp, phy, | 4109 | bnx2x_cl45_read(bp, phy, |
| 4154 | MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); | 4110 | MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); |
| 4155 | 4111 | ||
| @@ -6519,6 +6475,18 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, | |||
| 6519 | MDIO_PMA_DEVAD, | 6475 | MDIO_PMA_DEVAD, |
| 6520 | MDIO_PMA_REG_8481_LED1_MASK, | 6476 | MDIO_PMA_REG_8481_LED1_MASK, |
| 6521 | 0x80); | 6477 | 0x80); |
| 6478 | |||
| 6479 | /* Tell LED3 to blink on source */ | ||
| 6480 | bnx2x_cl45_read(bp, phy, | ||
| 6481 | MDIO_PMA_DEVAD, | ||
| 6482 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
| 6483 | &val); | ||
| 6484 | val &= ~(7<<6); | ||
| 6485 | val |= (1<<6); /* A83B[8:6]= 1 */ | ||
| 6486 | bnx2x_cl45_write(bp, phy, | ||
| 6487 | MDIO_PMA_DEVAD, | ||
| 6488 | MDIO_PMA_REG_8481_LINK_SIGNAL, | ||
| 6489 | val); | ||
| 6522 | } | 6490 | } |
| 6523 | break; | 6491 | break; |
| 6524 | } | 6492 | } |
| @@ -7720,10 +7688,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
| 7720 | struct bnx2x_phy phy[PORT_MAX]; | 7688 | struct bnx2x_phy phy[PORT_MAX]; |
| 7721 | struct bnx2x_phy *phy_blk[PORT_MAX]; | 7689 | struct bnx2x_phy *phy_blk[PORT_MAX]; |
| 7722 | u16 val; | 7690 | u16 val; |
| 7723 | s8 port; | 7691 | s8 port = 0; |
| 7724 | s8 port_of_path = 0; | 7692 | s8 port_of_path = 0; |
| 7725 | 7693 | u32 swap_val, swap_override; | |
| 7726 | bnx2x_ext_phy_hw_reset(bp, 0); | 7694 | swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); |
| 7695 | swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); | ||
| 7696 | port ^= (swap_val && swap_override); | ||
| 7697 | bnx2x_ext_phy_hw_reset(bp, port); | ||
| 7727 | /* PART1 - Reset both phys */ | 7698 | /* PART1 - Reset both phys */ |
| 7728 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 7699 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
| 7729 | u32 shmem_base, shmem2_base; | 7700 | u32 shmem_base, shmem2_base; |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 8cdcf5b39d1e..032ae184b605 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
| @@ -1974,13 +1974,22 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) | |||
| 1974 | vn_max_rate = 0; | 1974 | vn_max_rate = 0; |
| 1975 | 1975 | ||
| 1976 | } else { | 1976 | } else { |
| 1977 | u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg); | ||
| 1978 | |||
| 1977 | vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> | 1979 | vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> |
| 1978 | FUNC_MF_CFG_MIN_BW_SHIFT) * 100; | 1980 | FUNC_MF_CFG_MIN_BW_SHIFT) * 100; |
| 1979 | /* If min rate is zero - set it to 1 */ | 1981 | /* If fairness is enabled (not all min rates are zeroes) and |
| 1982 | if current min rate is zero - set it to 1. | ||
| 1983 | This is a requirement of the algorithm. */ | ||
| 1980 | if (bp->vn_weight_sum && (vn_min_rate == 0)) | 1984 | if (bp->vn_weight_sum && (vn_min_rate == 0)) |
| 1981 | vn_min_rate = DEF_MIN_RATE; | 1985 | vn_min_rate = DEF_MIN_RATE; |
| 1982 | vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> | 1986 | |
| 1983 | FUNC_MF_CFG_MAX_BW_SHIFT) * 100; | 1987 | if (IS_MF_SI(bp)) |
| 1988 | /* maxCfg in percents of linkspeed */ | ||
| 1989 | vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100; | ||
| 1990 | else | ||
| 1991 | /* maxCfg is absolute in 100Mb units */ | ||
| 1992 | vn_max_rate = maxCfg * 100; | ||
| 1984 | } | 1993 | } |
| 1985 | 1994 | ||
| 1986 | DP(NETIF_MSG_IFUP, | 1995 | DP(NETIF_MSG_IFUP, |
| @@ -2006,7 +2015,8 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) | |||
| 2006 | m_fair_vn.vn_credit_delta = | 2015 | m_fair_vn.vn_credit_delta = |
| 2007 | max_t(u32, (vn_min_rate * (T_FAIR_COEF / | 2016 | max_t(u32, (vn_min_rate * (T_FAIR_COEF / |
| 2008 | (8 * bp->vn_weight_sum))), | 2017 | (8 * bp->vn_weight_sum))), |
| 2009 | (bp->cmng.fair_vars.fair_threshold * 2)); | 2018 | (bp->cmng.fair_vars.fair_threshold + |
| 2019 | MIN_ABOVE_THRESH)); | ||
| 2010 | DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n", | 2020 | DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n", |
| 2011 | m_fair_vn.vn_credit_delta); | 2021 | m_fair_vn.vn_credit_delta); |
| 2012 | } | 2022 | } |
| @@ -2301,15 +2311,10 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) | |||
| 2301 | /* accept matched ucast */ | 2311 | /* accept matched ucast */ |
| 2302 | drop_all_ucast = 0; | 2312 | drop_all_ucast = 0; |
| 2303 | } | 2313 | } |
| 2304 | if (filters & BNX2X_ACCEPT_MULTICAST) { | 2314 | if (filters & BNX2X_ACCEPT_MULTICAST) |
| 2305 | /* accept matched mcast */ | 2315 | /* accept matched mcast */ |
| 2306 | drop_all_mcast = 0; | 2316 | drop_all_mcast = 0; |
| 2307 | if (IS_MF_SI(bp)) | 2317 | |
| 2308 | /* since mcast addresses won't arrive with ovlan, | ||
| 2309 | * fw needs to accept all of them in | ||
| 2310 | * switch-independent mode */ | ||
| 2311 | accp_all_mcast = 1; | ||
| 2312 | } | ||
| 2313 | if (filters & BNX2X_ACCEPT_ALL_UNICAST) { | 2318 | if (filters & BNX2X_ACCEPT_ALL_UNICAST) { |
| 2314 | /* accept all mcast */ | 2319 | /* accept all mcast */ |
| 2315 | drop_all_ucast = 0; | 2320 | drop_all_ucast = 0; |
| @@ -4281,9 +4286,12 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) | |||
| 4281 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | | 4286 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | |
| 4282 | BNX2X_ACCEPT_MULTICAST; | 4287 | BNX2X_ACCEPT_MULTICAST; |
| 4283 | #ifdef BCM_CNIC | 4288 | #ifdef BCM_CNIC |
| 4284 | cl_id = bnx2x_fcoe(bp, cl_id); | 4289 | if (!NO_FCOE(bp)) { |
| 4285 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | | 4290 | cl_id = bnx2x_fcoe(bp, cl_id); |
| 4286 | BNX2X_ACCEPT_MULTICAST); | 4291 | bnx2x_rxq_set_mac_filters(bp, cl_id, |
| 4292 | BNX2X_ACCEPT_UNICAST | | ||
| 4293 | BNX2X_ACCEPT_MULTICAST); | ||
| 4294 | } | ||
| 4287 | #endif | 4295 | #endif |
| 4288 | break; | 4296 | break; |
| 4289 | 4297 | ||
| @@ -4291,18 +4299,29 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) | |||
| 4291 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | | 4299 | def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | |
| 4292 | BNX2X_ACCEPT_ALL_MULTICAST; | 4300 | BNX2X_ACCEPT_ALL_MULTICAST; |
| 4293 | #ifdef BCM_CNIC | 4301 | #ifdef BCM_CNIC |
| 4294 | cl_id = bnx2x_fcoe(bp, cl_id); | 4302 | /* |
| 4295 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | | 4303 | * Prevent duplication of multicast packets by configuring FCoE |
| 4296 | BNX2X_ACCEPT_MULTICAST); | 4304 | * L2 Client to receive only matched unicast frames. |
| 4305 | */ | ||
| 4306 | if (!NO_FCOE(bp)) { | ||
| 4307 | cl_id = bnx2x_fcoe(bp, cl_id); | ||
| 4308 | bnx2x_rxq_set_mac_filters(bp, cl_id, | ||
| 4309 | BNX2X_ACCEPT_UNICAST); | ||
| 4310 | } | ||
| 4297 | #endif | 4311 | #endif |
| 4298 | break; | 4312 | break; |
| 4299 | 4313 | ||
| 4300 | case BNX2X_RX_MODE_PROMISC: | 4314 | case BNX2X_RX_MODE_PROMISC: |
| 4301 | def_q_filters |= BNX2X_PROMISCUOUS_MODE; | 4315 | def_q_filters |= BNX2X_PROMISCUOUS_MODE; |
| 4302 | #ifdef BCM_CNIC | 4316 | #ifdef BCM_CNIC |
| 4303 | cl_id = bnx2x_fcoe(bp, cl_id); | 4317 | /* |
| 4304 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | | 4318 | * Prevent packets duplication by configuring DROP_ALL for FCoE |
| 4305 | BNX2X_ACCEPT_MULTICAST); | 4319 | * L2 Client. |
| 4320 | */ | ||
| 4321 | if (!NO_FCOE(bp)) { | ||
| 4322 | cl_id = bnx2x_fcoe(bp, cl_id); | ||
| 4323 | bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); | ||
| 4324 | } | ||
| 4306 | #endif | 4325 | #endif |
| 4307 | /* pass management unicast packets as well */ | 4326 | /* pass management unicast packets as well */ |
| 4308 | llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; | 4327 | llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; |
| @@ -5296,10 +5315,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) | |||
| 5296 | } | 5315 | } |
| 5297 | } | 5316 | } |
| 5298 | 5317 | ||
| 5299 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | ||
| 5300 | bp->common.shmem_base, | ||
| 5301 | bp->common.shmem2_base); | ||
| 5302 | |||
| 5303 | bnx2x_setup_fan_failure_detection(bp); | 5318 | bnx2x_setup_fan_failure_detection(bp); |
| 5304 | 5319 | ||
| 5305 | /* clear PXP2 attentions */ | 5320 | /* clear PXP2 attentions */ |
| @@ -5503,9 +5518,6 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) | |||
| 5503 | 5518 | ||
| 5504 | bnx2x_init_block(bp, MCP_BLOCK, init_stage); | 5519 | bnx2x_init_block(bp, MCP_BLOCK, init_stage); |
| 5505 | bnx2x_init_block(bp, DMAE_BLOCK, init_stage); | 5520 | bnx2x_init_block(bp, DMAE_BLOCK, init_stage); |
| 5506 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | ||
| 5507 | bp->common.shmem_base, | ||
| 5508 | bp->common.shmem2_base); | ||
| 5509 | if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, | 5521 | if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, |
| 5510 | bp->common.shmem2_base, port)) { | 5522 | bp->common.shmem2_base, port)) { |
| 5511 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : | 5523 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : |
| @@ -8379,6 +8391,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
| 8379 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) | 8391 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) |
| 8380 | bp->mdio.prtad = | 8392 | bp->mdio.prtad = |
| 8381 | XGXS_EXT_PHY_ADDR(ext_phy_config); | 8393 | XGXS_EXT_PHY_ADDR(ext_phy_config); |
| 8394 | |||
| 8395 | /* | ||
| 8396 | * Check if hw lock is required to access MDC/MDIO bus to the PHY(s) | ||
| 8397 | * In MF mode, it is set to cover self test cases | ||
| 8398 | */ | ||
| 8399 | if (IS_MF(bp)) | ||
| 8400 | bp->port.need_hw_lock = 1; | ||
| 8401 | else | ||
| 8402 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | ||
| 8403 | bp->common.shmem_base, | ||
| 8404 | bp->common.shmem2_base); | ||
| 8382 | } | 8405 | } |
| 8383 | 8406 | ||
| 8384 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) | 8407 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) |
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index bda60d590fa8..3445ded6674f 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c | |||
| @@ -1239,14 +1239,14 @@ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) | |||
| 1239 | if (unlikely(bp->panic)) | 1239 | if (unlikely(bp->panic)) |
| 1240 | return; | 1240 | return; |
| 1241 | 1241 | ||
| 1242 | bnx2x_stats_stm[bp->stats_state][event].action(bp); | ||
| 1243 | |||
| 1242 | /* Protect a state change flow */ | 1244 | /* Protect a state change flow */ |
| 1243 | spin_lock_bh(&bp->stats_lock); | 1245 | spin_lock_bh(&bp->stats_lock); |
| 1244 | state = bp->stats_state; | 1246 | state = bp->stats_state; |
| 1245 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; | 1247 | bp->stats_state = bnx2x_stats_stm[state][event].next_state; |
| 1246 | spin_unlock_bh(&bp->stats_lock); | 1248 | spin_unlock_bh(&bp->stats_lock); |
| 1247 | 1249 | ||
| 1248 | bnx2x_stats_stm[state][event].action(bp); | ||
| 1249 | |||
| 1250 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) | 1250 | if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) |
| 1251 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", | 1251 | DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", |
| 1252 | state, event, bp->stats_state); | 1252 | state, event, bp->stats_state); |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 171782e2bb39..1024ae158227 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -2470,6 +2470,10 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac | |||
| 2470 | if (!(dev->flags & IFF_MASTER)) | 2470 | if (!(dev->flags & IFF_MASTER)) |
| 2471 | goto out; | 2471 | goto out; |
| 2472 | 2472 | ||
| 2473 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
| 2474 | if (!skb) | ||
| 2475 | goto out; | ||
| 2476 | |||
| 2473 | if (!pskb_may_pull(skb, sizeof(struct lacpdu))) | 2477 | if (!pskb_may_pull(skb, sizeof(struct lacpdu))) |
| 2474 | goto out; | 2478 | goto out; |
| 2475 | 2479 | ||
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index f4e638c65129..5c6fba802f2b 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
| @@ -326,6 +326,10 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct | |||
| 326 | goto out; | 326 | goto out; |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
| 330 | if (!skb) | ||
| 331 | goto out; | ||
| 332 | |||
| 329 | if (!pskb_may_pull(skb, arp_hdr_len(bond_dev))) | 333 | if (!pskb_may_pull(skb, arp_hdr_len(bond_dev))) |
| 330 | goto out; | 334 | goto out; |
| 331 | 335 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b1025b85acf1..163e0b06eaa5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -2733,6 +2733,10 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack | |||
| 2733 | if (!slave || !slave_do_arp_validate(bond, slave)) | 2733 | if (!slave || !slave_do_arp_validate(bond, slave)) |
| 2734 | goto out_unlock; | 2734 | goto out_unlock; |
| 2735 | 2735 | ||
| 2736 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
| 2737 | if (!skb) | ||
| 2738 | goto out_unlock; | ||
| 2739 | |||
| 2736 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) | 2740 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) |
| 2737 | goto out_unlock; | 2741 | goto out_unlock; |
| 2738 | 2742 | ||
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d5a9db60ade9..5dec456fd4a4 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
| @@ -23,7 +23,7 @@ config CAN_SLCAN | |||
| 23 | 23 | ||
| 24 | As only the sending and receiving of CAN frames is implemented, this | 24 | As only the sending and receiving of CAN frames is implemented, this |
| 25 | driver should work with the (serial/USB) CAN hardware from: | 25 | driver should work with the (serial/USB) CAN hardware from: |
| 26 | www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de | 26 | www.canusb.com / www.can232.com / www.mictronics.de / www.canhack.de |
| 27 | 27 | ||
| 28 | Userspace tools to attach the SLCAN line discipline (slcan_attach, | 28 | Userspace tools to attach the SLCAN line discipline (slcan_attach, |
| 29 | slcand) can be found in the can-utils at the SocketCAN SVN, see | 29 | slcand) can be found in the can-utils at the SocketCAN SVN, see |
| @@ -117,6 +117,8 @@ source "drivers/net/can/sja1000/Kconfig" | |||
| 117 | 117 | ||
| 118 | source "drivers/net/can/usb/Kconfig" | 118 | source "drivers/net/can/usb/Kconfig" |
| 119 | 119 | ||
| 120 | source "drivers/net/can/softing/Kconfig" | ||
| 121 | |||
| 120 | config CAN_DEBUG_DEVICES | 122 | config CAN_DEBUG_DEVICES |
| 121 | bool "CAN devices debugging messages" | 123 | bool "CAN devices debugging messages" |
| 122 | depends on CAN | 124 | depends on CAN |
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 07ca159ba3f9..53c82a71778e 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_CAN_DEV) += can-dev.o | |||
| 9 | can-dev-y := dev.o | 9 | can-dev-y := dev.o |
| 10 | 10 | ||
| 11 | obj-y += usb/ | 11 | obj-y += usb/ |
| 12 | obj-y += softing/ | ||
| 12 | 13 | ||
| 13 | obj-$(CONFIG_CAN_SJA1000) += sja1000/ | 14 | obj-$(CONFIG_CAN_SJA1000) += sja1000/ |
| 14 | obj-$(CONFIG_CAN_MSCAN) += mscan/ | 15 | obj-$(CONFIG_CAN_MSCAN) += mscan/ |
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c index 7ef83d06f7ed..57d2ffbbb433 100644 --- a/drivers/net/can/at91_can.c +++ b/drivers/net/can/at91_can.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * at91_can.c - CAN network driver for AT91 SoC CAN controller | 2 | * at91_can.c - CAN network driver for AT91 SoC CAN controller |
| 3 | * | 3 | * |
| 4 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> | 4 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> |
| 5 | * (C) 2008, 2009, 2010 by Marc Kleine-Budde <kernel@pengutronix.de> | 5 | * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de> |
| 6 | * | 6 | * |
| 7 | * This software may be distributed under the terms of the GNU General | 7 | * This software may be distributed under the terms of the GNU General |
| 8 | * Public License ("GPL") version 2 as distributed in the 'COPYING' | 8 | * Public License ("GPL") version 2 as distributed in the 'COPYING' |
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
| 32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
| 33 | #include <linux/rtnetlink.h> | ||
| 33 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
| 34 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
| 35 | #include <linux/string.h> | 36 | #include <linux/string.h> |
| @@ -40,22 +41,23 @@ | |||
| 40 | 41 | ||
| 41 | #include <mach/board.h> | 42 | #include <mach/board.h> |
| 42 | 43 | ||
| 43 | #define AT91_NAPI_WEIGHT 12 | 44 | #define AT91_NAPI_WEIGHT 11 |
| 44 | 45 | ||
| 45 | /* | 46 | /* |
| 46 | * RX/TX Mailbox split | 47 | * RX/TX Mailbox split |
| 47 | * don't dare to touch | 48 | * don't dare to touch |
| 48 | */ | 49 | */ |
| 49 | #define AT91_MB_RX_NUM 12 | 50 | #define AT91_MB_RX_NUM 11 |
| 50 | #define AT91_MB_TX_SHIFT 2 | 51 | #define AT91_MB_TX_SHIFT 2 |
| 51 | 52 | ||
| 52 | #define AT91_MB_RX_FIRST 0 | 53 | #define AT91_MB_RX_FIRST 1 |
| 53 | #define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) | 54 | #define AT91_MB_RX_LAST (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1) |
| 54 | 55 | ||
| 55 | #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) | 56 | #define AT91_MB_RX_MASK(i) ((1 << (i)) - 1) |
| 56 | #define AT91_MB_RX_SPLIT 8 | 57 | #define AT91_MB_RX_SPLIT 8 |
| 57 | #define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) | 58 | #define AT91_MB_RX_LOW_LAST (AT91_MB_RX_SPLIT - 1) |
| 58 | #define AT91_MB_RX_LOW_MASK (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT)) | 59 | #define AT91_MB_RX_LOW_MASK (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \ |
| 60 | ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST)) | ||
| 59 | 61 | ||
| 60 | #define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) | 62 | #define AT91_MB_TX_NUM (1 << AT91_MB_TX_SHIFT) |
| 61 | #define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) | 63 | #define AT91_MB_TX_FIRST (AT91_MB_RX_LAST + 1) |
| @@ -168,6 +170,8 @@ struct at91_priv { | |||
| 168 | 170 | ||
| 169 | struct clk *clk; | 171 | struct clk *clk; |
| 170 | struct at91_can_data *pdata; | 172 | struct at91_can_data *pdata; |
| 173 | |||
| 174 | canid_t mb0_id; | ||
| 171 | }; | 175 | }; |
| 172 | 176 | ||
| 173 | static struct can_bittiming_const at91_bittiming_const = { | 177 | static struct can_bittiming_const at91_bittiming_const = { |
| @@ -220,6 +224,18 @@ static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb, | |||
| 220 | set_mb_mode_prio(priv, mb, mode, 0); | 224 | set_mb_mode_prio(priv, mb, mode, 0); |
| 221 | } | 225 | } |
| 222 | 226 | ||
| 227 | static inline u32 at91_can_id_to_reg_mid(canid_t can_id) | ||
| 228 | { | ||
| 229 | u32 reg_mid; | ||
| 230 | |||
| 231 | if (can_id & CAN_EFF_FLAG) | ||
| 232 | reg_mid = (can_id & CAN_EFF_MASK) | AT91_MID_MIDE; | ||
| 233 | else | ||
| 234 | reg_mid = (can_id & CAN_SFF_MASK) << 18; | ||
| 235 | |||
| 236 | return reg_mid; | ||
| 237 | } | ||
| 238 | |||
| 223 | /* | 239 | /* |
| 224 | * Swtich transceiver on or off | 240 | * Swtich transceiver on or off |
| 225 | */ | 241 | */ |
| @@ -233,12 +249,22 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
| 233 | { | 249 | { |
| 234 | struct at91_priv *priv = netdev_priv(dev); | 250 | struct at91_priv *priv = netdev_priv(dev); |
| 235 | unsigned int i; | 251 | unsigned int i; |
| 252 | u32 reg_mid; | ||
| 236 | 253 | ||
| 237 | /* | 254 | /* |
| 238 | * The first 12 mailboxes are used as a reception FIFO. The | 255 | * Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first |
| 239 | * last mailbox is configured with overwrite option. The | 256 | * mailbox is disabled. The next 11 mailboxes are used as a |
| 240 | * overwrite flag indicates a FIFO overflow. | 257 | * reception FIFO. The last mailbox is configured with |
| 258 | * overwrite option. The overwrite flag indicates a FIFO | ||
| 259 | * overflow. | ||
| 241 | */ | 260 | */ |
| 261 | reg_mid = at91_can_id_to_reg_mid(priv->mb0_id); | ||
| 262 | for (i = 0; i < AT91_MB_RX_FIRST; i++) { | ||
| 263 | set_mb_mode(priv, i, AT91_MB_MODE_DISABLED); | ||
| 264 | at91_write(priv, AT91_MID(i), reg_mid); | ||
| 265 | at91_write(priv, AT91_MCR(i), 0x0); /* clear dlc */ | ||
| 266 | } | ||
| 267 | |||
| 242 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) | 268 | for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++) |
| 243 | set_mb_mode(priv, i, AT91_MB_MODE_RX); | 269 | set_mb_mode(priv, i, AT91_MB_MODE_RX); |
| 244 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); | 270 | set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR); |
| @@ -254,7 +280,8 @@ static void at91_setup_mailboxes(struct net_device *dev) | |||
| 254 | set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); | 280 | set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0); |
| 255 | 281 | ||
| 256 | /* Reset tx and rx helper pointers */ | 282 | /* Reset tx and rx helper pointers */ |
| 257 | priv->tx_next = priv->tx_echo = priv->rx_next = 0; | 283 | priv->tx_next = priv->tx_echo = 0; |
| 284 | priv->rx_next = AT91_MB_RX_FIRST; | ||
| 258 | } | 285 | } |
| 259 | 286 | ||
| 260 | static int at91_set_bittiming(struct net_device *dev) | 287 | static int at91_set_bittiming(struct net_device *dev) |
| @@ -372,12 +399,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 372 | netdev_err(dev, "BUG! TX buffer full when queue awake!\n"); | 399 | netdev_err(dev, "BUG! TX buffer full when queue awake!\n"); |
| 373 | return NETDEV_TX_BUSY; | 400 | return NETDEV_TX_BUSY; |
| 374 | } | 401 | } |
| 375 | 402 | reg_mid = at91_can_id_to_reg_mid(cf->can_id); | |
| 376 | if (cf->can_id & CAN_EFF_FLAG) | ||
| 377 | reg_mid = (cf->can_id & CAN_EFF_MASK) | AT91_MID_MIDE; | ||
| 378 | else | ||
| 379 | reg_mid = (cf->can_id & CAN_SFF_MASK) << 18; | ||
| 380 | |||
| 381 | reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) | | 403 | reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) | |
| 382 | (cf->can_dlc << 16) | AT91_MCR_MTCR; | 404 | (cf->can_dlc << 16) | AT91_MCR_MTCR; |
| 383 | 405 | ||
| @@ -539,27 +561,31 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb) | |||
| 539 | * | 561 | * |
| 540 | * Theory of Operation: | 562 | * Theory of Operation: |
| 541 | * | 563 | * |
| 542 | * 12 of the 16 mailboxes on the chip are reserved for RX. we split | 564 | * 11 of the 16 mailboxes on the chip are reserved for RX. we split |
| 543 | * them into 2 groups. The lower group holds 8 and upper 4 mailboxes. | 565 | * them into 2 groups. The lower group holds 7 and upper 4 mailboxes. |
| 544 | * | 566 | * |
| 545 | * Like it or not, but the chip always saves a received CAN message | 567 | * Like it or not, but the chip always saves a received CAN message |
| 546 | * into the first free mailbox it finds (starting with the | 568 | * into the first free mailbox it finds (starting with the |
| 547 | * lowest). This makes it very difficult to read the messages in the | 569 | * lowest). This makes it very difficult to read the messages in the |
| 548 | * right order from the chip. This is how we work around that problem: | 570 | * right order from the chip. This is how we work around that problem: |
| 549 | * | 571 | * |
| 550 | * The first message goes into mb nr. 0 and issues an interrupt. All | 572 | * The first message goes into mb nr. 1 and issues an interrupt. All |
| 551 | * rx ints are disabled in the interrupt handler and a napi poll is | 573 | * rx ints are disabled in the interrupt handler and a napi poll is |
| 552 | * scheduled. We read the mailbox, but do _not_ reenable the mb (to | 574 | * scheduled. We read the mailbox, but do _not_ reenable the mb (to |
| 553 | * receive another message). | 575 | * receive another message). |
| 554 | * | 576 | * |
| 555 | * lower mbxs upper | 577 | * lower mbxs upper |
| 556 | * ______^______ __^__ | 578 | * ____^______ __^__ |
| 557 | * / \ / \ | 579 | * / \ / \ |
| 558 | * +-+-+-+-+-+-+-+-++-+-+-+-+ | 580 | * +-+-+-+-+-+-+-+-++-+-+-+-+ |
| 559 | * |x|x|x|x|x|x|x|x|| | | | | | 581 | * | |x|x|x|x|x|x|x|| | | | | |
| 560 | * +-+-+-+-+-+-+-+-++-+-+-+-+ | 582 | * +-+-+-+-+-+-+-+-++-+-+-+-+ |
| 561 | * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail | 583 | * 0 0 0 0 0 0 0 0 0 0 1 1 \ mail |
| 562 | * 0 1 2 3 4 5 6 7 8 9 0 1 / box | 584 | * 0 1 2 3 4 5 6 7 8 9 0 1 / box |
| 585 | * ^ | ||
| 586 | * | | ||
| 587 | * \ | ||
| 588 | * unused, due to chip bug | ||
| 563 | * | 589 | * |
| 564 | * The variable priv->rx_next points to the next mailbox to read a | 590 | * The variable priv->rx_next points to the next mailbox to read a |
| 565 | * message from. As long we're in the lower mailboxes we just read the | 591 | * message from. As long we're in the lower mailboxes we just read the |
| @@ -590,10 +616,10 @@ static int at91_poll_rx(struct net_device *dev, int quota) | |||
| 590 | "order of incoming frames cannot be guaranteed\n"); | 616 | "order of incoming frames cannot be guaranteed\n"); |
| 591 | 617 | ||
| 592 | again: | 618 | again: |
| 593 | for (mb = find_next_bit(addr, AT91_MB_RX_NUM, priv->rx_next); | 619 | for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next); |
| 594 | mb < AT91_MB_RX_NUM && quota > 0; | 620 | mb < AT91_MB_RX_LAST + 1 && quota > 0; |
| 595 | reg_sr = at91_read(priv, AT91_SR), | 621 | reg_sr = at91_read(priv, AT91_SR), |
| 596 | mb = find_next_bit(addr, AT91_MB_RX_NUM, ++priv->rx_next)) { | 622 | mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) { |
| 597 | at91_read_msg(dev, mb); | 623 | at91_read_msg(dev, mb); |
| 598 | 624 | ||
| 599 | /* reactivate mailboxes */ | 625 | /* reactivate mailboxes */ |
| @@ -610,8 +636,8 @@ static int at91_poll_rx(struct net_device *dev, int quota) | |||
| 610 | 636 | ||
| 611 | /* upper group completed, look again in lower */ | 637 | /* upper group completed, look again in lower */ |
| 612 | if (priv->rx_next > AT91_MB_RX_LOW_LAST && | 638 | if (priv->rx_next > AT91_MB_RX_LOW_LAST && |
| 613 | quota > 0 && mb >= AT91_MB_RX_NUM) { | 639 | quota > 0 && mb > AT91_MB_RX_LAST) { |
| 614 | priv->rx_next = 0; | 640 | priv->rx_next = AT91_MB_RX_FIRST; |
| 615 | goto again; | 641 | goto again; |
| 616 | } | 642 | } |
| 617 | 643 | ||
| @@ -1037,6 +1063,64 @@ static const struct net_device_ops at91_netdev_ops = { | |||
| 1037 | .ndo_start_xmit = at91_start_xmit, | 1063 | .ndo_start_xmit = at91_start_xmit, |
| 1038 | }; | 1064 | }; |
| 1039 | 1065 | ||
| 1066 | static ssize_t at91_sysfs_show_mb0_id(struct device *dev, | ||
| 1067 | struct device_attribute *attr, char *buf) | ||
| 1068 | { | ||
| 1069 | struct at91_priv *priv = netdev_priv(to_net_dev(dev)); | ||
| 1070 | |||
| 1071 | if (priv->mb0_id & CAN_EFF_FLAG) | ||
| 1072 | return snprintf(buf, PAGE_SIZE, "0x%08x\n", priv->mb0_id); | ||
| 1073 | else | ||
| 1074 | return snprintf(buf, PAGE_SIZE, "0x%03x\n", priv->mb0_id); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | static ssize_t at91_sysfs_set_mb0_id(struct device *dev, | ||
| 1078 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 1079 | { | ||
| 1080 | struct net_device *ndev = to_net_dev(dev); | ||
| 1081 | struct at91_priv *priv = netdev_priv(ndev); | ||
| 1082 | unsigned long can_id; | ||
| 1083 | ssize_t ret; | ||
| 1084 | int err; | ||
| 1085 | |||
| 1086 | rtnl_lock(); | ||
| 1087 | |||
| 1088 | if (ndev->flags & IFF_UP) { | ||
| 1089 | ret = -EBUSY; | ||
| 1090 | goto out; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | err = strict_strtoul(buf, 0, &can_id); | ||
| 1094 | if (err) { | ||
| 1095 | ret = err; | ||
| 1096 | goto out; | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | if (can_id & CAN_EFF_FLAG) | ||
| 1100 | can_id &= CAN_EFF_MASK | CAN_EFF_FLAG; | ||
| 1101 | else | ||
| 1102 | can_id &= CAN_SFF_MASK; | ||
| 1103 | |||
| 1104 | priv->mb0_id = can_id; | ||
| 1105 | ret = count; | ||
| 1106 | |||
| 1107 | out: | ||
| 1108 | rtnl_unlock(); | ||
| 1109 | return ret; | ||
| 1110 | } | ||
| 1111 | |||
| 1112 | static DEVICE_ATTR(mb0_id, S_IWUSR | S_IRUGO, | ||
| 1113 | at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id); | ||
| 1114 | |||
| 1115 | static struct attribute *at91_sysfs_attrs[] = { | ||
| 1116 | &dev_attr_mb0_id.attr, | ||
| 1117 | NULL, | ||
| 1118 | }; | ||
| 1119 | |||
| 1120 | static struct attribute_group at91_sysfs_attr_group = { | ||
| 1121 | .attrs = at91_sysfs_attrs, | ||
| 1122 | }; | ||
| 1123 | |||
| 1040 | static int __devinit at91_can_probe(struct platform_device *pdev) | 1124 | static int __devinit at91_can_probe(struct platform_device *pdev) |
| 1041 | { | 1125 | { |
| 1042 | struct net_device *dev; | 1126 | struct net_device *dev; |
| @@ -1082,6 +1166,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
| 1082 | dev->netdev_ops = &at91_netdev_ops; | 1166 | dev->netdev_ops = &at91_netdev_ops; |
| 1083 | dev->irq = irq; | 1167 | dev->irq = irq; |
| 1084 | dev->flags |= IFF_ECHO; | 1168 | dev->flags |= IFF_ECHO; |
| 1169 | dev->sysfs_groups[0] = &at91_sysfs_attr_group; | ||
| 1085 | 1170 | ||
| 1086 | priv = netdev_priv(dev); | 1171 | priv = netdev_priv(dev); |
| 1087 | priv->can.clock.freq = clk_get_rate(clk); | 1172 | priv->can.clock.freq = clk_get_rate(clk); |
| @@ -1093,6 +1178,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev) | |||
| 1093 | priv->dev = dev; | 1178 | priv->dev = dev; |
| 1094 | priv->clk = clk; | 1179 | priv->clk = clk; |
| 1095 | priv->pdata = pdev->dev.platform_data; | 1180 | priv->pdata = pdev->dev.platform_data; |
| 1181 | priv->mb0_id = 0x7ff; | ||
| 1096 | 1182 | ||
| 1097 | netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); | 1183 | netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT); |
| 1098 | 1184 | ||
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index b9a6d7a5a739..366f5cc050ae 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
| @@ -1618,7 +1618,7 @@ static ssize_t ican3_sysfs_set_term(struct device *dev, | |||
| 1618 | return count; | 1618 | return count; |
| 1619 | } | 1619 | } |
| 1620 | 1620 | ||
| 1621 | static DEVICE_ATTR(termination, S_IWUGO | S_IRUGO, ican3_sysfs_show_term, | 1621 | static DEVICE_ATTR(termination, S_IWUSR | S_IRUGO, ican3_sysfs_show_term, |
| 1622 | ican3_sysfs_set_term); | 1622 | ican3_sysfs_set_term); |
| 1623 | 1623 | ||
| 1624 | static struct attribute *ican3_sysfs_attrs[] = { | 1624 | static struct attribute *ican3_sysfs_attrs[] = { |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 7ab534aee452..7513c4523ac4 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
| @@ -940,7 +940,7 @@ static int mcp251x_open(struct net_device *net) | |||
| 940 | goto open_unlock; | 940 | goto open_unlock; |
| 941 | } | 941 | } |
| 942 | 942 | ||
| 943 | priv->wq = create_freezeable_workqueue("mcp251x_wq"); | 943 | priv->wq = create_freezable_workqueue("mcp251x_wq"); |
| 944 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); | 944 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); |
| 945 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); | 945 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); |
| 946 | 946 | ||
diff --git a/drivers/net/can/mscan/Kconfig b/drivers/net/can/mscan/Kconfig index 27d1d398e25e..d38706958af6 100644 --- a/drivers/net/can/mscan/Kconfig +++ b/drivers/net/can/mscan/Kconfig | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | config CAN_MSCAN | 1 | config CAN_MSCAN |
| 2 | depends on CAN_DEV && (PPC || M68K || M68KNOMMU) | 2 | depends on CAN_DEV && (PPC || M68K) |
| 3 | tristate "Support for Freescale MSCAN based chips" | 3 | tristate "Support for Freescale MSCAN based chips" |
| 4 | ---help--- | 4 | ---help--- |
| 5 | The Motorola Scalable Controller Area Network (MSCAN) definition | 5 | The Motorola Scalable Controller Area Network (MSCAN) definition |
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index c42e97268248..e54712b22c27 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c | |||
| @@ -185,7 +185,7 @@ struct pch_can_priv { | |||
| 185 | 185 | ||
| 186 | static struct can_bittiming_const pch_can_bittiming_const = { | 186 | static struct can_bittiming_const pch_can_bittiming_const = { |
| 187 | .name = KBUILD_MODNAME, | 187 | .name = KBUILD_MODNAME, |
| 188 | .tseg1_min = 1, | 188 | .tseg1_min = 2, |
| 189 | .tseg1_max = 16, | 189 | .tseg1_max = 16, |
| 190 | .tseg2_min = 1, | 190 | .tseg2_min = 1, |
| 191 | .tseg2_max = 8, | 191 | .tseg2_max = 8, |
| @@ -959,13 +959,13 @@ static void __devexit pch_can_remove(struct pci_dev *pdev) | |||
| 959 | struct pch_can_priv *priv = netdev_priv(ndev); | 959 | struct pch_can_priv *priv = netdev_priv(ndev); |
| 960 | 960 | ||
| 961 | unregister_candev(priv->ndev); | 961 | unregister_candev(priv->ndev); |
| 962 | pci_iounmap(pdev, priv->regs); | ||
| 963 | if (priv->use_msi) | 962 | if (priv->use_msi) |
| 964 | pci_disable_msi(priv->dev); | 963 | pci_disable_msi(priv->dev); |
| 965 | pci_release_regions(pdev); | 964 | pci_release_regions(pdev); |
| 966 | pci_disable_device(pdev); | 965 | pci_disable_device(pdev); |
| 967 | pci_set_drvdata(pdev, NULL); | 966 | pci_set_drvdata(pdev, NULL); |
| 968 | pch_can_reset(priv); | 967 | pch_can_reset(priv); |
| 968 | pci_iounmap(pdev, priv->regs); | ||
| 969 | free_candev(priv->ndev); | 969 | free_candev(priv->ndev); |
| 970 | } | 970 | } |
| 971 | 971 | ||
| @@ -1238,6 +1238,7 @@ static int __devinit pch_can_probe(struct pci_dev *pdev, | |||
| 1238 | priv->use_msi = 0; | 1238 | priv->use_msi = 0; |
| 1239 | } else { | 1239 | } else { |
| 1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); | 1240 | netdev_err(ndev, "PCH CAN opened with MSI\n"); |
| 1241 | pci_set_master(pdev); | ||
| 1241 | priv->use_msi = 1; | 1242 | priv->use_msi = 1; |
| 1242 | } | 1243 | } |
| 1243 | 1244 | ||
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig new file mode 100644 index 000000000000..5de46a9a77bb --- /dev/null +++ b/drivers/net/can/softing/Kconfig | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | config CAN_SOFTING | ||
| 2 | tristate "Softing Gmbh CAN generic support" | ||
| 3 | depends on CAN_DEV && HAS_IOMEM | ||
| 4 | ---help--- | ||
| 5 | Support for CAN cards from Softing Gmbh & some cards | ||
| 6 | from Vector Gmbh. | ||
| 7 | Softing Gmbh CAN cards come with 1 or 2 physical busses. | ||
| 8 | Those cards typically use Dual Port RAM to communicate | ||
| 9 | with the host CPU. The interface is then identical for PCI | ||
| 10 | and PCMCIA cards. This driver operates on a platform device, | ||
| 11 | which has been created by softing_cs or softing_pci driver. | ||
| 12 | Warning: | ||
| 13 | The API of the card does not allow fine control per bus, but | ||
| 14 | controls the 2 busses on the card together. | ||
| 15 | As such, some actions (start/stop/busoff recovery) on 1 bus | ||
| 16 | must bring down the other bus too temporarily. | ||
| 17 | |||
| 18 | config CAN_SOFTING_CS | ||
| 19 | tristate "Softing Gmbh CAN pcmcia cards" | ||
| 20 | depends on PCMCIA | ||
| 21 | depends on CAN_SOFTING | ||
| 22 | ---help--- | ||
| 23 | Support for PCMCIA cards from Softing Gmbh & some cards | ||
| 24 | from Vector Gmbh. | ||
| 25 | You need firmware for these, which you can get at | ||
| 26 | http://developer.berlios.de/projects/socketcan/ | ||
| 27 | This version of the driver is written against | ||
| 28 | firmware version 4.6 (softing-fw-4.6-binaries.tar.gz) | ||
| 29 | In order to use the card as CAN device, you need the Softing generic | ||
| 30 | support too. | ||
diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile new file mode 100644 index 000000000000..c5e5016c742e --- /dev/null +++ b/drivers/net/can/softing/Makefile | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | |||
| 2 | softing-y := softing_main.o softing_fw.o | ||
| 3 | obj-$(CONFIG_CAN_SOFTING) += softing.o | ||
| 4 | obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o | ||
| 5 | |||
| 6 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | ||
diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h new file mode 100644 index 000000000000..7ec9f4db3d52 --- /dev/null +++ b/drivers/net/can/softing/softing.h | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | /* | ||
| 2 | * softing common interfaces | ||
| 3 | * | ||
| 4 | * by Kurt Van Dijck, 2008-2010 | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/atomic.h> | ||
| 8 | #include <linux/netdevice.h> | ||
| 9 | #include <linux/ktime.h> | ||
| 10 | #include <linux/mutex.h> | ||
| 11 | #include <linux/spinlock.h> | ||
| 12 | #include <linux/can.h> | ||
| 13 | #include <linux/can/dev.h> | ||
| 14 | |||
| 15 | #include "softing_platform.h" | ||
| 16 | |||
| 17 | struct softing; | ||
| 18 | |||
| 19 | struct softing_priv { | ||
| 20 | struct can_priv can; /* must be the first member! */ | ||
| 21 | struct net_device *netdev; | ||
| 22 | struct softing *card; | ||
| 23 | struct { | ||
| 24 | int pending; | ||
| 25 | /* variables wich hold the circular buffer */ | ||
| 26 | int echo_put; | ||
| 27 | int echo_get; | ||
| 28 | } tx; | ||
| 29 | struct can_bittiming_const btr_const; | ||
| 30 | int index; | ||
| 31 | uint8_t output; | ||
| 32 | uint16_t chip; | ||
| 33 | }; | ||
| 34 | #define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev)) | ||
| 35 | |||
| 36 | struct softing { | ||
| 37 | const struct softing_platform_data *pdat; | ||
| 38 | struct platform_device *pdev; | ||
| 39 | struct net_device *net[2]; | ||
| 40 | spinlock_t spin; /* protect this structure & DPRAM access */ | ||
| 41 | ktime_t ts_ref; | ||
| 42 | ktime_t ts_overflow; /* timestamp overflow value, in ktime */ | ||
| 43 | |||
| 44 | struct { | ||
| 45 | /* indication of firmware status */ | ||
| 46 | int up; | ||
| 47 | /* protection of the 'up' variable */ | ||
| 48 | struct mutex lock; | ||
| 49 | } fw; | ||
| 50 | struct { | ||
| 51 | int nr; | ||
| 52 | int requested; | ||
| 53 | int svc_count; | ||
| 54 | unsigned int dpram_position; | ||
| 55 | } irq; | ||
| 56 | struct { | ||
| 57 | int pending; | ||
| 58 | int last_bus; | ||
| 59 | /* | ||
| 60 | * keep the bus that last tx'd a message, | ||
| 61 | * in order to let every netdev queue resume | ||
| 62 | */ | ||
| 63 | } tx; | ||
| 64 | __iomem uint8_t *dpram; | ||
| 65 | unsigned long dpram_phys; | ||
| 66 | unsigned long dpram_size; | ||
| 67 | struct { | ||
| 68 | uint16_t fw_version, hw_version, license, serial; | ||
| 69 | uint16_t chip[2]; | ||
| 70 | unsigned int freq; /* remote cpu's operating frequency */ | ||
| 71 | } id; | ||
| 72 | }; | ||
| 73 | |||
| 74 | extern int softing_default_output(struct net_device *netdev); | ||
| 75 | |||
| 76 | extern ktime_t softing_raw2ktime(struct softing *card, u32 raw); | ||
| 77 | |||
| 78 | extern int softing_chip_poweron(struct softing *card); | ||
| 79 | |||
| 80 | extern int softing_bootloader_command(struct softing *card, int16_t cmd, | ||
| 81 | const char *msg); | ||
| 82 | |||
| 83 | /* Load firmware after reset */ | ||
| 84 | extern int softing_load_fw(const char *file, struct softing *card, | ||
| 85 | __iomem uint8_t *virt, unsigned int size, int offset); | ||
| 86 | |||
| 87 | /* Load final application firmware after bootloader */ | ||
| 88 | extern int softing_load_app_fw(const char *file, struct softing *card); | ||
| 89 | |||
| 90 | /* | ||
| 91 | * enable or disable irq | ||
| 92 | * only called with fw.lock locked | ||
| 93 | */ | ||
| 94 | extern int softing_enable_irq(struct softing *card, int enable); | ||
| 95 | |||
| 96 | /* start/stop 1 bus on card */ | ||
| 97 | extern int softing_startstop(struct net_device *netdev, int up); | ||
| 98 | |||
| 99 | /* netif_rx() */ | ||
| 100 | extern int softing_netdev_rx(struct net_device *netdev, | ||
| 101 | const struct can_frame *msg, ktime_t ktime); | ||
| 102 | |||
| 103 | /* SOFTING DPRAM mappings */ | ||
| 104 | #define DPRAM_RX 0x0000 | ||
| 105 | #define DPRAM_RX_SIZE 32 | ||
| 106 | #define DPRAM_RX_CNT 16 | ||
| 107 | #define DPRAM_RX_RD 0x0201 /* uint8_t */ | ||
| 108 | #define DPRAM_RX_WR 0x0205 /* uint8_t */ | ||
| 109 | #define DPRAM_RX_LOST 0x0207 /* uint8_t */ | ||
| 110 | |||
| 111 | #define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */ | ||
| 112 | #define DPRAM_FCT_RESULT 0x0328 /* int16_t */ | ||
| 113 | #define DPRAM_FCT_HOST 0x032b /* uint16_t */ | ||
| 114 | |||
| 115 | #define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */ | ||
| 116 | #define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */ | ||
| 117 | #define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */ | ||
| 118 | #define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */ | ||
| 119 | #define DPRAM_RESET 0x0341 /* uint16_t */ | ||
| 120 | #define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */ | ||
| 121 | #define DPRAM_RESET_TIME 0x034d /* uint16_t */ | ||
| 122 | #define DPRAM_TIME 0x0350 /* uint64_t */ | ||
| 123 | #define DPRAM_WR_START 0x0358 /* uint8_t */ | ||
| 124 | #define DPRAM_WR_END 0x0359 /* uint8_t */ | ||
| 125 | #define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */ | ||
| 126 | #define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */ | ||
| 127 | #define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */ | ||
| 128 | #define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */ | ||
| 129 | #define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */ | ||
| 130 | |||
| 131 | #define DPRAM_TX 0x0400 /* uint16_t */ | ||
| 132 | #define DPRAM_TX_SIZE 16 | ||
| 133 | #define DPRAM_TX_CNT 32 | ||
| 134 | #define DPRAM_TX_RD 0x0601 /* uint8_t */ | ||
| 135 | #define DPRAM_TX_WR 0x0605 /* uint8_t */ | ||
| 136 | |||
| 137 | #define DPRAM_COMMAND 0x07e0 /* uint16_t */ | ||
| 138 | #define DPRAM_RECEIPT 0x07f0 /* uint16_t */ | ||
| 139 | #define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */ | ||
| 140 | #define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */ | ||
| 141 | |||
| 142 | #define DPRAM_V2_RESET 0x0e00 /* uint8_t */ | ||
| 143 | #define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */ | ||
| 144 | |||
| 145 | #define TXMAX (DPRAM_TX_CNT - 1) | ||
| 146 | |||
| 147 | /* DPRAM return codes */ | ||
| 148 | #define RES_NONE 0 | ||
| 149 | #define RES_OK 1 | ||
| 150 | #define RES_NOK 2 | ||
| 151 | #define RES_UNKNOWN 3 | ||
| 152 | /* DPRAM flags */ | ||
| 153 | #define CMD_TX 0x01 | ||
| 154 | #define CMD_ACK 0x02 | ||
| 155 | #define CMD_XTD 0x04 | ||
| 156 | #define CMD_RTR 0x08 | ||
| 157 | #define CMD_ERR 0x10 | ||
| 158 | #define CMD_BUS2 0x80 | ||
| 159 | |||
| 160 | /* returned fifo entry bus state masks */ | ||
| 161 | #define SF_MASK_BUSOFF 0x80 | ||
| 162 | #define SF_MASK_EPASSIVE 0x60 | ||
| 163 | |||
| 164 | /* bus states */ | ||
| 165 | #define STATE_BUSOFF 2 | ||
| 166 | #define STATE_EPASSIVE 1 | ||
| 167 | #define STATE_EACTIVE 0 | ||
diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c new file mode 100644 index 000000000000..c11bb4de8630 --- /dev/null +++ b/drivers/net/can/softing/softing_cs.c | |||
| @@ -0,0 +1,360 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2010 | ||
| 3 | * | ||
| 4 | * - Kurt Van Dijck, EIA Electronics | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the version 2 of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | |||
| 24 | #include <pcmcia/cistpl.h> | ||
| 25 | #include <pcmcia/ds.h> | ||
| 26 | |||
| 27 | #include "softing_platform.h" | ||
| 28 | |||
| 29 | static int softingcs_index; | ||
| 30 | static spinlock_t softingcs_index_lock; | ||
| 31 | |||
| 32 | static int softingcs_reset(struct platform_device *pdev, int v); | ||
| 33 | static int softingcs_enable_irq(struct platform_device *pdev, int v); | ||
| 34 | |||
| 35 | /* | ||
| 36 | * platform_data descriptions | ||
| 37 | */ | ||
| 38 | #define MHZ (1000*1000) | ||
| 39 | static const struct softing_platform_data softingcs_platform_data[] = { | ||
| 40 | { | ||
| 41 | .name = "CANcard", | ||
| 42 | .manf = 0x0168, .prod = 0x001, | ||
| 43 | .generation = 1, | ||
| 44 | .nbus = 2, | ||
| 45 | .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
| 46 | .dpram_size = 0x0800, | ||
| 47 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
| 48 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
| 49 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
| 50 | .reset = softingcs_reset, | ||
| 51 | .enable_irq = softingcs_enable_irq, | ||
| 52 | }, { | ||
| 53 | .name = "CANcard-NEC", | ||
| 54 | .manf = 0x0168, .prod = 0x002, | ||
| 55 | .generation = 1, | ||
| 56 | .nbus = 2, | ||
| 57 | .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
| 58 | .dpram_size = 0x0800, | ||
| 59 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
| 60 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
| 61 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
| 62 | .reset = softingcs_reset, | ||
| 63 | .enable_irq = softingcs_enable_irq, | ||
| 64 | }, { | ||
| 65 | .name = "CANcard-SJA", | ||
| 66 | .manf = 0x0168, .prod = 0x004, | ||
| 67 | .generation = 1, | ||
| 68 | .nbus = 2, | ||
| 69 | .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
| 70 | .dpram_size = 0x0800, | ||
| 71 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
| 72 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
| 73 | .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, | ||
| 74 | .reset = softingcs_reset, | ||
| 75 | .enable_irq = softingcs_enable_irq, | ||
| 76 | }, { | ||
| 77 | .name = "CANcard-2", | ||
| 78 | .manf = 0x0168, .prod = 0x005, | ||
| 79 | .generation = 2, | ||
| 80 | .nbus = 2, | ||
| 81 | .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
| 82 | .dpram_size = 0x1000, | ||
| 83 | .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, | ||
| 84 | .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, | ||
| 85 | .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, | ||
| 86 | .reset = softingcs_reset, | ||
| 87 | .enable_irq = NULL, | ||
| 88 | }, { | ||
| 89 | .name = "Vector-CANcard", | ||
| 90 | .manf = 0x0168, .prod = 0x081, | ||
| 91 | .generation = 1, | ||
| 92 | .nbus = 2, | ||
| 93 | .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
| 94 | .dpram_size = 0x0800, | ||
| 95 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
| 96 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
| 97 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
| 98 | .reset = softingcs_reset, | ||
| 99 | .enable_irq = softingcs_enable_irq, | ||
| 100 | }, { | ||
| 101 | .name = "Vector-CANcard-SJA", | ||
| 102 | .manf = 0x0168, .prod = 0x084, | ||
| 103 | .generation = 1, | ||
| 104 | .nbus = 2, | ||
| 105 | .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, | ||
| 106 | .dpram_size = 0x0800, | ||
| 107 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
| 108 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
| 109 | .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, | ||
| 110 | .reset = softingcs_reset, | ||
| 111 | .enable_irq = softingcs_enable_irq, | ||
| 112 | }, { | ||
| 113 | .name = "Vector-CANcard-2", | ||
| 114 | .manf = 0x0168, .prod = 0x085, | ||
| 115 | .generation = 2, | ||
| 116 | .nbus = 2, | ||
| 117 | .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
| 118 | .dpram_size = 0x1000, | ||
| 119 | .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, | ||
| 120 | .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, | ||
| 121 | .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, | ||
| 122 | .reset = softingcs_reset, | ||
| 123 | .enable_irq = NULL, | ||
| 124 | }, { | ||
| 125 | .name = "EDICcard-NEC", | ||
| 126 | .manf = 0x0168, .prod = 0x102, | ||
| 127 | .generation = 1, | ||
| 128 | .nbus = 2, | ||
| 129 | .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
| 130 | .dpram_size = 0x0800, | ||
| 131 | .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, | ||
| 132 | .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, | ||
| 133 | .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, | ||
| 134 | .reset = softingcs_reset, | ||
| 135 | .enable_irq = softingcs_enable_irq, | ||
| 136 | }, { | ||
| 137 | .name = "EDICcard-2", | ||
| 138 | .manf = 0x0168, .prod = 0x105, | ||
| 139 | .generation = 2, | ||
| 140 | .nbus = 2, | ||
| 141 | .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, | ||
| 142 | .dpram_size = 0x1000, | ||
| 143 | .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, | ||
| 144 | .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, | ||
| 145 | .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, | ||
| 146 | .reset = softingcs_reset, | ||
| 147 | .enable_irq = NULL, | ||
| 148 | }, { | ||
| 149 | 0, 0, | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | MODULE_FIRMWARE(fw_dir "bcard.bin"); | ||
| 154 | MODULE_FIRMWARE(fw_dir "ldcard.bin"); | ||
| 155 | MODULE_FIRMWARE(fw_dir "cancard.bin"); | ||
| 156 | MODULE_FIRMWARE(fw_dir "cansja.bin"); | ||
| 157 | |||
| 158 | MODULE_FIRMWARE(fw_dir "bcard2.bin"); | ||
| 159 | MODULE_FIRMWARE(fw_dir "ldcard2.bin"); | ||
| 160 | MODULE_FIRMWARE(fw_dir "cancrd2.bin"); | ||
| 161 | |||
| 162 | static __devinit const struct softing_platform_data | ||
| 163 | *softingcs_find_platform_data(unsigned int manf, unsigned int prod) | ||
| 164 | { | ||
| 165 | const struct softing_platform_data *lp; | ||
| 166 | |||
| 167 | for (lp = softingcs_platform_data; lp->manf; ++lp) { | ||
| 168 | if ((lp->manf == manf) && (lp->prod == prod)) | ||
| 169 | return lp; | ||
| 170 | } | ||
| 171 | return NULL; | ||
| 172 | } | ||
| 173 | |||
| 174 | /* | ||
| 175 | * platformdata callbacks | ||
| 176 | */ | ||
| 177 | static int softingcs_reset(struct platform_device *pdev, int v) | ||
| 178 | { | ||
| 179 | struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); | ||
| 180 | |||
| 181 | dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20); | ||
| 182 | return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20); | ||
| 183 | } | ||
| 184 | |||
| 185 | static int softingcs_enable_irq(struct platform_device *pdev, int v) | ||
| 186 | { | ||
| 187 | struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); | ||
| 188 | |||
| 189 | dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0); | ||
| 190 | return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* | ||
| 194 | * pcmcia check | ||
| 195 | */ | ||
| 196 | static __devinit int softingcs_probe_config(struct pcmcia_device *pcmcia, | ||
| 197 | void *priv_data) | ||
| 198 | { | ||
| 199 | struct softing_platform_data *pdat = priv_data; | ||
| 200 | struct resource *pres; | ||
| 201 | int memspeed = 0; | ||
| 202 | |||
| 203 | WARN_ON(!pdat); | ||
| 204 | pres = pcmcia->resource[PCMCIA_IOMEM_0]; | ||
| 205 | if (resource_size(pres) < 0x1000) | ||
| 206 | return -ERANGE; | ||
| 207 | |||
| 208 | pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; | ||
| 209 | if (pdat->generation < 2) { | ||
| 210 | pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8; | ||
| 211 | memspeed = 3; | ||
| 212 | } else { | ||
| 213 | pres->flags |= WIN_DATA_WIDTH_16; | ||
| 214 | } | ||
| 215 | return pcmcia_request_window(pcmcia, pres, memspeed); | ||
| 216 | } | ||
| 217 | |||
| 218 | static __devexit void softingcs_remove(struct pcmcia_device *pcmcia) | ||
| 219 | { | ||
| 220 | struct platform_device *pdev = pcmcia->priv; | ||
| 221 | |||
| 222 | /* free bits */ | ||
| 223 | platform_device_unregister(pdev); | ||
| 224 | /* release pcmcia stuff */ | ||
| 225 | pcmcia_disable_device(pcmcia); | ||
| 226 | } | ||
| 227 | |||
| 228 | /* | ||
| 229 | * platform_device wrapper | ||
| 230 | * pdev->resource has 2 entries: io & irq | ||
| 231 | */ | ||
| 232 | static void softingcs_pdev_release(struct device *dev) | ||
| 233 | { | ||
| 234 | struct platform_device *pdev = to_platform_device(dev); | ||
| 235 | kfree(pdev); | ||
| 236 | } | ||
| 237 | |||
| 238 | static __devinit int softingcs_probe(struct pcmcia_device *pcmcia) | ||
| 239 | { | ||
| 240 | int ret; | ||
| 241 | struct platform_device *pdev; | ||
| 242 | const struct softing_platform_data *pdat; | ||
| 243 | struct resource *pres; | ||
| 244 | struct dev { | ||
| 245 | struct platform_device pdev; | ||
| 246 | struct resource res[2]; | ||
| 247 | } *dev; | ||
| 248 | |||
| 249 | /* find matching platform_data */ | ||
| 250 | pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id); | ||
| 251 | if (!pdat) | ||
| 252 | return -ENOTTY; | ||
| 253 | |||
| 254 | /* setup pcmcia device */ | ||
| 255 | pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM | | ||
| 256 | CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; | ||
| 257 | ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat); | ||
| 258 | if (ret) | ||
| 259 | goto pcmcia_failed; | ||
| 260 | |||
| 261 | ret = pcmcia_enable_device(pcmcia); | ||
| 262 | if (ret < 0) | ||
| 263 | goto pcmcia_failed; | ||
| 264 | |||
| 265 | pres = pcmcia->resource[PCMCIA_IOMEM_0]; | ||
| 266 | if (!pres) { | ||
| 267 | ret = -EBADF; | ||
| 268 | goto pcmcia_bad; | ||
| 269 | } | ||
| 270 | |||
| 271 | /* create softing platform device */ | ||
| 272 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 273 | if (!dev) { | ||
| 274 | ret = -ENOMEM; | ||
| 275 | goto mem_failed; | ||
| 276 | } | ||
| 277 | dev->pdev.resource = dev->res; | ||
| 278 | dev->pdev.num_resources = ARRAY_SIZE(dev->res); | ||
| 279 | dev->pdev.dev.release = softingcs_pdev_release; | ||
| 280 | |||
| 281 | pdev = &dev->pdev; | ||
| 282 | pdev->dev.platform_data = (void *)pdat; | ||
| 283 | pdev->dev.parent = &pcmcia->dev; | ||
| 284 | pcmcia->priv = pdev; | ||
| 285 | |||
| 286 | /* platform device resources */ | ||
| 287 | pdev->resource[0].flags = IORESOURCE_MEM; | ||
| 288 | pdev->resource[0].start = pres->start; | ||
| 289 | pdev->resource[0].end = pres->end; | ||
| 290 | |||
| 291 | pdev->resource[1].flags = IORESOURCE_IRQ; | ||
| 292 | pdev->resource[1].start = pcmcia->irq; | ||
| 293 | pdev->resource[1].end = pdev->resource[1].start; | ||
| 294 | |||
| 295 | /* platform device setup */ | ||
| 296 | spin_lock(&softingcs_index_lock); | ||
| 297 | pdev->id = softingcs_index++; | ||
| 298 | spin_unlock(&softingcs_index_lock); | ||
| 299 | pdev->name = "softing"; | ||
| 300 | dev_set_name(&pdev->dev, "softingcs.%i", pdev->id); | ||
| 301 | ret = platform_device_register(pdev); | ||
| 302 | if (ret < 0) | ||
| 303 | goto platform_failed; | ||
| 304 | |||
| 305 | dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev)); | ||
| 306 | return 0; | ||
| 307 | |||
| 308 | platform_failed: | ||
| 309 | kfree(dev); | ||
| 310 | mem_failed: | ||
| 311 | pcmcia_bad: | ||
| 312 | pcmcia_failed: | ||
| 313 | pcmcia_disable_device(pcmcia); | ||
| 314 | pcmcia->priv = NULL; | ||
| 315 | return ret ?: -ENODEV; | ||
| 316 | } | ||
| 317 | |||
| 318 | static /*const*/ struct pcmcia_device_id softingcs_ids[] = { | ||
| 319 | /* softing */ | ||
| 320 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001), | ||
| 321 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002), | ||
| 322 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004), | ||
| 323 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005), | ||
| 324 | /* vector, manufacturer? */ | ||
| 325 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081), | ||
| 326 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084), | ||
| 327 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085), | ||
| 328 | /* EDIC */ | ||
| 329 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102), | ||
| 330 | PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105), | ||
| 331 | PCMCIA_DEVICE_NULL, | ||
| 332 | }; | ||
| 333 | |||
| 334 | MODULE_DEVICE_TABLE(pcmcia, softingcs_ids); | ||
| 335 | |||
| 336 | static struct pcmcia_driver softingcs_driver = { | ||
| 337 | .owner = THIS_MODULE, | ||
| 338 | .name = "softingcs", | ||
| 339 | .id_table = softingcs_ids, | ||
| 340 | .probe = softingcs_probe, | ||
| 341 | .remove = __devexit_p(softingcs_remove), | ||
| 342 | }; | ||
| 343 | |||
| 344 | static int __init softingcs_start(void) | ||
| 345 | { | ||
| 346 | spin_lock_init(&softingcs_index_lock); | ||
| 347 | return pcmcia_register_driver(&softingcs_driver); | ||
| 348 | } | ||
| 349 | |||
| 350 | static void __exit softingcs_stop(void) | ||
| 351 | { | ||
| 352 | pcmcia_unregister_driver(&softingcs_driver); | ||
| 353 | } | ||
| 354 | |||
| 355 | module_init(softingcs_start); | ||
| 356 | module_exit(softingcs_stop); | ||
| 357 | |||
| 358 | MODULE_DESCRIPTION("softing CANcard driver" | ||
| 359 | ", links PCMCIA card to softing driver"); | ||
| 360 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c new file mode 100644 index 000000000000..b520784fb197 --- /dev/null +++ b/drivers/net/can/softing/softing_fw.c | |||
| @@ -0,0 +1,691 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2010 | ||
| 3 | * | ||
| 4 | * - Kurt Van Dijck, EIA Electronics | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the version 2 of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/firmware.h> | ||
| 21 | #include <linux/sched.h> | ||
| 22 | #include <asm/div64.h> | ||
| 23 | |||
| 24 | #include "softing.h" | ||
| 25 | |||
| 26 | /* | ||
| 27 | * low level DPRAM command. | ||
| 28 | * Make sure that card->dpram[DPRAM_FCT_HOST] is preset | ||
| 29 | */ | ||
| 30 | static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector, | ||
| 31 | const char *msg) | ||
| 32 | { | ||
| 33 | int ret; | ||
| 34 | unsigned long stamp; | ||
| 35 | |||
| 36 | iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]); | ||
| 37 | iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]); | ||
| 38 | iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]); | ||
| 39 | /* be sure to flush this to the card */ | ||
| 40 | wmb(); | ||
| 41 | stamp = jiffies + 1 * HZ; | ||
| 42 | /* wait for card */ | ||
| 43 | do { | ||
| 44 | /* DPRAM_FCT_HOST is _not_ aligned */ | ||
| 45 | ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) + | ||
| 46 | (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8); | ||
| 47 | /* don't have any cached variables */ | ||
| 48 | rmb(); | ||
| 49 | if (ret == RES_OK) | ||
| 50 | /* read return-value now */ | ||
| 51 | return ioread16(&card->dpram[DPRAM_FCT_RESULT]); | ||
| 52 | |||
| 53 | if ((ret != vector) || time_after(jiffies, stamp)) | ||
| 54 | break; | ||
| 55 | /* process context => relax */ | ||
| 56 | usleep_range(500, 10000); | ||
| 57 | } while (1); | ||
| 58 | |||
| 59 | ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; | ||
| 60 | dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret); | ||
| 61 | return ret; | ||
| 62 | } | ||
| 63 | |||
| 64 | static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg) | ||
| 65 | { | ||
| 66 | int ret; | ||
| 67 | |||
| 68 | ret = _softing_fct_cmd(card, cmd, 0, msg); | ||
| 69 | if (ret > 0) { | ||
| 70 | dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret); | ||
| 71 | ret = -EIO; | ||
| 72 | } | ||
| 73 | return ret; | ||
| 74 | } | ||
| 75 | |||
| 76 | int softing_bootloader_command(struct softing *card, int16_t cmd, | ||
| 77 | const char *msg) | ||
| 78 | { | ||
| 79 | int ret; | ||
| 80 | unsigned long stamp; | ||
| 81 | |||
| 82 | iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]); | ||
| 83 | iowrite16(cmd, &card->dpram[DPRAM_COMMAND]); | ||
| 84 | /* be sure to flush this to the card */ | ||
| 85 | wmb(); | ||
| 86 | stamp = jiffies + 3 * HZ; | ||
| 87 | /* wait for card */ | ||
| 88 | do { | ||
| 89 | ret = ioread16(&card->dpram[DPRAM_RECEIPT]); | ||
| 90 | /* don't have any cached variables */ | ||
| 91 | rmb(); | ||
| 92 | if (ret == RES_OK) | ||
| 93 | return 0; | ||
| 94 | if (time_after(jiffies, stamp)) | ||
| 95 | break; | ||
| 96 | /* process context => relax */ | ||
| 97 | usleep_range(500, 10000); | ||
| 98 | } while (!signal_pending(current)); | ||
| 99 | |||
| 100 | ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; | ||
| 101 | dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret); | ||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr, | ||
| 106 | uint16_t *plen, const uint8_t **pdat) | ||
| 107 | { | ||
| 108 | uint16_t checksum[2]; | ||
| 109 | const uint8_t *mem; | ||
| 110 | const uint8_t *end; | ||
| 111 | |||
| 112 | /* | ||
| 113 | * firmware records are a binary, unaligned stream composed of: | ||
| 114 | * uint16_t type; | ||
| 115 | * uint32_t addr; | ||
| 116 | * uint16_t len; | ||
| 117 | * uint8_t dat[len]; | ||
| 118 | * uint16_t checksum; | ||
| 119 | * all values in little endian. | ||
| 120 | * We could define a struct for this, with __attribute__((packed)), | ||
| 121 | * but would that solve the alignment in _all_ cases (cfr. the | ||
| 122 | * struct itself may be an odd address)? | ||
| 123 | * | ||
| 124 | * I chose to use leXX_to_cpup() since this solves both | ||
| 125 | * endianness & alignment. | ||
| 126 | */ | ||
| 127 | mem = *pmem; | ||
| 128 | *ptype = le16_to_cpup((void *)&mem[0]); | ||
| 129 | *paddr = le32_to_cpup((void *)&mem[2]); | ||
| 130 | *plen = le16_to_cpup((void *)&mem[6]); | ||
| 131 | *pdat = &mem[8]; | ||
| 132 | /* verify checksum */ | ||
| 133 | end = &mem[8 + *plen]; | ||
| 134 | checksum[0] = le16_to_cpup((void *)end); | ||
| 135 | for (checksum[1] = 0; mem < end; ++mem) | ||
| 136 | checksum[1] += *mem; | ||
| 137 | if (checksum[0] != checksum[1]) | ||
| 138 | return -EINVAL; | ||
| 139 | /* increment */ | ||
| 140 | *pmem += 10 + *plen; | ||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | int softing_load_fw(const char *file, struct softing *card, | ||
| 145 | __iomem uint8_t *dpram, unsigned int size, int offset) | ||
| 146 | { | ||
| 147 | const struct firmware *fw; | ||
| 148 | int ret; | ||
| 149 | const uint8_t *mem, *end, *dat; | ||
| 150 | uint16_t type, len; | ||
| 151 | uint32_t addr; | ||
| 152 | uint8_t *buf = NULL; | ||
| 153 | int buflen = 0; | ||
| 154 | int8_t type_end = 0; | ||
| 155 | |||
| 156 | ret = request_firmware(&fw, file, &card->pdev->dev); | ||
| 157 | if (ret < 0) | ||
| 158 | return ret; | ||
| 159 | dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes" | ||
| 160 | ", offset %c0x%04x\n", | ||
| 161 | card->pdat->name, file, (unsigned int)fw->size, | ||
| 162 | (offset >= 0) ? '+' : '-', (unsigned int)abs(offset)); | ||
| 163 | /* parse the firmware */ | ||
| 164 | mem = fw->data; | ||
| 165 | end = &mem[fw->size]; | ||
| 166 | /* look for header record */ | ||
| 167 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
| 168 | if (ret < 0) | ||
| 169 | goto failed; | ||
| 170 | if (type != 0xffff) | ||
| 171 | goto failed; | ||
| 172 | if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { | ||
| 173 | ret = -EINVAL; | ||
| 174 | goto failed; | ||
| 175 | } | ||
| 176 | /* ok, we had a header */ | ||
| 177 | while (mem < end) { | ||
| 178 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
| 179 | if (ret < 0) | ||
| 180 | goto failed; | ||
| 181 | if (type == 3) { | ||
| 182 | /* start address, not used here */ | ||
| 183 | continue; | ||
| 184 | } else if (type == 1) { | ||
| 185 | /* eof */ | ||
| 186 | type_end = 1; | ||
| 187 | break; | ||
| 188 | } else if (type != 0) { | ||
| 189 | ret = -EINVAL; | ||
| 190 | goto failed; | ||
| 191 | } | ||
| 192 | |||
| 193 | if ((addr + len + offset) > size) | ||
| 194 | goto failed; | ||
| 195 | memcpy_toio(&dpram[addr + offset], dat, len); | ||
| 196 | /* be sure to flush caches from IO space */ | ||
| 197 | mb(); | ||
| 198 | if (len > buflen) { | ||
| 199 | /* align buflen */ | ||
| 200 | buflen = (len + (1024-1)) & ~(1024-1); | ||
| 201 | buf = krealloc(buf, buflen, GFP_KERNEL); | ||
| 202 | if (!buf) { | ||
| 203 | ret = -ENOMEM; | ||
| 204 | goto failed; | ||
| 205 | } | ||
| 206 | } | ||
| 207 | /* verify record data */ | ||
| 208 | memcpy_fromio(buf, &dpram[addr + offset], len); | ||
| 209 | if (memcmp(buf, dat, len)) { | ||
| 210 | /* is not ok */ | ||
| 211 | dev_alert(&card->pdev->dev, "DPRAM readback failed\n"); | ||
| 212 | ret = -EIO; | ||
| 213 | goto failed; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | if (!type_end) | ||
| 217 | /* no end record seen */ | ||
| 218 | goto failed; | ||
| 219 | ret = 0; | ||
| 220 | failed: | ||
| 221 | kfree(buf); | ||
| 222 | release_firmware(fw); | ||
| 223 | if (ret < 0) | ||
| 224 | dev_info(&card->pdev->dev, "firmware %s failed\n", file); | ||
| 225 | return ret; | ||
| 226 | } | ||
| 227 | |||
| 228 | int softing_load_app_fw(const char *file, struct softing *card) | ||
| 229 | { | ||
| 230 | const struct firmware *fw; | ||
| 231 | const uint8_t *mem, *end, *dat; | ||
| 232 | int ret, j; | ||
| 233 | uint16_t type, len; | ||
| 234 | uint32_t addr, start_addr = 0; | ||
| 235 | unsigned int sum, rx_sum; | ||
| 236 | int8_t type_end = 0, type_entrypoint = 0; | ||
| 237 | |||
| 238 | ret = request_firmware(&fw, file, &card->pdev->dev); | ||
| 239 | if (ret) { | ||
| 240 | dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", | ||
| 241 | file, ret); | ||
| 242 | return ret; | ||
| 243 | } | ||
| 244 | dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", | ||
| 245 | file, (unsigned long)fw->size); | ||
| 246 | /* parse the firmware */ | ||
| 247 | mem = fw->data; | ||
| 248 | end = &mem[fw->size]; | ||
| 249 | /* look for header record */ | ||
| 250 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
| 251 | if (ret) | ||
| 252 | goto failed; | ||
| 253 | ret = -EINVAL; | ||
| 254 | if (type != 0xffff) { | ||
| 255 | dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n", | ||
| 256 | type); | ||
| 257 | goto failed; | ||
| 258 | } | ||
| 259 | if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) { | ||
| 260 | dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n", | ||
| 261 | len, dat); | ||
| 262 | goto failed; | ||
| 263 | } | ||
| 264 | /* ok, we had a header */ | ||
| 265 | while (mem < end) { | ||
| 266 | ret = fw_parse(&mem, &type, &addr, &len, &dat); | ||
| 267 | if (ret) | ||
| 268 | goto failed; | ||
| 269 | |||
| 270 | if (type == 3) { | ||
| 271 | /* start address */ | ||
| 272 | start_addr = addr; | ||
| 273 | type_entrypoint = 1; | ||
| 274 | continue; | ||
| 275 | } else if (type == 1) { | ||
| 276 | /* eof */ | ||
| 277 | type_end = 1; | ||
| 278 | break; | ||
| 279 | } else if (type != 0) { | ||
| 280 | dev_alert(&card->pdev->dev, | ||
| 281 | "unknown record type 0x%04x\n", type); | ||
| 282 | ret = -EINVAL; | ||
| 283 | goto failed; | ||
| 284 | } | ||
| 285 | |||
| 286 | /* regualar data */ | ||
| 287 | for (sum = 0, j = 0; j < len; ++j) | ||
| 288 | sum += dat[j]; | ||
| 289 | /* work in 16bit (target) */ | ||
| 290 | sum &= 0xffff; | ||
| 291 | |||
| 292 | memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); | ||
| 293 | iowrite32(card->pdat->app.offs + card->pdat->app.addr, | ||
| 294 | &card->dpram[DPRAM_COMMAND + 2]); | ||
| 295 | iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]); | ||
| 296 | iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]); | ||
| 297 | iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]); | ||
| 298 | ret = softing_bootloader_command(card, 1, "loading app."); | ||
| 299 | if (ret < 0) | ||
| 300 | goto failed; | ||
| 301 | /* verify checksum */ | ||
| 302 | rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]); | ||
| 303 | if (rx_sum != sum) { | ||
| 304 | dev_alert(&card->pdev->dev, "SRAM seems to be damaged" | ||
| 305 | ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum); | ||
| 306 | ret = -EIO; | ||
| 307 | goto failed; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | if (!type_end || !type_entrypoint) | ||
| 311 | goto failed; | ||
| 312 | /* start application in card */ | ||
| 313 | iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]); | ||
| 314 | iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]); | ||
| 315 | ret = softing_bootloader_command(card, 3, "start app."); | ||
| 316 | if (ret < 0) | ||
| 317 | goto failed; | ||
| 318 | ret = 0; | ||
| 319 | failed: | ||
| 320 | release_firmware(fw); | ||
| 321 | if (ret < 0) | ||
| 322 | dev_info(&card->pdev->dev, "firmware %s failed\n", file); | ||
| 323 | return ret; | ||
| 324 | } | ||
| 325 | |||
| 326 | static int softing_reset_chip(struct softing *card) | ||
| 327 | { | ||
| 328 | int ret; | ||
| 329 | |||
| 330 | do { | ||
| 331 | /* reset chip */ | ||
| 332 | iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]); | ||
| 333 | iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]); | ||
| 334 | iowrite8(1, &card->dpram[DPRAM_RESET]); | ||
| 335 | iowrite8(0, &card->dpram[DPRAM_RESET+1]); | ||
| 336 | |||
| 337 | ret = softing_fct_cmd(card, 0, "reset_can"); | ||
| 338 | if (!ret) | ||
| 339 | break; | ||
| 340 | if (signal_pending(current)) | ||
| 341 | /* don't wait any longer */ | ||
| 342 | break; | ||
| 343 | } while (1); | ||
| 344 | card->tx.pending = 0; | ||
| 345 | return ret; | ||
| 346 | } | ||
| 347 | |||
| 348 | int softing_chip_poweron(struct softing *card) | ||
| 349 | { | ||
| 350 | int ret; | ||
| 351 | /* sync */ | ||
| 352 | ret = _softing_fct_cmd(card, 99, 0x55, "sync-a"); | ||
| 353 | if (ret < 0) | ||
| 354 | goto failed; | ||
| 355 | |||
| 356 | ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b"); | ||
| 357 | if (ret < 0) | ||
| 358 | goto failed; | ||
| 359 | |||
| 360 | ret = softing_reset_chip(card); | ||
| 361 | if (ret < 0) | ||
| 362 | goto failed; | ||
| 363 | /* get_serial */ | ||
| 364 | ret = softing_fct_cmd(card, 43, "get_serial_number"); | ||
| 365 | if (ret < 0) | ||
| 366 | goto failed; | ||
| 367 | card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]); | ||
| 368 | /* get_version */ | ||
| 369 | ret = softing_fct_cmd(card, 12, "get_version"); | ||
| 370 | if (ret < 0) | ||
| 371 | goto failed; | ||
| 372 | card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 373 | card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 374 | card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]); | ||
| 375 | card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]); | ||
| 376 | card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]); | ||
| 377 | return 0; | ||
| 378 | failed: | ||
| 379 | return ret; | ||
| 380 | } | ||
| 381 | |||
| 382 | static void softing_initialize_timestamp(struct softing *card) | ||
| 383 | { | ||
| 384 | uint64_t ovf; | ||
| 385 | |||
| 386 | card->ts_ref = ktime_get(); | ||
| 387 | |||
| 388 | /* 16MHz is the reference */ | ||
| 389 | ovf = 0x100000000ULL * 16; | ||
| 390 | do_div(ovf, card->pdat->freq ?: 16); | ||
| 391 | |||
| 392 | card->ts_overflow = ktime_add_us(ktime_set(0, 0), ovf); | ||
| 393 | } | ||
| 394 | |||
| 395 | ktime_t softing_raw2ktime(struct softing *card, u32 raw) | ||
| 396 | { | ||
| 397 | uint64_t rawl; | ||
| 398 | ktime_t now, real_offset; | ||
| 399 | ktime_t target; | ||
| 400 | ktime_t tmp; | ||
| 401 | |||
| 402 | now = ktime_get(); | ||
| 403 | real_offset = ktime_sub(ktime_get_real(), now); | ||
| 404 | |||
| 405 | /* find nsec from card */ | ||
| 406 | rawl = raw * 16; | ||
| 407 | do_div(rawl, card->pdat->freq ?: 16); | ||
| 408 | target = ktime_add_us(card->ts_ref, rawl); | ||
| 409 | /* test for overflows */ | ||
| 410 | tmp = ktime_add(target, card->ts_overflow); | ||
| 411 | while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) { | ||
| 412 | card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow); | ||
| 413 | target = tmp; | ||
| 414 | tmp = ktime_add(target, card->ts_overflow); | ||
| 415 | } | ||
| 416 | return ktime_add(target, real_offset); | ||
| 417 | } | ||
| 418 | |||
| 419 | static inline int softing_error_reporting(struct net_device *netdev) | ||
| 420 | { | ||
| 421 | struct softing_priv *priv = netdev_priv(netdev); | ||
| 422 | |||
| 423 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | ||
| 424 | ? 1 : 0; | ||
| 425 | } | ||
| 426 | |||
| 427 | int softing_startstop(struct net_device *dev, int up) | ||
| 428 | { | ||
| 429 | int ret; | ||
| 430 | struct softing *card; | ||
| 431 | struct softing_priv *priv; | ||
| 432 | struct net_device *netdev; | ||
| 433 | int bus_bitmask_start; | ||
| 434 | int j, error_reporting; | ||
| 435 | struct can_frame msg; | ||
| 436 | const struct can_bittiming *bt; | ||
| 437 | |||
| 438 | priv = netdev_priv(dev); | ||
| 439 | card = priv->card; | ||
| 440 | |||
| 441 | if (!card->fw.up) | ||
| 442 | return -EIO; | ||
| 443 | |||
| 444 | ret = mutex_lock_interruptible(&card->fw.lock); | ||
| 445 | if (ret) | ||
| 446 | return ret; | ||
| 447 | |||
| 448 | bus_bitmask_start = 0; | ||
| 449 | if (dev && up) | ||
| 450 | /* prepare to start this bus as well */ | ||
| 451 | bus_bitmask_start |= (1 << priv->index); | ||
| 452 | /* bring netdevs down */ | ||
| 453 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 454 | netdev = card->net[j]; | ||
| 455 | if (!netdev) | ||
| 456 | continue; | ||
| 457 | priv = netdev_priv(netdev); | ||
| 458 | |||
| 459 | if (dev != netdev) | ||
| 460 | netif_stop_queue(netdev); | ||
| 461 | |||
| 462 | if (netif_running(netdev)) { | ||
| 463 | if (dev != netdev) | ||
| 464 | bus_bitmask_start |= (1 << j); | ||
| 465 | priv->tx.pending = 0; | ||
| 466 | priv->tx.echo_put = 0; | ||
| 467 | priv->tx.echo_get = 0; | ||
| 468 | /* | ||
| 469 | * this bus' may just have called open_candev() | ||
| 470 | * which is rather stupid to call close_candev() | ||
| 471 | * already | ||
| 472 | * but we may come here from busoff recovery too | ||
| 473 | * in which case the echo_skb _needs_ flushing too. | ||
| 474 | * just be sure to call open_candev() again | ||
| 475 | */ | ||
| 476 | close_candev(netdev); | ||
| 477 | } | ||
| 478 | priv->can.state = CAN_STATE_STOPPED; | ||
| 479 | } | ||
| 480 | card->tx.pending = 0; | ||
| 481 | |||
| 482 | softing_enable_irq(card, 0); | ||
| 483 | ret = softing_reset_chip(card); | ||
| 484 | if (ret) | ||
| 485 | goto failed; | ||
| 486 | if (!bus_bitmask_start) | ||
| 487 | /* no busses to be brought up */ | ||
| 488 | goto card_done; | ||
| 489 | |||
| 490 | if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2) | ||
| 491 | && (softing_error_reporting(card->net[0]) | ||
| 492 | != softing_error_reporting(card->net[1]))) { | ||
| 493 | dev_alert(&card->pdev->dev, | ||
| 494 | "err_reporting flag differs for busses\n"); | ||
| 495 | goto invalid; | ||
| 496 | } | ||
| 497 | error_reporting = 0; | ||
| 498 | if (bus_bitmask_start & 1) { | ||
| 499 | netdev = card->net[0]; | ||
| 500 | priv = netdev_priv(netdev); | ||
| 501 | error_reporting += softing_error_reporting(netdev); | ||
| 502 | /* init chip 1 */ | ||
| 503 | bt = &priv->can.bittiming; | ||
| 504 | iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 505 | iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 506 | iowrite16(bt->phase_seg1 + bt->prop_seg, | ||
| 507 | &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
| 508 | iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
| 509 | iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, | ||
| 510 | &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
| 511 | ret = softing_fct_cmd(card, 1, "initialize_chip[0]"); | ||
| 512 | if (ret < 0) | ||
| 513 | goto failed; | ||
| 514 | /* set mode */ | ||
| 515 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 516 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 517 | ret = softing_fct_cmd(card, 3, "set_mode[0]"); | ||
| 518 | if (ret < 0) | ||
| 519 | goto failed; | ||
| 520 | /* set filter */ | ||
| 521 | /* 11bit id & mask */ | ||
| 522 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 523 | iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 524 | /* 29bit id.lo & mask.lo & id.hi & mask.hi */ | ||
| 525 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
| 526 | iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
| 527 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
| 528 | iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); | ||
| 529 | ret = softing_fct_cmd(card, 7, "set_filter[0]"); | ||
| 530 | if (ret < 0) | ||
| 531 | goto failed; | ||
| 532 | /* set output control */ | ||
| 533 | iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 534 | ret = softing_fct_cmd(card, 5, "set_output[0]"); | ||
| 535 | if (ret < 0) | ||
| 536 | goto failed; | ||
| 537 | } | ||
| 538 | if (bus_bitmask_start & 2) { | ||
| 539 | netdev = card->net[1]; | ||
| 540 | priv = netdev_priv(netdev); | ||
| 541 | error_reporting += softing_error_reporting(netdev); | ||
| 542 | /* init chip2 */ | ||
| 543 | bt = &priv->can.bittiming; | ||
| 544 | iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 545 | iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 546 | iowrite16(bt->phase_seg1 + bt->prop_seg, | ||
| 547 | &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
| 548 | iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
| 549 | iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, | ||
| 550 | &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
| 551 | ret = softing_fct_cmd(card, 2, "initialize_chip[1]"); | ||
| 552 | if (ret < 0) | ||
| 553 | goto failed; | ||
| 554 | /* set mode2 */ | ||
| 555 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 556 | iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 557 | ret = softing_fct_cmd(card, 4, "set_mode[1]"); | ||
| 558 | if (ret < 0) | ||
| 559 | goto failed; | ||
| 560 | /* set filter2 */ | ||
| 561 | /* 11bit id & mask */ | ||
| 562 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 563 | iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 564 | /* 29bit id.lo & mask.lo & id.hi & mask.hi */ | ||
| 565 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
| 566 | iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
| 567 | iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
| 568 | iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); | ||
| 569 | ret = softing_fct_cmd(card, 8, "set_filter[1]"); | ||
| 570 | if (ret < 0) | ||
| 571 | goto failed; | ||
| 572 | /* set output control2 */ | ||
| 573 | iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 574 | ret = softing_fct_cmd(card, 6, "set_output[1]"); | ||
| 575 | if (ret < 0) | ||
| 576 | goto failed; | ||
| 577 | } | ||
| 578 | /* enable_error_frame */ | ||
| 579 | /* | ||
| 580 | * Error reporting is switched off at the moment since | ||
| 581 | * the receiving of them is not yet 100% verified | ||
| 582 | * This should be enabled sooner or later | ||
| 583 | * | ||
| 584 | if (error_reporting) { | ||
| 585 | ret = softing_fct_cmd(card, 51, "enable_error_frame"); | ||
| 586 | if (ret < 0) | ||
| 587 | goto failed; | ||
| 588 | } | ||
| 589 | */ | ||
| 590 | /* initialize interface */ | ||
| 591 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); | ||
| 592 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); | ||
| 593 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]); | ||
| 594 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]); | ||
| 595 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]); | ||
| 596 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]); | ||
| 597 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]); | ||
| 598 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]); | ||
| 599 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]); | ||
| 600 | iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]); | ||
| 601 | ret = softing_fct_cmd(card, 17, "initialize_interface"); | ||
| 602 | if (ret < 0) | ||
| 603 | goto failed; | ||
| 604 | /* enable_fifo */ | ||
| 605 | ret = softing_fct_cmd(card, 36, "enable_fifo"); | ||
| 606 | if (ret < 0) | ||
| 607 | goto failed; | ||
| 608 | /* enable fifo tx ack */ | ||
| 609 | ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]"); | ||
| 610 | if (ret < 0) | ||
| 611 | goto failed; | ||
| 612 | /* enable fifo tx ack2 */ | ||
| 613 | ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]"); | ||
| 614 | if (ret < 0) | ||
| 615 | goto failed; | ||
| 616 | /* start_chip */ | ||
| 617 | ret = softing_fct_cmd(card, 11, "start_chip"); | ||
| 618 | if (ret < 0) | ||
| 619 | goto failed; | ||
| 620 | iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]); | ||
| 621 | iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]); | ||
| 622 | if (card->pdat->generation < 2) { | ||
| 623 | iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); | ||
| 624 | /* flush the DPRAM caches */ | ||
| 625 | wmb(); | ||
| 626 | } | ||
| 627 | |||
| 628 | softing_initialize_timestamp(card); | ||
| 629 | |||
| 630 | /* | ||
| 631 | * do socketcan notifications/status changes | ||
| 632 | * from here, no errors should occur, or the failed: part | ||
| 633 | * must be reviewed | ||
| 634 | */ | ||
| 635 | memset(&msg, 0, sizeof(msg)); | ||
| 636 | msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; | ||
| 637 | msg.can_dlc = CAN_ERR_DLC; | ||
| 638 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 639 | if (!(bus_bitmask_start & (1 << j))) | ||
| 640 | continue; | ||
| 641 | netdev = card->net[j]; | ||
| 642 | if (!netdev) | ||
| 643 | continue; | ||
| 644 | priv = netdev_priv(netdev); | ||
| 645 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
| 646 | open_candev(netdev); | ||
| 647 | if (dev != netdev) { | ||
| 648 | /* notify other busses on the restart */ | ||
| 649 | softing_netdev_rx(netdev, &msg, ktime_set(0, 0)); | ||
| 650 | ++priv->can.can_stats.restarts; | ||
| 651 | } | ||
| 652 | netif_wake_queue(netdev); | ||
| 653 | } | ||
| 654 | |||
| 655 | /* enable interrupts */ | ||
| 656 | ret = softing_enable_irq(card, 1); | ||
| 657 | if (ret) | ||
| 658 | goto failed; | ||
| 659 | card_done: | ||
| 660 | mutex_unlock(&card->fw.lock); | ||
| 661 | return 0; | ||
| 662 | invalid: | ||
| 663 | ret = -EINVAL; | ||
| 664 | failed: | ||
| 665 | softing_enable_irq(card, 0); | ||
| 666 | softing_reset_chip(card); | ||
| 667 | mutex_unlock(&card->fw.lock); | ||
| 668 | /* bring all other interfaces down */ | ||
| 669 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 670 | netdev = card->net[j]; | ||
| 671 | if (!netdev) | ||
| 672 | continue; | ||
| 673 | dev_close(netdev); | ||
| 674 | } | ||
| 675 | return ret; | ||
| 676 | } | ||
| 677 | |||
| 678 | int softing_default_output(struct net_device *netdev) | ||
| 679 | { | ||
| 680 | struct softing_priv *priv = netdev_priv(netdev); | ||
| 681 | struct softing *card = priv->card; | ||
| 682 | |||
| 683 | switch (priv->chip) { | ||
| 684 | case 1000: | ||
| 685 | return (card->pdat->generation < 2) ? 0xfb : 0xfa; | ||
| 686 | case 5: | ||
| 687 | return 0x60; | ||
| 688 | default: | ||
| 689 | return 0x40; | ||
| 690 | } | ||
| 691 | } | ||
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c new file mode 100644 index 000000000000..aeea9f9ff6e8 --- /dev/null +++ b/drivers/net/can/softing/softing_main.c | |||
| @@ -0,0 +1,894 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008-2010 | ||
| 3 | * | ||
| 4 | * - Kurt Van Dijck, EIA Electronics | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the version 2 of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/version.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #include "softing.h" | ||
| 26 | |||
| 27 | #define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1) | ||
| 28 | |||
| 29 | /* | ||
| 30 | * test is a specific CAN netdev | ||
| 31 | * is online (ie. up 'n running, not sleeping, not busoff | ||
| 32 | */ | ||
| 33 | static inline int canif_is_active(struct net_device *netdev) | ||
| 34 | { | ||
| 35 | struct can_priv *can = netdev_priv(netdev); | ||
| 36 | |||
| 37 | if (!netif_running(netdev)) | ||
| 38 | return 0; | ||
| 39 | return (can->state <= CAN_STATE_ERROR_PASSIVE); | ||
| 40 | } | ||
| 41 | |||
| 42 | /* reset DPRAM */ | ||
| 43 | static inline void softing_set_reset_dpram(struct softing *card) | ||
| 44 | { | ||
| 45 | if (card->pdat->generation >= 2) { | ||
| 46 | spin_lock_bh(&card->spin); | ||
| 47 | iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1, | ||
| 48 | &card->dpram[DPRAM_V2_RESET]); | ||
| 49 | spin_unlock_bh(&card->spin); | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline void softing_clr_reset_dpram(struct softing *card) | ||
| 54 | { | ||
| 55 | if (card->pdat->generation >= 2) { | ||
| 56 | spin_lock_bh(&card->spin); | ||
| 57 | iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1, | ||
| 58 | &card->dpram[DPRAM_V2_RESET]); | ||
| 59 | spin_unlock_bh(&card->spin); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | /* trigger the tx queue-ing */ | ||
| 64 | static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb, | ||
| 65 | struct net_device *dev) | ||
| 66 | { | ||
| 67 | struct softing_priv *priv = netdev_priv(dev); | ||
| 68 | struct softing *card = priv->card; | ||
| 69 | int ret; | ||
| 70 | uint8_t *ptr; | ||
| 71 | uint8_t fifo_wr, fifo_rd; | ||
| 72 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
| 73 | uint8_t buf[DPRAM_TX_SIZE]; | ||
| 74 | |||
| 75 | if (can_dropped_invalid_skb(dev, skb)) | ||
| 76 | return NETDEV_TX_OK; | ||
| 77 | |||
| 78 | spin_lock(&card->spin); | ||
| 79 | |||
| 80 | ret = NETDEV_TX_BUSY; | ||
| 81 | if (!card->fw.up || | ||
| 82 | (card->tx.pending >= TXMAX) || | ||
| 83 | (priv->tx.pending >= TX_ECHO_SKB_MAX)) | ||
| 84 | goto xmit_done; | ||
| 85 | fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]); | ||
| 86 | fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]); | ||
| 87 | if (fifo_wr == fifo_rd) | ||
| 88 | /* fifo full */ | ||
| 89 | goto xmit_done; | ||
| 90 | memset(buf, 0, sizeof(buf)); | ||
| 91 | ptr = buf; | ||
| 92 | *ptr = CMD_TX; | ||
| 93 | if (cf->can_id & CAN_RTR_FLAG) | ||
| 94 | *ptr |= CMD_RTR; | ||
| 95 | if (cf->can_id & CAN_EFF_FLAG) | ||
| 96 | *ptr |= CMD_XTD; | ||
| 97 | if (priv->index) | ||
| 98 | *ptr |= CMD_BUS2; | ||
| 99 | ++ptr; | ||
| 100 | *ptr++ = cf->can_dlc; | ||
| 101 | *ptr++ = (cf->can_id >> 0); | ||
| 102 | *ptr++ = (cf->can_id >> 8); | ||
| 103 | if (cf->can_id & CAN_EFF_FLAG) { | ||
| 104 | *ptr++ = (cf->can_id >> 16); | ||
| 105 | *ptr++ = (cf->can_id >> 24); | ||
| 106 | } else { | ||
| 107 | /* increment 1, not 2 as you might think */ | ||
| 108 | ptr += 1; | ||
| 109 | } | ||
| 110 | if (!(cf->can_id & CAN_RTR_FLAG)) | ||
| 111 | memcpy(ptr, &cf->data[0], cf->can_dlc); | ||
| 112 | memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr], | ||
| 113 | buf, DPRAM_TX_SIZE); | ||
| 114 | if (++fifo_wr >= DPRAM_TX_CNT) | ||
| 115 | fifo_wr = 0; | ||
| 116 | iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]); | ||
| 117 | card->tx.last_bus = priv->index; | ||
| 118 | ++card->tx.pending; | ||
| 119 | ++priv->tx.pending; | ||
| 120 | can_put_echo_skb(skb, dev, priv->tx.echo_put); | ||
| 121 | ++priv->tx.echo_put; | ||
| 122 | if (priv->tx.echo_put >= TX_ECHO_SKB_MAX) | ||
| 123 | priv->tx.echo_put = 0; | ||
| 124 | /* can_put_echo_skb() saves the skb, safe to return TX_OK */ | ||
| 125 | ret = NETDEV_TX_OK; | ||
| 126 | xmit_done: | ||
| 127 | spin_unlock(&card->spin); | ||
| 128 | if (card->tx.pending >= TXMAX) { | ||
| 129 | int j; | ||
| 130 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 131 | if (card->net[j]) | ||
| 132 | netif_stop_queue(card->net[j]); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | if (ret != NETDEV_TX_OK) | ||
| 136 | netif_stop_queue(dev); | ||
| 137 | |||
| 138 | return ret; | ||
| 139 | } | ||
| 140 | |||
| 141 | /* | ||
| 142 | * shortcut for skb delivery | ||
| 143 | */ | ||
| 144 | int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, | ||
| 145 | ktime_t ktime) | ||
| 146 | { | ||
| 147 | struct sk_buff *skb; | ||
| 148 | struct can_frame *cf; | ||
| 149 | |||
| 150 | skb = alloc_can_skb(netdev, &cf); | ||
| 151 | if (!skb) | ||
| 152 | return -ENOMEM; | ||
| 153 | memcpy(cf, msg, sizeof(*msg)); | ||
| 154 | skb->tstamp = ktime; | ||
| 155 | return netif_rx(skb); | ||
| 156 | } | ||
| 157 | |||
| 158 | /* | ||
| 159 | * softing_handle_1 | ||
| 160 | * pop 1 entry from the DPRAM queue, and process | ||
| 161 | */ | ||
| 162 | static int softing_handle_1(struct softing *card) | ||
| 163 | { | ||
| 164 | struct net_device *netdev; | ||
| 165 | struct softing_priv *priv; | ||
| 166 | ktime_t ktime; | ||
| 167 | struct can_frame msg; | ||
| 168 | int cnt = 0, lost_msg; | ||
| 169 | uint8_t fifo_rd, fifo_wr, cmd; | ||
| 170 | uint8_t *ptr; | ||
| 171 | uint32_t tmp_u32; | ||
| 172 | uint8_t buf[DPRAM_RX_SIZE]; | ||
| 173 | |||
| 174 | memset(&msg, 0, sizeof(msg)); | ||
| 175 | /* test for lost msgs */ | ||
| 176 | lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]); | ||
| 177 | if (lost_msg) { | ||
| 178 | int j; | ||
| 179 | /* reset condition */ | ||
| 180 | iowrite8(0, &card->dpram[DPRAM_RX_LOST]); | ||
| 181 | /* prepare msg */ | ||
| 182 | msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL; | ||
| 183 | msg.can_dlc = CAN_ERR_DLC; | ||
| 184 | msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
| 185 | /* | ||
| 186 | * service to all busses, we don't know which it was applicable | ||
| 187 | * but only service busses that are online | ||
| 188 | */ | ||
| 189 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 190 | netdev = card->net[j]; | ||
| 191 | if (!netdev) | ||
| 192 | continue; | ||
| 193 | if (!canif_is_active(netdev)) | ||
| 194 | /* a dead bus has no overflows */ | ||
| 195 | continue; | ||
| 196 | ++netdev->stats.rx_over_errors; | ||
| 197 | softing_netdev_rx(netdev, &msg, ktime_set(0, 0)); | ||
| 198 | } | ||
| 199 | /* prepare for other use */ | ||
| 200 | memset(&msg, 0, sizeof(msg)); | ||
| 201 | ++cnt; | ||
| 202 | } | ||
| 203 | |||
| 204 | fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]); | ||
| 205 | fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]); | ||
| 206 | |||
| 207 | if (++fifo_rd >= DPRAM_RX_CNT) | ||
| 208 | fifo_rd = 0; | ||
| 209 | if (fifo_wr == fifo_rd) | ||
| 210 | return cnt; | ||
| 211 | |||
| 212 | memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd], | ||
| 213 | DPRAM_RX_SIZE); | ||
| 214 | mb(); | ||
| 215 | /* trigger dual port RAM */ | ||
| 216 | iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]); | ||
| 217 | |||
| 218 | ptr = buf; | ||
| 219 | cmd = *ptr++; | ||
| 220 | if (cmd == 0xff) | ||
| 221 | /* not quite usefull, probably the card has got out */ | ||
| 222 | return 0; | ||
| 223 | netdev = card->net[0]; | ||
| 224 | if (cmd & CMD_BUS2) | ||
| 225 | netdev = card->net[1]; | ||
| 226 | priv = netdev_priv(netdev); | ||
| 227 | |||
| 228 | if (cmd & CMD_ERR) { | ||
| 229 | uint8_t can_state, state; | ||
| 230 | |||
| 231 | state = *ptr++; | ||
| 232 | |||
| 233 | msg.can_id = CAN_ERR_FLAG; | ||
| 234 | msg.can_dlc = CAN_ERR_DLC; | ||
| 235 | |||
| 236 | if (state & SF_MASK_BUSOFF) { | ||
| 237 | can_state = CAN_STATE_BUS_OFF; | ||
| 238 | msg.can_id |= CAN_ERR_BUSOFF; | ||
| 239 | state = STATE_BUSOFF; | ||
| 240 | } else if (state & SF_MASK_EPASSIVE) { | ||
| 241 | can_state = CAN_STATE_ERROR_PASSIVE; | ||
| 242 | msg.can_id |= CAN_ERR_CRTL; | ||
| 243 | msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE; | ||
| 244 | state = STATE_EPASSIVE; | ||
| 245 | } else { | ||
| 246 | can_state = CAN_STATE_ERROR_ACTIVE; | ||
| 247 | msg.can_id |= CAN_ERR_CRTL; | ||
| 248 | state = STATE_EACTIVE; | ||
| 249 | } | ||
| 250 | /* update DPRAM */ | ||
| 251 | iowrite8(state, &card->dpram[priv->index ? | ||
| 252 | DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]); | ||
| 253 | /* timestamp */ | ||
| 254 | tmp_u32 = le32_to_cpup((void *)ptr); | ||
| 255 | ptr += 4; | ||
| 256 | ktime = softing_raw2ktime(card, tmp_u32); | ||
| 257 | |||
| 258 | ++netdev->stats.rx_errors; | ||
| 259 | /* update internal status */ | ||
| 260 | if (can_state != priv->can.state) { | ||
| 261 | priv->can.state = can_state; | ||
| 262 | if (can_state == CAN_STATE_ERROR_PASSIVE) | ||
| 263 | ++priv->can.can_stats.error_passive; | ||
| 264 | else if (can_state == CAN_STATE_BUS_OFF) { | ||
| 265 | /* this calls can_close_cleanup() */ | ||
| 266 | can_bus_off(netdev); | ||
| 267 | netif_stop_queue(netdev); | ||
| 268 | } | ||
| 269 | /* trigger socketcan */ | ||
| 270 | softing_netdev_rx(netdev, &msg, ktime); | ||
| 271 | } | ||
| 272 | |||
| 273 | } else { | ||
| 274 | if (cmd & CMD_RTR) | ||
| 275 | msg.can_id |= CAN_RTR_FLAG; | ||
| 276 | msg.can_dlc = get_can_dlc(*ptr++); | ||
| 277 | if (cmd & CMD_XTD) { | ||
| 278 | msg.can_id |= CAN_EFF_FLAG; | ||
| 279 | msg.can_id |= le32_to_cpup((void *)ptr); | ||
| 280 | ptr += 4; | ||
| 281 | } else { | ||
| 282 | msg.can_id |= le16_to_cpup((void *)ptr); | ||
| 283 | ptr += 2; | ||
| 284 | } | ||
| 285 | /* timestamp */ | ||
| 286 | tmp_u32 = le32_to_cpup((void *)ptr); | ||
| 287 | ptr += 4; | ||
| 288 | ktime = softing_raw2ktime(card, tmp_u32); | ||
| 289 | if (!(msg.can_id & CAN_RTR_FLAG)) | ||
| 290 | memcpy(&msg.data[0], ptr, 8); | ||
| 291 | ptr += 8; | ||
| 292 | /* update socket */ | ||
| 293 | if (cmd & CMD_ACK) { | ||
| 294 | /* acknowledge, was tx msg */ | ||
| 295 | struct sk_buff *skb; | ||
| 296 | skb = priv->can.echo_skb[priv->tx.echo_get]; | ||
| 297 | if (skb) | ||
| 298 | skb->tstamp = ktime; | ||
| 299 | can_get_echo_skb(netdev, priv->tx.echo_get); | ||
| 300 | ++priv->tx.echo_get; | ||
| 301 | if (priv->tx.echo_get >= TX_ECHO_SKB_MAX) | ||
| 302 | priv->tx.echo_get = 0; | ||
| 303 | if (priv->tx.pending) | ||
| 304 | --priv->tx.pending; | ||
| 305 | if (card->tx.pending) | ||
| 306 | --card->tx.pending; | ||
| 307 | ++netdev->stats.tx_packets; | ||
| 308 | if (!(msg.can_id & CAN_RTR_FLAG)) | ||
| 309 | netdev->stats.tx_bytes += msg.can_dlc; | ||
| 310 | } else { | ||
| 311 | int ret; | ||
| 312 | |||
| 313 | ret = softing_netdev_rx(netdev, &msg, ktime); | ||
| 314 | if (ret == NET_RX_SUCCESS) { | ||
| 315 | ++netdev->stats.rx_packets; | ||
| 316 | if (!(msg.can_id & CAN_RTR_FLAG)) | ||
| 317 | netdev->stats.rx_bytes += msg.can_dlc; | ||
| 318 | } else { | ||
| 319 | ++netdev->stats.rx_dropped; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | } | ||
| 323 | ++cnt; | ||
| 324 | return cnt; | ||
| 325 | } | ||
| 326 | |||
| 327 | /* | ||
| 328 | * real interrupt handler | ||
| 329 | */ | ||
| 330 | static irqreturn_t softing_irq_thread(int irq, void *dev_id) | ||
| 331 | { | ||
| 332 | struct softing *card = (struct softing *)dev_id; | ||
| 333 | struct net_device *netdev; | ||
| 334 | struct softing_priv *priv; | ||
| 335 | int j, offset, work_done; | ||
| 336 | |||
| 337 | work_done = 0; | ||
| 338 | spin_lock_bh(&card->spin); | ||
| 339 | while (softing_handle_1(card) > 0) { | ||
| 340 | ++card->irq.svc_count; | ||
| 341 | ++work_done; | ||
| 342 | } | ||
| 343 | spin_unlock_bh(&card->spin); | ||
| 344 | /* resume tx queue's */ | ||
| 345 | offset = card->tx.last_bus; | ||
| 346 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 347 | if (card->tx.pending >= TXMAX) | ||
| 348 | break; | ||
| 349 | netdev = card->net[(j + offset + 1) % card->pdat->nbus]; | ||
| 350 | if (!netdev) | ||
| 351 | continue; | ||
| 352 | priv = netdev_priv(netdev); | ||
| 353 | if (!canif_is_active(netdev)) | ||
| 354 | /* it makes no sense to wake dead busses */ | ||
| 355 | continue; | ||
| 356 | if (priv->tx.pending >= TX_ECHO_SKB_MAX) | ||
| 357 | continue; | ||
| 358 | ++work_done; | ||
| 359 | netif_wake_queue(netdev); | ||
| 360 | } | ||
| 361 | return work_done ? IRQ_HANDLED : IRQ_NONE; | ||
| 362 | } | ||
| 363 | |||
| 364 | /* | ||
| 365 | * interrupt routines: | ||
| 366 | * schedule the 'real interrupt handler' | ||
| 367 | */ | ||
| 368 | static irqreturn_t softing_irq_v2(int irq, void *dev_id) | ||
| 369 | { | ||
| 370 | struct softing *card = (struct softing *)dev_id; | ||
| 371 | uint8_t ir; | ||
| 372 | |||
| 373 | ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]); | ||
| 374 | iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); | ||
| 375 | return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE; | ||
| 376 | } | ||
| 377 | |||
| 378 | static irqreturn_t softing_irq_v1(int irq, void *dev_id) | ||
| 379 | { | ||
| 380 | struct softing *card = (struct softing *)dev_id; | ||
| 381 | uint8_t ir; | ||
| 382 | |||
| 383 | ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]); | ||
| 384 | iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]); | ||
| 385 | return ir ? IRQ_WAKE_THREAD : IRQ_NONE; | ||
| 386 | } | ||
| 387 | |||
| 388 | /* | ||
| 389 | * netdev/candev inter-operability | ||
| 390 | */ | ||
| 391 | static int softing_netdev_open(struct net_device *ndev) | ||
| 392 | { | ||
| 393 | int ret; | ||
| 394 | |||
| 395 | /* check or determine and set bittime */ | ||
| 396 | ret = open_candev(ndev); | ||
| 397 | if (!ret) | ||
| 398 | ret = softing_startstop(ndev, 1); | ||
| 399 | return ret; | ||
| 400 | } | ||
| 401 | |||
| 402 | static int softing_netdev_stop(struct net_device *ndev) | ||
| 403 | { | ||
| 404 | int ret; | ||
| 405 | |||
| 406 | netif_stop_queue(ndev); | ||
| 407 | |||
| 408 | /* softing cycle does close_candev() */ | ||
| 409 | ret = softing_startstop(ndev, 0); | ||
| 410 | return ret; | ||
| 411 | } | ||
| 412 | |||
| 413 | static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode) | ||
| 414 | { | ||
| 415 | int ret; | ||
| 416 | |||
| 417 | switch (mode) { | ||
| 418 | case CAN_MODE_START: | ||
| 419 | /* softing_startstop does close_candev() */ | ||
| 420 | ret = softing_startstop(ndev, 1); | ||
| 421 | return ret; | ||
| 422 | case CAN_MODE_STOP: | ||
| 423 | case CAN_MODE_SLEEP: | ||
| 424 | return -EOPNOTSUPP; | ||
| 425 | } | ||
| 426 | return 0; | ||
| 427 | } | ||
| 428 | |||
| 429 | /* | ||
| 430 | * Softing device management helpers | ||
| 431 | */ | ||
| 432 | int softing_enable_irq(struct softing *card, int enable) | ||
| 433 | { | ||
| 434 | int ret; | ||
| 435 | |||
| 436 | if (!card->irq.nr) { | ||
| 437 | return 0; | ||
| 438 | } else if (card->irq.requested && !enable) { | ||
| 439 | free_irq(card->irq.nr, card); | ||
| 440 | card->irq.requested = 0; | ||
| 441 | } else if (!card->irq.requested && enable) { | ||
| 442 | ret = request_threaded_irq(card->irq.nr, | ||
| 443 | (card->pdat->generation >= 2) ? | ||
| 444 | softing_irq_v2 : softing_irq_v1, | ||
| 445 | softing_irq_thread, IRQF_SHARED, | ||
| 446 | dev_name(&card->pdev->dev), card); | ||
| 447 | if (ret) { | ||
| 448 | dev_alert(&card->pdev->dev, | ||
| 449 | "request_threaded_irq(%u) failed\n", | ||
| 450 | card->irq.nr); | ||
| 451 | return ret; | ||
| 452 | } | ||
| 453 | card->irq.requested = 1; | ||
| 454 | } | ||
| 455 | return 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | static void softing_card_shutdown(struct softing *card) | ||
| 459 | { | ||
| 460 | int fw_up = 0; | ||
| 461 | |||
| 462 | if (mutex_lock_interruptible(&card->fw.lock)) | ||
| 463 | /* return -ERESTARTSYS */; | ||
| 464 | fw_up = card->fw.up; | ||
| 465 | card->fw.up = 0; | ||
| 466 | |||
| 467 | if (card->irq.requested && card->irq.nr) { | ||
| 468 | free_irq(card->irq.nr, card); | ||
| 469 | card->irq.requested = 0; | ||
| 470 | } | ||
| 471 | if (fw_up) { | ||
| 472 | if (card->pdat->enable_irq) | ||
| 473 | card->pdat->enable_irq(card->pdev, 0); | ||
| 474 | softing_set_reset_dpram(card); | ||
| 475 | if (card->pdat->reset) | ||
| 476 | card->pdat->reset(card->pdev, 1); | ||
| 477 | } | ||
| 478 | mutex_unlock(&card->fw.lock); | ||
| 479 | } | ||
| 480 | |||
| 481 | static __devinit int softing_card_boot(struct softing *card) | ||
| 482 | { | ||
| 483 | int ret, j; | ||
| 484 | static const uint8_t stream[] = { | ||
| 485 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; | ||
| 486 | unsigned char back[sizeof(stream)]; | ||
| 487 | |||
| 488 | if (mutex_lock_interruptible(&card->fw.lock)) | ||
| 489 | return -ERESTARTSYS; | ||
| 490 | if (card->fw.up) { | ||
| 491 | mutex_unlock(&card->fw.lock); | ||
| 492 | return 0; | ||
| 493 | } | ||
| 494 | /* reset board */ | ||
| 495 | if (card->pdat->enable_irq) | ||
| 496 | card->pdat->enable_irq(card->pdev, 1); | ||
| 497 | /* boot card */ | ||
| 498 | softing_set_reset_dpram(card); | ||
| 499 | if (card->pdat->reset) | ||
| 500 | card->pdat->reset(card->pdev, 1); | ||
| 501 | for (j = 0; (j + sizeof(stream)) < card->dpram_size; | ||
| 502 | j += sizeof(stream)) { | ||
| 503 | |||
| 504 | memcpy_toio(&card->dpram[j], stream, sizeof(stream)); | ||
| 505 | /* flush IO cache */ | ||
| 506 | mb(); | ||
| 507 | memcpy_fromio(back, &card->dpram[j], sizeof(stream)); | ||
| 508 | |||
| 509 | if (!memcmp(back, stream, sizeof(stream))) | ||
| 510 | continue; | ||
| 511 | /* memory is not equal */ | ||
| 512 | dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j); | ||
| 513 | ret = -EIO; | ||
| 514 | goto failed; | ||
| 515 | } | ||
| 516 | wmb(); | ||
| 517 | /* load boot firmware */ | ||
| 518 | ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram, | ||
| 519 | card->dpram_size, | ||
| 520 | card->pdat->boot.offs - card->pdat->boot.addr); | ||
| 521 | if (ret < 0) | ||
| 522 | goto failed; | ||
| 523 | /* load loader firmware */ | ||
| 524 | ret = softing_load_fw(card->pdat->load.fw, card, card->dpram, | ||
| 525 | card->dpram_size, | ||
| 526 | card->pdat->load.offs - card->pdat->load.addr); | ||
| 527 | if (ret < 0) | ||
| 528 | goto failed; | ||
| 529 | |||
| 530 | if (card->pdat->reset) | ||
| 531 | card->pdat->reset(card->pdev, 0); | ||
| 532 | softing_clr_reset_dpram(card); | ||
| 533 | ret = softing_bootloader_command(card, 0, "card boot"); | ||
| 534 | if (ret < 0) | ||
| 535 | goto failed; | ||
| 536 | ret = softing_load_app_fw(card->pdat->app.fw, card); | ||
| 537 | if (ret < 0) | ||
| 538 | goto failed; | ||
| 539 | |||
| 540 | ret = softing_chip_poweron(card); | ||
| 541 | if (ret < 0) | ||
| 542 | goto failed; | ||
| 543 | |||
| 544 | card->fw.up = 1; | ||
| 545 | mutex_unlock(&card->fw.lock); | ||
| 546 | return 0; | ||
| 547 | failed: | ||
| 548 | card->fw.up = 0; | ||
| 549 | if (card->pdat->enable_irq) | ||
| 550 | card->pdat->enable_irq(card->pdev, 0); | ||
| 551 | softing_set_reset_dpram(card); | ||
| 552 | if (card->pdat->reset) | ||
| 553 | card->pdat->reset(card->pdev, 1); | ||
| 554 | mutex_unlock(&card->fw.lock); | ||
| 555 | return ret; | ||
| 556 | } | ||
| 557 | |||
| 558 | /* | ||
| 559 | * netdev sysfs | ||
| 560 | */ | ||
| 561 | static ssize_t show_channel(struct device *dev, struct device_attribute *attr, | ||
| 562 | char *buf) | ||
| 563 | { | ||
| 564 | struct net_device *ndev = to_net_dev(dev); | ||
| 565 | struct softing_priv *priv = netdev2softing(ndev); | ||
| 566 | |||
| 567 | return sprintf(buf, "%i\n", priv->index); | ||
| 568 | } | ||
| 569 | |||
| 570 | static ssize_t show_chip(struct device *dev, struct device_attribute *attr, | ||
| 571 | char *buf) | ||
| 572 | { | ||
| 573 | struct net_device *ndev = to_net_dev(dev); | ||
| 574 | struct softing_priv *priv = netdev2softing(ndev); | ||
| 575 | |||
| 576 | return sprintf(buf, "%i\n", priv->chip); | ||
| 577 | } | ||
| 578 | |||
| 579 | static ssize_t show_output(struct device *dev, struct device_attribute *attr, | ||
| 580 | char *buf) | ||
| 581 | { | ||
| 582 | struct net_device *ndev = to_net_dev(dev); | ||
| 583 | struct softing_priv *priv = netdev2softing(ndev); | ||
| 584 | |||
| 585 | return sprintf(buf, "0x%02x\n", priv->output); | ||
| 586 | } | ||
| 587 | |||
| 588 | static ssize_t store_output(struct device *dev, struct device_attribute *attr, | ||
| 589 | const char *buf, size_t count) | ||
| 590 | { | ||
| 591 | struct net_device *ndev = to_net_dev(dev); | ||
| 592 | struct softing_priv *priv = netdev2softing(ndev); | ||
| 593 | struct softing *card = priv->card; | ||
| 594 | unsigned long val; | ||
| 595 | int ret; | ||
| 596 | |||
| 597 | ret = strict_strtoul(buf, 0, &val); | ||
| 598 | if (ret < 0) | ||
| 599 | return ret; | ||
| 600 | val &= 0xFF; | ||
| 601 | |||
| 602 | ret = mutex_lock_interruptible(&card->fw.lock); | ||
| 603 | if (ret) | ||
| 604 | return -ERESTARTSYS; | ||
| 605 | if (netif_running(ndev)) { | ||
| 606 | mutex_unlock(&card->fw.lock); | ||
| 607 | return -EBUSY; | ||
| 608 | } | ||
| 609 | priv->output = val; | ||
| 610 | mutex_unlock(&card->fw.lock); | ||
| 611 | return count; | ||
| 612 | } | ||
| 613 | |||
| 614 | static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); | ||
| 615 | static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL); | ||
| 616 | static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output); | ||
| 617 | |||
| 618 | static const struct attribute *const netdev_sysfs_attrs[] = { | ||
| 619 | &dev_attr_channel.attr, | ||
| 620 | &dev_attr_chip.attr, | ||
| 621 | &dev_attr_output.attr, | ||
| 622 | NULL, | ||
| 623 | }; | ||
| 624 | static const struct attribute_group netdev_sysfs_group = { | ||
| 625 | .name = NULL, | ||
| 626 | .attrs = (struct attribute **)netdev_sysfs_attrs, | ||
| 627 | }; | ||
| 628 | |||
| 629 | static const struct net_device_ops softing_netdev_ops = { | ||
| 630 | .ndo_open = softing_netdev_open, | ||
| 631 | .ndo_stop = softing_netdev_stop, | ||
| 632 | .ndo_start_xmit = softing_netdev_start_xmit, | ||
| 633 | }; | ||
| 634 | |||
| 635 | static const struct can_bittiming_const softing_btr_const = { | ||
| 636 | .name = "softing", | ||
| 637 | .tseg1_min = 1, | ||
| 638 | .tseg1_max = 16, | ||
| 639 | .tseg2_min = 1, | ||
| 640 | .tseg2_max = 8, | ||
| 641 | .sjw_max = 4, /* overruled */ | ||
| 642 | .brp_min = 1, | ||
| 643 | .brp_max = 32, /* overruled */ | ||
| 644 | .brp_inc = 1, | ||
| 645 | }; | ||
| 646 | |||
| 647 | |||
| 648 | static __devinit struct net_device *softing_netdev_create(struct softing *card, | ||
| 649 | uint16_t chip_id) | ||
| 650 | { | ||
| 651 | struct net_device *netdev; | ||
| 652 | struct softing_priv *priv; | ||
| 653 | |||
| 654 | netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); | ||
| 655 | if (!netdev) { | ||
| 656 | dev_alert(&card->pdev->dev, "alloc_candev failed\n"); | ||
| 657 | return NULL; | ||
| 658 | } | ||
| 659 | priv = netdev_priv(netdev); | ||
| 660 | priv->netdev = netdev; | ||
| 661 | priv->card = card; | ||
| 662 | memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const)); | ||
| 663 | priv->btr_const.brp_max = card->pdat->max_brp; | ||
| 664 | priv->btr_const.sjw_max = card->pdat->max_sjw; | ||
| 665 | priv->can.bittiming_const = &priv->btr_const; | ||
| 666 | priv->can.clock.freq = 8000000; | ||
| 667 | priv->chip = chip_id; | ||
| 668 | priv->output = softing_default_output(netdev); | ||
| 669 | SET_NETDEV_DEV(netdev, &card->pdev->dev); | ||
| 670 | |||
| 671 | netdev->flags |= IFF_ECHO; | ||
| 672 | netdev->netdev_ops = &softing_netdev_ops; | ||
| 673 | priv->can.do_set_mode = softing_candev_set_mode; | ||
| 674 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; | ||
| 675 | |||
| 676 | return netdev; | ||
| 677 | } | ||
| 678 | |||
| 679 | static __devinit int softing_netdev_register(struct net_device *netdev) | ||
| 680 | { | ||
| 681 | int ret; | ||
| 682 | |||
| 683 | netdev->sysfs_groups[0] = &netdev_sysfs_group; | ||
| 684 | ret = register_candev(netdev); | ||
| 685 | if (ret) { | ||
| 686 | dev_alert(&netdev->dev, "register failed\n"); | ||
| 687 | return ret; | ||
| 688 | } | ||
| 689 | return 0; | ||
| 690 | } | ||
| 691 | |||
| 692 | static void softing_netdev_cleanup(struct net_device *netdev) | ||
| 693 | { | ||
| 694 | unregister_candev(netdev); | ||
| 695 | free_candev(netdev); | ||
| 696 | } | ||
| 697 | |||
| 698 | /* | ||
| 699 | * sysfs for Platform device | ||
| 700 | */ | ||
| 701 | #define DEV_ATTR_RO(name, member) \ | ||
| 702 | static ssize_t show_##name(struct device *dev, \ | ||
| 703 | struct device_attribute *attr, char *buf) \ | ||
| 704 | { \ | ||
| 705 | struct softing *card = platform_get_drvdata(to_platform_device(dev)); \ | ||
| 706 | return sprintf(buf, "%u\n", card->member); \ | ||
| 707 | } \ | ||
| 708 | static DEVICE_ATTR(name, 0444, show_##name, NULL) | ||
| 709 | |||
| 710 | #define DEV_ATTR_RO_STR(name, member) \ | ||
| 711 | static ssize_t show_##name(struct device *dev, \ | ||
| 712 | struct device_attribute *attr, char *buf) \ | ||
| 713 | { \ | ||
| 714 | struct softing *card = platform_get_drvdata(to_platform_device(dev)); \ | ||
| 715 | return sprintf(buf, "%s\n", card->member); \ | ||
| 716 | } \ | ||
| 717 | static DEVICE_ATTR(name, 0444, show_##name, NULL) | ||
| 718 | |||
| 719 | DEV_ATTR_RO(serial, id.serial); | ||
| 720 | DEV_ATTR_RO_STR(firmware, pdat->app.fw); | ||
| 721 | DEV_ATTR_RO(firmware_version, id.fw_version); | ||
| 722 | DEV_ATTR_RO_STR(hardware, pdat->name); | ||
| 723 | DEV_ATTR_RO(hardware_version, id.hw_version); | ||
| 724 | DEV_ATTR_RO(license, id.license); | ||
| 725 | DEV_ATTR_RO(frequency, id.freq); | ||
| 726 | DEV_ATTR_RO(txpending, tx.pending); | ||
| 727 | |||
| 728 | static struct attribute *softing_pdev_attrs[] = { | ||
| 729 | &dev_attr_serial.attr, | ||
| 730 | &dev_attr_firmware.attr, | ||
| 731 | &dev_attr_firmware_version.attr, | ||
| 732 | &dev_attr_hardware.attr, | ||
| 733 | &dev_attr_hardware_version.attr, | ||
| 734 | &dev_attr_license.attr, | ||
| 735 | &dev_attr_frequency.attr, | ||
| 736 | &dev_attr_txpending.attr, | ||
| 737 | NULL, | ||
| 738 | }; | ||
| 739 | |||
| 740 | static const struct attribute_group softing_pdev_group = { | ||
| 741 | .name = NULL, | ||
| 742 | .attrs = softing_pdev_attrs, | ||
| 743 | }; | ||
| 744 | |||
| 745 | /* | ||
| 746 | * platform driver | ||
| 747 | */ | ||
| 748 | static __devexit int softing_pdev_remove(struct platform_device *pdev) | ||
| 749 | { | ||
| 750 | struct softing *card = platform_get_drvdata(pdev); | ||
| 751 | int j; | ||
| 752 | |||
| 753 | /* first, disable card*/ | ||
| 754 | softing_card_shutdown(card); | ||
| 755 | |||
| 756 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 757 | if (!card->net[j]) | ||
| 758 | continue; | ||
| 759 | softing_netdev_cleanup(card->net[j]); | ||
| 760 | card->net[j] = NULL; | ||
| 761 | } | ||
| 762 | sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); | ||
| 763 | |||
| 764 | iounmap(card->dpram); | ||
| 765 | kfree(card); | ||
| 766 | return 0; | ||
| 767 | } | ||
| 768 | |||
| 769 | static __devinit int softing_pdev_probe(struct platform_device *pdev) | ||
| 770 | { | ||
| 771 | const struct softing_platform_data *pdat = pdev->dev.platform_data; | ||
| 772 | struct softing *card; | ||
| 773 | struct net_device *netdev; | ||
| 774 | struct softing_priv *priv; | ||
| 775 | struct resource *pres; | ||
| 776 | int ret; | ||
| 777 | int j; | ||
| 778 | |||
| 779 | if (!pdat) { | ||
| 780 | dev_warn(&pdev->dev, "no platform data\n"); | ||
| 781 | return -EINVAL; | ||
| 782 | } | ||
| 783 | if (pdat->nbus > ARRAY_SIZE(card->net)) { | ||
| 784 | dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus); | ||
| 785 | return -EINVAL; | ||
| 786 | } | ||
| 787 | |||
| 788 | card = kzalloc(sizeof(*card), GFP_KERNEL); | ||
| 789 | if (!card) | ||
| 790 | return -ENOMEM; | ||
| 791 | card->pdat = pdat; | ||
| 792 | card->pdev = pdev; | ||
| 793 | platform_set_drvdata(pdev, card); | ||
| 794 | mutex_init(&card->fw.lock); | ||
| 795 | spin_lock_init(&card->spin); | ||
| 796 | |||
| 797 | ret = -EINVAL; | ||
| 798 | pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 799 | if (!pres) | ||
| 800 | goto platform_resource_failed;; | ||
| 801 | card->dpram_phys = pres->start; | ||
| 802 | card->dpram_size = pres->end - pres->start + 1; | ||
| 803 | card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size); | ||
| 804 | if (!card->dpram) { | ||
| 805 | dev_alert(&card->pdev->dev, "dpram ioremap failed\n"); | ||
| 806 | goto ioremap_failed; | ||
| 807 | } | ||
| 808 | |||
| 809 | pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 810 | if (pres) | ||
| 811 | card->irq.nr = pres->start; | ||
| 812 | |||
| 813 | /* reset card */ | ||
| 814 | ret = softing_card_boot(card); | ||
| 815 | if (ret < 0) { | ||
| 816 | dev_alert(&pdev->dev, "failed to boot\n"); | ||
| 817 | goto boot_failed; | ||
| 818 | } | ||
| 819 | |||
| 820 | /* only now, the chip's are known */ | ||
| 821 | card->id.freq = card->pdat->freq; | ||
| 822 | |||
| 823 | ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group); | ||
| 824 | if (ret < 0) { | ||
| 825 | dev_alert(&card->pdev->dev, "sysfs failed\n"); | ||
| 826 | goto sysfs_failed; | ||
| 827 | } | ||
| 828 | |||
| 829 | ret = -ENOMEM; | ||
| 830 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 831 | card->net[j] = netdev = | ||
| 832 | softing_netdev_create(card, card->id.chip[j]); | ||
| 833 | if (!netdev) { | ||
| 834 | dev_alert(&pdev->dev, "failed to make can[%i]", j); | ||
| 835 | goto netdev_failed; | ||
| 836 | } | ||
| 837 | priv = netdev_priv(card->net[j]); | ||
| 838 | priv->index = j; | ||
| 839 | ret = softing_netdev_register(netdev); | ||
| 840 | if (ret) { | ||
| 841 | free_candev(netdev); | ||
| 842 | card->net[j] = NULL; | ||
| 843 | dev_alert(&card->pdev->dev, | ||
| 844 | "failed to register can[%i]\n", j); | ||
| 845 | goto netdev_failed; | ||
| 846 | } | ||
| 847 | } | ||
| 848 | dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name); | ||
| 849 | return 0; | ||
| 850 | |||
| 851 | netdev_failed: | ||
| 852 | for (j = 0; j < ARRAY_SIZE(card->net); ++j) { | ||
| 853 | if (!card->net[j]) | ||
| 854 | continue; | ||
| 855 | softing_netdev_cleanup(card->net[j]); | ||
| 856 | } | ||
| 857 | sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); | ||
| 858 | sysfs_failed: | ||
| 859 | softing_card_shutdown(card); | ||
| 860 | boot_failed: | ||
| 861 | iounmap(card->dpram); | ||
| 862 | ioremap_failed: | ||
| 863 | platform_resource_failed: | ||
| 864 | kfree(card); | ||
| 865 | return ret; | ||
| 866 | } | ||
| 867 | |||
| 868 | static struct platform_driver softing_driver = { | ||
| 869 | .driver = { | ||
| 870 | .name = "softing", | ||
| 871 | .owner = THIS_MODULE, | ||
| 872 | }, | ||
| 873 | .probe = softing_pdev_probe, | ||
| 874 | .remove = __devexit_p(softing_pdev_remove), | ||
| 875 | }; | ||
| 876 | |||
| 877 | MODULE_ALIAS("platform:softing"); | ||
| 878 | |||
| 879 | static int __init softing_start(void) | ||
| 880 | { | ||
| 881 | return platform_driver_register(&softing_driver); | ||
| 882 | } | ||
| 883 | |||
| 884 | static void __exit softing_stop(void) | ||
| 885 | { | ||
| 886 | platform_driver_unregister(&softing_driver); | ||
| 887 | } | ||
| 888 | |||
| 889 | module_init(softing_start); | ||
| 890 | module_exit(softing_stop); | ||
| 891 | |||
| 892 | MODULE_DESCRIPTION("Softing DPRAM CAN driver"); | ||
| 893 | MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>"); | ||
| 894 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h new file mode 100644 index 000000000000..ebbf69815623 --- /dev/null +++ b/drivers/net/can/softing/softing_platform.h | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | |||
| 2 | #include <linux/platform_device.h> | ||
| 3 | |||
| 4 | #ifndef _SOFTING_DEVICE_H_ | ||
| 5 | #define _SOFTING_DEVICE_H_ | ||
| 6 | |||
| 7 | /* softing firmware directory prefix */ | ||
| 8 | #define fw_dir "softing-4.6/" | ||
| 9 | |||
| 10 | struct softing_platform_data { | ||
| 11 | unsigned int manf; | ||
| 12 | unsigned int prod; | ||
| 13 | /* | ||
| 14 | * generation | ||
| 15 | * 1st with NEC or SJA1000 | ||
| 16 | * 8bit, exclusive interrupt, ... | ||
| 17 | * 2nd only SJA1000 | ||
| 18 | * 16bit, shared interrupt | ||
| 19 | */ | ||
| 20 | int generation; | ||
| 21 | int nbus; /* # busses on device */ | ||
| 22 | unsigned int freq; /* operating frequency in Hz */ | ||
| 23 | unsigned int max_brp; | ||
| 24 | unsigned int max_sjw; | ||
| 25 | unsigned long dpram_size; | ||
| 26 | const char *name; | ||
| 27 | struct { | ||
| 28 | unsigned long offs; | ||
| 29 | unsigned long addr; | ||
| 30 | const char *fw; | ||
| 31 | } boot, load, app; | ||
| 32 | /* | ||
| 33 | * reset() function | ||
| 34 | * bring pdev in or out of reset, depending on value | ||
| 35 | */ | ||
| 36 | int (*reset)(struct platform_device *pdev, int value); | ||
| 37 | int (*enable_irq)(struct platform_device *pdev, int value); | ||
| 38 | }; | ||
| 39 | |||
| 40 | #endif | ||
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 263a2944566f..302be4aa69d6 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
| @@ -699,13 +699,13 @@ static void cnic_free_dma(struct cnic_dev *dev, struct cnic_dma *dma) | |||
| 699 | static void cnic_setup_page_tbl(struct cnic_dev *dev, struct cnic_dma *dma) | 699 | static void cnic_setup_page_tbl(struct cnic_dev *dev, struct cnic_dma *dma) |
| 700 | { | 700 | { |
| 701 | int i; | 701 | int i; |
| 702 | u32 *page_table = dma->pgtbl; | 702 | __le32 *page_table = (__le32 *) dma->pgtbl; |
| 703 | 703 | ||
| 704 | for (i = 0; i < dma->num_pages; i++) { | 704 | for (i = 0; i < dma->num_pages; i++) { |
| 705 | /* Each entry needs to be in big endian format. */ | 705 | /* Each entry needs to be in big endian format. */ |
| 706 | *page_table = (u32) ((u64) dma->pg_map_arr[i] >> 32); | 706 | *page_table = cpu_to_le32((u64) dma->pg_map_arr[i] >> 32); |
| 707 | page_table++; | 707 | page_table++; |
| 708 | *page_table = (u32) dma->pg_map_arr[i]; | 708 | *page_table = cpu_to_le32(dma->pg_map_arr[i] & 0xffffffff); |
| 709 | page_table++; | 709 | page_table++; |
| 710 | } | 710 | } |
| 711 | } | 711 | } |
| @@ -713,13 +713,13 @@ static void cnic_setup_page_tbl(struct cnic_dev *dev, struct cnic_dma *dma) | |||
| 713 | static void cnic_setup_page_tbl_le(struct cnic_dev *dev, struct cnic_dma *dma) | 713 | static void cnic_setup_page_tbl_le(struct cnic_dev *dev, struct cnic_dma *dma) |
| 714 | { | 714 | { |
| 715 | int i; | 715 | int i; |
| 716 | u32 *page_table = dma->pgtbl; | 716 | __le32 *page_table = (__le32 *) dma->pgtbl; |
| 717 | 717 | ||
| 718 | for (i = 0; i < dma->num_pages; i++) { | 718 | for (i = 0; i < dma->num_pages; i++) { |
| 719 | /* Each entry needs to be in little endian format. */ | 719 | /* Each entry needs to be in little endian format. */ |
| 720 | *page_table = dma->pg_map_arr[i] & 0xffffffff; | 720 | *page_table = cpu_to_le32(dma->pg_map_arr[i] & 0xffffffff); |
| 721 | page_table++; | 721 | page_table++; |
| 722 | *page_table = (u32) ((u64) dma->pg_map_arr[i] >> 32); | 722 | *page_table = cpu_to_le32((u64) dma->pg_map_arr[i] >> 32); |
| 723 | page_table++; | 723 | page_table++; |
| 724 | } | 724 | } |
| 725 | } | 725 | } |
| @@ -2760,6 +2760,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) | |||
| 2760 | u32 status_idx = (u16) *cp->kcq1.status_idx_ptr; | 2760 | u32 status_idx = (u16) *cp->kcq1.status_idx_ptr; |
| 2761 | int kcqe_cnt; | 2761 | int kcqe_cnt; |
| 2762 | 2762 | ||
| 2763 | /* status block index must be read before reading other fields */ | ||
| 2764 | rmb(); | ||
| 2763 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; | 2765 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; |
| 2764 | 2766 | ||
| 2765 | while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { | 2767 | while ((kcqe_cnt = cnic_get_kcqes(dev, &cp->kcq1))) { |
| @@ -2770,6 +2772,8 @@ static u32 cnic_service_bnx2_queues(struct cnic_dev *dev) | |||
| 2770 | barrier(); | 2772 | barrier(); |
| 2771 | if (status_idx != *cp->kcq1.status_idx_ptr) { | 2773 | if (status_idx != *cp->kcq1.status_idx_ptr) { |
| 2772 | status_idx = (u16) *cp->kcq1.status_idx_ptr; | 2774 | status_idx = (u16) *cp->kcq1.status_idx_ptr; |
| 2775 | /* status block index must be read first */ | ||
| 2776 | rmb(); | ||
| 2773 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; | 2777 | cp->kwq_con_idx = *cp->kwq_con_idx_ptr; |
| 2774 | } else | 2778 | } else |
| 2775 | break; | 2779 | break; |
| @@ -2888,6 +2892,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) | |||
| 2888 | u32 last_status = *info->status_idx_ptr; | 2892 | u32 last_status = *info->status_idx_ptr; |
| 2889 | int kcqe_cnt; | 2893 | int kcqe_cnt; |
| 2890 | 2894 | ||
| 2895 | /* status block index must be read before reading the KCQ */ | ||
| 2896 | rmb(); | ||
| 2891 | while ((kcqe_cnt = cnic_get_kcqes(dev, info))) { | 2897 | while ((kcqe_cnt = cnic_get_kcqes(dev, info))) { |
| 2892 | 2898 | ||
| 2893 | service_kcqes(dev, kcqe_cnt); | 2899 | service_kcqes(dev, kcqe_cnt); |
| @@ -2898,6 +2904,8 @@ static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) | |||
| 2898 | break; | 2904 | break; |
| 2899 | 2905 | ||
| 2900 | last_status = *info->status_idx_ptr; | 2906 | last_status = *info->status_idx_ptr; |
| 2907 | /* status block index must be read before reading the KCQ */ | ||
| 2908 | rmb(); | ||
| 2901 | } | 2909 | } |
| 2902 | return last_status; | 2910 | return last_status; |
| 2903 | } | 2911 | } |
| @@ -2906,26 +2914,35 @@ static void cnic_service_bnx2x_bh(unsigned long data) | |||
| 2906 | { | 2914 | { |
| 2907 | struct cnic_dev *dev = (struct cnic_dev *) data; | 2915 | struct cnic_dev *dev = (struct cnic_dev *) data; |
| 2908 | struct cnic_local *cp = dev->cnic_priv; | 2916 | struct cnic_local *cp = dev->cnic_priv; |
| 2909 | u32 status_idx; | 2917 | u32 status_idx, new_status_idx; |
| 2910 | 2918 | ||
| 2911 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) | 2919 | if (unlikely(!test_bit(CNIC_F_CNIC_UP, &dev->flags))) |
| 2912 | return; | 2920 | return; |
| 2913 | 2921 | ||
| 2914 | status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); | 2922 | while (1) { |
| 2923 | status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); | ||
| 2915 | 2924 | ||
| 2916 | CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); | 2925 | CNIC_WR16(dev, cp->kcq1.io_addr, |
| 2926 | cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); | ||
| 2917 | 2927 | ||
| 2918 | if (BNX2X_CHIP_IS_E2(cp->chip_id)) { | 2928 | if (!BNX2X_CHIP_IS_E2(cp->chip_id)) { |
| 2919 | status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); | 2929 | cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, |
| 2930 | status_idx, IGU_INT_ENABLE, 1); | ||
| 2931 | break; | ||
| 2932 | } | ||
| 2933 | |||
| 2934 | new_status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq2); | ||
| 2935 | |||
| 2936 | if (new_status_idx != status_idx) | ||
| 2937 | continue; | ||
| 2920 | 2938 | ||
| 2921 | CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx + | 2939 | CNIC_WR16(dev, cp->kcq2.io_addr, cp->kcq2.sw_prod_idx + |
| 2922 | MAX_KCQ_IDX); | 2940 | MAX_KCQ_IDX); |
| 2923 | 2941 | ||
| 2924 | cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, | 2942 | cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, |
| 2925 | status_idx, IGU_INT_ENABLE, 1); | 2943 | status_idx, IGU_INT_ENABLE, 1); |
| 2926 | } else { | 2944 | |
| 2927 | cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, | 2945 | break; |
| 2928 | status_idx, IGU_INT_ENABLE, 1); | ||
| 2929 | } | 2946 | } |
| 2930 | } | 2947 | } |
| 2931 | 2948 | ||
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 059c1eec8c3f..ec35d458102c 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c | |||
| @@ -2710,6 +2710,8 @@ static int cxgb_open(struct net_device *dev) | |||
| 2710 | struct port_info *pi = netdev_priv(dev); | 2710 | struct port_info *pi = netdev_priv(dev); |
| 2711 | struct adapter *adapter = pi->adapter; | 2711 | struct adapter *adapter = pi->adapter; |
| 2712 | 2712 | ||
| 2713 | netif_carrier_off(dev); | ||
| 2714 | |||
| 2713 | if (!(adapter->flags & FULL_INIT_DONE)) { | 2715 | if (!(adapter->flags & FULL_INIT_DONE)) { |
| 2714 | err = cxgb_up(adapter); | 2716 | err = cxgb_up(adapter); |
| 2715 | if (err < 0) | 2717 | if (err < 0) |
| @@ -3661,7 +3663,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3661 | pi->xact_addr_filt = -1; | 3663 | pi->xact_addr_filt = -1; |
| 3662 | pi->rx_offload = RX_CSO; | 3664 | pi->rx_offload = RX_CSO; |
| 3663 | pi->port_id = i; | 3665 | pi->port_id = i; |
| 3664 | netif_carrier_off(netdev); | ||
| 3665 | netdev->irq = pdev->irq; | 3666 | netdev->irq = pdev->irq; |
| 3666 | 3667 | ||
| 3667 | netdev->features |= NETIF_F_SG | TSO_FLAGS; | 3668 | netdev->features |= NETIF_F_SG | TSO_FLAGS; |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 56166ae2059f..6aad64df4dcb 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -2040,7 +2040,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) | |||
| 2040 | { | 2040 | { |
| 2041 | int i; | 2041 | int i; |
| 2042 | 2042 | ||
| 2043 | BUG_ON(adapter->debugfs_root == NULL); | 2043 | BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); |
| 2044 | 2044 | ||
| 2045 | /* | 2045 | /* |
| 2046 | * Debugfs support is best effort. | 2046 | * Debugfs support is best effort. |
| @@ -2061,7 +2061,7 @@ static int __devinit setup_debugfs(struct adapter *adapter) | |||
| 2061 | */ | 2061 | */ |
| 2062 | static void cleanup_debugfs(struct adapter *adapter) | 2062 | static void cleanup_debugfs(struct adapter *adapter) |
| 2063 | { | 2063 | { |
| 2064 | BUG_ON(adapter->debugfs_root == NULL); | 2064 | BUG_ON(IS_ERR_OR_NULL(adapter->debugfs_root)); |
| 2065 | 2065 | ||
| 2066 | /* | 2066 | /* |
| 2067 | * Unlike our sister routine cleanup_proc(), we don't need to remove | 2067 | * Unlike our sister routine cleanup_proc(), we don't need to remove |
| @@ -2489,17 +2489,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2489 | struct net_device *netdev; | 2489 | struct net_device *netdev; |
| 2490 | 2490 | ||
| 2491 | /* | 2491 | /* |
| 2492 | * Vet our module parameters. | ||
| 2493 | */ | ||
| 2494 | if (msi != MSI_MSIX && msi != MSI_MSI) { | ||
| 2495 | dev_err(&pdev->dev, "bad module parameter msi=%d; must be %d" | ||
| 2496 | " (MSI-X or MSI) or %d (MSI)\n", msi, MSI_MSIX, | ||
| 2497 | MSI_MSI); | ||
| 2498 | err = -EINVAL; | ||
| 2499 | goto err_out; | ||
| 2500 | } | ||
| 2501 | |||
| 2502 | /* | ||
| 2503 | * Print our driver banner the first time we're called to initialize a | 2492 | * Print our driver banner the first time we're called to initialize a |
| 2504 | * device. | 2493 | * device. |
| 2505 | */ | 2494 | */ |
| @@ -2711,11 +2700,11 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2711 | /* | 2700 | /* |
| 2712 | * Set up our debugfs entries. | 2701 | * Set up our debugfs entries. |
| 2713 | */ | 2702 | */ |
| 2714 | if (cxgb4vf_debugfs_root) { | 2703 | if (!IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) { |
| 2715 | adapter->debugfs_root = | 2704 | adapter->debugfs_root = |
| 2716 | debugfs_create_dir(pci_name(pdev), | 2705 | debugfs_create_dir(pci_name(pdev), |
| 2717 | cxgb4vf_debugfs_root); | 2706 | cxgb4vf_debugfs_root); |
| 2718 | if (adapter->debugfs_root == NULL) | 2707 | if (IS_ERR_OR_NULL(adapter->debugfs_root)) |
| 2719 | dev_warn(&pdev->dev, "could not create debugfs" | 2708 | dev_warn(&pdev->dev, "could not create debugfs" |
| 2720 | " directory"); | 2709 | " directory"); |
| 2721 | else | 2710 | else |
| @@ -2770,7 +2759,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2770 | */ | 2759 | */ |
| 2771 | 2760 | ||
| 2772 | err_free_debugfs: | 2761 | err_free_debugfs: |
| 2773 | if (adapter->debugfs_root) { | 2762 | if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { |
| 2774 | cleanup_debugfs(adapter); | 2763 | cleanup_debugfs(adapter); |
| 2775 | debugfs_remove_recursive(adapter->debugfs_root); | 2764 | debugfs_remove_recursive(adapter->debugfs_root); |
| 2776 | } | 2765 | } |
| @@ -2802,7 +2791,6 @@ err_release_regions: | |||
| 2802 | err_disable_device: | 2791 | err_disable_device: |
| 2803 | pci_disable_device(pdev); | 2792 | pci_disable_device(pdev); |
| 2804 | 2793 | ||
| 2805 | err_out: | ||
| 2806 | return err; | 2794 | return err; |
| 2807 | } | 2795 | } |
| 2808 | 2796 | ||
| @@ -2840,7 +2828,7 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) | |||
| 2840 | /* | 2828 | /* |
| 2841 | * Tear down our debugfs entries. | 2829 | * Tear down our debugfs entries. |
| 2842 | */ | 2830 | */ |
| 2843 | if (adapter->debugfs_root) { | 2831 | if (!IS_ERR_OR_NULL(adapter->debugfs_root)) { |
| 2844 | cleanup_debugfs(adapter); | 2832 | cleanup_debugfs(adapter); |
| 2845 | debugfs_remove_recursive(adapter->debugfs_root); | 2833 | debugfs_remove_recursive(adapter->debugfs_root); |
| 2846 | } | 2834 | } |
| @@ -2874,6 +2862,46 @@ static void __devexit cxgb4vf_pci_remove(struct pci_dev *pdev) | |||
| 2874 | } | 2862 | } |
| 2875 | 2863 | ||
| 2876 | /* | 2864 | /* |
| 2865 | * "Shutdown" quiesce the device, stopping Ingress Packet and Interrupt | ||
| 2866 | * delivery. | ||
| 2867 | */ | ||
| 2868 | static void __devexit cxgb4vf_pci_shutdown(struct pci_dev *pdev) | ||
| 2869 | { | ||
| 2870 | struct adapter *adapter; | ||
| 2871 | int pidx; | ||
| 2872 | |||
| 2873 | adapter = pci_get_drvdata(pdev); | ||
| 2874 | if (!adapter) | ||
| 2875 | return; | ||
| 2876 | |||
| 2877 | /* | ||
| 2878 | * Disable all Virtual Interfaces. This will shut down the | ||
| 2879 | * delivery of all ingress packets into the chip for these | ||
| 2880 | * Virtual Interfaces. | ||
| 2881 | */ | ||
| 2882 | for_each_port(adapter, pidx) { | ||
| 2883 | struct net_device *netdev; | ||
| 2884 | struct port_info *pi; | ||
| 2885 | |||
| 2886 | if (!test_bit(pidx, &adapter->registered_device_map)) | ||
| 2887 | continue; | ||
| 2888 | |||
| 2889 | netdev = adapter->port[pidx]; | ||
| 2890 | if (!netdev) | ||
| 2891 | continue; | ||
| 2892 | |||
| 2893 | pi = netdev_priv(netdev); | ||
| 2894 | t4vf_enable_vi(adapter, pi->viid, false, false); | ||
| 2895 | } | ||
| 2896 | |||
| 2897 | /* | ||
| 2898 | * Free up all Queues which will prevent further DMA and | ||
| 2899 | * Interrupts allowing various internal pathways to drain. | ||
| 2900 | */ | ||
| 2901 | t4vf_free_sge_resources(adapter); | ||
| 2902 | } | ||
| 2903 | |||
| 2904 | /* | ||
| 2877 | * PCI Device registration data structures. | 2905 | * PCI Device registration data structures. |
| 2878 | */ | 2906 | */ |
| 2879 | #define CH_DEVICE(devid, idx) \ | 2907 | #define CH_DEVICE(devid, idx) \ |
| @@ -2906,6 +2934,7 @@ static struct pci_driver cxgb4vf_driver = { | |||
| 2906 | .id_table = cxgb4vf_pci_tbl, | 2934 | .id_table = cxgb4vf_pci_tbl, |
| 2907 | .probe = cxgb4vf_pci_probe, | 2935 | .probe = cxgb4vf_pci_probe, |
| 2908 | .remove = __devexit_p(cxgb4vf_pci_remove), | 2936 | .remove = __devexit_p(cxgb4vf_pci_remove), |
| 2937 | .shutdown = __devexit_p(cxgb4vf_pci_shutdown), | ||
| 2909 | }; | 2938 | }; |
| 2910 | 2939 | ||
| 2911 | /* | 2940 | /* |
| @@ -2915,14 +2944,25 @@ static int __init cxgb4vf_module_init(void) | |||
| 2915 | { | 2944 | { |
| 2916 | int ret; | 2945 | int ret; |
| 2917 | 2946 | ||
| 2947 | /* | ||
| 2948 | * Vet our module parameters. | ||
| 2949 | */ | ||
| 2950 | if (msi != MSI_MSIX && msi != MSI_MSI) { | ||
| 2951 | printk(KERN_WARNING KBUILD_MODNAME | ||
| 2952 | ": bad module parameter msi=%d; must be %d" | ||
| 2953 | " (MSI-X or MSI) or %d (MSI)\n", | ||
| 2954 | msi, MSI_MSIX, MSI_MSI); | ||
| 2955 | return -EINVAL; | ||
| 2956 | } | ||
| 2957 | |||
| 2918 | /* Debugfs support is optional, just warn if this fails */ | 2958 | /* Debugfs support is optional, just warn if this fails */ |
| 2919 | cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | 2959 | cxgb4vf_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); |
| 2920 | if (!cxgb4vf_debugfs_root) | 2960 | if (IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) |
| 2921 | printk(KERN_WARNING KBUILD_MODNAME ": could not create" | 2961 | printk(KERN_WARNING KBUILD_MODNAME ": could not create" |
| 2922 | " debugfs entry, continuing\n"); | 2962 | " debugfs entry, continuing\n"); |
| 2923 | 2963 | ||
| 2924 | ret = pci_register_driver(&cxgb4vf_driver); | 2964 | ret = pci_register_driver(&cxgb4vf_driver); |
| 2925 | if (ret < 0) | 2965 | if (ret < 0 && !IS_ERR_OR_NULL(cxgb4vf_debugfs_root)) |
| 2926 | debugfs_remove(cxgb4vf_debugfs_root); | 2966 | debugfs_remove(cxgb4vf_debugfs_root); |
| 2927 | return ret; | 2967 | return ret; |
| 2928 | } | 2968 | } |
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index 0f51c80475ce..192db226ec7f 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c | |||
| @@ -171,7 +171,7 @@ int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size, | |||
| 171 | delay_idx = 0; | 171 | delay_idx = 0; |
| 172 | ms = delay[0]; | 172 | ms = delay[0]; |
| 173 | 173 | ||
| 174 | for (i = 0; i < 500; i += ms) { | 174 | for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) { |
| 175 | if (sleep_ok) { | 175 | if (sleep_ok) { |
| 176 | ms = delay[delay_idx]; | 176 | ms = delay[delay_idx]; |
| 177 | if (delay_idx < ARRAY_SIZE(delay) - 1) | 177 | if (delay_idx < ARRAY_SIZE(delay) - 1) |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 2a628d17d178..7018bfe408a4 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
| @@ -1008,7 +1008,7 @@ static void emac_rx_handler(void *token, int len, int status) | |||
| 1008 | int ret; | 1008 | int ret; |
| 1009 | 1009 | ||
| 1010 | /* free and bail if we are shutting down */ | 1010 | /* free and bail if we are shutting down */ |
| 1011 | if (unlikely(!netif_running(ndev))) { | 1011 | if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { |
| 1012 | dev_kfree_skb_any(skb); | 1012 | dev_kfree_skb_any(skb); |
| 1013 | return; | 1013 | return; |
| 1014 | } | 1014 | } |
diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 1b48b68ad4fd..8b0084d17c8c 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c | |||
| @@ -1094,7 +1094,7 @@ static int depca_rx(struct net_device *dev) | |||
| 1094 | } | 1094 | } |
| 1095 | } | 1095 | } |
| 1096 | /* Change buffer ownership for this last frame, back to the adapter */ | 1096 | /* Change buffer ownership for this last frame, back to the adapter */ |
| 1097 | for (; lp->rx_old != entry; lp->rx_old = (++lp->rx_old) & lp->rxRingMask) { | 1097 | for (; lp->rx_old != entry; lp->rx_old = (lp->rx_old + 1) & lp->rxRingMask) { |
| 1098 | writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base); | 1098 | writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, &lp->rx_ring[lp->rx_old].base); |
| 1099 | } | 1099 | } |
| 1100 | writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base); | 1100 | writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base); |
| @@ -1103,7 +1103,7 @@ static int depca_rx(struct net_device *dev) | |||
| 1103 | /* | 1103 | /* |
| 1104 | ** Update entry information | 1104 | ** Update entry information |
| 1105 | */ | 1105 | */ |
| 1106 | lp->rx_new = (++lp->rx_new) & lp->rxRingMask; | 1106 | lp->rx_new = (lp->rx_new + 1) & lp->rxRingMask; |
| 1107 | } | 1107 | } |
| 1108 | 1108 | ||
| 1109 | return 0; | 1109 | return 0; |
| @@ -1148,7 +1148,7 @@ static int depca_tx(struct net_device *dev) | |||
| 1148 | } | 1148 | } |
| 1149 | 1149 | ||
| 1150 | /* Update all the pointers */ | 1150 | /* Update all the pointers */ |
| 1151 | lp->tx_old = (++lp->tx_old) & lp->txRingMask; | 1151 | lp->tx_old = (lp->tx_old + 1) & lp->txRingMask; |
| 1152 | } | 1152 | } |
| 1153 | 1153 | ||
| 1154 | return 0; | 1154 | return 0; |
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index e1a8216ff692..c05db6046050 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c | |||
| @@ -1753,8 +1753,6 @@ rio_close (struct net_device *dev) | |||
| 1753 | 1753 | ||
| 1754 | /* Free all the skbuffs in the queue. */ | 1754 | /* Free all the skbuffs in the queue. */ |
| 1755 | for (i = 0; i < RX_RING_SIZE; i++) { | 1755 | for (i = 0; i < RX_RING_SIZE; i++) { |
| 1756 | np->rx_ring[i].status = 0; | ||
| 1757 | np->rx_ring[i].fraginfo = 0; | ||
| 1758 | skb = np->rx_skbuff[i]; | 1756 | skb = np->rx_skbuff[i]; |
| 1759 | if (skb) { | 1757 | if (skb) { |
| 1760 | pci_unmap_single(np->pdev, | 1758 | pci_unmap_single(np->pdev, |
| @@ -1763,6 +1761,8 @@ rio_close (struct net_device *dev) | |||
| 1763 | dev_kfree_skb (skb); | 1761 | dev_kfree_skb (skb); |
| 1764 | np->rx_skbuff[i] = NULL; | 1762 | np->rx_skbuff[i] = NULL; |
| 1765 | } | 1763 | } |
| 1764 | np->rx_ring[i].status = 0; | ||
| 1765 | np->rx_ring[i].fraginfo = 0; | ||
| 1766 | } | 1766 | } |
| 1767 | for (i = 0; i < TX_RING_SIZE; i++) { | 1767 | for (i = 0; i < TX_RING_SIZE; i++) { |
| 1768 | skb = np->tx_skbuff[i]; | 1768 | skb = np->tx_skbuff[i]; |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 2d4c4fc1d900..461dd6f905f7 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
| @@ -802,10 +802,7 @@ dm9000_init_dm9000(struct net_device *dev) | |||
| 802 | /* Checksum mode */ | 802 | /* Checksum mode */ |
| 803 | dm9000_set_rx_csum_unlocked(dev, db->rx_csum); | 803 | dm9000_set_rx_csum_unlocked(dev, db->rx_csum); |
| 804 | 804 | ||
| 805 | /* GPIO0 on pre-activate PHY */ | ||
| 806 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ | ||
| 807 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ | 805 | iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ |
| 808 | iow(db, DM9000_GPR, 0); /* Enable PHY */ | ||
| 809 | 806 | ||
| 810 | ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; | 807 | ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; |
| 811 | 808 | ||
| @@ -852,8 +849,8 @@ static void dm9000_timeout(struct net_device *dev) | |||
| 852 | unsigned long flags; | 849 | unsigned long flags; |
| 853 | 850 | ||
| 854 | /* Save previous register address */ | 851 | /* Save previous register address */ |
| 855 | reg_save = readb(db->io_addr); | ||
| 856 | spin_lock_irqsave(&db->lock, flags); | 852 | spin_lock_irqsave(&db->lock, flags); |
| 853 | reg_save = readb(db->io_addr); | ||
| 857 | 854 | ||
| 858 | netif_stop_queue(dev); | 855 | netif_stop_queue(dev); |
| 859 | dm9000_reset(db); | 856 | dm9000_reset(db); |
| @@ -1194,6 +1191,10 @@ dm9000_open(struct net_device *dev) | |||
| 1194 | if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev)) | 1191 | if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev)) |
| 1195 | return -EAGAIN; | 1192 | return -EAGAIN; |
| 1196 | 1193 | ||
| 1194 | /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */ | ||
| 1195 | iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */ | ||
| 1196 | mdelay(1); /* delay needs by DM9000B */ | ||
| 1197 | |||
| 1197 | /* Initialize DM9000 board */ | 1198 | /* Initialize DM9000 board */ |
| 1198 | dm9000_reset(db); | 1199 | dm9000_reset(db); |
| 1199 | dm9000_init_dm9000(dev); | 1200 | dm9000_init_dm9000(dev); |
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 9d8a20b72fa9..8318ea06cb6d 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c | |||
| @@ -337,8 +337,6 @@ static int dnet_mii_init(struct dnet *bp) | |||
| 337 | for (i = 0; i < PHY_MAX_ADDR; i++) | 337 | for (i = 0; i < PHY_MAX_ADDR; i++) |
| 338 | bp->mii_bus->irq[i] = PHY_POLL; | 338 | bp->mii_bus->irq[i] = PHY_POLL; |
| 339 | 339 | ||
| 340 | platform_set_drvdata(bp->dev, bp->mii_bus); | ||
| 341 | |||
| 342 | if (mdiobus_register(bp->mii_bus)) { | 340 | if (mdiobus_register(bp->mii_bus)) { |
| 343 | err = -ENXIO; | 341 | err = -ENXIO; |
| 344 | goto err_out_free_mdio_irq; | 342 | goto err_out_free_mdio_irq; |
| @@ -863,6 +861,7 @@ static int __devinit dnet_probe(struct platform_device *pdev) | |||
| 863 | bp = netdev_priv(dev); | 861 | bp = netdev_priv(dev); |
| 864 | bp->dev = dev; | 862 | bp->dev = dev; |
| 865 | 863 | ||
| 864 | platform_set_drvdata(pdev, dev); | ||
| 866 | SET_NETDEV_DEV(dev, &pdev->dev); | 865 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 867 | 866 | ||
| 868 | spin_lock_init(&bp->lock); | 867 | spin_lock_init(&bp->lock); |
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index aed223b1b897..7501d977d992 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c | |||
| @@ -124,6 +124,7 @@ static s32 e1000_set_phy_type(struct e1000_hw *hw) | |||
| 124 | case M88E1000_I_PHY_ID: | 124 | case M88E1000_I_PHY_ID: |
| 125 | case M88E1011_I_PHY_ID: | 125 | case M88E1011_I_PHY_ID: |
| 126 | case M88E1111_I_PHY_ID: | 126 | case M88E1111_I_PHY_ID: |
| 127 | case M88E1118_E_PHY_ID: | ||
| 127 | hw->phy_type = e1000_phy_m88; | 128 | hw->phy_type = e1000_phy_m88; |
| 128 | break; | 129 | break; |
| 129 | case IGP01E1000_I_PHY_ID: | 130 | case IGP01E1000_I_PHY_ID: |
| @@ -3222,7 +3223,8 @@ static s32 e1000_detect_gig_phy(struct e1000_hw *hw) | |||
| 3222 | break; | 3223 | break; |
| 3223 | case e1000_ce4100: | 3224 | case e1000_ce4100: |
| 3224 | if ((hw->phy_id == RTL8211B_PHY_ID) || | 3225 | if ((hw->phy_id == RTL8211B_PHY_ID) || |
| 3225 | (hw->phy_id == RTL8201N_PHY_ID)) | 3226 | (hw->phy_id == RTL8201N_PHY_ID) || |
| 3227 | (hw->phy_id == M88E1118_E_PHY_ID)) | ||
| 3226 | match = true; | 3228 | match = true; |
| 3227 | break; | 3229 | break; |
| 3228 | case e1000_82541: | 3230 | case e1000_82541: |
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 196eeda2dd6c..c70b23d52284 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h | |||
| @@ -2917,6 +2917,7 @@ struct e1000_host_command_info { | |||
| 2917 | #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID | 2917 | #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID |
| 2918 | #define M88E1011_I_REV_4 0x04 | 2918 | #define M88E1011_I_REV_4 0x04 |
| 2919 | #define M88E1111_I_PHY_ID 0x01410CC0 | 2919 | #define M88E1111_I_PHY_ID 0x01410CC0 |
| 2920 | #define M88E1118_E_PHY_ID 0x01410E40 | ||
| 2920 | #define L1LXT971A_PHY_ID 0x001378E0 | 2921 | #define L1LXT971A_PHY_ID 0x001378E0 |
| 2921 | 2922 | ||
| 2922 | #define RTL8211B_PHY_ID 0x001CC910 | 2923 | #define RTL8211B_PHY_ID 0x001CC910 |
diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 55c1711f1688..33e7c45a4fe4 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h | |||
| @@ -42,7 +42,8 @@ | |||
| 42 | #define GBE_CONFIG_RAM_BASE \ | 42 | #define GBE_CONFIG_RAM_BASE \ |
| 43 | ((unsigned int)(CONFIG_RAM_BASE + GBE_CONFIG_OFFSET)) | 43 | ((unsigned int)(CONFIG_RAM_BASE + GBE_CONFIG_OFFSET)) |
| 44 | 44 | ||
| 45 | #define GBE_CONFIG_BASE_VIRT phys_to_virt(GBE_CONFIG_RAM_BASE) | 45 | #define GBE_CONFIG_BASE_VIRT \ |
| 46 | ((void __iomem *)phys_to_virt(GBE_CONFIG_RAM_BASE)) | ||
| 46 | 47 | ||
| 47 | #define GBE_CONFIG_FLASH_WRITE(base, offset, count, data) \ | 48 | #define GBE_CONFIG_FLASH_WRITE(base, offset, count, data) \ |
| 48 | (iowrite16_rep(base + offset, data, count)) | 49 | (iowrite16_rep(base + offset, data, count)) |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1c18f26b0812..2e5022849f18 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
| @@ -937,6 +937,9 @@ static void e1000_print_hw_hang(struct work_struct *work) | |||
| 937 | u16 phy_status, phy_1000t_status, phy_ext_status; | 937 | u16 phy_status, phy_1000t_status, phy_ext_status; |
| 938 | u16 pci_status; | 938 | u16 pci_status; |
| 939 | 939 | ||
| 940 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 941 | return; | ||
| 942 | |||
| 940 | e1e_rphy(hw, PHY_STATUS, &phy_status); | 943 | e1e_rphy(hw, PHY_STATUS, &phy_status); |
| 941 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); | 944 | e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status); |
| 942 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); | 945 | e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status); |
| @@ -1506,6 +1509,9 @@ static void e1000e_downshift_workaround(struct work_struct *work) | |||
| 1506 | struct e1000_adapter *adapter = container_of(work, | 1509 | struct e1000_adapter *adapter = container_of(work, |
| 1507 | struct e1000_adapter, downshift_task); | 1510 | struct e1000_adapter, downshift_task); |
| 1508 | 1511 | ||
| 1512 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 1513 | return; | ||
| 1514 | |||
| 1509 | e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); | 1515 | e1000e_gig_downshift_workaround_ich8lan(&adapter->hw); |
| 1510 | } | 1516 | } |
| 1511 | 1517 | ||
| @@ -3338,6 +3344,21 @@ int e1000e_up(struct e1000_adapter *adapter) | |||
| 3338 | return 0; | 3344 | return 0; |
| 3339 | } | 3345 | } |
| 3340 | 3346 | ||
| 3347 | static void e1000e_flush_descriptors(struct e1000_adapter *adapter) | ||
| 3348 | { | ||
| 3349 | struct e1000_hw *hw = &adapter->hw; | ||
| 3350 | |||
| 3351 | if (!(adapter->flags2 & FLAG2_DMA_BURST)) | ||
| 3352 | return; | ||
| 3353 | |||
| 3354 | /* flush pending descriptor writebacks to memory */ | ||
| 3355 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
| 3356 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | ||
| 3357 | |||
| 3358 | /* execute the writes immediately */ | ||
| 3359 | e1e_flush(); | ||
| 3360 | } | ||
| 3361 | |||
| 3341 | void e1000e_down(struct e1000_adapter *adapter) | 3362 | void e1000e_down(struct e1000_adapter *adapter) |
| 3342 | { | 3363 | { |
| 3343 | struct net_device *netdev = adapter->netdev; | 3364 | struct net_device *netdev = adapter->netdev; |
| @@ -3377,6 +3398,9 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
| 3377 | 3398 | ||
| 3378 | if (!pci_channel_offline(adapter->pdev)) | 3399 | if (!pci_channel_offline(adapter->pdev)) |
| 3379 | e1000e_reset(adapter); | 3400 | e1000e_reset(adapter); |
| 3401 | |||
| 3402 | e1000e_flush_descriptors(adapter); | ||
| 3403 | |||
| 3380 | e1000_clean_tx_ring(adapter); | 3404 | e1000_clean_tx_ring(adapter); |
| 3381 | e1000_clean_rx_ring(adapter); | 3405 | e1000_clean_rx_ring(adapter); |
| 3382 | 3406 | ||
| @@ -3765,6 +3789,10 @@ static void e1000e_update_phy_task(struct work_struct *work) | |||
| 3765 | { | 3789 | { |
| 3766 | struct e1000_adapter *adapter = container_of(work, | 3790 | struct e1000_adapter *adapter = container_of(work, |
| 3767 | struct e1000_adapter, update_phy_task); | 3791 | struct e1000_adapter, update_phy_task); |
| 3792 | |||
| 3793 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 3794 | return; | ||
| 3795 | |||
| 3768 | e1000_get_phy_info(&adapter->hw); | 3796 | e1000_get_phy_info(&adapter->hw); |
| 3769 | } | 3797 | } |
| 3770 | 3798 | ||
| @@ -3775,6 +3803,10 @@ static void e1000e_update_phy_task(struct work_struct *work) | |||
| 3775 | static void e1000_update_phy_info(unsigned long data) | 3803 | static void e1000_update_phy_info(unsigned long data) |
| 3776 | { | 3804 | { |
| 3777 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; | 3805 | struct e1000_adapter *adapter = (struct e1000_adapter *) data; |
| 3806 | |||
| 3807 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 3808 | return; | ||
| 3809 | |||
| 3778 | schedule_work(&adapter->update_phy_task); | 3810 | schedule_work(&adapter->update_phy_task); |
| 3779 | } | 3811 | } |
| 3780 | 3812 | ||
| @@ -4149,6 +4181,9 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
| 4149 | u32 link, tctl; | 4181 | u32 link, tctl; |
| 4150 | int tx_pending = 0; | 4182 | int tx_pending = 0; |
| 4151 | 4183 | ||
| 4184 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 4185 | return; | ||
| 4186 | |||
| 4152 | link = e1000e_has_link(adapter); | 4187 | link = e1000e_has_link(adapter); |
| 4153 | if ((netif_carrier_ok(netdev)) && link) { | 4188 | if ((netif_carrier_ok(netdev)) && link) { |
| 4154 | /* Cancel scheduled suspend requests. */ | 4189 | /* Cancel scheduled suspend requests. */ |
| @@ -4309,7 +4344,6 @@ link_up: | |||
| 4309 | * to get done, so reset controller to flush Tx. | 4344 | * to get done, so reset controller to flush Tx. |
| 4310 | * (Do the reset outside of interrupt context). | 4345 | * (Do the reset outside of interrupt context). |
| 4311 | */ | 4346 | */ |
| 4312 | adapter->tx_timeout_count++; | ||
| 4313 | schedule_work(&adapter->reset_task); | 4347 | schedule_work(&adapter->reset_task); |
| 4314 | /* return immediately since reset is imminent */ | 4348 | /* return immediately since reset is imminent */ |
| 4315 | return; | 4349 | return; |
| @@ -4338,19 +4372,12 @@ link_up: | |||
| 4338 | else | 4372 | else |
| 4339 | ew32(ICS, E1000_ICS_RXDMT0); | 4373 | ew32(ICS, E1000_ICS_RXDMT0); |
| 4340 | 4374 | ||
| 4375 | /* flush pending descriptors to memory before detecting Tx hang */ | ||
| 4376 | e1000e_flush_descriptors(adapter); | ||
| 4377 | |||
| 4341 | /* Force detection of hung controller every watchdog period */ | 4378 | /* Force detection of hung controller every watchdog period */ |
| 4342 | adapter->detect_tx_hung = 1; | 4379 | adapter->detect_tx_hung = 1; |
| 4343 | 4380 | ||
| 4344 | /* flush partial descriptors to memory before detecting Tx hang */ | ||
| 4345 | if (adapter->flags2 & FLAG2_DMA_BURST) { | ||
| 4346 | ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); | ||
| 4347 | ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); | ||
| 4348 | /* | ||
| 4349 | * no need to flush the writes because the timeout code does | ||
| 4350 | * an er32 first thing | ||
| 4351 | */ | ||
| 4352 | } | ||
| 4353 | |||
| 4354 | /* | 4381 | /* |
| 4355 | * With 82571 controllers, LAA may be overwritten due to controller | 4382 | * With 82571 controllers, LAA may be overwritten due to controller |
| 4356 | * reset from the other port. Set the appropriate LAA in RAR[0] | 4383 | * reset from the other port. Set the appropriate LAA in RAR[0] |
| @@ -4888,6 +4915,10 @@ static void e1000_reset_task(struct work_struct *work) | |||
| 4888 | struct e1000_adapter *adapter; | 4915 | struct e1000_adapter *adapter; |
| 4889 | adapter = container_of(work, struct e1000_adapter, reset_task); | 4916 | adapter = container_of(work, struct e1000_adapter, reset_task); |
| 4890 | 4917 | ||
| 4918 | /* don't run the task if already down */ | ||
| 4919 | if (test_bit(__E1000_DOWN, &adapter->state)) | ||
| 4920 | return; | ||
| 4921 | |||
| 4891 | if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && | 4922 | if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) && |
| 4892 | (adapter->flags & FLAG_RX_RESTART_NOW))) { | 4923 | (adapter->flags & FLAG_RX_RESTART_NOW))) { |
| 4893 | e1000e_dump(adapter); | 4924 | e1000e_dump(adapter); |
| @@ -5936,7 +5967,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
| 5936 | /* APME bit in EEPROM is mapped to WUC.APME */ | 5967 | /* APME bit in EEPROM is mapped to WUC.APME */ |
| 5937 | eeprom_data = er32(WUC); | 5968 | eeprom_data = er32(WUC); |
| 5938 | eeprom_apme_mask = E1000_WUC_APME; | 5969 | eeprom_apme_mask = E1000_WUC_APME; |
| 5939 | if (eeprom_data & E1000_WUC_PHY_WAKE) | 5970 | if ((hw->mac.type > e1000_ich10lan) && |
| 5971 | (eeprom_data & E1000_WUC_PHY_WAKE)) | ||
| 5940 | adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP; | 5972 | adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP; |
| 5941 | } else if (adapter->flags & FLAG_APME_IN_CTRL3) { | 5973 | } else if (adapter->flags & FLAG_APME_IN_CTRL3) { |
| 5942 | if (adapter->flags & FLAG_APME_CHECK_PORT_B && | 5974 | if (adapter->flags & FLAG_APME_CHECK_PORT_B && |
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 112c5aa9af7f..907b05a1c659 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c | |||
| @@ -812,7 +812,7 @@ static void enc28j60_read_tsv(struct enc28j60_net *priv, u8 tsv[TSV_SIZE]) | |||
| 812 | if (netif_msg_hw(priv)) | 812 | if (netif_msg_hw(priv)) |
| 813 | printk(KERN_DEBUG DRV_NAME ": reading TSV at addr:0x%04x\n", | 813 | printk(KERN_DEBUG DRV_NAME ": reading TSV at addr:0x%04x\n", |
| 814 | endptr + 1); | 814 | endptr + 1); |
| 815 | enc28j60_mem_read(priv, endptr + 1, sizeof(tsv), tsv); | 815 | enc28j60_mem_read(priv, endptr + 1, TSV_SIZE, tsv); |
| 816 | } | 816 | } |
| 817 | 817 | ||
| 818 | static void enc28j60_dump_tsv(struct enc28j60_net *priv, const char *msg, | 818 | static void enc28j60_dump_tsv(struct enc28j60_net *priv, const char *msg, |
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 2a71373719ae..cd0282d5d40f 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
| @@ -74,7 +74,8 @@ static struct platform_device_id fec_devtype[] = { | |||
| 74 | }, { | 74 | }, { |
| 75 | .name = "imx28-fec", | 75 | .name = "imx28-fec", |
| 76 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, | 76 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, |
| 77 | } | 77 | }, |
| 78 | { } | ||
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 80 | static unsigned char macaddr[ETH_ALEN]; | 81 | static unsigned char macaddr[ETH_ALEN]; |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index af09296ef0dd..9c0b1bac6af6 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -5645,6 +5645,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
| 5645 | goto out_error; | 5645 | goto out_error; |
| 5646 | } | 5646 | } |
| 5647 | 5647 | ||
| 5648 | netif_carrier_off(dev); | ||
| 5649 | |||
| 5648 | dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", | 5650 | dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n", |
| 5649 | dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); | 5651 | dev->name, np->phy_oui, np->phyaddr, dev->dev_addr); |
| 5650 | 5652 | ||
diff --git a/drivers/net/igbvf/vf.c b/drivers/net/igbvf/vf.c index 74486a8b009a..af3822f9ea9a 100644 --- a/drivers/net/igbvf/vf.c +++ b/drivers/net/igbvf/vf.c | |||
| @@ -220,7 +220,7 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr) | |||
| 220 | * The parameter rar_count will usually be hw->mac.rar_entry_count | 220 | * The parameter rar_count will usually be hw->mac.rar_entry_count |
| 221 | * unless there are workarounds that change this. | 221 | * unless there are workarounds that change this. |
| 222 | **/ | 222 | **/ |
| 223 | void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, | 223 | static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, |
| 224 | u8 *mc_addr_list, u32 mc_addr_count, | 224 | u8 *mc_addr_list, u32 mc_addr_count, |
| 225 | u32 rar_used_count, u32 rar_count) | 225 | u32 rar_used_count, u32 rar_count) |
| 226 | { | 226 | { |
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index d5ede2df3e42..ebbda7d15254 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
| @@ -1370,6 +1370,9 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) | |||
| 1370 | hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr); | 1370 | hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr); |
| 1371 | 1371 | ||
| 1372 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | 1372 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); |
| 1373 | |||
| 1374 | /* clear VMDq pool/queue selection for RAR 0 */ | ||
| 1375 | hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); | ||
| 1373 | } | 1376 | } |
| 1374 | hw->addr_ctrl.overflow_promisc = 0; | 1377 | hw->addr_ctrl.overflow_promisc = 0; |
| 1375 | 1378 | ||
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 6342d4859790..c54a88274d51 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
| @@ -159,13 +159,13 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | |||
| 159 | struct scatterlist *sg; | 159 | struct scatterlist *sg; |
| 160 | unsigned int i, j, dmacount; | 160 | unsigned int i, j, dmacount; |
| 161 | unsigned int len; | 161 | unsigned int len; |
| 162 | static const unsigned int bufflen = 4096; | 162 | static const unsigned int bufflen = IXGBE_FCBUFF_MIN; |
| 163 | unsigned int firstoff = 0; | 163 | unsigned int firstoff = 0; |
| 164 | unsigned int lastsize; | 164 | unsigned int lastsize; |
| 165 | unsigned int thisoff = 0; | 165 | unsigned int thisoff = 0; |
| 166 | unsigned int thislen = 0; | 166 | unsigned int thislen = 0; |
| 167 | u32 fcbuff, fcdmarw, fcfltrw; | 167 | u32 fcbuff, fcdmarw, fcfltrw; |
| 168 | dma_addr_t addr; | 168 | dma_addr_t addr = 0; |
| 169 | 169 | ||
| 170 | if (!netdev || !sgl) | 170 | if (!netdev || !sgl) |
| 171 | return 0; | 171 | return 0; |
| @@ -254,6 +254,24 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, | |||
| 254 | /* only the last buffer may have non-full bufflen */ | 254 | /* only the last buffer may have non-full bufflen */ |
| 255 | lastsize = thisoff + thislen; | 255 | lastsize = thisoff + thislen; |
| 256 | 256 | ||
| 257 | /* | ||
| 258 | * lastsize can not be buffer len. | ||
| 259 | * If it is then adding another buffer with lastsize = 1. | ||
| 260 | */ | ||
| 261 | if (lastsize == bufflen) { | ||
| 262 | if (j >= IXGBE_BUFFCNT_MAX) { | ||
| 263 | e_err(drv, "xid=%x:%d,%d,%d:addr=%llx " | ||
| 264 | "not enough user buffers. We need an extra " | ||
| 265 | "buffer because lastsize is bufflen.\n", | ||
| 266 | xid, i, j, dmacount, (u64)addr); | ||
| 267 | goto out_noddp_free; | ||
| 268 | } | ||
| 269 | |||
| 270 | ddp->udl[j] = (u64)(fcoe->extra_ddp_buffer_dma); | ||
| 271 | j++; | ||
| 272 | lastsize = 1; | ||
| 273 | } | ||
| 274 | |||
| 257 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); | 275 | fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT); |
| 258 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); | 276 | fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT); |
| 259 | fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); | 277 | fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT); |
| @@ -532,6 +550,24 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
| 532 | e_err(drv, "failed to allocated FCoE DDP pool\n"); | 550 | e_err(drv, "failed to allocated FCoE DDP pool\n"); |
| 533 | 551 | ||
| 534 | spin_lock_init(&fcoe->lock); | 552 | spin_lock_init(&fcoe->lock); |
| 553 | |||
| 554 | /* Extra buffer to be shared by all DDPs for HW work around */ | ||
| 555 | fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC); | ||
| 556 | if (fcoe->extra_ddp_buffer == NULL) { | ||
| 557 | e_err(drv, "failed to allocated extra DDP buffer\n"); | ||
| 558 | goto out_extra_ddp_buffer_alloc; | ||
| 559 | } | ||
| 560 | |||
| 561 | fcoe->extra_ddp_buffer_dma = | ||
| 562 | dma_map_single(&adapter->pdev->dev, | ||
| 563 | fcoe->extra_ddp_buffer, | ||
| 564 | IXGBE_FCBUFF_MIN, | ||
| 565 | DMA_FROM_DEVICE); | ||
| 566 | if (dma_mapping_error(&adapter->pdev->dev, | ||
| 567 | fcoe->extra_ddp_buffer_dma)) { | ||
| 568 | e_err(drv, "failed to map extra DDP buffer\n"); | ||
| 569 | goto out_extra_ddp_buffer_dma; | ||
| 570 | } | ||
| 535 | } | 571 | } |
| 536 | 572 | ||
| 537 | /* Enable L2 eth type filter for FCoE */ | 573 | /* Enable L2 eth type filter for FCoE */ |
| @@ -581,6 +617,14 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter) | |||
| 581 | } | 617 | } |
| 582 | } | 618 | } |
| 583 | #endif | 619 | #endif |
| 620 | |||
| 621 | return; | ||
| 622 | |||
| 623 | out_extra_ddp_buffer_dma: | ||
| 624 | kfree(fcoe->extra_ddp_buffer); | ||
| 625 | out_extra_ddp_buffer_alloc: | ||
| 626 | pci_pool_destroy(fcoe->pool); | ||
| 627 | fcoe->pool = NULL; | ||
| 584 | } | 628 | } |
| 585 | 629 | ||
| 586 | /** | 630 | /** |
| @@ -600,6 +644,11 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter) | |||
| 600 | if (fcoe->pool) { | 644 | if (fcoe->pool) { |
| 601 | for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) | 645 | for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++) |
| 602 | ixgbe_fcoe_ddp_put(adapter->netdev, i); | 646 | ixgbe_fcoe_ddp_put(adapter->netdev, i); |
| 647 | dma_unmap_single(&adapter->pdev->dev, | ||
| 648 | fcoe->extra_ddp_buffer_dma, | ||
| 649 | IXGBE_FCBUFF_MIN, | ||
| 650 | DMA_FROM_DEVICE); | ||
| 651 | kfree(fcoe->extra_ddp_buffer); | ||
| 603 | pci_pool_destroy(fcoe->pool); | 652 | pci_pool_destroy(fcoe->pool); |
| 604 | fcoe->pool = NULL; | 653 | fcoe->pool = NULL; |
| 605 | } | 654 | } |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index 4bc2c551c8db..65cc8fb14fe7 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h | |||
| @@ -70,6 +70,8 @@ struct ixgbe_fcoe { | |||
| 70 | spinlock_t lock; | 70 | spinlock_t lock; |
| 71 | struct pci_pool *pool; | 71 | struct pci_pool *pool; |
| 72 | struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; | 72 | struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; |
| 73 | unsigned char *extra_ddp_buffer; | ||
| 74 | dma_addr_t extra_ddp_buffer_dma; | ||
| 73 | }; | 75 | }; |
| 74 | 76 | ||
| 75 | #endif /* _IXGBE_FCOE_H */ | 77 | #endif /* _IXGBE_FCOE_H */ |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 602078b84892..30f9ccfb4f87 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -52,7 +52,7 @@ char ixgbe_driver_name[] = "ixgbe"; | |||
| 52 | static const char ixgbe_driver_string[] = | 52 | static const char ixgbe_driver_string[] = |
| 53 | "Intel(R) 10 Gigabit PCI Express Network Driver"; | 53 | "Intel(R) 10 Gigabit PCI Express Network Driver"; |
| 54 | 54 | ||
| 55 | #define DRV_VERSION "3.0.12-k2" | 55 | #define DRV_VERSION "3.2.9-k2" |
| 56 | const char ixgbe_driver_version[] = DRV_VERSION; | 56 | const char ixgbe_driver_version[] = DRV_VERSION; |
| 57 | static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; | 57 | static char ixgbe_copyright[] = "Copyright (c) 1999-2010 Intel Corporation."; |
| 58 | 58 | ||
| @@ -3176,9 +3176,16 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) | |||
| 3176 | u32 mhadd, hlreg0; | 3176 | u32 mhadd, hlreg0; |
| 3177 | 3177 | ||
| 3178 | /* Decide whether to use packet split mode or not */ | 3178 | /* Decide whether to use packet split mode or not */ |
| 3179 | /* On by default */ | ||
| 3180 | adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; | ||
| 3181 | |||
| 3179 | /* Do not use packet split if we're in SR-IOV Mode */ | 3182 | /* Do not use packet split if we're in SR-IOV Mode */ |
| 3180 | if (!adapter->num_vfs) | 3183 | if (adapter->num_vfs) |
| 3181 | adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; | 3184 | adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; |
| 3185 | |||
| 3186 | /* Disable packet split due to 82599 erratum #45 */ | ||
| 3187 | if (hw->mac.type == ixgbe_mac_82599EB) | ||
| 3188 | adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; | ||
| 3182 | 3189 | ||
| 3183 | /* Set the RX buffer length according to the mode */ | 3190 | /* Set the RX buffer length according to the mode */ |
| 3184 | if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { | 3191 | if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { |
| @@ -3721,7 +3728,8 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter) | |||
| 3721 | * We need to try and force an autonegotiation | 3728 | * We need to try and force an autonegotiation |
| 3722 | * session, then bring up link. | 3729 | * session, then bring up link. |
| 3723 | */ | 3730 | */ |
| 3724 | hw->mac.ops.setup_sfp(hw); | 3731 | if (hw->mac.ops.setup_sfp) |
| 3732 | hw->mac.ops.setup_sfp(hw); | ||
| 3725 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) | 3733 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) |
| 3726 | schedule_work(&adapter->multispeed_fiber_task); | 3734 | schedule_work(&adapter->multispeed_fiber_task); |
| 3727 | } else { | 3735 | } else { |
| @@ -4863,16 +4871,13 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) | |||
| 4863 | { | 4871 | { |
| 4864 | int q_idx, num_q_vectors; | 4872 | int q_idx, num_q_vectors; |
| 4865 | struct ixgbe_q_vector *q_vector; | 4873 | struct ixgbe_q_vector *q_vector; |
| 4866 | int napi_vectors; | ||
| 4867 | int (*poll)(struct napi_struct *, int); | 4874 | int (*poll)(struct napi_struct *, int); |
| 4868 | 4875 | ||
| 4869 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { | 4876 | if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { |
| 4870 | num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; | 4877 | num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; |
| 4871 | napi_vectors = adapter->num_rx_queues; | ||
| 4872 | poll = &ixgbe_clean_rxtx_many; | 4878 | poll = &ixgbe_clean_rxtx_many; |
| 4873 | } else { | 4879 | } else { |
| 4874 | num_q_vectors = 1; | 4880 | num_q_vectors = 1; |
| 4875 | napi_vectors = 1; | ||
| 4876 | poll = &ixgbe_poll; | 4881 | poll = &ixgbe_poll; |
| 4877 | } | 4882 | } |
| 4878 | 4883 | ||
| @@ -5964,7 +5969,8 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) | |||
| 5964 | unregister_netdev(adapter->netdev); | 5969 | unregister_netdev(adapter->netdev); |
| 5965 | return; | 5970 | return; |
| 5966 | } | 5971 | } |
| 5967 | hw->mac.ops.setup_sfp(hw); | 5972 | if (hw->mac.ops.setup_sfp) |
| 5973 | hw->mac.ops.setup_sfp(hw); | ||
| 5968 | 5974 | ||
| 5969 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) | 5975 | if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) |
| 5970 | /* This will also work for DA Twinax connections */ | 5976 | /* This will also work for DA Twinax connections */ |
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 47b15738b009..187b3a16ec1f 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c | |||
| @@ -110,12 +110,10 @@ static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, | |||
| 110 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); | 110 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | |||
| 114 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) | 113 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) |
| 115 | { | 114 | { |
| 116 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); | 115 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); |
| 117 | vmolr |= (IXGBE_VMOLR_ROMPE | | 116 | vmolr |= (IXGBE_VMOLR_ROMPE | |
| 118 | IXGBE_VMOLR_ROPE | | ||
| 119 | IXGBE_VMOLR_BAM); | 117 | IXGBE_VMOLR_BAM); |
| 120 | if (aupe) | 118 | if (aupe) |
| 121 | vmolr |= IXGBE_VMOLR_AUPE; | 119 | vmolr |= IXGBE_VMOLR_AUPE; |
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index 3a8923993ce3..f2518b01067d 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c | |||
| @@ -133,17 +133,17 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) | |||
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 135 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); |
| 136 | IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST)); | 136 | IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | reset_bit)); |
| 137 | IXGBE_WRITE_FLUSH(hw); | 137 | IXGBE_WRITE_FLUSH(hw); |
| 138 | 138 | ||
| 139 | /* Poll for reset bit to self-clear indicating reset is complete */ | 139 | /* Poll for reset bit to self-clear indicating reset is complete */ |
| 140 | for (i = 0; i < 10; i++) { | 140 | for (i = 0; i < 10; i++) { |
| 141 | udelay(1); | 141 | udelay(1); |
| 142 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); | 142 | ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); |
| 143 | if (!(ctrl & IXGBE_CTRL_RST)) | 143 | if (!(ctrl & reset_bit)) |
| 144 | break; | 144 | break; |
| 145 | } | 145 | } |
| 146 | if (ctrl & IXGBE_CTRL_RST) { | 146 | if (ctrl & reset_bit) { |
| 147 | status = IXGBE_ERR_RESET_FAILED; | 147 | status = IXGBE_ERR_RESET_FAILED; |
| 148 | hw_dbg(hw, "Reset polling failed to complete.\n"); | 148 | hw_dbg(hw, "Reset polling failed to complete.\n"); |
| 149 | } | 149 | } |
diff --git a/drivers/net/macb.c b/drivers/net/macb.c index f69e73e2191e..79ccb54ab00c 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c | |||
| @@ -260,7 +260,7 @@ static int macb_mii_init(struct macb *bp) | |||
| 260 | for (i = 0; i < PHY_MAX_ADDR; i++) | 260 | for (i = 0; i < PHY_MAX_ADDR; i++) |
| 261 | bp->mii_bus->irq[i] = PHY_POLL; | 261 | bp->mii_bus->irq[i] = PHY_POLL; |
| 262 | 262 | ||
| 263 | platform_set_drvdata(bp->dev, bp->mii_bus); | 263 | dev_set_drvdata(&bp->dev->dev, bp->mii_bus); |
| 264 | 264 | ||
| 265 | if (mdiobus_register(bp->mii_bus)) | 265 | if (mdiobus_register(bp->mii_bus)) |
| 266 | goto err_out_free_mdio_irq; | 266 | goto err_out_free_mdio_irq; |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 4ffdc18fcb8a..2765a3ce9c24 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
| @@ -1286,6 +1286,21 @@ static DEFINE_PCI_DEVICE_TABLE(mlx4_pci_table) = { | |||
| 1286 | { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ | 1286 | { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ |
| 1287 | { PCI_VDEVICE(MELLANOX, 0x6746) }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ | 1287 | { PCI_VDEVICE(MELLANOX, 0x6746) }, /* MT26438 ConnectX EN 40GigE PCIe gen2 5GT/s */ |
| 1288 | { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */ | 1288 | { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */ |
| 1289 | { PCI_VDEVICE(MELLANOX, 0x1002) }, /* MT25400 Family [ConnectX-2 Virtual Function] */ | ||
| 1290 | { PCI_VDEVICE(MELLANOX, 0x1003) }, /* MT27500 Family [ConnectX-3] */ | ||
| 1291 | { PCI_VDEVICE(MELLANOX, 0x1004) }, /* MT27500 Family [ConnectX-3 Virtual Function] */ | ||
| 1292 | { PCI_VDEVICE(MELLANOX, 0x1005) }, /* MT27510 Family */ | ||
| 1293 | { PCI_VDEVICE(MELLANOX, 0x1006) }, /* MT27511 Family */ | ||
| 1294 | { PCI_VDEVICE(MELLANOX, 0x1007) }, /* MT27520 Family */ | ||
| 1295 | { PCI_VDEVICE(MELLANOX, 0x1008) }, /* MT27521 Family */ | ||
| 1296 | { PCI_VDEVICE(MELLANOX, 0x1009) }, /* MT27530 Family */ | ||
| 1297 | { PCI_VDEVICE(MELLANOX, 0x100a) }, /* MT27531 Family */ | ||
| 1298 | { PCI_VDEVICE(MELLANOX, 0x100b) }, /* MT27540 Family */ | ||
| 1299 | { PCI_VDEVICE(MELLANOX, 0x100c) }, /* MT27541 Family */ | ||
| 1300 | { PCI_VDEVICE(MELLANOX, 0x100d) }, /* MT27550 Family */ | ||
| 1301 | { PCI_VDEVICE(MELLANOX, 0x100e) }, /* MT27551 Family */ | ||
| 1302 | { PCI_VDEVICE(MELLANOX, 0x100f) }, /* MT27560 Family */ | ||
| 1303 | { PCI_VDEVICE(MELLANOX, 0x1010) }, /* MT27561 Family */ | ||
| 1289 | { 0, } | 1304 | { 0, } |
| 1290 | }; | 1305 | }; |
| 1291 | 1306 | ||
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 2541321bad82..9fb59d3f9c92 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
| @@ -4489,6 +4489,9 @@ static int niu_alloc_channels(struct niu *np) | |||
| 4489 | { | 4489 | { |
| 4490 | struct niu_parent *parent = np->parent; | 4490 | struct niu_parent *parent = np->parent; |
| 4491 | int first_rx_channel, first_tx_channel; | 4491 | int first_rx_channel, first_tx_channel; |
| 4492 | int num_rx_rings, num_tx_rings; | ||
| 4493 | struct rx_ring_info *rx_rings; | ||
| 4494 | struct tx_ring_info *tx_rings; | ||
| 4492 | int i, port, err; | 4495 | int i, port, err; |
| 4493 | 4496 | ||
| 4494 | port = np->port; | 4497 | port = np->port; |
| @@ -4498,18 +4501,21 @@ static int niu_alloc_channels(struct niu *np) | |||
| 4498 | first_tx_channel += parent->txchan_per_port[i]; | 4501 | first_tx_channel += parent->txchan_per_port[i]; |
| 4499 | } | 4502 | } |
| 4500 | 4503 | ||
| 4501 | np->num_rx_rings = parent->rxchan_per_port[port]; | 4504 | num_rx_rings = parent->rxchan_per_port[port]; |
| 4502 | np->num_tx_rings = parent->txchan_per_port[port]; | 4505 | num_tx_rings = parent->txchan_per_port[port]; |
| 4503 | 4506 | ||
| 4504 | netif_set_real_num_rx_queues(np->dev, np->num_rx_rings); | 4507 | rx_rings = kcalloc(num_rx_rings, sizeof(struct rx_ring_info), |
| 4505 | netif_set_real_num_tx_queues(np->dev, np->num_tx_rings); | 4508 | GFP_KERNEL); |
| 4506 | |||
| 4507 | np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), | ||
| 4508 | GFP_KERNEL); | ||
| 4509 | err = -ENOMEM; | 4509 | err = -ENOMEM; |
| 4510 | if (!np->rx_rings) | 4510 | if (!rx_rings) |
| 4511 | goto out_err; | 4511 | goto out_err; |
| 4512 | 4512 | ||
| 4513 | np->num_rx_rings = num_rx_rings; | ||
| 4514 | smp_wmb(); | ||
| 4515 | np->rx_rings = rx_rings; | ||
| 4516 | |||
| 4517 | netif_set_real_num_rx_queues(np->dev, num_rx_rings); | ||
| 4518 | |||
| 4513 | for (i = 0; i < np->num_rx_rings; i++) { | 4519 | for (i = 0; i < np->num_rx_rings; i++) { |
| 4514 | struct rx_ring_info *rp = &np->rx_rings[i]; | 4520 | struct rx_ring_info *rp = &np->rx_rings[i]; |
| 4515 | 4521 | ||
| @@ -4538,12 +4544,18 @@ static int niu_alloc_channels(struct niu *np) | |||
| 4538 | return err; | 4544 | return err; |
| 4539 | } | 4545 | } |
| 4540 | 4546 | ||
| 4541 | np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info), | 4547 | tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), |
| 4542 | GFP_KERNEL); | 4548 | GFP_KERNEL); |
| 4543 | err = -ENOMEM; | 4549 | err = -ENOMEM; |
| 4544 | if (!np->tx_rings) | 4550 | if (!tx_rings) |
| 4545 | goto out_err; | 4551 | goto out_err; |
| 4546 | 4552 | ||
| 4553 | np->num_tx_rings = num_tx_rings; | ||
| 4554 | smp_wmb(); | ||
| 4555 | np->tx_rings = tx_rings; | ||
| 4556 | |||
| 4557 | netif_set_real_num_tx_queues(np->dev, num_tx_rings); | ||
| 4558 | |||
| 4547 | for (i = 0; i < np->num_tx_rings; i++) { | 4559 | for (i = 0; i < np->num_tx_rings; i++) { |
| 4548 | struct tx_ring_info *rp = &np->tx_rings[i]; | 4560 | struct tx_ring_info *rp = &np->tx_rings[i]; |
| 4549 | 4561 | ||
| @@ -6246,11 +6258,17 @@ static void niu_sync_mac_stats(struct niu *np) | |||
| 6246 | static void niu_get_rx_stats(struct niu *np) | 6258 | static void niu_get_rx_stats(struct niu *np) |
| 6247 | { | 6259 | { |
| 6248 | unsigned long pkts, dropped, errors, bytes; | 6260 | unsigned long pkts, dropped, errors, bytes; |
| 6261 | struct rx_ring_info *rx_rings; | ||
| 6249 | int i; | 6262 | int i; |
| 6250 | 6263 | ||
| 6251 | pkts = dropped = errors = bytes = 0; | 6264 | pkts = dropped = errors = bytes = 0; |
| 6265 | |||
| 6266 | rx_rings = ACCESS_ONCE(np->rx_rings); | ||
| 6267 | if (!rx_rings) | ||
| 6268 | goto no_rings; | ||
| 6269 | |||
| 6252 | for (i = 0; i < np->num_rx_rings; i++) { | 6270 | for (i = 0; i < np->num_rx_rings; i++) { |
| 6253 | struct rx_ring_info *rp = &np->rx_rings[i]; | 6271 | struct rx_ring_info *rp = &rx_rings[i]; |
| 6254 | 6272 | ||
| 6255 | niu_sync_rx_discard_stats(np, rp, 0); | 6273 | niu_sync_rx_discard_stats(np, rp, 0); |
| 6256 | 6274 | ||
| @@ -6259,6 +6277,8 @@ static void niu_get_rx_stats(struct niu *np) | |||
| 6259 | dropped += rp->rx_dropped; | 6277 | dropped += rp->rx_dropped; |
| 6260 | errors += rp->rx_errors; | 6278 | errors += rp->rx_errors; |
| 6261 | } | 6279 | } |
| 6280 | |||
| 6281 | no_rings: | ||
| 6262 | np->dev->stats.rx_packets = pkts; | 6282 | np->dev->stats.rx_packets = pkts; |
| 6263 | np->dev->stats.rx_bytes = bytes; | 6283 | np->dev->stats.rx_bytes = bytes; |
| 6264 | np->dev->stats.rx_dropped = dropped; | 6284 | np->dev->stats.rx_dropped = dropped; |
| @@ -6268,16 +6288,24 @@ static void niu_get_rx_stats(struct niu *np) | |||
| 6268 | static void niu_get_tx_stats(struct niu *np) | 6288 | static void niu_get_tx_stats(struct niu *np) |
| 6269 | { | 6289 | { |
| 6270 | unsigned long pkts, errors, bytes; | 6290 | unsigned long pkts, errors, bytes; |
| 6291 | struct tx_ring_info *tx_rings; | ||
| 6271 | int i; | 6292 | int i; |
| 6272 | 6293 | ||
| 6273 | pkts = errors = bytes = 0; | 6294 | pkts = errors = bytes = 0; |
| 6295 | |||
| 6296 | tx_rings = ACCESS_ONCE(np->tx_rings); | ||
| 6297 | if (!tx_rings) | ||
| 6298 | goto no_rings; | ||
| 6299 | |||
| 6274 | for (i = 0; i < np->num_tx_rings; i++) { | 6300 | for (i = 0; i < np->num_tx_rings; i++) { |
| 6275 | struct tx_ring_info *rp = &np->tx_rings[i]; | 6301 | struct tx_ring_info *rp = &tx_rings[i]; |
| 6276 | 6302 | ||
| 6277 | pkts += rp->tx_packets; | 6303 | pkts += rp->tx_packets; |
| 6278 | bytes += rp->tx_bytes; | 6304 | bytes += rp->tx_bytes; |
| 6279 | errors += rp->tx_errors; | 6305 | errors += rp->tx_errors; |
| 6280 | } | 6306 | } |
| 6307 | |||
| 6308 | no_rings: | ||
| 6281 | np->dev->stats.tx_packets = pkts; | 6309 | np->dev->stats.tx_packets = pkts; |
| 6282 | np->dev->stats.tx_bytes = bytes; | 6310 | np->dev->stats.tx_bytes = bytes; |
| 6283 | np->dev->stats.tx_errors = errors; | 6311 | np->dev->stats.tx_errors = errors; |
| @@ -6287,9 +6315,10 @@ static struct net_device_stats *niu_get_stats(struct net_device *dev) | |||
| 6287 | { | 6315 | { |
| 6288 | struct niu *np = netdev_priv(dev); | 6316 | struct niu *np = netdev_priv(dev); |
| 6289 | 6317 | ||
| 6290 | niu_get_rx_stats(np); | 6318 | if (netif_running(dev)) { |
| 6291 | niu_get_tx_stats(np); | 6319 | niu_get_rx_stats(np); |
| 6292 | 6320 | niu_get_tx_stats(np); | |
| 6321 | } | ||
| 6293 | return &dev->stats; | 6322 | return &dev->stats; |
| 6294 | } | 6323 | } |
| 6295 | 6324 | ||
diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h index a0c26a99520f..e1e33c80fb25 100644 --- a/drivers/net/pch_gbe/pch_gbe.h +++ b/drivers/net/pch_gbe/pch_gbe.h | |||
| @@ -73,7 +73,7 @@ struct pch_gbe_regs { | |||
| 73 | struct pch_gbe_regs_mac_adr mac_adr[16]; | 73 | struct pch_gbe_regs_mac_adr mac_adr[16]; |
| 74 | u32 ADDR_MASK; | 74 | u32 ADDR_MASK; |
| 75 | u32 MIIM; | 75 | u32 MIIM; |
| 76 | u32 reserve2; | 76 | u32 MAC_ADDR_LOAD; |
| 77 | u32 RGMII_ST; | 77 | u32 RGMII_ST; |
| 78 | u32 RGMII_CTRL; | 78 | u32 RGMII_CTRL; |
| 79 | u32 reserve3[3]; | 79 | u32 reserve3[3]; |
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index d7355306a738..b99e90aca37d 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c | |||
| @@ -29,6 +29,7 @@ const char pch_driver_version[] = DRV_VERSION; | |||
| 29 | #define PCH_GBE_SHORT_PKT 64 | 29 | #define PCH_GBE_SHORT_PKT 64 |
| 30 | #define DSC_INIT16 0xC000 | 30 | #define DSC_INIT16 0xC000 |
| 31 | #define PCH_GBE_DMA_ALIGN 0 | 31 | #define PCH_GBE_DMA_ALIGN 0 |
| 32 | #define PCH_GBE_DMA_PADDING 2 | ||
| 32 | #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ | 33 | #define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ |
| 33 | #define PCH_GBE_COPYBREAK_DEFAULT 256 | 34 | #define PCH_GBE_COPYBREAK_DEFAULT 256 |
| 34 | #define PCH_GBE_PCI_BAR 1 | 35 | #define PCH_GBE_PCI_BAR 1 |
| @@ -88,6 +89,12 @@ static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; | |||
| 88 | static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); | 89 | static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); |
| 89 | static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, | 90 | static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, |
| 90 | int data); | 91 | int data); |
| 92 | |||
| 93 | inline void pch_gbe_mac_load_mac_addr(struct pch_gbe_hw *hw) | ||
| 94 | { | ||
| 95 | iowrite32(0x01, &hw->reg->MAC_ADDR_LOAD); | ||
| 96 | } | ||
| 97 | |||
| 91 | /** | 98 | /** |
| 92 | * pch_gbe_mac_read_mac_addr - Read MAC address | 99 | * pch_gbe_mac_read_mac_addr - Read MAC address |
| 93 | * @hw: Pointer to the HW structure | 100 | * @hw: Pointer to the HW structure |
| @@ -519,7 +526,9 @@ static void pch_gbe_reset_task(struct work_struct *work) | |||
| 519 | struct pch_gbe_adapter *adapter; | 526 | struct pch_gbe_adapter *adapter; |
| 520 | adapter = container_of(work, struct pch_gbe_adapter, reset_task); | 527 | adapter = container_of(work, struct pch_gbe_adapter, reset_task); |
| 521 | 528 | ||
| 529 | rtnl_lock(); | ||
| 522 | pch_gbe_reinit_locked(adapter); | 530 | pch_gbe_reinit_locked(adapter); |
| 531 | rtnl_unlock(); | ||
| 523 | } | 532 | } |
| 524 | 533 | ||
| 525 | /** | 534 | /** |
| @@ -528,14 +537,8 @@ static void pch_gbe_reset_task(struct work_struct *work) | |||
| 528 | */ | 537 | */ |
| 529 | void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) | 538 | void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) |
| 530 | { | 539 | { |
| 531 | struct net_device *netdev = adapter->netdev; | 540 | pch_gbe_down(adapter); |
| 532 | 541 | pch_gbe_up(adapter); | |
| 533 | rtnl_lock(); | ||
| 534 | if (netif_running(netdev)) { | ||
| 535 | pch_gbe_down(adapter); | ||
| 536 | pch_gbe_up(adapter); | ||
| 537 | } | ||
| 538 | rtnl_unlock(); | ||
| 539 | } | 542 | } |
| 540 | 543 | ||
| 541 | /** | 544 | /** |
| @@ -1369,16 +1372,13 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1369 | struct pch_gbe_buffer *buffer_info; | 1372 | struct pch_gbe_buffer *buffer_info; |
| 1370 | struct pch_gbe_rx_desc *rx_desc; | 1373 | struct pch_gbe_rx_desc *rx_desc; |
| 1371 | u32 length; | 1374 | u32 length; |
| 1372 | unsigned char tmp_packet[ETH_HLEN]; | ||
| 1373 | unsigned int i; | 1375 | unsigned int i; |
| 1374 | unsigned int cleaned_count = 0; | 1376 | unsigned int cleaned_count = 0; |
| 1375 | bool cleaned = false; | 1377 | bool cleaned = false; |
| 1376 | struct sk_buff *skb; | 1378 | struct sk_buff *skb, *new_skb; |
| 1377 | u8 dma_status; | 1379 | u8 dma_status; |
| 1378 | u16 gbec_status; | 1380 | u16 gbec_status; |
| 1379 | u32 tcp_ip_status; | 1381 | u32 tcp_ip_status; |
| 1380 | u8 skb_copy_flag = 0; | ||
| 1381 | u8 skb_padding_flag = 0; | ||
| 1382 | 1382 | ||
| 1383 | i = rx_ring->next_to_clean; | 1383 | i = rx_ring->next_to_clean; |
| 1384 | 1384 | ||
| @@ -1422,55 +1422,70 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, | |||
| 1422 | pr_err("Receive CRC Error\n"); | 1422 | pr_err("Receive CRC Error\n"); |
| 1423 | } else { | 1423 | } else { |
| 1424 | /* get receive length */ | 1424 | /* get receive length */ |
| 1425 | /* length convert[-3], padding[-2] */ | 1425 | /* length convert[-3] */ |
| 1426 | length = (rx_desc->rx_words_eob) - 3 - 2; | 1426 | length = (rx_desc->rx_words_eob) - 3; |
| 1427 | 1427 | ||
| 1428 | /* Decide the data conversion method */ | 1428 | /* Decide the data conversion method */ |
| 1429 | if (!adapter->rx_csum) { | 1429 | if (!adapter->rx_csum) { |
| 1430 | /* [Header:14][payload] */ | 1430 | /* [Header:14][payload] */ |
| 1431 | skb_padding_flag = 0; | 1431 | if (NET_IP_ALIGN) { |
| 1432 | skb_copy_flag = 1; | 1432 | /* Because alignment differs, |
| 1433 | * the new_skb is newly allocated, | ||
| 1434 | * and data is copied to new_skb.*/ | ||
| 1435 | new_skb = netdev_alloc_skb(netdev, | ||
| 1436 | length + NET_IP_ALIGN); | ||
| 1437 | if (!new_skb) { | ||
| 1438 | /* dorrop error */ | ||
| 1439 | pr_err("New skb allocation " | ||
| 1440 | "Error\n"); | ||
| 1441 | goto dorrop; | ||
| 1442 | } | ||
| 1443 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 1444 | memcpy(new_skb->data, skb->data, | ||
| 1445 | length); | ||
| 1446 | skb = new_skb; | ||
| 1447 | } else { | ||
| 1448 | /* DMA buffer is used as SKB as it is.*/ | ||
| 1449 | buffer_info->skb = NULL; | ||
| 1450 | } | ||
| 1433 | } else { | 1451 | } else { |
| 1434 | /* [Header:14][padding:2][payload] */ | 1452 | /* [Header:14][padding:2][payload] */ |
| 1435 | skb_padding_flag = 1; | 1453 | /* The length includes padding length */ |
| 1436 | if (length < copybreak) | 1454 | length = length - PCH_GBE_DMA_PADDING; |
| 1437 | skb_copy_flag = 1; | 1455 | if ((length < copybreak) || |
| 1438 | else | 1456 | (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) { |
| 1439 | skb_copy_flag = 0; | 1457 | /* Because alignment differs, |
| 1440 | } | 1458 | * the new_skb is newly allocated, |
| 1441 | 1459 | * and data is copied to new_skb. | |
| 1442 | /* Data conversion */ | 1460 | * Padding data is deleted |
| 1443 | if (skb_copy_flag) { /* recycle skb */ | 1461 | * at the time of a copy.*/ |
| 1444 | struct sk_buff *new_skb; | 1462 | new_skb = netdev_alloc_skb(netdev, |
| 1445 | new_skb = | 1463 | length + NET_IP_ALIGN); |
| 1446 | netdev_alloc_skb(netdev, | 1464 | if (!new_skb) { |
| 1447 | length + NET_IP_ALIGN); | 1465 | /* dorrop error */ |
| 1448 | if (new_skb) { | 1466 | pr_err("New skb allocation " |
| 1449 | if (!skb_padding_flag) { | 1467 | "Error\n"); |
| 1450 | skb_reserve(new_skb, | 1468 | goto dorrop; |
| 1451 | NET_IP_ALIGN); | ||
| 1452 | } | 1469 | } |
| 1470 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 1453 | memcpy(new_skb->data, skb->data, | 1471 | memcpy(new_skb->data, skb->data, |
| 1454 | length); | 1472 | ETH_HLEN); |
| 1455 | /* save the skb | 1473 | memcpy(&new_skb->data[ETH_HLEN], |
| 1456 | * in buffer_info as good */ | 1474 | &skb->data[ETH_HLEN + |
| 1475 | PCH_GBE_DMA_PADDING], | ||
| 1476 | length - ETH_HLEN); | ||
| 1457 | skb = new_skb; | 1477 | skb = new_skb; |
| 1458 | } else if (!skb_padding_flag) { | 1478 | } else { |
| 1459 | /* dorrop error */ | 1479 | /* Padding data is deleted |
| 1460 | pr_err("New skb allocation Error\n"); | 1480 | * by moving header data.*/ |
| 1461 | goto dorrop; | 1481 | memmove(&skb->data[PCH_GBE_DMA_PADDING], |
| 1482 | &skb->data[0], ETH_HLEN); | ||
| 1483 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 1484 | buffer_info->skb = NULL; | ||
| 1462 | } | 1485 | } |
| 1463 | } else { | ||
| 1464 | buffer_info->skb = NULL; | ||
| 1465 | } | 1486 | } |
| 1466 | if (skb_padding_flag) { | 1487 | /* The length includes FCS length */ |
| 1467 | memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); | 1488 | length = length - ETH_FCS_LEN; |
| 1468 | memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], | ||
| 1469 | ETH_HLEN); | ||
| 1470 | skb_reserve(skb, NET_IP_ALIGN); | ||
| 1471 | |||
| 1472 | } | ||
| 1473 | |||
| 1474 | /* update status of driver */ | 1489 | /* update status of driver */ |
| 1475 | adapter->stats.rx_bytes += length; | 1490 | adapter->stats.rx_bytes += length; |
| 1476 | adapter->stats.rx_packets++; | 1491 | adapter->stats.rx_packets++; |
| @@ -2247,7 +2262,7 @@ static void pch_gbe_remove(struct pci_dev *pdev) | |||
| 2247 | struct net_device *netdev = pci_get_drvdata(pdev); | 2262 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 2248 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); | 2263 | struct pch_gbe_adapter *adapter = netdev_priv(netdev); |
| 2249 | 2264 | ||
| 2250 | flush_scheduled_work(); | 2265 | cancel_work_sync(&adapter->reset_task); |
| 2251 | unregister_netdev(netdev); | 2266 | unregister_netdev(netdev); |
| 2252 | 2267 | ||
| 2253 | pch_gbe_hal_phy_hw_reset(&adapter->hw); | 2268 | pch_gbe_hal_phy_hw_reset(&adapter->hw); |
| @@ -2322,6 +2337,7 @@ static int pch_gbe_probe(struct pci_dev *pdev, | |||
| 2322 | netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; | 2337 | netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO; |
| 2323 | pch_gbe_set_ethtool_ops(netdev); | 2338 | pch_gbe_set_ethtool_ops(netdev); |
| 2324 | 2339 | ||
| 2340 | pch_gbe_mac_load_mac_addr(&adapter->hw); | ||
| 2325 | pch_gbe_mac_reset_hw(&adapter->hw); | 2341 | pch_gbe_mac_reset_hw(&adapter->hw); |
| 2326 | 2342 | ||
| 2327 | /* setup the private structure */ | 2343 | /* setup the private structure */ |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 1f42f6ac8551..d3cb77205863 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
| @@ -1488,12 +1488,10 @@ static void ei_rx_overrun(struct net_device *dev) | |||
| 1488 | 1488 | ||
| 1489 | /* | 1489 | /* |
| 1490 | * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. | 1490 | * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. |
| 1491 | * Early datasheets said to poll the reset bit, but now they say that | 1491 | * We wait at least 2ms. |
| 1492 | * it "is not a reliable indicator and subsequently should be ignored." | ||
| 1493 | * We wait at least 10ms. | ||
| 1494 | */ | 1492 | */ |
| 1495 | 1493 | ||
| 1496 | mdelay(10); | 1494 | mdelay(2); |
| 1497 | 1495 | ||
| 1498 | /* | 1496 | /* |
| 1499 | * Reset RBCR[01] back to zero as per magic incantation. | 1497 | * Reset RBCR[01] back to zero as per magic incantation. |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9226cda4d054..530ab5a10bd3 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
| @@ -691,6 +691,7 @@ static struct pcmcia_device_id fmvj18x_ids[] = { | |||
| 691 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), | 691 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a), |
| 692 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01), | 692 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0e01), |
| 693 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), | 693 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05), |
| 694 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0b05), | ||
| 694 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101), | 695 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101), |
| 695 | PCMCIA_DEVICE_NULL, | 696 | PCMCIA_DEVICE_NULL, |
| 696 | }; | 697 | }; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index bde7d61f1930..7ffdb80adf40 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
| 26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 27 | #include <linux/firmware.h> | 27 | #include <linux/firmware.h> |
| 28 | #include <linux/pci-aspm.h> | ||
| 28 | 29 | ||
| 29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
| 30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
| @@ -617,8 +618,9 @@ static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data) | |||
| 617 | } | 618 | } |
| 618 | } | 619 | } |
| 619 | 620 | ||
| 620 | static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd) | 621 | static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) |
| 621 | { | 622 | { |
| 623 | void __iomem *ioaddr = tp->mmio_addr; | ||
| 622 | int i; | 624 | int i; |
| 623 | 625 | ||
| 624 | RTL_W8(ERIDR, cmd); | 626 | RTL_W8(ERIDR, cmd); |
| @@ -630,7 +632,7 @@ static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd) | |||
| 630 | break; | 632 | break; |
| 631 | } | 633 | } |
| 632 | 634 | ||
| 633 | ocp_write(ioaddr, 0x1, 0x30, 0x00000001); | 635 | ocp_write(tp, 0x1, 0x30, 0x00000001); |
| 634 | } | 636 | } |
| 635 | 637 | ||
| 636 | #define OOB_CMD_RESET 0x00 | 638 | #define OOB_CMD_RESET 0x00 |
| @@ -973,7 +975,8 @@ static void __rtl8169_check_link_status(struct net_device *dev, | |||
| 973 | if (pm) | 975 | if (pm) |
| 974 | pm_request_resume(&tp->pci_dev->dev); | 976 | pm_request_resume(&tp->pci_dev->dev); |
| 975 | netif_carrier_on(dev); | 977 | netif_carrier_on(dev); |
| 976 | netif_info(tp, ifup, dev, "link up\n"); | 978 | if (net_ratelimit()) |
| 979 | netif_info(tp, ifup, dev, "link up\n"); | ||
| 977 | } else { | 980 | } else { |
| 978 | netif_carrier_off(dev); | 981 | netif_carrier_off(dev); |
| 979 | netif_info(tp, ifdown, dev, "link down\n"); | 982 | netif_info(tp, ifdown, dev, "link down\n"); |
| @@ -2867,8 +2870,11 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) | |||
| 2867 | { | 2870 | { |
| 2868 | void __iomem *ioaddr = tp->mmio_addr; | 2871 | void __iomem *ioaddr = tp->mmio_addr; |
| 2869 | 2872 | ||
| 2870 | if (tp->mac_version == RTL_GIGA_MAC_VER_27) | 2873 | if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || |
| 2874 | (tp->mac_version == RTL_GIGA_MAC_VER_28)) && | ||
| 2875 | (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { | ||
| 2871 | return; | 2876 | return; |
| 2877 | } | ||
| 2872 | 2878 | ||
| 2873 | if (((tp->mac_version == RTL_GIGA_MAC_VER_23) || | 2879 | if (((tp->mac_version == RTL_GIGA_MAC_VER_23) || |
| 2874 | (tp->mac_version == RTL_GIGA_MAC_VER_24)) && | 2880 | (tp->mac_version == RTL_GIGA_MAC_VER_24)) && |
| @@ -2890,6 +2896,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) | |||
| 2890 | switch (tp->mac_version) { | 2896 | switch (tp->mac_version) { |
| 2891 | case RTL_GIGA_MAC_VER_25: | 2897 | case RTL_GIGA_MAC_VER_25: |
| 2892 | case RTL_GIGA_MAC_VER_26: | 2898 | case RTL_GIGA_MAC_VER_26: |
| 2899 | case RTL_GIGA_MAC_VER_27: | ||
| 2900 | case RTL_GIGA_MAC_VER_28: | ||
| 2893 | RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); | 2901 | RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); |
| 2894 | break; | 2902 | break; |
| 2895 | } | 2903 | } |
| @@ -2899,12 +2907,17 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) | |||
| 2899 | { | 2907 | { |
| 2900 | void __iomem *ioaddr = tp->mmio_addr; | 2908 | void __iomem *ioaddr = tp->mmio_addr; |
| 2901 | 2909 | ||
| 2902 | if (tp->mac_version == RTL_GIGA_MAC_VER_27) | 2910 | if (((tp->mac_version == RTL_GIGA_MAC_VER_27) || |
| 2911 | (tp->mac_version == RTL_GIGA_MAC_VER_28)) && | ||
| 2912 | (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) { | ||
| 2903 | return; | 2913 | return; |
| 2914 | } | ||
| 2904 | 2915 | ||
| 2905 | switch (tp->mac_version) { | 2916 | switch (tp->mac_version) { |
| 2906 | case RTL_GIGA_MAC_VER_25: | 2917 | case RTL_GIGA_MAC_VER_25: |
| 2907 | case RTL_GIGA_MAC_VER_26: | 2918 | case RTL_GIGA_MAC_VER_26: |
| 2919 | case RTL_GIGA_MAC_VER_27: | ||
| 2920 | case RTL_GIGA_MAC_VER_28: | ||
| 2908 | RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); | 2921 | RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); |
| 2909 | break; | 2922 | break; |
| 2910 | } | 2923 | } |
| @@ -3008,6 +3021,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3008 | mii->reg_num_mask = 0x1f; | 3021 | mii->reg_num_mask = 0x1f; |
| 3009 | mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); | 3022 | mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); |
| 3010 | 3023 | ||
| 3024 | /* disable ASPM completely as that cause random device stop working | ||
| 3025 | * problems as well as full system hangs for some PCIe devices users */ | ||
| 3026 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | ||
| 3027 | PCIE_LINK_STATE_CLKPM); | ||
| 3028 | |||
| 3011 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ | 3029 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ |
| 3012 | rc = pci_enable_device(pdev); | 3030 | rc = pci_enable_device(pdev); |
| 3013 | if (rc < 0) { | 3031 | if (rc < 0) { |
| @@ -3041,7 +3059,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3041 | goto err_out_mwi_2; | 3059 | goto err_out_mwi_2; |
| 3042 | } | 3060 | } |
| 3043 | 3061 | ||
| 3044 | tp->cp_cmd = PCIMulRW | RxChkSum; | 3062 | tp->cp_cmd = RxChkSum; |
| 3045 | 3063 | ||
| 3046 | if ((sizeof(dma_addr_t) > 4) && | 3064 | if ((sizeof(dma_addr_t) > 4) && |
| 3047 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { | 3065 | !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) { |
| @@ -3189,6 +3207,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3189 | if (pci_dev_run_wake(pdev)) | 3207 | if (pci_dev_run_wake(pdev)) |
| 3190 | pm_runtime_put_noidle(&pdev->dev); | 3208 | pm_runtime_put_noidle(&pdev->dev); |
| 3191 | 3209 | ||
| 3210 | netif_carrier_off(dev); | ||
| 3211 | |||
| 3192 | out: | 3212 | out: |
| 3193 | return rc; | 3213 | return rc; |
| 3194 | 3214 | ||
| @@ -3315,7 +3335,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) | |||
| 3315 | /* Disable interrupts */ | 3335 | /* Disable interrupts */ |
| 3316 | rtl8169_irq_mask_and_ack(ioaddr); | 3336 | rtl8169_irq_mask_and_ack(ioaddr); |
| 3317 | 3337 | ||
| 3318 | if (tp->mac_version == RTL_GIGA_MAC_VER_28) { | 3338 | if (tp->mac_version == RTL_GIGA_MAC_VER_27 || |
| 3339 | tp->mac_version == RTL_GIGA_MAC_VER_28) { | ||
| 3319 | while (RTL_R8(TxPoll) & NPQ) | 3340 | while (RTL_R8(TxPoll) & NPQ) |
| 3320 | udelay(20); | 3341 | udelay(20); |
| 3321 | 3342 | ||
| @@ -3757,7 +3778,8 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
| 3757 | RTL_W16(IntrMitigate, 0x5151); | 3778 | RTL_W16(IntrMitigate, 0x5151); |
| 3758 | 3779 | ||
| 3759 | /* Work around for RxFIFO overflow. */ | 3780 | /* Work around for RxFIFO overflow. */ |
| 3760 | if (tp->mac_version == RTL_GIGA_MAC_VER_11) { | 3781 | if (tp->mac_version == RTL_GIGA_MAC_VER_11 || |
| 3782 | tp->mac_version == RTL_GIGA_MAC_VER_22) { | ||
| 3761 | tp->intr_event |= RxFIFOOver | PCSTimeout; | 3783 | tp->intr_event |= RxFIFOOver | PCSTimeout; |
| 3762 | tp->intr_event &= ~RxOverflow; | 3784 | tp->intr_event &= ~RxOverflow; |
| 3763 | } | 3785 | } |
| @@ -3843,8 +3865,7 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
| 3843 | Cxpl_dbg_sel | \ | 3865 | Cxpl_dbg_sel | \ |
| 3844 | ASF | \ | 3866 | ASF | \ |
| 3845 | PktCntrDisable | \ | 3867 | PktCntrDisable | \ |
| 3846 | PCIDAC | \ | 3868 | Mac_dbgo_sel) |
| 3847 | PCIMulRW) | ||
| 3848 | 3869 | ||
| 3849 | static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) | 3870 | static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) |
| 3850 | { | 3871 | { |
| @@ -3874,8 +3895,6 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) | |||
| 3874 | if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) | 3895 | if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) |
| 3875 | RTL_W8(Config1, cfg1 & ~LEDS0); | 3896 | RTL_W8(Config1, cfg1 & ~LEDS0); |
| 3876 | 3897 | ||
| 3877 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); | ||
| 3878 | |||
| 3879 | rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); | 3898 | rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); |
| 3880 | } | 3899 | } |
| 3881 | 3900 | ||
| @@ -3887,8 +3906,6 @@ static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev) | |||
| 3887 | 3906 | ||
| 3888 | RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); | 3907 | RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); |
| 3889 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | 3908 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); |
| 3890 | |||
| 3891 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); | ||
| 3892 | } | 3909 | } |
| 3893 | 3910 | ||
| 3894 | static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev) | 3911 | static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev) |
| @@ -3914,6 +3931,8 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
| 3914 | } | 3931 | } |
| 3915 | } | 3932 | } |
| 3916 | 3933 | ||
| 3934 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
| 3935 | |||
| 3917 | switch (tp->mac_version) { | 3936 | switch (tp->mac_version) { |
| 3918 | case RTL_GIGA_MAC_VER_07: | 3937 | case RTL_GIGA_MAC_VER_07: |
| 3919 | rtl_hw_start_8102e_1(ioaddr, pdev); | 3938 | rtl_hw_start_8102e_1(ioaddr, pdev); |
| @@ -3928,14 +3947,13 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
| 3928 | break; | 3947 | break; |
| 3929 | } | 3948 | } |
| 3930 | 3949 | ||
| 3931 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 3950 | RTL_W8(Cfg9346, Cfg9346_Lock); |
| 3932 | 3951 | ||
| 3933 | RTL_W8(MaxTxPacketSize, TxPacketMax); | 3952 | RTL_W8(MaxTxPacketSize, TxPacketMax); |
| 3934 | 3953 | ||
| 3935 | rtl_set_rx_max_size(ioaddr, rx_buf_sz); | 3954 | rtl_set_rx_max_size(ioaddr, rx_buf_sz); |
| 3936 | 3955 | ||
| 3937 | tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; | 3956 | tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK; |
| 3938 | |||
| 3939 | RTL_W16(CPlusCmd, tp->cp_cmd); | 3957 | RTL_W16(CPlusCmd, tp->cp_cmd); |
| 3940 | 3958 | ||
| 3941 | RTL_W16(IntrMitigate, 0x0000); | 3959 | RTL_W16(IntrMitigate, 0x0000); |
| @@ -3945,14 +3963,10 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
| 3945 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 3963 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); |
| 3946 | rtl_set_rx_tx_config_registers(tp); | 3964 | rtl_set_rx_tx_config_registers(tp); |
| 3947 | 3965 | ||
| 3948 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
| 3949 | |||
| 3950 | RTL_R8(IntrMask); | 3966 | RTL_R8(IntrMask); |
| 3951 | 3967 | ||
| 3952 | rtl_set_rx_mode(dev); | 3968 | rtl_set_rx_mode(dev); |
| 3953 | 3969 | ||
| 3954 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
| 3955 | |||
| 3956 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); | 3970 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); |
| 3957 | 3971 | ||
| 3958 | RTL_W16(IntrMask, tp->intr_event); | 3972 | RTL_W16(IntrMask, tp->intr_event); |
| @@ -4639,12 +4653,33 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 4639 | break; | 4653 | break; |
| 4640 | } | 4654 | } |
| 4641 | 4655 | ||
| 4642 | /* Work around for rx fifo overflow */ | 4656 | if (unlikely(status & RxFIFOOver)) { |
| 4643 | if (unlikely(status & RxFIFOOver) && | 4657 | switch (tp->mac_version) { |
| 4644 | (tp->mac_version == RTL_GIGA_MAC_VER_11)) { | 4658 | /* Work around for rx fifo overflow */ |
| 4645 | netif_stop_queue(dev); | 4659 | case RTL_GIGA_MAC_VER_11: |
| 4646 | rtl8169_tx_timeout(dev); | 4660 | case RTL_GIGA_MAC_VER_22: |
| 4647 | break; | 4661 | case RTL_GIGA_MAC_VER_26: |
| 4662 | netif_stop_queue(dev); | ||
| 4663 | rtl8169_tx_timeout(dev); | ||
| 4664 | goto done; | ||
| 4665 | /* Testers needed. */ | ||
| 4666 | case RTL_GIGA_MAC_VER_17: | ||
| 4667 | case RTL_GIGA_MAC_VER_19: | ||
| 4668 | case RTL_GIGA_MAC_VER_20: | ||
| 4669 | case RTL_GIGA_MAC_VER_21: | ||
| 4670 | case RTL_GIGA_MAC_VER_23: | ||
| 4671 | case RTL_GIGA_MAC_VER_24: | ||
| 4672 | case RTL_GIGA_MAC_VER_27: | ||
| 4673 | case RTL_GIGA_MAC_VER_28: | ||
| 4674 | /* Experimental science. Pktgen proof. */ | ||
| 4675 | case RTL_GIGA_MAC_VER_12: | ||
| 4676 | case RTL_GIGA_MAC_VER_25: | ||
| 4677 | if (status == RxFIFOOver) | ||
| 4678 | goto done; | ||
| 4679 | break; | ||
| 4680 | default: | ||
| 4681 | break; | ||
| 4682 | } | ||
| 4648 | } | 4683 | } |
| 4649 | 4684 | ||
| 4650 | if (unlikely(status & SYSErr)) { | 4685 | if (unlikely(status & SYSErr)) { |
| @@ -4680,7 +4715,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 4680 | (status & RxFIFOOver) ? (status | RxOverflow) : status); | 4715 | (status & RxFIFOOver) ? (status | RxOverflow) : status); |
| 4681 | status = RTL_R16(IntrStatus); | 4716 | status = RTL_R16(IntrStatus); |
| 4682 | } | 4717 | } |
| 4683 | 4718 | done: | |
| 4684 | return IRQ_RETVAL(handled); | 4719 | return IRQ_RETVAL(handled); |
| 4685 | } | 4720 | } |
| 4686 | 4721 | ||
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 0e8bb19ed60d..ca886d98bdc7 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
| @@ -569,9 +569,14 @@ static void efx_ethtool_self_test(struct net_device *net_dev, | |||
| 569 | struct ethtool_test *test, u64 *data) | 569 | struct ethtool_test *test, u64 *data) |
| 570 | { | 570 | { |
| 571 | struct efx_nic *efx = netdev_priv(net_dev); | 571 | struct efx_nic *efx = netdev_priv(net_dev); |
| 572 | struct efx_self_tests efx_tests; | 572 | struct efx_self_tests *efx_tests; |
| 573 | int already_up; | 573 | int already_up; |
| 574 | int rc; | 574 | int rc = -ENOMEM; |
| 575 | |||
| 576 | efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); | ||
| 577 | if (!efx_tests) | ||
| 578 | goto fail; | ||
| 579 | |||
| 575 | 580 | ||
| 576 | ASSERT_RTNL(); | 581 | ASSERT_RTNL(); |
| 577 | if (efx->state != STATE_RUNNING) { | 582 | if (efx->state != STATE_RUNNING) { |
| @@ -589,13 +594,11 @@ static void efx_ethtool_self_test(struct net_device *net_dev, | |||
| 589 | if (rc) { | 594 | if (rc) { |
| 590 | netif_err(efx, drv, efx->net_dev, | 595 | netif_err(efx, drv, efx->net_dev, |
| 591 | "failed opening device.\n"); | 596 | "failed opening device.\n"); |
| 592 | goto fail2; | 597 | goto fail1; |
| 593 | } | 598 | } |
| 594 | } | 599 | } |
| 595 | 600 | ||
| 596 | memset(&efx_tests, 0, sizeof(efx_tests)); | 601 | rc = efx_selftest(efx, efx_tests, test->flags); |
| 597 | |||
| 598 | rc = efx_selftest(efx, &efx_tests, test->flags); | ||
| 599 | 602 | ||
| 600 | if (!already_up) | 603 | if (!already_up) |
| 601 | dev_close(efx->net_dev); | 604 | dev_close(efx->net_dev); |
| @@ -604,10 +607,11 @@ static void efx_ethtool_self_test(struct net_device *net_dev, | |||
| 604 | rc == 0 ? "passed" : "failed", | 607 | rc == 0 ? "passed" : "failed", |
| 605 | (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); | 608 | (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on"); |
| 606 | 609 | ||
| 607 | fail2: | 610 | fail1: |
| 608 | fail1: | ||
| 609 | /* Fill ethtool results structures */ | 611 | /* Fill ethtool results structures */ |
| 610 | efx_ethtool_fill_self_tests(efx, &efx_tests, NULL, data); | 612 | efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data); |
| 613 | kfree(efx_tests); | ||
| 614 | fail: | ||
| 611 | if (rc) | 615 | if (rc) |
| 612 | test->flags |= ETH_TEST_FL_FAILED; | 616 | test->flags |= ETH_TEST_FL_FAILED; |
| 613 | } | 617 | } |
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 5976d1d51df1..640e368ebeee 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c | |||
| @@ -1777,6 +1777,7 @@ static int sis900_rx(struct net_device *net_dev) | |||
| 1777 | "cur_rx:%4.4d, dirty_rx:%4.4d\n", | 1777 | "cur_rx:%4.4d, dirty_rx:%4.4d\n", |
| 1778 | net_dev->name, sis_priv->cur_rx, | 1778 | net_dev->name, sis_priv->cur_rx, |
| 1779 | sis_priv->dirty_rx); | 1779 | sis_priv->dirty_rx); |
| 1780 | dev_kfree_skb(skb); | ||
| 1780 | break; | 1781 | break; |
| 1781 | } | 1782 | } |
| 1782 | 1783 | ||
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 42daf98ba736..35b28f42d208 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
| @@ -3856,9 +3856,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
| 3856 | memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); | 3856 | memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); |
| 3857 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 3857 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
| 3858 | 3858 | ||
| 3859 | /* device is off until link detection */ | ||
| 3860 | netif_carrier_off(dev); | ||
| 3861 | |||
| 3862 | return dev; | 3859 | return dev; |
| 3863 | } | 3860 | } |
| 3864 | 3861 | ||
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 34a0af3837f9..0e5f03135b50 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
| @@ -1560,8 +1560,10 @@ static int stmmac_mac_device_setup(struct net_device *dev) | |||
| 1560 | 1560 | ||
| 1561 | priv->hw = device; | 1561 | priv->hw = device; |
| 1562 | 1562 | ||
| 1563 | if (device_can_wakeup(priv->device)) | 1563 | if (device_can_wakeup(priv->device)) { |
| 1564 | priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ | 1564 | priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ |
| 1565 | enable_irq_wake(dev->irq); | ||
| 1566 | } | ||
| 1565 | 1567 | ||
| 1566 | return 0; | 1568 | return 0; |
| 1567 | } | 1569 | } |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7841a8f69998..06c0e5033656 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -60,12 +60,6 @@ | |||
| 60 | #define BAR_0 0 | 60 | #define BAR_0 0 |
| 61 | #define BAR_2 2 | 61 | #define BAR_2 2 |
| 62 | 62 | ||
| 63 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
| 64 | #define TG3_VLAN_TAG_USED 1 | ||
| 65 | #else | ||
| 66 | #define TG3_VLAN_TAG_USED 0 | ||
| 67 | #endif | ||
| 68 | |||
| 69 | #include "tg3.h" | 63 | #include "tg3.h" |
| 70 | 64 | ||
| 71 | #define DRV_MODULE_NAME "tg3" | 65 | #define DRV_MODULE_NAME "tg3" |
| @@ -134,9 +128,6 @@ | |||
| 134 | TG3_TX_RING_SIZE) | 128 | TG3_TX_RING_SIZE) |
| 135 | #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) | 129 | #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) |
| 136 | 130 | ||
| 137 | #define TG3_RX_DMA_ALIGN 16 | ||
| 138 | #define TG3_RX_HEADROOM ALIGN(VLAN_HLEN, TG3_RX_DMA_ALIGN) | ||
| 139 | |||
| 140 | #define TG3_DMA_BYTE_ENAB 64 | 131 | #define TG3_DMA_BYTE_ENAB 64 |
| 141 | 132 | ||
| 142 | #define TG3_RX_STD_DMA_SZ 1536 | 133 | #define TG3_RX_STD_DMA_SZ 1536 |
| @@ -4722,8 +4713,6 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
| 4722 | struct sk_buff *skb; | 4713 | struct sk_buff *skb; |
| 4723 | dma_addr_t dma_addr; | 4714 | dma_addr_t dma_addr; |
| 4724 | u32 opaque_key, desc_idx, *post_ptr; | 4715 | u32 opaque_key, desc_idx, *post_ptr; |
| 4725 | bool hw_vlan __maybe_unused = false; | ||
| 4726 | u16 vtag __maybe_unused = 0; | ||
| 4727 | 4716 | ||
| 4728 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | 4717 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; |
| 4729 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | 4718 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; |
| @@ -4782,12 +4771,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
| 4782 | tg3_recycle_rx(tnapi, tpr, opaque_key, | 4771 | tg3_recycle_rx(tnapi, tpr, opaque_key, |
| 4783 | desc_idx, *post_ptr); | 4772 | desc_idx, *post_ptr); |
| 4784 | 4773 | ||
| 4785 | copy_skb = netdev_alloc_skb(tp->dev, len + VLAN_HLEN + | 4774 | copy_skb = netdev_alloc_skb(tp->dev, len + |
| 4786 | TG3_RAW_IP_ALIGN); | 4775 | TG3_RAW_IP_ALIGN); |
| 4787 | if (copy_skb == NULL) | 4776 | if (copy_skb == NULL) |
| 4788 | goto drop_it_no_recycle; | 4777 | goto drop_it_no_recycle; |
| 4789 | 4778 | ||
| 4790 | skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN); | 4779 | skb_reserve(copy_skb, TG3_RAW_IP_ALIGN); |
| 4791 | skb_put(copy_skb, len); | 4780 | skb_put(copy_skb, len); |
| 4792 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); | 4781 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); |
| 4793 | skb_copy_from_linear_data(skb, copy_skb->data, len); | 4782 | skb_copy_from_linear_data(skb, copy_skb->data, len); |
| @@ -4814,30 +4803,11 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
| 4814 | } | 4803 | } |
| 4815 | 4804 | ||
| 4816 | if (desc->type_flags & RXD_FLAG_VLAN && | 4805 | if (desc->type_flags & RXD_FLAG_VLAN && |
| 4817 | !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) { | 4806 | !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) |
| 4818 | vtag = desc->err_vlan & RXD_VLAN_MASK; | 4807 | __vlan_hwaccel_put_tag(skb, |
| 4819 | #if TG3_VLAN_TAG_USED | 4808 | desc->err_vlan & RXD_VLAN_MASK); |
| 4820 | if (tp->vlgrp) | ||
| 4821 | hw_vlan = true; | ||
| 4822 | else | ||
| 4823 | #endif | ||
| 4824 | { | ||
| 4825 | struct vlan_ethhdr *ve = (struct vlan_ethhdr *) | ||
| 4826 | __skb_push(skb, VLAN_HLEN); | ||
| 4827 | |||
| 4828 | memmove(ve, skb->data + VLAN_HLEN, | ||
| 4829 | ETH_ALEN * 2); | ||
| 4830 | ve->h_vlan_proto = htons(ETH_P_8021Q); | ||
| 4831 | ve->h_vlan_TCI = htons(vtag); | ||
| 4832 | } | ||
| 4833 | } | ||
| 4834 | 4809 | ||
| 4835 | #if TG3_VLAN_TAG_USED | 4810 | napi_gro_receive(&tnapi->napi, skb); |
| 4836 | if (hw_vlan) | ||
| 4837 | vlan_gro_receive(&tnapi->napi, tp->vlgrp, vtag, skb); | ||
| 4838 | else | ||
| 4839 | #endif | ||
| 4840 | napi_gro_receive(&tnapi->napi, skb); | ||
| 4841 | 4811 | ||
| 4842 | received++; | 4812 | received++; |
| 4843 | budget--; | 4813 | budget--; |
| @@ -5740,11 +5710,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, | |||
| 5740 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | 5710 | base_flags |= TXD_FLAG_TCPUDP_CSUM; |
| 5741 | } | 5711 | } |
| 5742 | 5712 | ||
| 5743 | #if TG3_VLAN_TAG_USED | ||
| 5744 | if (vlan_tx_tag_present(skb)) | 5713 | if (vlan_tx_tag_present(skb)) |
| 5745 | base_flags |= (TXD_FLAG_VLAN | | 5714 | base_flags |= (TXD_FLAG_VLAN | |
| 5746 | (vlan_tx_tag_get(skb) << 16)); | 5715 | (vlan_tx_tag_get(skb) << 16)); |
| 5747 | #endif | ||
| 5748 | 5716 | ||
| 5749 | len = skb_headlen(skb); | 5717 | len = skb_headlen(skb); |
| 5750 | 5718 | ||
| @@ -5986,11 +5954,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, | |||
| 5986 | } | 5954 | } |
| 5987 | } | 5955 | } |
| 5988 | } | 5956 | } |
| 5989 | #if TG3_VLAN_TAG_USED | 5957 | |
| 5990 | if (vlan_tx_tag_present(skb)) | 5958 | if (vlan_tx_tag_present(skb)) |
| 5991 | base_flags |= (TXD_FLAG_VLAN | | 5959 | base_flags |= (TXD_FLAG_VLAN | |
| 5992 | (vlan_tx_tag_get(skb) << 16)); | 5960 | (vlan_tx_tag_get(skb) << 16)); |
| 5993 | #endif | ||
| 5994 | 5961 | ||
| 5995 | if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) && | 5962 | if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) && |
| 5996 | !mss && skb->len > VLAN_ETH_FRAME_LEN) | 5963 | !mss && skb->len > VLAN_ETH_FRAME_LEN) |
| @@ -9532,17 +9499,10 @@ static void __tg3_set_rx_mode(struct net_device *dev) | |||
| 9532 | rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | | 9499 | rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC | |
| 9533 | RX_MODE_KEEP_VLAN_TAG); | 9500 | RX_MODE_KEEP_VLAN_TAG); |
| 9534 | 9501 | ||
| 9502 | #if !defined(CONFIG_VLAN_8021Q) && !defined(CONFIG_VLAN_8021Q_MODULE) | ||
| 9535 | /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG | 9503 | /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG |
| 9536 | * flag clear. | 9504 | * flag clear. |
| 9537 | */ | 9505 | */ |
| 9538 | #if TG3_VLAN_TAG_USED | ||
| 9539 | if (!tp->vlgrp && | ||
| 9540 | !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) | ||
| 9541 | rx_mode |= RX_MODE_KEEP_VLAN_TAG; | ||
| 9542 | #else | ||
| 9543 | /* By definition, VLAN is disabled always in this | ||
| 9544 | * case. | ||
| 9545 | */ | ||
| 9546 | if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) | 9506 | if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) |
| 9547 | rx_mode |= RX_MODE_KEEP_VLAN_TAG; | 9507 | rx_mode |= RX_MODE_KEEP_VLAN_TAG; |
| 9548 | #endif | 9508 | #endif |
| @@ -11198,7 +11158,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 11198 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) | 11158 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) |
| 11199 | break; /* We have no PHY */ | 11159 | break; /* We have no PHY */ |
| 11200 | 11160 | ||
| 11201 | if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) | 11161 | if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || |
| 11162 | ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && | ||
| 11163 | !netif_running(dev))) | ||
| 11202 | return -EAGAIN; | 11164 | return -EAGAIN; |
| 11203 | 11165 | ||
| 11204 | spin_lock_bh(&tp->lock); | 11166 | spin_lock_bh(&tp->lock); |
| @@ -11214,7 +11176,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 11214 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) | 11176 | if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) |
| 11215 | break; /* We have no PHY */ | 11177 | break; /* We have no PHY */ |
| 11216 | 11178 | ||
| 11217 | if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) | 11179 | if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) || |
| 11180 | ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && | ||
| 11181 | !netif_running(dev))) | ||
| 11218 | return -EAGAIN; | 11182 | return -EAGAIN; |
| 11219 | 11183 | ||
| 11220 | spin_lock_bh(&tp->lock); | 11184 | spin_lock_bh(&tp->lock); |
| @@ -11230,31 +11194,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 11230 | return -EOPNOTSUPP; | 11194 | return -EOPNOTSUPP; |
| 11231 | } | 11195 | } |
| 11232 | 11196 | ||
| 11233 | #if TG3_VLAN_TAG_USED | ||
| 11234 | static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) | ||
| 11235 | { | ||
| 11236 | struct tg3 *tp = netdev_priv(dev); | ||
| 11237 | |||
| 11238 | if (!netif_running(dev)) { | ||
| 11239 | tp->vlgrp = grp; | ||
| 11240 | return; | ||
| 11241 | } | ||
| 11242 | |||
| 11243 | tg3_netif_stop(tp); | ||
| 11244 | |||
| 11245 | tg3_full_lock(tp, 0); | ||
| 11246 | |||
| 11247 | tp->vlgrp = grp; | ||
| 11248 | |||
| 11249 | /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */ | ||
| 11250 | __tg3_set_rx_mode(dev); | ||
| 11251 | |||
| 11252 | tg3_netif_start(tp); | ||
| 11253 | |||
| 11254 | tg3_full_unlock(tp); | ||
| 11255 | } | ||
| 11256 | #endif | ||
| 11257 | |||
| 11258 | static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) | 11197 | static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) |
| 11259 | { | 11198 | { |
| 11260 | struct tg3 *tp = netdev_priv(dev); | 11199 | struct tg3 *tp = netdev_priv(dev); |
| @@ -13066,9 +13005,7 @@ static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); | |||
| 13066 | 13005 | ||
| 13067 | static void inline vlan_features_add(struct net_device *dev, unsigned long flags) | 13006 | static void inline vlan_features_add(struct net_device *dev, unsigned long flags) |
| 13068 | { | 13007 | { |
| 13069 | #if TG3_VLAN_TAG_USED | ||
| 13070 | dev->vlan_features |= flags; | 13008 | dev->vlan_features |= flags; |
| 13071 | #endif | ||
| 13072 | } | 13009 | } |
| 13073 | 13010 | ||
| 13074 | static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) | 13011 | static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) |
| @@ -13861,11 +13798,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
| 13861 | else | 13798 | else |
| 13862 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; | 13799 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; |
| 13863 | 13800 | ||
| 13864 | tp->rx_offset = NET_IP_ALIGN + TG3_RX_HEADROOM; | 13801 | tp->rx_offset = NET_IP_ALIGN; |
| 13865 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; | 13802 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; |
| 13866 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && | 13803 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && |
| 13867 | (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { | 13804 | (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { |
| 13868 | tp->rx_offset -= NET_IP_ALIGN; | 13805 | tp->rx_offset = 0; |
| 13869 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | 13806 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS |
| 13870 | tp->rx_copy_thresh = ~(u16)0; | 13807 | tp->rx_copy_thresh = ~(u16)0; |
| 13871 | #endif | 13808 | #endif |
| @@ -14629,9 +14566,6 @@ static const struct net_device_ops tg3_netdev_ops = { | |||
| 14629 | .ndo_do_ioctl = tg3_ioctl, | 14566 | .ndo_do_ioctl = tg3_ioctl, |
| 14630 | .ndo_tx_timeout = tg3_tx_timeout, | 14567 | .ndo_tx_timeout = tg3_tx_timeout, |
| 14631 | .ndo_change_mtu = tg3_change_mtu, | 14568 | .ndo_change_mtu = tg3_change_mtu, |
| 14632 | #if TG3_VLAN_TAG_USED | ||
| 14633 | .ndo_vlan_rx_register = tg3_vlan_rx_register, | ||
| 14634 | #endif | ||
| 14635 | #ifdef CONFIG_NET_POLL_CONTROLLER | 14569 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 14636 | .ndo_poll_controller = tg3_poll_controller, | 14570 | .ndo_poll_controller = tg3_poll_controller, |
| 14637 | #endif | 14571 | #endif |
| @@ -14648,9 +14582,6 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = { | |||
| 14648 | .ndo_do_ioctl = tg3_ioctl, | 14582 | .ndo_do_ioctl = tg3_ioctl, |
| 14649 | .ndo_tx_timeout = tg3_tx_timeout, | 14583 | .ndo_tx_timeout = tg3_tx_timeout, |
| 14650 | .ndo_change_mtu = tg3_change_mtu, | 14584 | .ndo_change_mtu = tg3_change_mtu, |
| 14651 | #if TG3_VLAN_TAG_USED | ||
| 14652 | .ndo_vlan_rx_register = tg3_vlan_rx_register, | ||
| 14653 | #endif | ||
| 14654 | #ifdef CONFIG_NET_POLL_CONTROLLER | 14585 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 14655 | .ndo_poll_controller = tg3_poll_controller, | 14586 | .ndo_poll_controller = tg3_poll_controller, |
| 14656 | #endif | 14587 | #endif |
| @@ -14700,9 +14631,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 14700 | 14631 | ||
| 14701 | SET_NETDEV_DEV(dev, &pdev->dev); | 14632 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 14702 | 14633 | ||
| 14703 | #if TG3_VLAN_TAG_USED | ||
| 14704 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 14634 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
| 14705 | #endif | ||
| 14706 | 14635 | ||
| 14707 | tp = netdev_priv(dev); | 14636 | tp = netdev_priv(dev); |
| 14708 | tp->pdev = pdev; | 14637 | tp->pdev = pdev; |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index d62c8d937c82..f528243e1a4f 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
| @@ -2808,9 +2808,6 @@ struct tg3 { | |||
| 2808 | u32 rx_std_max_post; | 2808 | u32 rx_std_max_post; |
| 2809 | u32 rx_offset; | 2809 | u32 rx_offset; |
| 2810 | u32 rx_pkt_map_sz; | 2810 | u32 rx_pkt_map_sz; |
| 2811 | #if TG3_VLAN_TAG_USED | ||
| 2812 | struct vlan_group *vlgrp; | ||
| 2813 | #endif | ||
| 2814 | 2811 | ||
| 2815 | 2812 | ||
| 2816 | /* begin "everything else" cacheline(s) section */ | 2813 | /* begin "everything else" cacheline(s) section */ |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 04e8ce14a1d0..7113168473cf 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * cdc_ncm.c | 2 | * cdc_ncm.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) ST-Ericsson 2010 | 4 | * Copyright (C) ST-Ericsson 2010-2011 |
| 5 | * Contact: Alexey Orishko <alexey.orishko@stericsson.com> | 5 | * Contact: Alexey Orishko <alexey.orishko@stericsson.com> |
| 6 | * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com> | 6 | * Original author: Hans Petter Selasky <hans.petter.selasky@stericsson.com> |
| 7 | * | 7 | * |
| @@ -54,7 +54,7 @@ | |||
| 54 | #include <linux/usb/usbnet.h> | 54 | #include <linux/usb/usbnet.h> |
| 55 | #include <linux/usb/cdc.h> | 55 | #include <linux/usb/cdc.h> |
| 56 | 56 | ||
| 57 | #define DRIVER_VERSION "17-Jan-2011" | 57 | #define DRIVER_VERSION "7-Feb-2011" |
| 58 | 58 | ||
| 59 | /* CDC NCM subclass 3.2.1 */ | 59 | /* CDC NCM subclass 3.2.1 */ |
| 60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 | 60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 |
| @@ -77,6 +77,9 @@ | |||
| 77 | */ | 77 | */ |
| 78 | #define CDC_NCM_DPT_DATAGRAMS_MAX 32 | 78 | #define CDC_NCM_DPT_DATAGRAMS_MAX 32 |
| 79 | 79 | ||
| 80 | /* Maximum amount of IN datagrams in NTB */ | ||
| 81 | #define CDC_NCM_DPT_DATAGRAMS_IN_MAX 0 /* unlimited */ | ||
| 82 | |||
| 80 | /* Restart the timer, if amount of datagrams is less than given value */ | 83 | /* Restart the timer, if amount of datagrams is less than given value */ |
| 81 | #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 | 84 | #define CDC_NCM_RESTART_TIMER_DATAGRAM_CNT 3 |
| 82 | 85 | ||
| @@ -85,11 +88,6 @@ | |||
| 85 | (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ | 88 | (sizeof(struct usb_cdc_ncm_nth16) + sizeof(struct usb_cdc_ncm_ndp16) + \ |
| 86 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) | 89 | (CDC_NCM_DPT_DATAGRAMS_MAX + 1) * sizeof(struct usb_cdc_ncm_dpe16)) |
| 87 | 90 | ||
| 88 | struct connection_speed_change { | ||
| 89 | __le32 USBitRate; /* holds 3GPP downlink value, bits per second */ | ||
| 90 | __le32 DSBitRate; /* holds 3GPP uplink value, bits per second */ | ||
| 91 | } __attribute__ ((packed)); | ||
| 92 | |||
| 93 | struct cdc_ncm_data { | 91 | struct cdc_ncm_data { |
| 94 | struct usb_cdc_ncm_nth16 nth16; | 92 | struct usb_cdc_ncm_nth16 nth16; |
| 95 | struct usb_cdc_ncm_ndp16 ndp16; | 93 | struct usb_cdc_ncm_ndp16 ndp16; |
| @@ -198,10 +196,10 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 198 | { | 196 | { |
| 199 | struct usb_cdc_notification req; | 197 | struct usb_cdc_notification req; |
| 200 | u32 val; | 198 | u32 val; |
| 201 | __le16 max_datagram_size; | ||
| 202 | u8 flags; | 199 | u8 flags; |
| 203 | u8 iface_no; | 200 | u8 iface_no; |
| 204 | int err; | 201 | int err; |
| 202 | u16 ntb_fmt_supported; | ||
| 205 | 203 | ||
| 206 | iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; | 204 | iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; |
| 207 | 205 | ||
| @@ -223,6 +221,9 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 223 | ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); | 221 | ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); |
| 224 | ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); | 222 | ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); |
| 225 | ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); | 223 | ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); |
| 224 | /* devices prior to NCM Errata shall set this field to zero */ | ||
| 225 | ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); | ||
| 226 | ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); | ||
| 226 | 227 | ||
| 227 | if (ctx->func_desc != NULL) | 228 | if (ctx->func_desc != NULL) |
| 228 | flags = ctx->func_desc->bmNetworkCapabilities; | 229 | flags = ctx->func_desc->bmNetworkCapabilities; |
| @@ -231,22 +232,58 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 231 | 232 | ||
| 232 | pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " | 233 | pr_debug("dwNtbInMaxSize=%u dwNtbOutMaxSize=%u " |
| 233 | "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " | 234 | "wNdpOutPayloadRemainder=%u wNdpOutDivisor=%u " |
| 234 | "wNdpOutAlignment=%u flags=0x%x\n", | 235 | "wNdpOutAlignment=%u wNtbOutMaxDatagrams=%u flags=0x%x\n", |
| 235 | ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, | 236 | ctx->rx_max, ctx->tx_max, ctx->tx_remainder, ctx->tx_modulus, |
| 236 | ctx->tx_ndp_modulus, flags); | 237 | ctx->tx_ndp_modulus, ctx->tx_max_datagrams, flags); |
| 237 | 238 | ||
| 238 | /* max count of tx datagrams without terminating NULL entry */ | 239 | /* max count of tx datagrams */ |
| 239 | ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; | 240 | if ((ctx->tx_max_datagrams == 0) || |
| 241 | (ctx->tx_max_datagrams > CDC_NCM_DPT_DATAGRAMS_MAX)) | ||
| 242 | ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; | ||
| 240 | 243 | ||
| 241 | /* verify maximum size of received NTB in bytes */ | 244 | /* verify maximum size of received NTB in bytes */ |
| 242 | if ((ctx->rx_max < | 245 | if (ctx->rx_max < USB_CDC_NCM_NTB_MIN_IN_SIZE) { |
| 243 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || | 246 | pr_debug("Using min receive length=%d\n", |
| 244 | (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX)) { | 247 | USB_CDC_NCM_NTB_MIN_IN_SIZE); |
| 248 | ctx->rx_max = USB_CDC_NCM_NTB_MIN_IN_SIZE; | ||
| 249 | } | ||
| 250 | |||
| 251 | if (ctx->rx_max > CDC_NCM_NTB_MAX_SIZE_RX) { | ||
| 245 | pr_debug("Using default maximum receive length=%d\n", | 252 | pr_debug("Using default maximum receive length=%d\n", |
| 246 | CDC_NCM_NTB_MAX_SIZE_RX); | 253 | CDC_NCM_NTB_MAX_SIZE_RX); |
| 247 | ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; | 254 | ctx->rx_max = CDC_NCM_NTB_MAX_SIZE_RX; |
| 248 | } | 255 | } |
| 249 | 256 | ||
| 257 | /* inform device about NTB input size changes */ | ||
| 258 | if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { | ||
| 259 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | | ||
| 260 | USB_RECIP_INTERFACE; | ||
| 261 | req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE; | ||
| 262 | req.wValue = 0; | ||
| 263 | req.wIndex = cpu_to_le16(iface_no); | ||
| 264 | |||
| 265 | if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { | ||
| 266 | struct usb_cdc_ncm_ndp_input_size ndp_in_sz; | ||
| 267 | |||
| 268 | req.wLength = 8; | ||
| 269 | ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | ||
| 270 | ndp_in_sz.wNtbInMaxDatagrams = | ||
| 271 | cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX); | ||
| 272 | ndp_in_sz.wReserved = 0; | ||
| 273 | err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL, | ||
| 274 | 1000); | ||
| 275 | } else { | ||
| 276 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | ||
| 277 | |||
| 278 | req.wLength = 4; | ||
| 279 | err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0, | ||
| 280 | NULL, 1000); | ||
| 281 | } | ||
| 282 | |||
| 283 | if (err) | ||
| 284 | pr_debug("Setting NTB Input Size failed\n"); | ||
| 285 | } | ||
| 286 | |||
| 250 | /* verify maximum size of transmitted NTB in bytes */ | 287 | /* verify maximum size of transmitted NTB in bytes */ |
| 251 | if ((ctx->tx_max < | 288 | if ((ctx->tx_max < |
| 252 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || | 289 | (CDC_NCM_MIN_HDR_SIZE + CDC_NCM_MIN_DATAGRAM_SIZE)) || |
| @@ -297,47 +334,84 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) | |||
| 297 | /* additional configuration */ | 334 | /* additional configuration */ |
| 298 | 335 | ||
| 299 | /* set CRC Mode */ | 336 | /* set CRC Mode */ |
| 300 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; | 337 | if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { |
| 301 | req.bNotificationType = USB_CDC_SET_CRC_MODE; | 338 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | |
| 302 | req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); | 339 | USB_RECIP_INTERFACE; |
| 303 | req.wIndex = cpu_to_le16(iface_no); | 340 | req.bNotificationType = USB_CDC_SET_CRC_MODE; |
| 304 | req.wLength = 0; | 341 | req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); |
| 305 | 342 | req.wIndex = cpu_to_le16(iface_no); | |
| 306 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); | 343 | req.wLength = 0; |
| 307 | if (err) | 344 | |
| 308 | pr_debug("Setting CRC mode off failed\n"); | 345 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); |
| 346 | if (err) | ||
| 347 | pr_debug("Setting CRC mode off failed\n"); | ||
| 348 | } | ||
| 309 | 349 | ||
| 310 | /* set NTB format */ | 350 | /* set NTB format, if both formats are supported */ |
| 311 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; | 351 | if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { |
| 312 | req.bNotificationType = USB_CDC_SET_NTB_FORMAT; | 352 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | |
| 313 | req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); | 353 | USB_RECIP_INTERFACE; |
| 314 | req.wIndex = cpu_to_le16(iface_no); | 354 | req.bNotificationType = USB_CDC_SET_NTB_FORMAT; |
| 315 | req.wLength = 0; | 355 | req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); |
| 356 | req.wIndex = cpu_to_le16(iface_no); | ||
| 357 | req.wLength = 0; | ||
| 358 | |||
| 359 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); | ||
| 360 | if (err) | ||
| 361 | pr_debug("Setting NTB format to 16-bit failed\n"); | ||
| 362 | } | ||
| 316 | 363 | ||
| 317 | err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); | 364 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; |
| 318 | if (err) | ||
| 319 | pr_debug("Setting NTB format to 16-bit failed\n"); | ||
| 320 | 365 | ||
| 321 | /* set Max Datagram Size (MTU) */ | 366 | /* set Max Datagram Size (MTU) */ |
| 322 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; | 367 | if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { |
| 323 | req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; | 368 | __le16 max_datagram_size; |
| 324 | req.wValue = 0; | 369 | u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); |
| 325 | req.wIndex = cpu_to_le16(iface_no); | 370 | |
| 326 | req.wLength = cpu_to_le16(2); | 371 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | |
| 372 | USB_RECIP_INTERFACE; | ||
| 373 | req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; | ||
| 374 | req.wValue = 0; | ||
| 375 | req.wIndex = cpu_to_le16(iface_no); | ||
| 376 | req.wLength = cpu_to_le16(2); | ||
| 377 | |||
| 378 | err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, | ||
| 379 | 1000); | ||
| 380 | if (err) { | ||
| 381 | pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", | ||
| 382 | CDC_NCM_MIN_DATAGRAM_SIZE); | ||
| 383 | } else { | ||
| 384 | ctx->max_datagram_size = le16_to_cpu(max_datagram_size); | ||
| 385 | /* Check Eth descriptor value */ | ||
| 386 | if (eth_max_sz < CDC_NCM_MAX_DATAGRAM_SIZE) { | ||
| 387 | if (ctx->max_datagram_size > eth_max_sz) | ||
| 388 | ctx->max_datagram_size = eth_max_sz; | ||
| 389 | } else { | ||
| 390 | if (ctx->max_datagram_size > | ||
| 391 | CDC_NCM_MAX_DATAGRAM_SIZE) | ||
| 392 | ctx->max_datagram_size = | ||
| 393 | CDC_NCM_MAX_DATAGRAM_SIZE; | ||
| 394 | } | ||
| 327 | 395 | ||
| 328 | err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, 1000); | 396 | if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) |
| 329 | if (err) { | 397 | ctx->max_datagram_size = |
| 330 | pr_debug(" GET_MAX_DATAGRAM_SIZE failed, using size=%u\n", | 398 | CDC_NCM_MIN_DATAGRAM_SIZE; |
| 331 | CDC_NCM_MIN_DATAGRAM_SIZE); | 399 | |
| 332 | /* use default */ | 400 | /* if value changed, update device */ |
| 333 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; | 401 | req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | |
| 334 | } else { | 402 | USB_RECIP_INTERFACE; |
| 335 | ctx->max_datagram_size = le16_to_cpu(max_datagram_size); | 403 | req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE; |
| 404 | req.wValue = 0; | ||
| 405 | req.wIndex = cpu_to_le16(iface_no); | ||
| 406 | req.wLength = 2; | ||
| 407 | max_datagram_size = cpu_to_le16(ctx->max_datagram_size); | ||
| 408 | |||
| 409 | err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, | ||
| 410 | 0, NULL, 1000); | ||
| 411 | if (err) | ||
| 412 | pr_debug("SET_MAX_DATAGRAM_SIZE failed\n"); | ||
| 413 | } | ||
| 336 | 414 | ||
| 337 | if (ctx->max_datagram_size < CDC_NCM_MIN_DATAGRAM_SIZE) | ||
| 338 | ctx->max_datagram_size = CDC_NCM_MIN_DATAGRAM_SIZE; | ||
| 339 | else if (ctx->max_datagram_size > CDC_NCM_MAX_DATAGRAM_SIZE) | ||
| 340 | ctx->max_datagram_size = CDC_NCM_MAX_DATAGRAM_SIZE; | ||
| 341 | } | 415 | } |
| 342 | 416 | ||
| 343 | if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) | 417 | if (ctx->netdev->mtu != (ctx->max_datagram_size - ETH_HLEN)) |
| @@ -466,19 +540,13 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) | |||
| 466 | 540 | ||
| 467 | ctx->ether_desc = | 541 | ctx->ether_desc = |
| 468 | (const struct usb_cdc_ether_desc *)buf; | 542 | (const struct usb_cdc_ether_desc *)buf; |
| 469 | |||
| 470 | dev->hard_mtu = | 543 | dev->hard_mtu = |
| 471 | le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); | 544 | le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); |
| 472 | 545 | ||
| 473 | if (dev->hard_mtu < | 546 | if (dev->hard_mtu < CDC_NCM_MIN_DATAGRAM_SIZE) |
| 474 | (CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN)) | 547 | dev->hard_mtu = CDC_NCM_MIN_DATAGRAM_SIZE; |
| 475 | dev->hard_mtu = | 548 | else if (dev->hard_mtu > CDC_NCM_MAX_DATAGRAM_SIZE) |
| 476 | CDC_NCM_MIN_DATAGRAM_SIZE - ETH_HLEN; | 549 | dev->hard_mtu = CDC_NCM_MAX_DATAGRAM_SIZE; |
| 477 | |||
| 478 | else if (dev->hard_mtu > | ||
| 479 | (CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN)) | ||
| 480 | dev->hard_mtu = | ||
| 481 | CDC_NCM_MAX_DATAGRAM_SIZE - ETH_HLEN; | ||
| 482 | break; | 550 | break; |
| 483 | 551 | ||
| 484 | case USB_CDC_NCM_TYPE: | 552 | case USB_CDC_NCM_TYPE: |
| @@ -628,13 +696,13 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 628 | u32 offset; | 696 | u32 offset; |
| 629 | u32 last_offset; | 697 | u32 last_offset; |
| 630 | u16 n = 0; | 698 | u16 n = 0; |
| 631 | u8 timeout = 0; | 699 | u8 ready2send = 0; |
| 632 | 700 | ||
| 633 | /* if there is a remaining skb, it gets priority */ | 701 | /* if there is a remaining skb, it gets priority */ |
| 634 | if (skb != NULL) | 702 | if (skb != NULL) |
| 635 | swap(skb, ctx->tx_rem_skb); | 703 | swap(skb, ctx->tx_rem_skb); |
| 636 | else | 704 | else |
| 637 | timeout = 1; | 705 | ready2send = 1; |
| 638 | 706 | ||
| 639 | /* | 707 | /* |
| 640 | * +----------------+ | 708 | * +----------------+ |
| @@ -682,9 +750,10 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 682 | 750 | ||
| 683 | for (; n < ctx->tx_max_datagrams; n++) { | 751 | for (; n < ctx->tx_max_datagrams; n++) { |
| 684 | /* check if end of transmit buffer is reached */ | 752 | /* check if end of transmit buffer is reached */ |
| 685 | if (offset >= ctx->tx_max) | 753 | if (offset >= ctx->tx_max) { |
| 754 | ready2send = 1; | ||
| 686 | break; | 755 | break; |
| 687 | 756 | } | |
| 688 | /* compute maximum buffer size */ | 757 | /* compute maximum buffer size */ |
| 689 | rem = ctx->tx_max - offset; | 758 | rem = ctx->tx_max - offset; |
| 690 | 759 | ||
| @@ -711,9 +780,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 711 | } | 780 | } |
| 712 | ctx->tx_rem_skb = skb; | 781 | ctx->tx_rem_skb = skb; |
| 713 | skb = NULL; | 782 | skb = NULL; |
| 714 | 783 | ready2send = 1; | |
| 715 | /* loop one more time */ | ||
| 716 | timeout = 1; | ||
| 717 | } | 784 | } |
| 718 | break; | 785 | break; |
| 719 | } | 786 | } |
| @@ -756,7 +823,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 756 | ctx->tx_curr_last_offset = last_offset; | 823 | ctx->tx_curr_last_offset = last_offset; |
| 757 | goto exit_no_skb; | 824 | goto exit_no_skb; |
| 758 | 825 | ||
| 759 | } else if ((n < ctx->tx_max_datagrams) && (timeout == 0)) { | 826 | } else if ((n < ctx->tx_max_datagrams) && (ready2send == 0)) { |
| 760 | /* wait for more frames */ | 827 | /* wait for more frames */ |
| 761 | /* push variables */ | 828 | /* push variables */ |
| 762 | ctx->tx_curr_skb = skb_out; | 829 | ctx->tx_curr_skb = skb_out; |
| @@ -813,7 +880,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 813 | cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); | 880 | cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); |
| 814 | ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); | 881 | ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); |
| 815 | ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); | 882 | ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); |
| 816 | ctx->tx_ncm.nth16.wFpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), | 883 | ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), |
| 817 | ctx->tx_ndp_modulus); | 884 | ctx->tx_ndp_modulus); |
| 818 | 885 | ||
| 819 | memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); | 886 | memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); |
| @@ -825,13 +892,13 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) | |||
| 825 | rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) * | 892 | rem = sizeof(ctx->tx_ncm.ndp16) + ((ctx->tx_curr_frame_num + 1) * |
| 826 | sizeof(struct usb_cdc_ncm_dpe16)); | 893 | sizeof(struct usb_cdc_ncm_dpe16)); |
| 827 | ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); | 894 | ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); |
| 828 | ctx->tx_ncm.ndp16.wNextFpIndex = 0; /* reserved */ | 895 | ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ |
| 829 | 896 | ||
| 830 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex, | 897 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex, |
| 831 | &(ctx->tx_ncm.ndp16), | 898 | &(ctx->tx_ncm.ndp16), |
| 832 | sizeof(ctx->tx_ncm.ndp16)); | 899 | sizeof(ctx->tx_ncm.ndp16)); |
| 833 | 900 | ||
| 834 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wFpIndex + | 901 | memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex + |
| 835 | sizeof(ctx->tx_ncm.ndp16), | 902 | sizeof(ctx->tx_ncm.ndp16), |
| 836 | &(ctx->tx_ncm.dpe16), | 903 | &(ctx->tx_ncm.dpe16), |
| 837 | (ctx->tx_curr_frame_num + 1) * | 904 | (ctx->tx_curr_frame_num + 1) * |
| @@ -961,7 +1028,7 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
| 961 | goto error; | 1028 | goto error; |
| 962 | } | 1029 | } |
| 963 | 1030 | ||
| 964 | temp = le16_to_cpu(ctx->rx_ncm.nth16.wFpIndex); | 1031 | temp = le16_to_cpu(ctx->rx_ncm.nth16.wNdpIndex); |
| 965 | if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { | 1032 | if ((temp + sizeof(ctx->rx_ncm.ndp16)) > actlen) { |
| 966 | pr_debug("invalid DPT16 index\n"); | 1033 | pr_debug("invalid DPT16 index\n"); |
| 967 | goto error; | 1034 | goto error; |
| @@ -1048,10 +1115,10 @@ error: | |||
| 1048 | 1115 | ||
| 1049 | static void | 1116 | static void |
| 1050 | cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx, | 1117 | cdc_ncm_speed_change(struct cdc_ncm_ctx *ctx, |
| 1051 | struct connection_speed_change *data) | 1118 | struct usb_cdc_speed_change *data) |
| 1052 | { | 1119 | { |
| 1053 | uint32_t rx_speed = le32_to_cpu(data->USBitRate); | 1120 | uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); |
| 1054 | uint32_t tx_speed = le32_to_cpu(data->DSBitRate); | 1121 | uint32_t tx_speed = le32_to_cpu(data->ULBitRate); |
| 1055 | 1122 | ||
| 1056 | /* | 1123 | /* |
| 1057 | * Currently the USB-NET API does not support reporting the actual | 1124 | * Currently the USB-NET API does not support reporting the actual |
| @@ -1092,7 +1159,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) | |||
| 1092 | /* test for split data in 8-byte chunks */ | 1159 | /* test for split data in 8-byte chunks */ |
| 1093 | if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { | 1160 | if (test_and_clear_bit(EVENT_STS_SPLIT, &dev->flags)) { |
| 1094 | cdc_ncm_speed_change(ctx, | 1161 | cdc_ncm_speed_change(ctx, |
| 1095 | (struct connection_speed_change *)urb->transfer_buffer); | 1162 | (struct usb_cdc_speed_change *)urb->transfer_buffer); |
| 1096 | return; | 1163 | return; |
| 1097 | } | 1164 | } |
| 1098 | 1165 | ||
| @@ -1120,12 +1187,12 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) | |||
| 1120 | break; | 1187 | break; |
| 1121 | 1188 | ||
| 1122 | case USB_CDC_NOTIFY_SPEED_CHANGE: | 1189 | case USB_CDC_NOTIFY_SPEED_CHANGE: |
| 1123 | if (urb->actual_length < | 1190 | if (urb->actual_length < (sizeof(*event) + |
| 1124 | (sizeof(*event) + sizeof(struct connection_speed_change))) | 1191 | sizeof(struct usb_cdc_speed_change))) |
| 1125 | set_bit(EVENT_STS_SPLIT, &dev->flags); | 1192 | set_bit(EVENT_STS_SPLIT, &dev->flags); |
| 1126 | else | 1193 | else |
| 1127 | cdc_ncm_speed_change(ctx, | 1194 | cdc_ncm_speed_change(ctx, |
| 1128 | (struct connection_speed_change *) &event[1]); | 1195 | (struct usb_cdc_speed_change *) &event[1]); |
| 1129 | break; | 1196 | break; |
| 1130 | 1197 | ||
| 1131 | default: | 1198 | default: |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 02b622e3b9fb..5002f5be47be 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
| @@ -651,6 +651,10 @@ static const struct usb_device_id products[] = { | |||
| 651 | .driver_info = (unsigned long)&dm9601_info, | 651 | .driver_info = (unsigned long)&dm9601_info, |
| 652 | }, | 652 | }, |
| 653 | { | 653 | { |
| 654 | USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */ | ||
| 655 | .driver_info = (unsigned long)&dm9601_info, | ||
| 656 | }, | ||
| 657 | { | ||
| 654 | USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ | 658 | USB_DEVICE(0x0a46, 0x9000), /* DM9000E */ |
| 655 | .driver_info = (unsigned long)&dm9601_info, | 659 | .driver_info = (unsigned long)&dm9601_info, |
| 656 | }, | 660 | }, |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index bed8fcedff49..6d83812603b6 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -2628,15 +2628,15 @@ exit: | |||
| 2628 | 2628 | ||
| 2629 | static void hso_free_tiomget(struct hso_serial *serial) | 2629 | static void hso_free_tiomget(struct hso_serial *serial) |
| 2630 | { | 2630 | { |
| 2631 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 2631 | struct hso_tiocmget *tiocmget; |
| 2632 | if (!serial) | ||
| 2633 | return; | ||
| 2634 | tiocmget = serial->tiocmget; | ||
| 2632 | if (tiocmget) { | 2635 | if (tiocmget) { |
| 2633 | if (tiocmget->urb) { | 2636 | usb_free_urb(tiocmget->urb); |
| 2634 | usb_free_urb(tiocmget->urb); | 2637 | tiocmget->urb = NULL; |
| 2635 | tiocmget->urb = NULL; | ||
| 2636 | } | ||
| 2637 | serial->tiocmget = NULL; | 2638 | serial->tiocmget = NULL; |
| 2638 | kfree(tiocmget); | 2639 | kfree(tiocmget); |
| 2639 | |||
| 2640 | } | 2640 | } |
| 2641 | } | 2641 | } |
| 2642 | 2642 | ||
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 5e98643a4a21..7dc84971f26f 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
| @@ -406,6 +406,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth, | |||
| 406 | 406 | ||
| 407 | if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { | 407 | if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { |
| 408 | err("Firmware too big: %zu", fw->size); | 408 | err("Firmware too big: %zu", fw->size); |
| 409 | release_firmware(fw); | ||
| 409 | return -ENOSPC; | 410 | return -ENOSPC; |
| 410 | } | 411 | } |
| 411 | data_len = fw->size; | 412 | data_len = fw->size; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ed9a41643ff4..95c41d56631c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -931,8 +931,10 @@ fail_halt: | |||
| 931 | if (urb != NULL) { | 931 | if (urb != NULL) { |
| 932 | clear_bit (EVENT_RX_MEMORY, &dev->flags); | 932 | clear_bit (EVENT_RX_MEMORY, &dev->flags); |
| 933 | status = usb_autopm_get_interface(dev->intf); | 933 | status = usb_autopm_get_interface(dev->intf); |
| 934 | if (status < 0) | 934 | if (status < 0) { |
| 935 | usb_free_urb(urb); | ||
| 935 | goto fail_lowmem; | 936 | goto fail_lowmem; |
| 937 | } | ||
| 936 | if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK) | 938 | if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK) |
| 937 | resched = 0; | 939 | resched = 0; |
| 938 | usb_autopm_put_interface(dev->intf); | 940 | usb_autopm_put_interface(dev->intf); |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 90a23e410d1b..82dba5aaf423 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -446,6 +446,20 @@ static void skb_recv_done(struct virtqueue *rvq) | |||
| 446 | } | 446 | } |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | static void virtnet_napi_enable(struct virtnet_info *vi) | ||
| 450 | { | ||
| 451 | napi_enable(&vi->napi); | ||
| 452 | |||
| 453 | /* If all buffers were filled by other side before we napi_enabled, we | ||
| 454 | * won't get another interrupt, so process any outstanding packets | ||
| 455 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
| 456 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
| 457 | if (napi_schedule_prep(&vi->napi)) { | ||
| 458 | virtqueue_disable_cb(vi->rvq); | ||
| 459 | __napi_schedule(&vi->napi); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 449 | static void refill_work(struct work_struct *work) | 463 | static void refill_work(struct work_struct *work) |
| 450 | { | 464 | { |
| 451 | struct virtnet_info *vi; | 465 | struct virtnet_info *vi; |
| @@ -454,7 +468,7 @@ static void refill_work(struct work_struct *work) | |||
| 454 | vi = container_of(work, struct virtnet_info, refill.work); | 468 | vi = container_of(work, struct virtnet_info, refill.work); |
| 455 | napi_disable(&vi->napi); | 469 | napi_disable(&vi->napi); |
| 456 | still_empty = !try_fill_recv(vi, GFP_KERNEL); | 470 | still_empty = !try_fill_recv(vi, GFP_KERNEL); |
| 457 | napi_enable(&vi->napi); | 471 | virtnet_napi_enable(vi); |
| 458 | 472 | ||
| 459 | /* In theory, this can happen: if we don't get any buffers in | 473 | /* In theory, this can happen: if we don't get any buffers in |
| 460 | * we will *never* try to fill again. */ | 474 | * we will *never* try to fill again. */ |
| @@ -638,16 +652,7 @@ static int virtnet_open(struct net_device *dev) | |||
| 638 | { | 652 | { |
| 639 | struct virtnet_info *vi = netdev_priv(dev); | 653 | struct virtnet_info *vi = netdev_priv(dev); |
| 640 | 654 | ||
| 641 | napi_enable(&vi->napi); | 655 | virtnet_napi_enable(vi); |
| 642 | |||
| 643 | /* If all buffers were filled by other side before we napi_enabled, we | ||
| 644 | * won't get another interrupt, so process any outstanding packets | ||
| 645 | * now. virtnet_poll wants re-enable the queue, so we disable here. | ||
| 646 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | ||
| 647 | if (napi_schedule_prep(&vi->napi)) { | ||
| 648 | virtqueue_disable_cb(vi->rvq); | ||
| 649 | __napi_schedule(&vi->napi); | ||
| 650 | } | ||
| 651 | return 0; | 656 | return 0; |
| 652 | } | 657 | } |
| 653 | 658 | ||
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 01c05f53e2f9..228d4f7a58af 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c | |||
| @@ -3690,7 +3690,7 @@ __vxge_hw_vpath_rts_table_get(struct __vxge_hw_vpath_handle *vp, | |||
| 3690 | if (status != VXGE_HW_OK) | 3690 | if (status != VXGE_HW_OK) |
| 3691 | goto exit; | 3691 | goto exit; |
| 3692 | 3692 | ||
| 3693 | if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) || | 3693 | if ((rts_table != VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) && |
| 3694 | (rts_table != | 3694 | (rts_table != |
| 3695 | VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) | 3695 | VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) |
| 3696 | *data1 = 0; | 3696 | *data1 = 0; |
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 0064be7ce5c9..21091c26a9a5 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c | |||
| @@ -838,9 +838,9 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah) | |||
| 838 | for (i = 0; i < qmax; i++) { | 838 | for (i = 0; i < qmax; i++) { |
| 839 | err = ath5k_hw_stop_tx_dma(ah, i); | 839 | err = ath5k_hw_stop_tx_dma(ah, i); |
| 840 | /* -EINVAL -> queue inactive */ | 840 | /* -EINVAL -> queue inactive */ |
| 841 | if (err != -EINVAL) | 841 | if (err && err != -EINVAL) |
| 842 | return err; | 842 | return err; |
| 843 | } | 843 | } |
| 844 | 844 | ||
| 845 | return err; | 845 | return 0; |
| 846 | } | 846 | } |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e5f2b96a4c63..a702817daf72 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
| @@ -86,7 +86,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
| 86 | if (!ah->ah_bwmode) { | 86 | if (!ah->ah_bwmode) { |
| 87 | dur = ieee80211_generic_frame_duration(sc->hw, | 87 | dur = ieee80211_generic_frame_duration(sc->hw, |
| 88 | NULL, len, rate); | 88 | NULL, len, rate); |
| 89 | return dur; | 89 | return le16_to_cpu(dur); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | bitrate = rate->bitrate; | 92 | bitrate = rate->bitrate; |
| @@ -265,8 +265,6 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
| 265 | * what rate we should choose to TX ACKs. */ | 265 | * what rate we should choose to TX ACKs. */ |
| 266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); |
| 267 | 267 | ||
| 268 | tx_time = le16_to_cpu(tx_time); | ||
| 269 | |||
| 270 | ath5k_hw_reg_write(ah, tx_time, reg); | 268 | ath5k_hw_reg_write(ah, tx_time, reg); |
| 271 | 269 | ||
| 272 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 270 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 78c26fdccad1..62ce2f4e8605 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
| @@ -282,6 +282,34 @@ int ath5k_hw_phy_disable(struct ath5k_hw *ah) | |||
| 282 | return 0; | 282 | return 0; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | /* | ||
| 286 | * Wait for synth to settle | ||
| 287 | */ | ||
| 288 | static void ath5k_hw_wait_for_synth(struct ath5k_hw *ah, | ||
| 289 | struct ieee80211_channel *channel) | ||
| 290 | { | ||
| 291 | /* | ||
| 292 | * On 5211+ read activation -> rx delay | ||
| 293 | * and use it (100ns steps). | ||
| 294 | */ | ||
| 295 | if (ah->ah_version != AR5K_AR5210) { | ||
| 296 | u32 delay; | ||
| 297 | delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | ||
| 298 | AR5K_PHY_RX_DELAY_M; | ||
| 299 | delay = (channel->hw_value & CHANNEL_CCK) ? | ||
| 300 | ((delay << 2) / 22) : (delay / 10); | ||
| 301 | if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) | ||
| 302 | delay = delay << 1; | ||
| 303 | if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) | ||
| 304 | delay = delay << 2; | ||
| 305 | /* XXX: /2 on turbo ? Let's be safe | ||
| 306 | * for now */ | ||
| 307 | udelay(100 + delay); | ||
| 308 | } else { | ||
| 309 | mdelay(1); | ||
| 310 | } | ||
| 311 | } | ||
| 312 | |||
| 285 | 313 | ||
| 286 | /**********************\ | 314 | /**********************\ |
| 287 | * RF Gain optimization * | 315 | * RF Gain optimization * |
| @@ -1253,6 +1281,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah, | |||
| 1253 | case AR5K_RF5111: | 1281 | case AR5K_RF5111: |
| 1254 | ret = ath5k_hw_rf5111_channel(ah, channel); | 1282 | ret = ath5k_hw_rf5111_channel(ah, channel); |
| 1255 | break; | 1283 | break; |
| 1284 | case AR5K_RF2317: | ||
| 1256 | case AR5K_RF2425: | 1285 | case AR5K_RF2425: |
| 1257 | ret = ath5k_hw_rf2425_channel(ah, channel); | 1286 | ret = ath5k_hw_rf2425_channel(ah, channel); |
| 1258 | break; | 1287 | break; |
| @@ -3237,6 +3266,13 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
| 3237 | /* Failed */ | 3266 | /* Failed */ |
| 3238 | if (i >= 100) | 3267 | if (i >= 100) |
| 3239 | return -EIO; | 3268 | return -EIO; |
| 3269 | |||
| 3270 | /* Set channel and wait for synth */ | ||
| 3271 | ret = ath5k_hw_channel(ah, channel); | ||
| 3272 | if (ret) | ||
| 3273 | return ret; | ||
| 3274 | |||
| 3275 | ath5k_hw_wait_for_synth(ah, channel); | ||
| 3240 | } | 3276 | } |
| 3241 | 3277 | ||
| 3242 | /* | 3278 | /* |
| @@ -3251,13 +3287,53 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
| 3251 | if (ret) | 3287 | if (ret) |
| 3252 | return ret; | 3288 | return ret; |
| 3253 | 3289 | ||
| 3290 | /* Write OFDM timings on 5212*/ | ||
| 3291 | if (ah->ah_version == AR5K_AR5212 && | ||
| 3292 | channel->hw_value & CHANNEL_OFDM) { | ||
| 3293 | |||
| 3294 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | ||
| 3295 | if (ret) | ||
| 3296 | return ret; | ||
| 3297 | |||
| 3298 | /* Spur info is available only from EEPROM versions | ||
| 3299 | * greater than 5.3, but the EEPROM routines will use | ||
| 3300 | * static values for older versions */ | ||
| 3301 | if (ah->ah_mac_srev >= AR5K_SREV_AR5424) | ||
| 3302 | ath5k_hw_set_spur_mitigation_filter(ah, | ||
| 3303 | channel); | ||
| 3304 | } | ||
| 3305 | |||
| 3306 | /* If we used fast channel switching | ||
| 3307 | * we are done, release RF bus and | ||
| 3308 | * fire up NF calibration. | ||
| 3309 | * | ||
| 3310 | * Note: Only NF calibration due to | ||
| 3311 | * channel change, not AGC calibration | ||
| 3312 | * since AGC is still running ! | ||
| 3313 | */ | ||
| 3314 | if (fast) { | ||
| 3315 | /* | ||
| 3316 | * Release RF Bus grant | ||
| 3317 | */ | ||
| 3318 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, | ||
| 3319 | AR5K_PHY_RFBUS_REQ_REQUEST); | ||
| 3320 | |||
| 3321 | /* | ||
| 3322 | * Start NF calibration | ||
| 3323 | */ | ||
| 3324 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
| 3325 | AR5K_PHY_AGCCTL_NF); | ||
| 3326 | |||
| 3327 | return ret; | ||
| 3328 | } | ||
| 3329 | |||
| 3254 | /* | 3330 | /* |
| 3255 | * For 5210 we do all initialization using | 3331 | * For 5210 we do all initialization using |
| 3256 | * initvals, so we don't have to modify | 3332 | * initvals, so we don't have to modify |
| 3257 | * any settings (5210 also only supports | 3333 | * any settings (5210 also only supports |
| 3258 | * a/aturbo modes) | 3334 | * a/aturbo modes) |
| 3259 | */ | 3335 | */ |
| 3260 | if ((ah->ah_version != AR5K_AR5210) && !fast) { | 3336 | if (ah->ah_version != AR5K_AR5210) { |
| 3261 | 3337 | ||
| 3262 | /* | 3338 | /* |
| 3263 | * Write initial RF gain settings | 3339 | * Write initial RF gain settings |
| @@ -3276,22 +3352,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
| 3276 | if (ret) | 3352 | if (ret) |
| 3277 | return ret; | 3353 | return ret; |
| 3278 | 3354 | ||
| 3279 | /* Write OFDM timings on 5212*/ | ||
| 3280 | if (ah->ah_version == AR5K_AR5212 && | ||
| 3281 | channel->hw_value & CHANNEL_OFDM) { | ||
| 3282 | |||
| 3283 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | ||
| 3284 | if (ret) | ||
| 3285 | return ret; | ||
| 3286 | |||
| 3287 | /* Spur info is available only from EEPROM versions | ||
| 3288 | * greater than 5.3, but the EEPROM routines will use | ||
| 3289 | * static values for older versions */ | ||
| 3290 | if (ah->ah_mac_srev >= AR5K_SREV_AR5424) | ||
| 3291 | ath5k_hw_set_spur_mitigation_filter(ah, | ||
| 3292 | channel); | ||
| 3293 | } | ||
| 3294 | |||
| 3295 | /*Enable/disable 802.11b mode on 5111 | 3355 | /*Enable/disable 802.11b mode on 5111 |
| 3296 | (enable 2111 frequency converter + CCK)*/ | 3356 | (enable 2111 frequency converter + CCK)*/ |
| 3297 | if (ah->ah_radio == AR5K_RF5111) { | 3357 | if (ah->ah_radio == AR5K_RF5111) { |
| @@ -3322,47 +3382,20 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
| 3322 | */ | 3382 | */ |
| 3323 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | 3383 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); |
| 3324 | 3384 | ||
| 3385 | ath5k_hw_wait_for_synth(ah, channel); | ||
| 3386 | |||
| 3325 | /* | 3387 | /* |
| 3326 | * On 5211+ read activation -> rx delay | 3388 | * Perform ADC test to see if baseband is ready |
| 3327 | * and use it. | 3389 | * Set tx hold and check adc test register |
| 3328 | */ | 3390 | */ |
| 3329 | if (ah->ah_version != AR5K_AR5210) { | 3391 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); |
| 3330 | u32 delay; | 3392 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); |
| 3331 | delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | 3393 | for (i = 0; i <= 20; i++) { |
| 3332 | AR5K_PHY_RX_DELAY_M; | 3394 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) |
| 3333 | delay = (channel->hw_value & CHANNEL_CCK) ? | 3395 | break; |
| 3334 | ((delay << 2) / 22) : (delay / 10); | 3396 | udelay(200); |
| 3335 | if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) | ||
| 3336 | delay = delay << 1; | ||
| 3337 | if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) | ||
| 3338 | delay = delay << 2; | ||
| 3339 | /* XXX: /2 on turbo ? Let's be safe | ||
| 3340 | * for now */ | ||
| 3341 | udelay(100 + delay); | ||
| 3342 | } else { | ||
| 3343 | mdelay(1); | ||
| 3344 | } | ||
| 3345 | |||
| 3346 | if (fast) | ||
| 3347 | /* | ||
| 3348 | * Release RF Bus grant | ||
| 3349 | */ | ||
| 3350 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, | ||
| 3351 | AR5K_PHY_RFBUS_REQ_REQUEST); | ||
| 3352 | else { | ||
| 3353 | /* | ||
| 3354 | * Perform ADC test to see if baseband is ready | ||
| 3355 | * Set tx hold and check adc test register | ||
| 3356 | */ | ||
| 3357 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | ||
| 3358 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | ||
| 3359 | for (i = 0; i <= 20; i++) { | ||
| 3360 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | ||
| 3361 | break; | ||
| 3362 | udelay(200); | ||
| 3363 | } | ||
| 3364 | ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); | ||
| 3365 | } | 3397 | } |
| 3398 | ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); | ||
| 3366 | 3399 | ||
| 3367 | /* | 3400 | /* |
| 3368 | * Start automatic gain control calibration | 3401 | * Start automatic gain control calibration |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f8a7771faee2..f44c84ab5dce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
| @@ -426,9 +426,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | |||
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | /* WAR for ASPM system hang */ | 428 | /* WAR for ASPM system hang */ |
| 429 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { | 429 | if (AR_SREV_9285(ah) || AR_SREV_9287(ah)) |
| 430 | val |= (AR_WA_BIT6 | AR_WA_BIT7); | 430 | val |= (AR_WA_BIT6 | AR_WA_BIT7); |
| 431 | } | ||
| 432 | 431 | ||
| 433 | if (AR_SREV_9285E_20(ah)) | 432 | if (AR_SREV_9285E_20(ah)) |
| 434 | val |= AR_WA_BIT23; | 433 | val |= AR_WA_BIT23; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3681caf54282..1a7fa6ea4cf5 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
| 22 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
| 23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
| 24 | #include <linux/pm_qos_params.h> | ||
| 25 | 24 | ||
| 26 | #include "debug.h" | 25 | #include "debug.h" |
| 27 | #include "common.h" | 26 | #include "common.h" |
| @@ -57,8 +56,6 @@ struct ath_node; | |||
| 57 | 56 | ||
| 58 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) | 57 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) |
| 59 | 58 | ||
| 60 | #define ATH9K_PM_QOS_DEFAULT_VALUE 55 | ||
| 61 | |||
| 62 | #define TSF_TO_TU(_h,_l) \ | 59 | #define TSF_TO_TU(_h,_l) \ |
| 63 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | 60 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) |
| 64 | 61 | ||
| @@ -218,6 +215,7 @@ struct ath_frame_info { | |||
| 218 | struct ath_buf_state { | 215 | struct ath_buf_state { |
| 219 | u8 bf_type; | 216 | u8 bf_type; |
| 220 | u8 bfs_paprd; | 217 | u8 bfs_paprd; |
| 218 | unsigned long bfs_paprd_timestamp; | ||
| 221 | enum ath9k_internal_frame_type bfs_ftype; | 219 | enum ath9k_internal_frame_type bfs_ftype; |
| 222 | }; | 220 | }; |
| 223 | 221 | ||
| @@ -593,7 +591,6 @@ struct ath_softc { | |||
| 593 | struct work_struct paprd_work; | 591 | struct work_struct paprd_work; |
| 594 | struct work_struct hw_check_work; | 592 | struct work_struct hw_check_work; |
| 595 | struct completion paprd_complete; | 593 | struct completion paprd_complete; |
| 596 | bool paprd_pending; | ||
| 597 | 594 | ||
| 598 | u32 intrstatus; | 595 | u32 intrstatus; |
| 599 | u32 sc_flags; /* SC_OP_* */ | 596 | u32 sc_flags; /* SC_OP_* */ |
| @@ -633,8 +630,6 @@ struct ath_softc { | |||
| 633 | struct ath_descdma txsdma; | 630 | struct ath_descdma txsdma; |
| 634 | 631 | ||
| 635 | struct ath_ant_comb ant_comb; | 632 | struct ath_ant_comb ant_comb; |
| 636 | |||
| 637 | struct pm_qos_request_list pm_qos_req; | ||
| 638 | }; | 633 | }; |
| 639 | 634 | ||
| 640 | struct ath_wiphy { | 635 | struct ath_wiphy { |
| @@ -666,7 +661,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
| 666 | extern struct ieee80211_ops ath9k_ops; | 661 | extern struct ieee80211_ops ath9k_ops; |
| 667 | extern int ath9k_modparam_nohwcrypt; | 662 | extern int ath9k_modparam_nohwcrypt; |
| 668 | extern int led_blink; | 663 | extern int led_blink; |
| 669 | extern int ath9k_pm_qos_value; | ||
| 670 | extern bool is_ath9k_unloaded; | 664 | extern bool is_ath9k_unloaded; |
| 671 | 665 | ||
| 672 | irqreturn_t ath_isr(int irq, void *dev); | 666 | irqreturn_t ath_isr(int irq, void *dev); |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 5ab3084eb9cb..07b1633b7f3f 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
| @@ -219,8 +219,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
| 219 | struct tx_buf *tx_buf = NULL; | 219 | struct tx_buf *tx_buf = NULL; |
| 220 | struct sk_buff *nskb = NULL; | 220 | struct sk_buff *nskb = NULL; |
| 221 | int ret = 0, i; | 221 | int ret = 0, i; |
| 222 | u16 *hdr, tx_skb_cnt = 0; | 222 | u16 tx_skb_cnt = 0; |
| 223 | u8 *buf; | 223 | u8 *buf; |
| 224 | __le16 *hdr; | ||
| 224 | 225 | ||
| 225 | if (hif_dev->tx.tx_skb_cnt == 0) | 226 | if (hif_dev->tx.tx_skb_cnt == 0) |
| 226 | return 0; | 227 | return 0; |
| @@ -245,9 +246,9 @@ static int __hif_usb_tx(struct hif_device_usb *hif_dev) | |||
| 245 | 246 | ||
| 246 | buf = tx_buf->buf; | 247 | buf = tx_buf->buf; |
| 247 | buf += tx_buf->offset; | 248 | buf += tx_buf->offset; |
| 248 | hdr = (u16 *)buf; | 249 | hdr = (__le16 *)buf; |
| 249 | *hdr++ = nskb->len; | 250 | *hdr++ = cpu_to_le16(nskb->len); |
| 250 | *hdr++ = ATH_USB_TX_STREAM_MODE_TAG; | 251 | *hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG); |
| 251 | buf += 4; | 252 | buf += 4; |
| 252 | memcpy(buf, nskb->data, nskb->len); | 253 | memcpy(buf, nskb->data, nskb->len); |
| 253 | tx_buf->len = nskb->len + 4; | 254 | tx_buf->len = nskb->len + 4; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 38433f9bfe59..0352f0994caa 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
| @@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) | |||
| 142 | { | 142 | { |
| 143 | ath9k_htc_exit_debug(priv->ah); | 143 | ath9k_htc_exit_debug(priv->ah); |
| 144 | ath9k_hw_deinit(priv->ah); | 144 | ath9k_hw_deinit(priv->ah); |
| 145 | tasklet_kill(&priv->swba_tasklet); | ||
| 146 | tasklet_kill(&priv->rx_tasklet); | ||
| 147 | tasklet_kill(&priv->tx_tasklet); | ||
| 148 | kfree(priv->ah); | 145 | kfree(priv->ah); |
| 149 | priv->ah = NULL; | 146 | priv->ah = NULL; |
| 150 | } | 147 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f4d576bc3ccd..6bb59958f71e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -1025,12 +1025,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 1025 | int ret = 0; | 1025 | int ret = 0; |
| 1026 | u8 cmd_rsp; | 1026 | u8 cmd_rsp; |
| 1027 | 1027 | ||
| 1028 | /* Cancel all the running timers/work .. */ | ||
| 1029 | cancel_work_sync(&priv->fatal_work); | ||
| 1030 | cancel_work_sync(&priv->ps_work); | ||
| 1031 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
| 1032 | ath9k_led_stop_brightness(priv); | ||
| 1033 | |||
| 1034 | mutex_lock(&priv->mutex); | 1028 | mutex_lock(&priv->mutex); |
| 1035 | 1029 | ||
| 1036 | if (priv->op_flags & OP_INVALID) { | 1030 | if (priv->op_flags & OP_INVALID) { |
| @@ -1044,8 +1038,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 1044 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 1038 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
| 1045 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 1039 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
| 1046 | WMI_CMD(WMI_STOP_RECV_CMDID); | 1040 | WMI_CMD(WMI_STOP_RECV_CMDID); |
| 1041 | |||
| 1042 | tasklet_kill(&priv->swba_tasklet); | ||
| 1043 | tasklet_kill(&priv->rx_tasklet); | ||
| 1044 | tasklet_kill(&priv->tx_tasklet); | ||
| 1045 | |||
| 1047 | skb_queue_purge(&priv->tx_queue); | 1046 | skb_queue_purge(&priv->tx_queue); |
| 1048 | 1047 | ||
| 1048 | mutex_unlock(&priv->mutex); | ||
| 1049 | |||
| 1050 | /* Cancel all the running timers/work .. */ | ||
| 1051 | cancel_work_sync(&priv->fatal_work); | ||
| 1052 | cancel_work_sync(&priv->ps_work); | ||
| 1053 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
| 1054 | ath9k_led_stop_brightness(priv); | ||
| 1055 | |||
| 1056 | mutex_lock(&priv->mutex); | ||
| 1057 | |||
| 1049 | /* Remove monitor interface here */ | 1058 | /* Remove monitor interface here */ |
| 1050 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | 1059 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { |
| 1051 | if (ath9k_htc_remove_monitor_interface(priv)) | 1060 | if (ath9k_htc_remove_monitor_interface(priv)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1afb8bb85756..9f01e50d5cda 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -369,6 +369,9 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
| 369 | else | 369 | else |
| 370 | ah->config.ht_enable = 0; | 370 | ah->config.ht_enable = 0; |
| 371 | 371 | ||
| 372 | /* PAPRD needs some more work to be enabled */ | ||
| 373 | ah->config.paprd_disable = 1; | ||
| 374 | |||
| 372 | ah->config.rx_intr_mitigation = true; | 375 | ah->config.rx_intr_mitigation = true; |
| 373 | ah->config.pcieSerDesWrite = true; | 376 | ah->config.pcieSerDesWrite = true; |
| 374 | 377 | ||
| @@ -1933,7 +1936,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
| 1933 | pCap->rx_status_len = sizeof(struct ar9003_rxs); | 1936 | pCap->rx_status_len = sizeof(struct ar9003_rxs); |
| 1934 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | 1937 | pCap->tx_desc_len = sizeof(struct ar9003_txc); |
| 1935 | pCap->txs_len = sizeof(struct ar9003_txs); | 1938 | pCap->txs_len = sizeof(struct ar9003_txs); |
| 1936 | if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | 1939 | if (!ah->config.paprd_disable && |
| 1940 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | ||
| 1937 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; | 1941 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; |
| 1938 | } else { | 1942 | } else { |
| 1939 | pCap->tx_desc_len = sizeof(struct ath_desc); | 1943 | pCap->tx_desc_len = sizeof(struct ath_desc); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5a3dfec45e96..ea9fde670646 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
| @@ -225,6 +225,7 @@ struct ath9k_ops_config { | |||
| 225 | u32 pcie_waen; | 225 | u32 pcie_waen; |
| 226 | u8 analog_shiftreg; | 226 | u8 analog_shiftreg; |
| 227 | u8 ht_enable; | 227 | u8 ht_enable; |
| 228 | u8 paprd_disable; | ||
| 228 | u32 ofdm_trig_low; | 229 | u32 ofdm_trig_low; |
| 229 | u32 ofdm_trig_high; | 230 | u32 ofdm_trig_high; |
| 230 | u32 cck_trig_high; | 231 | u32 cck_trig_high; |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 767d8b86f1e1..a033d01bf8a0 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -41,10 +41,6 @@ static int ath9k_btcoex_enable; | |||
| 41 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); | 41 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); |
| 42 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 42 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
| 43 | 43 | ||
| 44 | int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE; | ||
| 45 | module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); | ||
| 46 | MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); | ||
| 47 | |||
| 48 | bool is_ath9k_unloaded; | 44 | bool is_ath9k_unloaded; |
| 49 | /* We use the hw_value as an index into our private channel structure */ | 45 | /* We use the hw_value as an index into our private channel structure */ |
| 50 | 46 | ||
| @@ -598,8 +594,6 @@ err_btcoex: | |||
| 598 | err_queues: | 594 | err_queues: |
| 599 | ath9k_hw_deinit(ah); | 595 | ath9k_hw_deinit(ah); |
| 600 | err_hw: | 596 | err_hw: |
| 601 | tasklet_kill(&sc->intr_tq); | ||
| 602 | tasklet_kill(&sc->bcon_tasklet); | ||
| 603 | 597 | ||
| 604 | kfree(ah); | 598 | kfree(ah); |
| 605 | sc->sc_ah = NULL; | 599 | sc->sc_ah = NULL; |
| @@ -764,9 +758,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
| 764 | ath_init_leds(sc); | 758 | ath_init_leds(sc); |
| 765 | ath_start_rfkill_poll(sc); | 759 | ath_start_rfkill_poll(sc); |
| 766 | 760 | ||
| 767 | pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | ||
| 768 | PM_QOS_DEFAULT_VALUE); | ||
| 769 | |||
| 770 | return 0; | 761 | return 0; |
| 771 | 762 | ||
| 772 | error_world: | 763 | error_world: |
| @@ -807,9 +798,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
| 807 | 798 | ||
| 808 | ath9k_hw_deinit(sc->sc_ah); | 799 | ath9k_hw_deinit(sc->sc_ah); |
| 809 | 800 | ||
| 810 | tasklet_kill(&sc->intr_tq); | ||
| 811 | tasklet_kill(&sc->bcon_tasklet); | ||
| 812 | |||
| 813 | kfree(sc->sc_ah); | 801 | kfree(sc->sc_ah); |
| 814 | sc->sc_ah = NULL; | 802 | sc->sc_ah = NULL; |
| 815 | } | 803 | } |
| @@ -824,6 +812,8 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
| 824 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | 812 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
| 825 | ath_deinit_leds(sc); | 813 | ath_deinit_leds(sc); |
| 826 | 814 | ||
| 815 | ath9k_ps_restore(sc); | ||
| 816 | |||
| 827 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 817 | for (i = 0; i < sc->num_sec_wiphy; i++) { |
| 828 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | 818 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; |
| 829 | if (aphy == NULL) | 819 | if (aphy == NULL) |
| @@ -834,7 +824,6 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
| 834 | } | 824 | } |
| 835 | 825 | ||
| 836 | ieee80211_unregister_hw(hw); | 826 | ieee80211_unregister_hw(hw); |
| 837 | pm_qos_remove_request(&sc->pm_qos_req); | ||
| 838 | ath_rx_cleanup(sc); | 827 | ath_rx_cleanup(sc); |
| 839 | ath_tx_cleanup(sc); | 828 | ath_tx_cleanup(sc); |
| 840 | ath9k_deinit_softc(sc); | 829 | ath9k_deinit_softc(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 180170d3ce25..2915b11edefb 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
| @@ -885,7 +885,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
| 885 | struct ath_common *common = ath9k_hw_common(ah); | 885 | struct ath_common *common = ath9k_hw_common(ah); |
| 886 | 886 | ||
| 887 | if (!(ints & ATH9K_INT_GLOBAL)) | 887 | if (!(ints & ATH9K_INT_GLOBAL)) |
| 888 | ath9k_hw_enable_interrupts(ah); | 888 | ath9k_hw_disable_interrupts(ah); |
| 889 | 889 | ||
| 890 | ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); | 890 | ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); |
| 891 | 891 | ||
| @@ -963,7 +963,8 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
| 963 | REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | 963 | REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); |
| 964 | } | 964 | } |
| 965 | 965 | ||
| 966 | ath9k_hw_enable_interrupts(ah); | 966 | if (ints & ATH9K_INT_GLOBAL) |
| 967 | ath9k_hw_enable_interrupts(ah); | ||
| 967 | 968 | ||
| 968 | return; | 969 | return; |
| 969 | } | 970 | } |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f90a6ca94a76..a09d15f7aa6e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -325,6 +325,8 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
| 325 | { | 325 | { |
| 326 | struct ieee80211_hw *hw = sc->hw; | 326 | struct ieee80211_hw *hw = sc->hw; |
| 327 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 327 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
| 328 | struct ath_hw *ah = sc->sc_ah; | ||
| 329 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 328 | struct ath_tx_control txctl; | 330 | struct ath_tx_control txctl; |
| 329 | int time_left; | 331 | int time_left; |
| 330 | 332 | ||
| @@ -340,14 +342,16 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
| 340 | tx_info->control.rates[1].idx = -1; | 342 | tx_info->control.rates[1].idx = -1; |
| 341 | 343 | ||
| 342 | init_completion(&sc->paprd_complete); | 344 | init_completion(&sc->paprd_complete); |
| 343 | sc->paprd_pending = true; | ||
| 344 | txctl.paprd = BIT(chain); | 345 | txctl.paprd = BIT(chain); |
| 345 | if (ath_tx_start(hw, skb, &txctl) != 0) | 346 | |
| 347 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
| 348 | ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); | ||
| 349 | dev_kfree_skb_any(skb); | ||
| 346 | return false; | 350 | return false; |
| 351 | } | ||
| 347 | 352 | ||
| 348 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | 353 | time_left = wait_for_completion_timeout(&sc->paprd_complete, |
| 349 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 354 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); |
| 350 | sc->paprd_pending = false; | ||
| 351 | 355 | ||
| 352 | if (!time_left) | 356 | if (!time_left) |
| 353 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, | 357 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CALIBRATE, |
| @@ -592,14 +596,12 @@ void ath9k_tasklet(unsigned long data) | |||
| 592 | u32 status = sc->intrstatus; | 596 | u32 status = sc->intrstatus; |
| 593 | u32 rxmask; | 597 | u32 rxmask; |
| 594 | 598 | ||
| 595 | ath9k_ps_wakeup(sc); | ||
| 596 | |||
| 597 | if (status & ATH9K_INT_FATAL) { | 599 | if (status & ATH9K_INT_FATAL) { |
| 598 | ath_reset(sc, true); | 600 | ath_reset(sc, true); |
| 599 | ath9k_ps_restore(sc); | ||
| 600 | return; | 601 | return; |
| 601 | } | 602 | } |
| 602 | 603 | ||
| 604 | ath9k_ps_wakeup(sc); | ||
| 603 | spin_lock(&sc->sc_pcu_lock); | 605 | spin_lock(&sc->sc_pcu_lock); |
| 604 | 606 | ||
| 605 | if (!ath9k_hw_check_alive(ah)) | 607 | if (!ath9k_hw_check_alive(ah)) |
| @@ -955,8 +957,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 955 | 957 | ||
| 956 | spin_unlock_bh(&sc->sc_pcu_lock); | 958 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 957 | ath9k_ps_restore(sc); | 959 | ath9k_ps_restore(sc); |
| 958 | |||
| 959 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | ||
| 960 | } | 960 | } |
| 961 | 961 | ||
| 962 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 962 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
| @@ -969,6 +969,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 969 | /* Stop ANI */ | 969 | /* Stop ANI */ |
| 970 | del_timer_sync(&common->ani.timer); | 970 | del_timer_sync(&common->ani.timer); |
| 971 | 971 | ||
| 972 | ath9k_ps_wakeup(sc); | ||
| 972 | spin_lock_bh(&sc->sc_pcu_lock); | 973 | spin_lock_bh(&sc->sc_pcu_lock); |
| 973 | 974 | ||
| 974 | ieee80211_stop_queues(hw); | 975 | ieee80211_stop_queues(hw); |
| @@ -1015,6 +1016,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 1015 | 1016 | ||
| 1016 | /* Start ANI */ | 1017 | /* Start ANI */ |
| 1017 | ath_start_ani(common); | 1018 | ath_start_ani(common); |
| 1019 | ath9k_ps_restore(sc); | ||
| 1018 | 1020 | ||
| 1019 | return r; | 1021 | return r; |
| 1020 | } | 1022 | } |
| @@ -1171,12 +1173,6 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 1171 | ath9k_btcoex_timer_resume(sc); | 1173 | ath9k_btcoex_timer_resume(sc); |
| 1172 | } | 1174 | } |
| 1173 | 1175 | ||
| 1174 | /* User has the option to provide pm-qos value as a module | ||
| 1175 | * parameter rather than using the default value of | ||
| 1176 | * 'ATH9K_PM_QOS_DEFAULT_VALUE'. | ||
| 1177 | */ | ||
| 1178 | pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value); | ||
| 1179 | |||
| 1180 | if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) | 1176 | if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) |
| 1181 | common->bus_ops->extn_synch_en(common); | 1177 | common->bus_ops->extn_synch_en(common); |
| 1182 | 1178 | ||
| @@ -1309,6 +1305,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1309 | 1305 | ||
| 1310 | spin_lock_bh(&sc->sc_pcu_lock); | 1306 | spin_lock_bh(&sc->sc_pcu_lock); |
| 1311 | 1307 | ||
| 1308 | /* prevent tasklets to enable interrupts once we disable them */ | ||
| 1309 | ah->imask &= ~ATH9K_INT_GLOBAL; | ||
| 1310 | |||
| 1312 | /* make sure h/w will not generate any interrupt | 1311 | /* make sure h/w will not generate any interrupt |
| 1313 | * before setting the invalid flag. */ | 1312 | * before setting the invalid flag. */ |
| 1314 | ath9k_hw_disable_interrupts(ah); | 1313 | ath9k_hw_disable_interrupts(ah); |
| @@ -1326,6 +1325,12 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1326 | 1325 | ||
| 1327 | spin_unlock_bh(&sc->sc_pcu_lock); | 1326 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 1328 | 1327 | ||
| 1328 | /* we can now sync irq and kill any running tasklets, since we already | ||
| 1329 | * disabled interrupts and not holding a spin lock */ | ||
| 1330 | synchronize_irq(sc->irq); | ||
| 1331 | tasklet_kill(&sc->intr_tq); | ||
| 1332 | tasklet_kill(&sc->bcon_tasklet); | ||
| 1333 | |||
| 1329 | ath9k_ps_restore(sc); | 1334 | ath9k_ps_restore(sc); |
| 1330 | 1335 | ||
| 1331 | sc->ps_idle = true; | 1336 | sc->ps_idle = true; |
| @@ -1334,8 +1339,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
| 1334 | 1339 | ||
| 1335 | sc->sc_flags |= SC_OP_INVALID; | 1340 | sc->sc_flags |= SC_OP_INVALID; |
| 1336 | 1341 | ||
| 1337 | pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); | ||
| 1338 | |||
| 1339 | mutex_unlock(&sc->mutex); | 1342 | mutex_unlock(&sc->mutex); |
| 1340 | 1343 | ||
| 1341 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); | 1344 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); |
| @@ -1701,7 +1704,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1701 | skip_chan_change: | 1704 | skip_chan_change: |
| 1702 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 1705 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
| 1703 | sc->config.txpowlimit = 2 * conf->power_level; | 1706 | sc->config.txpowlimit = 2 * conf->power_level; |
| 1707 | ath9k_ps_wakeup(sc); | ||
| 1704 | ath_update_txpow(sc); | 1708 | ath_update_txpow(sc); |
| 1709 | ath9k_ps_restore(sc); | ||
| 1705 | } | 1710 | } |
| 1706 | 1711 | ||
| 1707 | spin_lock_bh(&sc->wiphy_lock); | 1712 | spin_lock_bh(&sc->wiphy_lock); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 332d1feb5c18..07b7804aec5b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -1725,6 +1725,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1725 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, | 1725 | ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc, |
| 1726 | bf->bf_state.bfs_paprd); | 1726 | bf->bf_state.bfs_paprd); |
| 1727 | 1727 | ||
| 1728 | if (txctl->paprd) | ||
| 1729 | bf->bf_state.bfs_paprd_timestamp = jiffies; | ||
| 1730 | |||
| 1728 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); | 1731 | ath_tx_send_normal(sc, txctl->txq, tid, &bf_head); |
| 1729 | } | 1732 | } |
| 1730 | 1733 | ||
| @@ -1886,7 +1889,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
| 1886 | bf->bf_buf_addr = 0; | 1889 | bf->bf_buf_addr = 0; |
| 1887 | 1890 | ||
| 1888 | if (bf->bf_state.bfs_paprd) { | 1891 | if (bf->bf_state.bfs_paprd) { |
| 1889 | if (!sc->paprd_pending) | 1892 | if (time_after(jiffies, |
| 1893 | bf->bf_state.bfs_paprd_timestamp + | ||
| 1894 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) | ||
| 1890 | dev_kfree_skb_any(skb); | 1895 | dev_kfree_skb_any(skb); |
| 1891 | else | 1896 | else |
| 1892 | complete(&sc->paprd_complete); | 1897 | complete(&sc->paprd_complete); |
| @@ -2113,9 +2118,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
| 2113 | if (needreset) { | 2118 | if (needreset) { |
| 2114 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, | 2119 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, |
| 2115 | "tx hung, resetting the chip\n"); | 2120 | "tx hung, resetting the chip\n"); |
| 2116 | ath9k_ps_wakeup(sc); | ||
| 2117 | ath_reset(sc, true); | 2121 | ath_reset(sc, true); |
| 2118 | ath9k_ps_restore(sc); | ||
| 2119 | } | 2122 | } |
| 2120 | 2123 | ||
| 2121 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | 2124 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, |
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 939a0e96ed1f..84866a4b8350 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
| @@ -564,7 +564,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | |||
| 564 | cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); | 564 | cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); |
| 565 | 565 | ||
| 566 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ | 566 | /* 2. Maybe the AP wants to send multicast/broadcast data? */ |
| 567 | cam = !!(tim_ie->bitmap_ctrl & 0x01); | 567 | cam |= !!(tim_ie->bitmap_ctrl & 0x01); |
| 568 | 568 | ||
| 569 | if (!cam) { | 569 | if (!cam) { |
| 570 | /* back to low-power land. */ | 570 | /* back to low-power land. */ |
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 537732e5964f..f82c400be288 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
| @@ -118,6 +118,8 @@ static struct usb_device_id carl9170_usb_ids[] = { | |||
| 118 | { USB_DEVICE(0x057c, 0x8402) }, | 118 | { USB_DEVICE(0x057c, 0x8402) }, |
| 119 | /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ | 119 | /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ |
| 120 | { USB_DEVICE(0x1668, 0x1200) }, | 120 | { USB_DEVICE(0x1668, 0x1200) }, |
| 121 | /* Airlive X.USB a/b/g/n */ | ||
| 122 | { USB_DEVICE(0x1b75, 0x9170) }, | ||
| 121 | 123 | ||
| 122 | /* terminate */ | 124 | /* terminate */ |
| 123 | {} | 125 | {} |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a9b852be4509..39b6f16c87fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
| @@ -402,72 +402,6 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv, | |||
| 402 | } | 402 | } |
| 403 | #endif | 403 | #endif |
| 404 | 404 | ||
| 405 | /** | ||
| 406 | * iwl3945_good_plcp_health - checks for plcp error. | ||
| 407 | * | ||
| 408 | * When the plcp error is exceeding the thresholds, reset the radio | ||
| 409 | * to improve the throughput. | ||
| 410 | */ | ||
| 411 | static bool iwl3945_good_plcp_health(struct iwl_priv *priv, | ||
| 412 | struct iwl_rx_packet *pkt) | ||
| 413 | { | ||
| 414 | bool rc = true; | ||
| 415 | struct iwl3945_notif_statistics current_stat; | ||
| 416 | int combined_plcp_delta; | ||
| 417 | unsigned int plcp_msec; | ||
| 418 | unsigned long plcp_received_jiffies; | ||
| 419 | |||
| 420 | if (priv->cfg->base_params->plcp_delta_threshold == | ||
| 421 | IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { | ||
| 422 | IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); | ||
| 423 | return rc; | ||
| 424 | } | ||
| 425 | memcpy(¤t_stat, pkt->u.raw, sizeof(struct | ||
| 426 | iwl3945_notif_statistics)); | ||
| 427 | /* | ||
| 428 | * check for plcp_err and trigger radio reset if it exceeds | ||
| 429 | * the plcp error threshold plcp_delta. | ||
| 430 | */ | ||
| 431 | plcp_received_jiffies = jiffies; | ||
| 432 | plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - | ||
| 433 | (long) priv->plcp_jiffies); | ||
| 434 | priv->plcp_jiffies = plcp_received_jiffies; | ||
| 435 | /* | ||
| 436 | * check to make sure plcp_msec is not 0 to prevent division | ||
| 437 | * by zero. | ||
| 438 | */ | ||
| 439 | if (plcp_msec) { | ||
| 440 | combined_plcp_delta = | ||
| 441 | (le32_to_cpu(current_stat.rx.ofdm.plcp_err) - | ||
| 442 | le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err)); | ||
| 443 | |||
| 444 | if ((combined_plcp_delta > 0) && | ||
| 445 | ((combined_plcp_delta * 100) / plcp_msec) > | ||
| 446 | priv->cfg->base_params->plcp_delta_threshold) { | ||
| 447 | /* | ||
| 448 | * if plcp_err exceed the threshold, the following | ||
| 449 | * data is printed in csv format: | ||
| 450 | * Text: plcp_err exceeded %d, | ||
| 451 | * Received ofdm.plcp_err, | ||
| 452 | * Current ofdm.plcp_err, | ||
| 453 | * combined_plcp_delta, | ||
| 454 | * plcp_msec | ||
| 455 | */ | ||
| 456 | IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " | ||
| 457 | "%u, %d, %u mSecs\n", | ||
| 458 | priv->cfg->base_params->plcp_delta_threshold, | ||
| 459 | le32_to_cpu(current_stat.rx.ofdm.plcp_err), | ||
| 460 | combined_plcp_delta, plcp_msec); | ||
| 461 | /* | ||
| 462 | * Reset the RF radio due to the high plcp | ||
| 463 | * error rate | ||
| 464 | */ | ||
| 465 | rc = false; | ||
| 466 | } | ||
| 467 | } | ||
| 468 | return rc; | ||
| 469 | } | ||
| 470 | |||
| 471 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 405 | void iwl3945_hw_rx_statistics(struct iwl_priv *priv, |
| 472 | struct iwl_rx_mem_buffer *rxb) | 406 | struct iwl_rx_mem_buffer *rxb) |
| 473 | { | 407 | { |
| @@ -2734,7 +2668,6 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
| 2734 | .isr_ops = { | 2668 | .isr_ops = { |
| 2735 | .isr = iwl_isr_legacy, | 2669 | .isr = iwl_isr_legacy, |
| 2736 | }, | 2670 | }, |
| 2737 | .check_plcp_health = iwl3945_good_plcp_health, | ||
| 2738 | 2671 | ||
| 2739 | .debugfs_ops = { | 2672 | .debugfs_ops = { |
| 2740 | .rx_stats_read = iwl3945_ucode_rx_stats_read, | 2673 | .rx_stats_read = iwl3945_ucode_rx_stats_read, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 3f1e5f1bf847..91a9f5253469 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
| @@ -2624,6 +2624,7 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
| 2624 | .fw_name_pre = IWL4965_FW_PRE, | 2624 | .fw_name_pre = IWL4965_FW_PRE, |
| 2625 | .ucode_api_max = IWL4965_UCODE_API_MAX, | 2625 | .ucode_api_max = IWL4965_UCODE_API_MAX, |
| 2626 | .ucode_api_min = IWL4965_UCODE_API_MIN, | 2626 | .ucode_api_min = IWL4965_UCODE_API_MIN, |
| 2627 | .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, | ||
| 2627 | .valid_tx_ant = ANT_AB, | 2628 | .valid_tx_ant = ANT_AB, |
| 2628 | .valid_rx_ant = ANT_ABC, | 2629 | .valid_rx_ant = ANT_ABC, |
| 2629 | .eeprom_ver = EEPROM_4965_EEPROM_VERSION, | 2630 | .eeprom_ver = EEPROM_4965_EEPROM_VERSION, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 79ab0a6b1386..537fb8c84e3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | #include "iwl-agn-debugfs.h" | 51 | #include "iwl-agn-debugfs.h" |
| 52 | 52 | ||
| 53 | /* Highest firmware API version supported */ | 53 | /* Highest firmware API version supported */ |
| 54 | #define IWL5000_UCODE_API_MAX 2 | 54 | #define IWL5000_UCODE_API_MAX 5 |
| 55 | #define IWL5150_UCODE_API_MAX 2 | 55 | #define IWL5150_UCODE_API_MAX 2 |
| 56 | 56 | ||
| 57 | /* Lowest firmware API version supported */ | 57 | /* Lowest firmware API version supported */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index af505bcd7ae0..ef36aff1bb43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
| @@ -681,6 +681,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
| 681 | .fw_name_pre = IWL6050_FW_PRE, \ | 681 | .fw_name_pre = IWL6050_FW_PRE, \ |
| 682 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ | 682 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ |
| 683 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ | 683 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ |
| 684 | .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ | ||
| 685 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ | ||
| 684 | .ops = &iwl6050_ops, \ | 686 | .ops = &iwl6050_ops, \ |
| 685 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ | 687 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ |
| 686 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ | 688 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index 14ceb4df72f6..27b5a3eec9dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | |||
| @@ -152,11 +152,14 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv) | |||
| 152 | 152 | ||
| 153 | eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); | 153 | eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); |
| 154 | 154 | ||
| 155 | priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> | 155 | if (!priv->cfg->sku) { |
| 156 | /* not using sku overwrite */ | ||
| 157 | priv->cfg->sku = | ||
| 158 | ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> | ||
| 156 | EEPROM_SKU_CAP_BAND_POS); | 159 | EEPROM_SKU_CAP_BAND_POS); |
| 157 | if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) | 160 | if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) |
| 158 | priv->cfg->sku |= IWL_SKU_N; | 161 | priv->cfg->sku |= IWL_SKU_N; |
| 159 | 162 | } | |
| 160 | if (!priv->cfg->sku) { | 163 | if (!priv->cfg->sku) { |
| 161 | IWL_ERR(priv, "Invalid device sku\n"); | 164 | IWL_ERR(priv, "Invalid device sku\n"); |
| 162 | return -EINVAL; | 165 | return -EINVAL; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 36335b1b54d4..c1cfd9952e52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -1157,6 +1157,9 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
| 1157 | /* only Re-enable if disabled by irq */ | 1157 | /* only Re-enable if disabled by irq */ |
| 1158 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1158 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
| 1159 | iwl_enable_interrupts(priv); | 1159 | iwl_enable_interrupts(priv); |
| 1160 | /* Re-enable RF_KILL if it occurred */ | ||
| 1161 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
| 1162 | iwl_enable_rfkill_int(priv); | ||
| 1160 | 1163 | ||
| 1161 | #ifdef CONFIG_IWLWIFI_DEBUG | 1164 | #ifdef CONFIG_IWLWIFI_DEBUG |
| 1162 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { | 1165 | if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { |
| @@ -1371,6 +1374,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
| 1371 | /* only Re-enable if disabled by irq */ | 1374 | /* only Re-enable if disabled by irq */ |
| 1372 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1375 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
| 1373 | iwl_enable_interrupts(priv); | 1376 | iwl_enable_interrupts(priv); |
| 1377 | /* Re-enable RF_KILL if it occurred */ | ||
| 1378 | else if (handled & CSR_INT_BIT_RF_KILL) | ||
| 1379 | iwl_enable_rfkill_int(priv); | ||
| 1374 | } | 1380 | } |
| 1375 | 1381 | ||
| 1376 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | 1382 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 1eacba4daa5b..0494d7b102d4 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
| @@ -199,6 +199,7 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, | |||
| 199 | while (i != idx) { | 199 | while (i != idx) { |
| 200 | u16 len; | 200 | u16 len; |
| 201 | struct sk_buff *skb; | 201 | struct sk_buff *skb; |
| 202 | dma_addr_t dma_addr; | ||
| 202 | desc = &ring[i]; | 203 | desc = &ring[i]; |
| 203 | len = le16_to_cpu(desc->len); | 204 | len = le16_to_cpu(desc->len); |
| 204 | skb = rx_buf[i]; | 205 | skb = rx_buf[i]; |
| @@ -216,17 +217,20 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, | |||
| 216 | 217 | ||
| 217 | len = priv->common.rx_mtu; | 218 | len = priv->common.rx_mtu; |
| 218 | } | 219 | } |
| 220 | dma_addr = le32_to_cpu(desc->host_addr); | ||
| 221 | pci_dma_sync_single_for_cpu(priv->pdev, dma_addr, | ||
| 222 | priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); | ||
| 219 | skb_put(skb, len); | 223 | skb_put(skb, len); |
| 220 | 224 | ||
| 221 | if (p54_rx(dev, skb)) { | 225 | if (p54_rx(dev, skb)) { |
| 222 | pci_unmap_single(priv->pdev, | 226 | pci_unmap_single(priv->pdev, dma_addr, |
| 223 | le32_to_cpu(desc->host_addr), | 227 | priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); |
| 224 | priv->common.rx_mtu + 32, | ||
| 225 | PCI_DMA_FROMDEVICE); | ||
| 226 | rx_buf[i] = NULL; | 228 | rx_buf[i] = NULL; |
| 227 | desc->host_addr = 0; | 229 | desc->host_addr = cpu_to_le32(0); |
| 228 | } else { | 230 | } else { |
| 229 | skb_trim(skb, 0); | 231 | skb_trim(skb, 0); |
| 232 | pci_dma_sync_single_for_device(priv->pdev, dma_addr, | ||
| 233 | priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); | ||
| 230 | desc->len = cpu_to_le16(priv->common.rx_mtu + 32); | 234 | desc->len = cpu_to_le16(priv->common.rx_mtu + 32); |
| 231 | } | 235 | } |
| 232 | 236 | ||
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 21713a7638c4..9b344a921e74 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
| @@ -98,6 +98,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
| 98 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ | 98 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ |
| 99 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ | 99 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ |
| 100 | {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ | 100 | {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ |
| 101 | {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */ | ||
| 101 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ | 102 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ |
| 102 | {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ | 103 | {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ |
| 103 | {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ | 104 | {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 848cc2cce247..518542b4bf9e 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
| @@ -2597,6 +2597,9 @@ static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
| 2597 | __le32 mode; | 2597 | __le32 mode; |
| 2598 | int ret; | 2598 | int ret; |
| 2599 | 2599 | ||
| 2600 | if (priv->device_type != RNDIS_BCM4320B) | ||
| 2601 | return -ENOTSUPP; | ||
| 2602 | |||
| 2600 | netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__, | 2603 | netdev_dbg(usbdev->net, "%s(): %s, %d\n", __func__, |
| 2601 | enabled ? "enabled" : "disabled", | 2604 | enabled ? "enabled" : "disabled", |
| 2602 | timeout); | 2605 | timeout); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index aa97971a38af..3b3f1e45ab3e 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
| @@ -652,6 +652,12 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, | |||
| 652 | */ | 652 | */ |
| 653 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | 653 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; |
| 654 | 654 | ||
| 655 | /* | ||
| 656 | * The hardware has already checked the Michael Mic and has | ||
| 657 | * stripped it from the frame. Signal this to mac80211. | ||
| 658 | */ | ||
| 659 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; | ||
| 660 | |||
| 655 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) | 661 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) |
| 656 | rxdesc->flags |= RX_FLAG_DECRYPTED; | 662 | rxdesc->flags |= RX_FLAG_DECRYPTED; |
| 657 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) | 663 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) |
| @@ -1065,6 +1071,8 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | |||
| 1065 | { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1071 | { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
| 1066 | #endif | 1072 | #endif |
| 1067 | #ifdef CONFIG_RT2800PCI_RT35XX | 1073 | #ifdef CONFIG_RT2800PCI_RT35XX |
| 1074 | { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) }, | ||
| 1075 | { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) }, | ||
| 1068 | { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1076 | { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
| 1069 | { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1077 | { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
| 1070 | { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1078 | { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index b97a4a54ff4c..197a36c05fda 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -486,6 +486,12 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
| 486 | */ | 486 | */ |
| 487 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; | 487 | rxdesc->flags |= RX_FLAG_IV_STRIPPED; |
| 488 | 488 | ||
| 489 | /* | ||
| 490 | * The hardware has already checked the Michael Mic and has | ||
| 491 | * stripped it from the frame. Signal this to mac80211. | ||
| 492 | */ | ||
| 493 | rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; | ||
| 494 | |||
| 489 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) | 495 | if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) |
| 490 | rxdesc->flags |= RX_FLAG_DECRYPTED; | 496 | rxdesc->flags |= RX_FLAG_DECRYPTED; |
| 491 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) | 497 | else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 0b4e8590cbb7..029be3c6c030 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
| @@ -2446,6 +2446,7 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
| 2446 | { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, | 2446 | { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2447 | { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, | 2447 | { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2448 | { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, | 2448 | { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2449 | { USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
| 2449 | /* Qcom */ | 2450 | /* Qcom */ |
| 2450 | { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, | 2451 | { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) }, |
| 2451 | { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, | 2452 | { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index b8433f3a9bc2..62876cd5c41a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
| @@ -726,9 +726,9 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data) | |||
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | 728 | static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, |
| 729 | u8 efuse_data, u8 offset, int *bcontinual, | 729 | u8 efuse_data, u8 offset, int *bcontinual, |
| 730 | u8 *write_state, struct pgpkt_struct target_pkt, | 730 | u8 *write_state, struct pgpkt_struct *target_pkt, |
| 731 | int *repeat_times, int *bresult, u8 word_en) | 731 | int *repeat_times, int *bresult, u8 word_en) |
| 732 | { | 732 | { |
| 733 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 733 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 734 | struct pgpkt_struct tmp_pkt; | 734 | struct pgpkt_struct tmp_pkt; |
| @@ -744,8 +744,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 744 | tmp_pkt.word_en = tmp_header & 0x0F; | 744 | tmp_pkt.word_en = tmp_header & 0x0F; |
| 745 | tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); | 745 | tmp_word_cnts = efuse_calculate_word_cnts(tmp_pkt.word_en); |
| 746 | 746 | ||
| 747 | if (tmp_pkt.offset != target_pkt.offset) { | 747 | if (tmp_pkt.offset != target_pkt->offset) { |
| 748 | efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; | 748 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; |
| 749 | *write_state = PG_STATE_HEADER; | 749 | *write_state = PG_STATE_HEADER; |
| 750 | } else { | 750 | } else { |
| 751 | for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { | 751 | for (tmpindex = 0; tmpindex < (tmp_word_cnts * 2); tmpindex++) { |
| @@ -756,23 +756,23 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 756 | } | 756 | } |
| 757 | 757 | ||
| 758 | if (bdataempty == false) { | 758 | if (bdataempty == false) { |
| 759 | efuse_addr = efuse_addr + (tmp_word_cnts * 2) + 1; | 759 | *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; |
| 760 | *write_state = PG_STATE_HEADER; | 760 | *write_state = PG_STATE_HEADER; |
| 761 | } else { | 761 | } else { |
| 762 | match_word_en = 0x0F; | 762 | match_word_en = 0x0F; |
| 763 | if (!((target_pkt.word_en & BIT(0)) | | 763 | if (!((target_pkt->word_en & BIT(0)) | |
| 764 | (tmp_pkt.word_en & BIT(0)))) | 764 | (tmp_pkt.word_en & BIT(0)))) |
| 765 | match_word_en &= (~BIT(0)); | 765 | match_word_en &= (~BIT(0)); |
| 766 | 766 | ||
| 767 | if (!((target_pkt.word_en & BIT(1)) | | 767 | if (!((target_pkt->word_en & BIT(1)) | |
| 768 | (tmp_pkt.word_en & BIT(1)))) | 768 | (tmp_pkt.word_en & BIT(1)))) |
| 769 | match_word_en &= (~BIT(1)); | 769 | match_word_en &= (~BIT(1)); |
| 770 | 770 | ||
| 771 | if (!((target_pkt.word_en & BIT(2)) | | 771 | if (!((target_pkt->word_en & BIT(2)) | |
| 772 | (tmp_pkt.word_en & BIT(2)))) | 772 | (tmp_pkt.word_en & BIT(2)))) |
| 773 | match_word_en &= (~BIT(2)); | 773 | match_word_en &= (~BIT(2)); |
| 774 | 774 | ||
| 775 | if (!((target_pkt.word_en & BIT(3)) | | 775 | if (!((target_pkt->word_en & BIT(3)) | |
| 776 | (tmp_pkt.word_en & BIT(3)))) | 776 | (tmp_pkt.word_en & BIT(3)))) |
| 777 | match_word_en &= (~BIT(3)); | 777 | match_word_en &= (~BIT(3)); |
| 778 | 778 | ||
| @@ -780,7 +780,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 780 | badworden = efuse_word_enable_data_write( | 780 | badworden = efuse_word_enable_data_write( |
| 781 | hw, *efuse_addr + 1, | 781 | hw, *efuse_addr + 1, |
| 782 | tmp_pkt.word_en, | 782 | tmp_pkt.word_en, |
| 783 | target_pkt.data); | 783 | target_pkt->data); |
| 784 | 784 | ||
| 785 | if (0x0F != (badworden & 0x0F)) { | 785 | if (0x0F != (badworden & 0x0F)) { |
| 786 | u8 reorg_offset = offset; | 786 | u8 reorg_offset = offset; |
| @@ -791,26 +791,26 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 791 | } | 791 | } |
| 792 | 792 | ||
| 793 | tmp_word_en = 0x0F; | 793 | tmp_word_en = 0x0F; |
| 794 | if ((target_pkt.word_en & BIT(0)) ^ | 794 | if ((target_pkt->word_en & BIT(0)) ^ |
| 795 | (match_word_en & BIT(0))) | 795 | (match_word_en & BIT(0))) |
| 796 | tmp_word_en &= (~BIT(0)); | 796 | tmp_word_en &= (~BIT(0)); |
| 797 | 797 | ||
| 798 | if ((target_pkt.word_en & BIT(1)) ^ | 798 | if ((target_pkt->word_en & BIT(1)) ^ |
| 799 | (match_word_en & BIT(1))) | 799 | (match_word_en & BIT(1))) |
| 800 | tmp_word_en &= (~BIT(1)); | 800 | tmp_word_en &= (~BIT(1)); |
| 801 | 801 | ||
| 802 | if ((target_pkt.word_en & BIT(2)) ^ | 802 | if ((target_pkt->word_en & BIT(2)) ^ |
| 803 | (match_word_en & BIT(2))) | 803 | (match_word_en & BIT(2))) |
| 804 | tmp_word_en &= (~BIT(2)); | 804 | tmp_word_en &= (~BIT(2)); |
| 805 | 805 | ||
| 806 | if ((target_pkt.word_en & BIT(3)) ^ | 806 | if ((target_pkt->word_en & BIT(3)) ^ |
| 807 | (match_word_en & BIT(3))) | 807 | (match_word_en & BIT(3))) |
| 808 | tmp_word_en &= (~BIT(3)); | 808 | tmp_word_en &= (~BIT(3)); |
| 809 | 809 | ||
| 810 | if ((tmp_word_en & 0x0F) != 0x0F) { | 810 | if ((tmp_word_en & 0x0F) != 0x0F) { |
| 811 | *efuse_addr = efuse_get_current_size(hw); | 811 | *efuse_addr = efuse_get_current_size(hw); |
| 812 | target_pkt.offset = offset; | 812 | target_pkt->offset = offset; |
| 813 | target_pkt.word_en = tmp_word_en; | 813 | target_pkt->word_en = tmp_word_en; |
| 814 | } else | 814 | } else |
| 815 | *bcontinual = false; | 815 | *bcontinual = false; |
| 816 | *write_state = PG_STATE_HEADER; | 816 | *write_state = PG_STATE_HEADER; |
| @@ -821,8 +821,8 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, | |||
| 821 | } | 821 | } |
| 822 | } else { | 822 | } else { |
| 823 | *efuse_addr += (2 * tmp_word_cnts) + 1; | 823 | *efuse_addr += (2 * tmp_word_cnts) + 1; |
| 824 | target_pkt.offset = offset; | 824 | target_pkt->offset = offset; |
| 825 | target_pkt.word_en = word_en; | 825 | target_pkt->word_en = word_en; |
| 826 | *write_state = PG_STATE_HEADER; | 826 | *write_state = PG_STATE_HEADER; |
| 827 | } | 827 | } |
| 828 | } | 828 | } |
| @@ -938,7 +938,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
| 938 | efuse_write_data_case1(hw, &efuse_addr, | 938 | efuse_write_data_case1(hw, &efuse_addr, |
| 939 | efuse_data, offset, | 939 | efuse_data, offset, |
| 940 | &bcontinual, | 940 | &bcontinual, |
| 941 | &write_state, target_pkt, | 941 | &write_state, &target_pkt, |
| 942 | &repeat_times, &bresult, | 942 | &repeat_times, &bresult, |
| 943 | word_en); | 943 | word_en); |
| 944 | else | 944 | else |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 0fa36aa6701a..1758d4463247 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
| @@ -619,6 +619,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
| 619 | struct sk_buff *uskb = NULL; | 619 | struct sk_buff *uskb = NULL; |
| 620 | u8 *pdata; | 620 | u8 *pdata; |
| 621 | uskb = dev_alloc_skb(skb->len + 128); | 621 | uskb = dev_alloc_skb(skb->len + 128); |
| 622 | if (!uskb) { | ||
| 623 | RT_TRACE(rtlpriv, | ||
| 624 | (COMP_INTR | COMP_RECV), | ||
| 625 | DBG_EMERG, | ||
| 626 | ("can't alloc rx skb\n")); | ||
| 627 | goto done; | ||
| 628 | } | ||
| 622 | memcpy(IEEE80211_SKB_RXCB(uskb), | 629 | memcpy(IEEE80211_SKB_RXCB(uskb), |
| 623 | &rx_status, | 630 | &rx_status, |
| 624 | sizeof(rx_status)); | 631 | sizeof(rx_status)); |
| @@ -641,7 +648,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
| 641 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | 648 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); |
| 642 | if (unlikely(!new_skb)) { | 649 | if (unlikely(!new_skb)) { |
| 643 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), | 650 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), |
| 644 | DBG_DMESG, | 651 | DBG_EMERG, |
| 645 | ("can't alloc skb for rx\n")); | 652 | ("can't alloc skb for rx\n")); |
| 646 | goto done; | 653 | goto done; |
| 647 | } | 654 | } |
| @@ -1066,9 +1073,9 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) | |||
| 1066 | struct sk_buff *skb = | 1073 | struct sk_buff *skb = |
| 1067 | dev_alloc_skb(rtlpci->rxbuffersize); | 1074 | dev_alloc_skb(rtlpci->rxbuffersize); |
| 1068 | u32 bufferaddress; | 1075 | u32 bufferaddress; |
| 1069 | entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; | ||
| 1070 | if (!skb) | 1076 | if (!skb) |
| 1071 | return 0; | 1077 | return 0; |
| 1078 | entry = &rtlpci->rx_ring[rx_queue_idx].desc[i]; | ||
| 1072 | 1079 | ||
| 1073 | /*skb->dev = dev; */ | 1080 | /*skb->dev = dev; */ |
| 1074 | 1081 | ||
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 012e1a4016fe..40372bac9482 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c | |||
| @@ -1039,6 +1039,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, | |||
| 1039 | 1039 | ||
| 1040 | if (changed & BSS_CHANGED_BEACON) { | 1040 | if (changed & BSS_CHANGED_BEACON) { |
| 1041 | beacon = ieee80211_beacon_get(hw, vif); | 1041 | beacon = ieee80211_beacon_get(hw, vif); |
| 1042 | if (!beacon) | ||
| 1043 | goto out_sleep; | ||
| 1044 | |||
| 1042 | ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data, | 1045 | ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data, |
| 1043 | beacon->len); | 1046 | beacon->len); |
| 1044 | 1047 | ||
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 46714910f98c..7145ea543783 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c | |||
| @@ -110,9 +110,8 @@ static void wl1271_spi_reset(struct wl1271 *wl) | |||
| 110 | spi_message_add_tail(&t, &m); | 110 | spi_message_add_tail(&t, &m); |
| 111 | 111 | ||
| 112 | spi_sync(wl_to_spi(wl), &m); | 112 | spi_sync(wl_to_spi(wl), &m); |
| 113 | kfree(cmd); | ||
| 114 | |||
| 115 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); | 113 | wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); |
| 114 | kfree(cmd); | ||
| 116 | } | 115 | } |
| 117 | 116 | ||
| 118 | static void wl1271_spi_init(struct wl1271 *wl) | 117 | static void wl1271_spi_init(struct wl1271 *wl) |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 546de5749824..da1f12120346 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -120,6 +120,9 @@ struct netfront_info { | |||
| 120 | unsigned long rx_pfn_array[NET_RX_RING_SIZE]; | 120 | unsigned long rx_pfn_array[NET_RX_RING_SIZE]; |
| 121 | struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; | 121 | struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; |
| 122 | struct mmu_update rx_mmu[NET_RX_RING_SIZE]; | 122 | struct mmu_update rx_mmu[NET_RX_RING_SIZE]; |
| 123 | |||
| 124 | /* Statistics */ | ||
| 125 | int rx_gso_checksum_fixup; | ||
| 123 | }; | 126 | }; |
| 124 | 127 | ||
| 125 | struct netfront_rx_info { | 128 | struct netfront_rx_info { |
| @@ -770,11 +773,29 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np, | |||
| 770 | return cons; | 773 | return cons; |
| 771 | } | 774 | } |
| 772 | 775 | ||
| 773 | static int skb_checksum_setup(struct sk_buff *skb) | 776 | static int checksum_setup(struct net_device *dev, struct sk_buff *skb) |
| 774 | { | 777 | { |
| 775 | struct iphdr *iph; | 778 | struct iphdr *iph; |
| 776 | unsigned char *th; | 779 | unsigned char *th; |
| 777 | int err = -EPROTO; | 780 | int err = -EPROTO; |
| 781 | int recalculate_partial_csum = 0; | ||
| 782 | |||
| 783 | /* | ||
| 784 | * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy | ||
| 785 | * peers can fail to set NETRXF_csum_blank when sending a GSO | ||
| 786 | * frame. In this case force the SKB to CHECKSUM_PARTIAL and | ||
| 787 | * recalculate the partial checksum. | ||
| 788 | */ | ||
| 789 | if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) { | ||
| 790 | struct netfront_info *np = netdev_priv(dev); | ||
| 791 | np->rx_gso_checksum_fixup++; | ||
| 792 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
| 793 | recalculate_partial_csum = 1; | ||
| 794 | } | ||
| 795 | |||
| 796 | /* A non-CHECKSUM_PARTIAL SKB does not require setup. */ | ||
| 797 | if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
| 798 | return 0; | ||
| 778 | 799 | ||
| 779 | if (skb->protocol != htons(ETH_P_IP)) | 800 | if (skb->protocol != htons(ETH_P_IP)) |
| 780 | goto out; | 801 | goto out; |
| @@ -788,9 +809,23 @@ static int skb_checksum_setup(struct sk_buff *skb) | |||
| 788 | switch (iph->protocol) { | 809 | switch (iph->protocol) { |
| 789 | case IPPROTO_TCP: | 810 | case IPPROTO_TCP: |
| 790 | skb->csum_offset = offsetof(struct tcphdr, check); | 811 | skb->csum_offset = offsetof(struct tcphdr, check); |
| 812 | |||
| 813 | if (recalculate_partial_csum) { | ||
| 814 | struct tcphdr *tcph = (struct tcphdr *)th; | ||
| 815 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
| 816 | skb->len - iph->ihl*4, | ||
| 817 | IPPROTO_TCP, 0); | ||
| 818 | } | ||
| 791 | break; | 819 | break; |
| 792 | case IPPROTO_UDP: | 820 | case IPPROTO_UDP: |
| 793 | skb->csum_offset = offsetof(struct udphdr, check); | 821 | skb->csum_offset = offsetof(struct udphdr, check); |
| 822 | |||
| 823 | if (recalculate_partial_csum) { | ||
| 824 | struct udphdr *udph = (struct udphdr *)th; | ||
| 825 | udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
| 826 | skb->len - iph->ihl*4, | ||
| 827 | IPPROTO_UDP, 0); | ||
| 828 | } | ||
| 794 | break; | 829 | break; |
| 795 | default: | 830 | default: |
| 796 | if (net_ratelimit()) | 831 | if (net_ratelimit()) |
| @@ -829,13 +864,11 @@ static int handle_incoming_queue(struct net_device *dev, | |||
| 829 | /* Ethernet work: Delayed to here as it peeks the header. */ | 864 | /* Ethernet work: Delayed to here as it peeks the header. */ |
| 830 | skb->protocol = eth_type_trans(skb, dev); | 865 | skb->protocol = eth_type_trans(skb, dev); |
| 831 | 866 | ||
| 832 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 867 | if (checksum_setup(dev, skb)) { |
| 833 | if (skb_checksum_setup(skb)) { | 868 | kfree_skb(skb); |
| 834 | kfree_skb(skb); | 869 | packets_dropped++; |
| 835 | packets_dropped++; | 870 | dev->stats.rx_errors++; |
| 836 | dev->stats.rx_errors++; | 871 | continue; |
| 837 | continue; | ||
| 838 | } | ||
| 839 | } | 872 | } |
| 840 | 873 | ||
| 841 | dev->stats.rx_packets++; | 874 | dev->stats.rx_packets++; |
| @@ -1632,12 +1665,59 @@ static void netback_changed(struct xenbus_device *dev, | |||
| 1632 | } | 1665 | } |
| 1633 | } | 1666 | } |
| 1634 | 1667 | ||
| 1668 | static const struct xennet_stat { | ||
| 1669 | char name[ETH_GSTRING_LEN]; | ||
| 1670 | u16 offset; | ||
| 1671 | } xennet_stats[] = { | ||
| 1672 | { | ||
| 1673 | "rx_gso_checksum_fixup", | ||
| 1674 | offsetof(struct netfront_info, rx_gso_checksum_fixup) | ||
| 1675 | }, | ||
| 1676 | }; | ||
| 1677 | |||
| 1678 | static int xennet_get_sset_count(struct net_device *dev, int string_set) | ||
| 1679 | { | ||
| 1680 | switch (string_set) { | ||
| 1681 | case ETH_SS_STATS: | ||
| 1682 | return ARRAY_SIZE(xennet_stats); | ||
| 1683 | default: | ||
| 1684 | return -EINVAL; | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | static void xennet_get_ethtool_stats(struct net_device *dev, | ||
| 1689 | struct ethtool_stats *stats, u64 * data) | ||
| 1690 | { | ||
| 1691 | void *np = netdev_priv(dev); | ||
| 1692 | int i; | ||
| 1693 | |||
| 1694 | for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) | ||
| 1695 | data[i] = *(int *)(np + xennet_stats[i].offset); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data) | ||
| 1699 | { | ||
| 1700 | int i; | ||
| 1701 | |||
| 1702 | switch (stringset) { | ||
| 1703 | case ETH_SS_STATS: | ||
| 1704 | for (i = 0; i < ARRAY_SIZE(xennet_stats); i++) | ||
| 1705 | memcpy(data + i * ETH_GSTRING_LEN, | ||
| 1706 | xennet_stats[i].name, ETH_GSTRING_LEN); | ||
| 1707 | break; | ||
| 1708 | } | ||
| 1709 | } | ||
| 1710 | |||
| 1635 | static const struct ethtool_ops xennet_ethtool_ops = | 1711 | static const struct ethtool_ops xennet_ethtool_ops = |
| 1636 | { | 1712 | { |
| 1637 | .set_tx_csum = ethtool_op_set_tx_csum, | 1713 | .set_tx_csum = ethtool_op_set_tx_csum, |
| 1638 | .set_sg = xennet_set_sg, | 1714 | .set_sg = xennet_set_sg, |
| 1639 | .set_tso = xennet_set_tso, | 1715 | .set_tso = xennet_set_tso, |
| 1640 | .get_link = ethtool_op_get_link, | 1716 | .get_link = ethtool_op_get_link, |
| 1717 | |||
| 1718 | .get_sset_count = xennet_get_sset_count, | ||
| 1719 | .get_ethtool_stats = xennet_get_ethtool_stats, | ||
| 1720 | .get_strings = xennet_get_strings, | ||
| 1641 | }; | 1721 | }; |
| 1642 | 1722 | ||
| 1643 | #ifdef CONFIG_SYSFS | 1723 | #ifdef CONFIG_SYSFS |
