diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/atl1c/atl1c_main.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/atl1c/atl1c_main.c')
-rw-r--r-- | drivers/net/atl1c/atl1c_main.c | 298 |
1 files changed, 196 insertions, 102 deletions
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 1372e9a99f5b..50dc531a02d8 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -21,11 +21,18 @@ | |||
21 | 21 | ||
22 | #include "atl1c.h" | 22 | #include "atl1c.h" |
23 | 23 | ||
24 | #define ATL1C_DRV_VERSION "1.0.0.1-NAPI" | 24 | #define ATL1C_DRV_VERSION "1.0.0.2-NAPI" |
25 | char atl1c_driver_name[] = "atl1c"; | 25 | char atl1c_driver_name[] = "atl1c"; |
26 | char atl1c_driver_version[] = ATL1C_DRV_VERSION; | 26 | char atl1c_driver_version[] = ATL1C_DRV_VERSION; |
27 | #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 | 27 | #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 |
28 | #define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063 | 28 | #define PCI_DEVICE_ID_ATTANSIC_L1C 0x1063 |
29 | #define PCI_DEVICE_ID_ATHEROS_L2C_B 0x2060 /* AR8152 v1.1 Fast 10/100 */ | ||
30 | #define PCI_DEVICE_ID_ATHEROS_L2C_B2 0x2062 /* AR8152 v2.0 Fast 10/100 */ | ||
31 | #define PCI_DEVICE_ID_ATHEROS_L1D 0x1073 /* AR8151 v1.0 Gigabit 1000 */ | ||
32 | |||
33 | #define L2CB_V10 0xc0 | ||
34 | #define L2CB_V11 0xc1 | ||
35 | |||
29 | /* | 36 | /* |
30 | * atl1c_pci_tbl - PCI Device ID Table | 37 | * atl1c_pci_tbl - PCI Device ID Table |
31 | * | 38 | * |
@@ -35,9 +42,12 @@ char atl1c_driver_version[] = ATL1C_DRV_VERSION; | |||
35 | * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, | 42 | * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, |
36 | * Class, Class Mask, private data (not used) } | 43 | * Class, Class Mask, private data (not used) } |
37 | */ | 44 | */ |
38 | static struct pci_device_id atl1c_pci_tbl[] = { | 45 | static DEFINE_PCI_DEVICE_TABLE(atl1c_pci_tbl) = { |
39 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)}, | 46 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1C)}, |
40 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)}, | 47 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2C)}, |
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)}, | ||
50 | {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATHEROS_L1D)}, | ||
41 | /* required last entry */ | 51 | /* required last entry */ |
42 | { 0 } | 52 | { 0 } |
43 | }; | 53 | }; |
@@ -198,27 +208,12 @@ static void atl1c_phy_config(unsigned long data) | |||
198 | 208 | ||
199 | void atl1c_reinit_locked(struct atl1c_adapter *adapter) | 209 | void atl1c_reinit_locked(struct atl1c_adapter *adapter) |
200 | { | 210 | { |
201 | |||
202 | WARN_ON(in_interrupt()); | 211 | WARN_ON(in_interrupt()); |
203 | atl1c_down(adapter); | 212 | atl1c_down(adapter); |
204 | atl1c_up(adapter); | 213 | atl1c_up(adapter); |
205 | clear_bit(__AT_RESETTING, &adapter->flags); | 214 | clear_bit(__AT_RESETTING, &adapter->flags); |
206 | } | 215 | } |
207 | 216 | ||
208 | static void atl1c_reset_task(struct work_struct *work) | ||
209 | { | ||
210 | struct atl1c_adapter *adapter; | ||
211 | struct net_device *netdev; | ||
212 | |||
213 | adapter = container_of(work, struct atl1c_adapter, reset_task); | ||
214 | netdev = adapter->netdev; | ||
215 | |||
216 | netif_device_detach(netdev); | ||
217 | atl1c_down(adapter); | ||
218 | atl1c_up(adapter); | ||
219 | netif_device_attach(netdev); | ||
220 | } | ||
221 | |||
222 | static void atl1c_check_link_status(struct atl1c_adapter *adapter) | 217 | static void atl1c_check_link_status(struct atl1c_adapter *adapter) |
223 | { | 218 | { |
224 | struct atl1c_hw *hw = &adapter->hw; | 219 | struct atl1c_hw *hw = &adapter->hw; |
@@ -275,18 +270,6 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) | |||
275 | } | 270 | } |
276 | } | 271 | } |
277 | 272 | ||
278 | /* | ||
279 | * atl1c_link_chg_task - deal with link change event Out of interrupt context | ||
280 | * @netdev: network interface device structure | ||
281 | */ | ||
282 | static void atl1c_link_chg_task(struct work_struct *work) | ||
283 | { | ||
284 | struct atl1c_adapter *adapter; | ||
285 | |||
286 | adapter = container_of(work, struct atl1c_adapter, link_chg_task); | ||
287 | atl1c_check_link_status(adapter); | ||
288 | } | ||
289 | |||
290 | static void atl1c_link_chg_event(struct atl1c_adapter *adapter) | 273 | static void atl1c_link_chg_event(struct atl1c_adapter *adapter) |
291 | { | 274 | { |
292 | struct net_device *netdev = adapter->netdev; | 275 | struct net_device *netdev = adapter->netdev; |
@@ -311,20 +294,40 @@ static void atl1c_link_chg_event(struct atl1c_adapter *adapter) | |||
311 | adapter->link_speed = SPEED_0; | 294 | adapter->link_speed = SPEED_0; |
312 | } | 295 | } |
313 | } | 296 | } |
314 | schedule_work(&adapter->link_chg_task); | 297 | |
298 | adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE; | ||
299 | schedule_work(&adapter->common_task); | ||
315 | } | 300 | } |
316 | 301 | ||
317 | static void atl1c_del_timer(struct atl1c_adapter *adapter) | 302 | static void atl1c_common_task(struct work_struct *work) |
318 | { | 303 | { |
319 | del_timer_sync(&adapter->phy_config_timer); | 304 | struct atl1c_adapter *adapter; |
305 | struct net_device *netdev; | ||
306 | |||
307 | adapter = container_of(work, struct atl1c_adapter, common_task); | ||
308 | netdev = adapter->netdev; | ||
309 | |||
310 | if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { | ||
311 | netif_device_detach(netdev); | ||
312 | atl1c_down(adapter); | ||
313 | atl1c_up(adapter); | ||
314 | netif_device_attach(netdev); | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) | ||
319 | atl1c_check_link_status(adapter); | ||
320 | |||
321 | return; | ||
320 | } | 322 | } |
321 | 323 | ||
322 | static void atl1c_cancel_work(struct atl1c_adapter *adapter) | 324 | |
325 | static void atl1c_del_timer(struct atl1c_adapter *adapter) | ||
323 | { | 326 | { |
324 | cancel_work_sync(&adapter->reset_task); | 327 | del_timer_sync(&adapter->phy_config_timer); |
325 | cancel_work_sync(&adapter->link_chg_task); | ||
326 | } | 328 | } |
327 | 329 | ||
330 | |||
328 | /* | 331 | /* |
329 | * atl1c_tx_timeout - Respond to a Tx Hang | 332 | * atl1c_tx_timeout - Respond to a Tx Hang |
330 | * @netdev: network interface device structure | 333 | * @netdev: network interface device structure |
@@ -334,7 +337,8 @@ static void atl1c_tx_timeout(struct net_device *netdev) | |||
334 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 337 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
335 | 338 | ||
336 | /* Do the reset outside of interrupt context */ | 339 | /* Do the reset outside of interrupt context */ |
337 | schedule_work(&adapter->reset_task); | 340 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; |
341 | schedule_work(&adapter->common_task); | ||
338 | } | 342 | } |
339 | 343 | ||
340 | /* | 344 | /* |
@@ -373,7 +377,7 @@ static void atl1c_set_multi(struct net_device *netdev) | |||
373 | AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); | 377 | AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); |
374 | 378 | ||
375 | /* comoute mc addresses' hash value ,and put it into hash table */ | 379 | /* comoute mc addresses' hash value ,and put it into hash table */ |
376 | for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { | 380 | netdev_for_each_mc_addr(mc_ptr, netdev) { |
377 | hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr); | 381 | hash_value = atl1c_hash_mc_addr(hw, mc_ptr->dmi_addr); |
378 | atl1c_hash_set(hw, hash_value); | 382 | atl1c_hash_set(hw, hash_value); |
379 | } | 383 | } |
@@ -599,11 +603,18 @@ static void atl1c_set_mac_type(struct atl1c_hw *hw) | |||
599 | case PCI_DEVICE_ID_ATTANSIC_L2C: | 603 | case PCI_DEVICE_ID_ATTANSIC_L2C: |
600 | hw->nic_type = athr_l2c; | 604 | hw->nic_type = athr_l2c; |
601 | break; | 605 | break; |
602 | |||
603 | case PCI_DEVICE_ID_ATTANSIC_L1C: | 606 | case PCI_DEVICE_ID_ATTANSIC_L1C: |
604 | hw->nic_type = athr_l1c; | 607 | hw->nic_type = athr_l1c; |
605 | break; | 608 | break; |
606 | 609 | case PCI_DEVICE_ID_ATHEROS_L2C_B: | |
610 | hw->nic_type = athr_l2c_b; | ||
611 | break; | ||
612 | case PCI_DEVICE_ID_ATHEROS_L2C_B2: | ||
613 | hw->nic_type = athr_l2c_b2; | ||
614 | break; | ||
615 | case PCI_DEVICE_ID_ATHEROS_L1D: | ||
616 | hw->nic_type = athr_l1d; | ||
617 | break; | ||
607 | default: | 618 | default: |
608 | break; | 619 | break; |
609 | } | 620 | } |
@@ -626,10 +637,13 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) | |||
626 | hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT; | 637 | hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT; |
627 | if (link_ctrl_data & LINK_CTRL_L1_EN) | 638 | if (link_ctrl_data & LINK_CTRL_L1_EN) |
628 | hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT; | 639 | hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT; |
640 | if (link_ctrl_data & LINK_CTRL_EXT_SYNC) | ||
641 | hw->ctrl_flags |= ATL1C_LINK_EXT_SYNC; | ||
629 | 642 | ||
630 | if (hw->nic_type == athr_l1c) { | 643 | if (hw->nic_type == athr_l1c || |
644 | hw->nic_type == athr_l1d) { | ||
631 | hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON; | 645 | hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON; |
632 | hw->ctrl_flags |= ATL1C_LINK_CAP_1000M; | 646 | hw->link_cap_flags |= ATL1C_LINK_CAP_1000M; |
633 | } | 647 | } |
634 | return 0; | 648 | return 0; |
635 | } | 649 | } |
@@ -710,6 +724,35 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) | |||
710 | return 0; | 724 | return 0; |
711 | } | 725 | } |
712 | 726 | ||
727 | static inline void atl1c_clean_buffer(struct pci_dev *pdev, | ||
728 | struct atl1c_buffer *buffer_info, int in_irq) | ||
729 | { | ||
730 | u16 pci_driection; | ||
731 | if (buffer_info->flags & ATL1C_BUFFER_FREE) | ||
732 | return; | ||
733 | if (buffer_info->dma) { | ||
734 | if (buffer_info->flags & ATL1C_PCIMAP_FROMDEVICE) | ||
735 | pci_driection = PCI_DMA_FROMDEVICE; | ||
736 | else | ||
737 | pci_driection = PCI_DMA_TODEVICE; | ||
738 | |||
739 | if (buffer_info->flags & ATL1C_PCIMAP_SINGLE) | ||
740 | pci_unmap_single(pdev, buffer_info->dma, | ||
741 | buffer_info->length, pci_driection); | ||
742 | else if (buffer_info->flags & ATL1C_PCIMAP_PAGE) | ||
743 | pci_unmap_page(pdev, buffer_info->dma, | ||
744 | buffer_info->length, pci_driection); | ||
745 | } | ||
746 | if (buffer_info->skb) { | ||
747 | if (in_irq) | ||
748 | dev_kfree_skb_irq(buffer_info->skb); | ||
749 | else | ||
750 | dev_kfree_skb(buffer_info->skb); | ||
751 | } | ||
752 | buffer_info->dma = 0; | ||
753 | buffer_info->skb = NULL; | ||
754 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); | ||
755 | } | ||
713 | /* | 756 | /* |
714 | * atl1c_clean_tx_ring - Free Tx-skb | 757 | * atl1c_clean_tx_ring - Free Tx-skb |
715 | * @adapter: board private structure | 758 | * @adapter: board private structure |
@@ -725,22 +768,12 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter, | |||
725 | ring_count = tpd_ring->count; | 768 | ring_count = tpd_ring->count; |
726 | for (index = 0; index < ring_count; index++) { | 769 | for (index = 0; index < ring_count; index++) { |
727 | buffer_info = &tpd_ring->buffer_info[index]; | 770 | buffer_info = &tpd_ring->buffer_info[index]; |
728 | if (buffer_info->state == ATL1_BUFFER_FREE) | 771 | atl1c_clean_buffer(pdev, buffer_info, 0); |
729 | continue; | ||
730 | if (buffer_info->dma) | ||
731 | pci_unmap_single(pdev, buffer_info->dma, | ||
732 | buffer_info->length, | ||
733 | PCI_DMA_TODEVICE); | ||
734 | if (buffer_info->skb) | ||
735 | dev_kfree_skb(buffer_info->skb); | ||
736 | buffer_info->dma = 0; | ||
737 | buffer_info->skb = NULL; | ||
738 | buffer_info->state = ATL1_BUFFER_FREE; | ||
739 | } | 772 | } |
740 | 773 | ||
741 | /* Zero out Tx-buffers */ | 774 | /* Zero out Tx-buffers */ |
742 | memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) * | 775 | memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) * |
743 | ring_count); | 776 | ring_count); |
744 | atomic_set(&tpd_ring->next_to_clean, 0); | 777 | atomic_set(&tpd_ring->next_to_clean, 0); |
745 | tpd_ring->next_to_use = 0; | 778 | tpd_ring->next_to_use = 0; |
746 | } | 779 | } |
@@ -760,16 +793,7 @@ static void atl1c_clean_rx_ring(struct atl1c_adapter *adapter) | |||
760 | for (i = 0; i < adapter->num_rx_queues; i++) { | 793 | for (i = 0; i < adapter->num_rx_queues; i++) { |
761 | for (j = 0; j < rfd_ring[i].count; j++) { | 794 | for (j = 0; j < rfd_ring[i].count; j++) { |
762 | buffer_info = &rfd_ring[i].buffer_info[j]; | 795 | buffer_info = &rfd_ring[i].buffer_info[j]; |
763 | if (buffer_info->state == ATL1_BUFFER_FREE) | 796 | atl1c_clean_buffer(pdev, buffer_info, 0); |
764 | continue; | ||
765 | if (buffer_info->dma) | ||
766 | pci_unmap_single(pdev, buffer_info->dma, | ||
767 | buffer_info->length, | ||
768 | PCI_DMA_FROMDEVICE); | ||
769 | if (buffer_info->skb) | ||
770 | dev_kfree_skb(buffer_info->skb); | ||
771 | buffer_info->state = ATL1_BUFFER_FREE; | ||
772 | buffer_info->skb = NULL; | ||
773 | } | 797 | } |
774 | /* zero out the descriptor ring */ | 798 | /* zero out the descriptor ring */ |
775 | memset(rfd_ring[i].desc, 0, rfd_ring[i].size); | 799 | memset(rfd_ring[i].desc, 0, rfd_ring[i].size); |
@@ -796,7 +820,8 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) | |||
796 | atomic_set(&tpd_ring[i].next_to_clean, 0); | 820 | atomic_set(&tpd_ring[i].next_to_clean, 0); |
797 | buffer_info = tpd_ring[i].buffer_info; | 821 | buffer_info = tpd_ring[i].buffer_info; |
798 | for (j = 0; j < tpd_ring->count; j++) | 822 | for (j = 0; j < tpd_ring->count; j++) |
799 | buffer_info[i].state = ATL1_BUFFER_FREE; | 823 | ATL1C_SET_BUFFER_STATE(&buffer_info[i], |
824 | ATL1C_BUFFER_FREE); | ||
800 | } | 825 | } |
801 | for (i = 0; i < adapter->num_rx_queues; i++) { | 826 | for (i = 0; i < adapter->num_rx_queues; i++) { |
802 | rfd_ring[i].next_to_use = 0; | 827 | rfd_ring[i].next_to_use = 0; |
@@ -805,7 +830,7 @@ static void atl1c_init_ring_ptrs(struct atl1c_adapter *adapter) | |||
805 | rrd_ring[i].next_to_clean = 0; | 830 | rrd_ring[i].next_to_clean = 0; |
806 | for (j = 0; j < rfd_ring[i].count; j++) { | 831 | for (j = 0; j < rfd_ring[i].count; j++) { |
807 | buffer_info = &rfd_ring[i].buffer_info[j]; | 832 | buffer_info = &rfd_ring[i].buffer_info[j]; |
808 | buffer_info->state = ATL1_BUFFER_FREE; | 833 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_FREE); |
809 | } | 834 | } |
810 | } | 835 | } |
811 | } | 836 | } |
@@ -1229,21 +1254,92 @@ static void atl1c_disable_l0s_l1(struct atl1c_hw *hw) | |||
1229 | static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) | 1254 | static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) |
1230 | { | 1255 | { |
1231 | u32 pm_ctrl_data; | 1256 | u32 pm_ctrl_data; |
1257 | u32 link_ctrl_data; | ||
1232 | 1258 | ||
1233 | AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); | 1259 | AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); |
1234 | 1260 | AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); | |
1235 | pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1; | 1261 | pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1; |
1262 | |||
1236 | pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << | 1263 | pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << |
1237 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); | 1264 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); |
1265 | pm_ctrl_data &= ~(PM_CTRL_LCKDET_TIMER_MASK << | ||
1266 | PM_CTRL_LCKDET_TIMER_SHIFT); | ||
1238 | 1267 | ||
1239 | pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK; | 1268 | pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK; |
1269 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; | ||
1270 | pm_ctrl_data |= PM_CTRL_RBER_EN; | ||
1271 | pm_ctrl_data |= PM_CTRL_SDES_EN; | ||
1272 | |||
1273 | if (hw->nic_type == athr_l2c_b || | ||
1274 | hw->nic_type == athr_l1d || | ||
1275 | hw->nic_type == athr_l2c_b2) { | ||
1276 | link_ctrl_data &= ~LINK_CTRL_EXT_SYNC; | ||
1277 | if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) { | ||
1278 | if (hw->nic_type == athr_l2c_b && | ||
1279 | hw->revision_id == L2CB_V10) | ||
1280 | link_ctrl_data |= LINK_CTRL_EXT_SYNC; | ||
1281 | } | ||
1282 | |||
1283 | AT_WRITE_REG(hw, REG_LINK_CTRL, link_ctrl_data); | ||
1284 | |||
1285 | pm_ctrl_data |= PM_CTRL_PCIE_RECV; | ||
1286 | pm_ctrl_data |= AT_ASPM_L1_TIMER << PM_CTRL_PM_REQ_TIMER_SHIFT; | ||
1287 | pm_ctrl_data &= ~PM_CTRL_EN_BUFS_RX_L0S; | ||
1288 | pm_ctrl_data &= ~PM_CTRL_SA_DLY_EN; | ||
1289 | pm_ctrl_data &= ~PM_CTRL_HOTRST; | ||
1290 | pm_ctrl_data |= 1 << PM_CTRL_L1_ENTRY_TIMER_SHIFT; | ||
1291 | pm_ctrl_data |= PM_CTRL_SERDES_PD_EX_L1; | ||
1292 | } | ||
1240 | 1293 | ||
1241 | if (linkup) { | 1294 | if (linkup) { |
1242 | pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN; | 1295 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; |
1243 | pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; | 1296 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; |
1297 | if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) | ||
1298 | pm_ctrl_data |= PM_CTRL_ASPM_L1_EN; | ||
1299 | if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT) | ||
1300 | pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN; | ||
1301 | |||
1302 | if (hw->nic_type == athr_l2c_b || | ||
1303 | hw->nic_type == athr_l1d || | ||
1304 | hw->nic_type == athr_l2c_b2) { | ||
1305 | if (hw->nic_type == athr_l2c_b) | ||
1306 | if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) | ||
1307 | pm_ctrl_data &= PM_CTRL_ASPM_L0S_EN; | ||
1308 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; | ||
1309 | pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; | ||
1310 | pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; | ||
1311 | pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; | ||
1312 | if (hw->adapter->link_speed == SPEED_100 || | ||
1313 | hw->adapter->link_speed == SPEED_1000) { | ||
1314 | pm_ctrl_data &= | ||
1315 | ~(PM_CTRL_L1_ENTRY_TIMER_MASK << | ||
1316 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); | ||
1317 | if (hw->nic_type == athr_l1d) | ||
1318 | pm_ctrl_data |= 0xF << | ||
1319 | PM_CTRL_L1_ENTRY_TIMER_SHIFT; | ||
1320 | else | ||
1321 | pm_ctrl_data |= 7 << | ||
1322 | PM_CTRL_L1_ENTRY_TIMER_SHIFT; | ||
1323 | } | ||
1324 | } else { | ||
1325 | pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; | ||
1326 | pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN; | ||
1327 | pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN; | ||
1328 | pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; | ||
1329 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; | ||
1330 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; | ||
1331 | } | ||
1332 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29); | ||
1333 | if (hw->adapter->link_speed == SPEED_10) | ||
1334 | if (hw->nic_type == athr_l1d) | ||
1335 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0xB69D); | ||
1336 | else | ||
1337 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD); | ||
1338 | else if (hw->adapter->link_speed == SPEED_100) | ||
1339 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB2DD); | ||
1340 | else | ||
1341 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x96DD); | ||
1244 | 1342 | ||
1245 | pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN; | ||
1246 | pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; | ||
1247 | } else { | 1343 | } else { |
1248 | pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; | 1344 | pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; |
1249 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; | 1345 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; |
@@ -1297,6 +1393,10 @@ static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) | |||
1297 | mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; | 1393 | mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; |
1298 | 1394 | ||
1299 | mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN; | 1395 | mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN; |
1396 | if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2) { | ||
1397 | mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW; | ||
1398 | mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32; | ||
1399 | } | ||
1300 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); | 1400 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); |
1301 | } | 1401 | } |
1302 | 1402 | ||
@@ -1447,6 +1547,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, | |||
1447 | struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) | 1547 | struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) |
1448 | &adapter->tpd_ring[type]; | 1548 | &adapter->tpd_ring[type]; |
1449 | struct atl1c_buffer *buffer_info; | 1549 | struct atl1c_buffer *buffer_info; |
1550 | struct pci_dev *pdev = adapter->pdev; | ||
1450 | u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); | 1551 | u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); |
1451 | u16 hw_next_to_clean; | 1552 | u16 hw_next_to_clean; |
1452 | u16 shift; | 1553 | u16 shift; |
@@ -1462,16 +1563,7 @@ static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, | |||
1462 | 1563 | ||
1463 | while (next_to_clean != hw_next_to_clean) { | 1564 | while (next_to_clean != hw_next_to_clean) { |
1464 | buffer_info = &tpd_ring->buffer_info[next_to_clean]; | 1565 | buffer_info = &tpd_ring->buffer_info[next_to_clean]; |
1465 | if (buffer_info->state == ATL1_BUFFER_BUSY) { | 1566 | atl1c_clean_buffer(pdev, buffer_info, 1); |
1466 | pci_unmap_page(adapter->pdev, buffer_info->dma, | ||
1467 | buffer_info->length, PCI_DMA_TODEVICE); | ||
1468 | buffer_info->dma = 0; | ||
1469 | if (buffer_info->skb) { | ||
1470 | dev_kfree_skb_irq(buffer_info->skb); | ||
1471 | buffer_info->skb = NULL; | ||
1472 | } | ||
1473 | buffer_info->state = ATL1_BUFFER_FREE; | ||
1474 | } | ||
1475 | if (++next_to_clean == tpd_ring->count) | 1567 | if (++next_to_clean == tpd_ring->count) |
1476 | next_to_clean = 0; | 1568 | next_to_clean = 0; |
1477 | atomic_set(&tpd_ring->next_to_clean, next_to_clean); | 1569 | atomic_set(&tpd_ring->next_to_clean, next_to_clean); |
@@ -1536,14 +1628,15 @@ static irqreturn_t atl1c_intr(int irq, void *data) | |||
1536 | /* reset MAC */ | 1628 | /* reset MAC */ |
1537 | hw->intr_mask &= ~ISR_ERROR; | 1629 | hw->intr_mask &= ~ISR_ERROR; |
1538 | AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); | 1630 | AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); |
1539 | schedule_work(&adapter->reset_task); | 1631 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; |
1632 | schedule_work(&adapter->common_task); | ||
1540 | break; | 1633 | break; |
1541 | } | 1634 | } |
1542 | 1635 | ||
1543 | if (status & ISR_OVER) | 1636 | if (status & ISR_OVER) |
1544 | if (netif_msg_intr(adapter)) | 1637 | if (netif_msg_intr(adapter)) |
1545 | dev_warn(&pdev->dev, | 1638 | dev_warn(&pdev->dev, |
1546 | "TX/RX over flow (status = 0x%x)\n", | 1639 | "TX/RX overflow (status = 0x%x)\n", |
1547 | status & ISR_OVER); | 1640 | status & ISR_OVER); |
1548 | 1641 | ||
1549 | /* link event */ | 1642 | /* link event */ |
@@ -1587,7 +1680,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid | |||
1587 | buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; | 1680 | buffer_info = &rfd_ring->buffer_info[rfd_next_to_use]; |
1588 | next_info = &rfd_ring->buffer_info[next_next]; | 1681 | next_info = &rfd_ring->buffer_info[next_next]; |
1589 | 1682 | ||
1590 | while (next_info->state == ATL1_BUFFER_FREE) { | 1683 | while (next_info->flags & ATL1C_BUFFER_FREE) { |
1591 | rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); | 1684 | rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use); |
1592 | 1685 | ||
1593 | skb = dev_alloc_skb(adapter->rx_buffer_len); | 1686 | skb = dev_alloc_skb(adapter->rx_buffer_len); |
@@ -1603,12 +1696,14 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid | |||
1603 | * the 14 byte MAC header is removed | 1696 | * the 14 byte MAC header is removed |
1604 | */ | 1697 | */ |
1605 | vir_addr = skb->data; | 1698 | vir_addr = skb->data; |
1606 | buffer_info->state = ATL1_BUFFER_BUSY; | 1699 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); |
1607 | buffer_info->skb = skb; | 1700 | buffer_info->skb = skb; |
1608 | buffer_info->length = adapter->rx_buffer_len; | 1701 | buffer_info->length = adapter->rx_buffer_len; |
1609 | buffer_info->dma = pci_map_single(pdev, vir_addr, | 1702 | buffer_info->dma = pci_map_single(pdev, vir_addr, |
1610 | buffer_info->length, | 1703 | buffer_info->length, |
1611 | PCI_DMA_FROMDEVICE); | 1704 | PCI_DMA_FROMDEVICE); |
1705 | ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE, | ||
1706 | ATL1C_PCIMAP_FROMDEVICE); | ||
1612 | rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); | 1707 | rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma); |
1613 | rfd_next_to_use = next_next; | 1708 | rfd_next_to_use = next_next; |
1614 | if (++next_next == rfd_ring->count) | 1709 | if (++next_next == rfd_ring->count) |
@@ -1653,7 +1748,8 @@ static void atl1c_clean_rfd(struct atl1c_rfd_ring *rfd_ring, | |||
1653 | RRS_RX_RFD_INDEX_MASK; | 1748 | RRS_RX_RFD_INDEX_MASK; |
1654 | for (i = 0; i < num; i++) { | 1749 | for (i = 0; i < num; i++) { |
1655 | buffer_info[rfd_index].skb = NULL; | 1750 | buffer_info[rfd_index].skb = NULL; |
1656 | buffer_info[rfd_index].state = ATL1_BUFFER_FREE; | 1751 | ATL1C_SET_BUFFER_STATE(&buffer_info[rfd_index], |
1752 | ATL1C_BUFFER_FREE); | ||
1657 | if (++rfd_index == rfd_ring->count) | 1753 | if (++rfd_index == rfd_ring->count) |
1658 | rfd_index = 0; | 1754 | rfd_index = 0; |
1659 | } | 1755 | } |
@@ -1967,7 +2063,9 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter, | |||
1967 | buffer_info->length = map_len; | 2063 | buffer_info->length = map_len; |
1968 | buffer_info->dma = pci_map_single(adapter->pdev, | 2064 | buffer_info->dma = pci_map_single(adapter->pdev, |
1969 | skb->data, hdr_len, PCI_DMA_TODEVICE); | 2065 | skb->data, hdr_len, PCI_DMA_TODEVICE); |
1970 | buffer_info->state = ATL1_BUFFER_BUSY; | 2066 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); |
2067 | ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE, | ||
2068 | ATL1C_PCIMAP_TODEVICE); | ||
1971 | mapped_len += map_len; | 2069 | mapped_len += map_len; |
1972 | use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); | 2070 | use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); |
1973 | use_tpd->buffer_len = cpu_to_le16(buffer_info->length); | 2071 | use_tpd->buffer_len = cpu_to_le16(buffer_info->length); |
@@ -1981,16 +2079,15 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter, | |||
1981 | else { | 2079 | else { |
1982 | use_tpd = atl1c_get_tpd(adapter, type); | 2080 | use_tpd = atl1c_get_tpd(adapter, type); |
1983 | memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); | 2081 | memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); |
1984 | use_tpd = atl1c_get_tpd(adapter, type); | ||
1985 | memcpy(use_tpd, tpd, sizeof(struct atl1c_tpd_desc)); | ||
1986 | } | 2082 | } |
1987 | buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); | 2083 | buffer_info = atl1c_get_tx_buffer(adapter, use_tpd); |
1988 | buffer_info->length = buf_len - mapped_len; | 2084 | buffer_info->length = buf_len - mapped_len; |
1989 | buffer_info->dma = | 2085 | buffer_info->dma = |
1990 | pci_map_single(adapter->pdev, skb->data + mapped_len, | 2086 | pci_map_single(adapter->pdev, skb->data + mapped_len, |
1991 | buffer_info->length, PCI_DMA_TODEVICE); | 2087 | buffer_info->length, PCI_DMA_TODEVICE); |
1992 | buffer_info->state = ATL1_BUFFER_BUSY; | 2088 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); |
1993 | 2089 | ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_SINGLE, | |
2090 | ATL1C_PCIMAP_TODEVICE); | ||
1994 | use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); | 2091 | use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); |
1995 | use_tpd->buffer_len = cpu_to_le16(buffer_info->length); | 2092 | use_tpd->buffer_len = cpu_to_le16(buffer_info->length); |
1996 | } | 2093 | } |
@@ -2010,8 +2107,9 @@ static void atl1c_tx_map(struct atl1c_adapter *adapter, | |||
2010 | frag->page_offset, | 2107 | frag->page_offset, |
2011 | buffer_info->length, | 2108 | buffer_info->length, |
2012 | PCI_DMA_TODEVICE); | 2109 | PCI_DMA_TODEVICE); |
2013 | buffer_info->state = ATL1_BUFFER_BUSY; | 2110 | ATL1C_SET_BUFFER_STATE(buffer_info, ATL1C_BUFFER_BUSY); |
2014 | 2111 | ATL1C_SET_PCIMAP_TYPE(buffer_info, ATL1C_PCIMAP_PAGE, | |
2112 | ATL1C_PCIMAP_TODEVICE); | ||
2015 | use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); | 2113 | use_tpd->buffer_addr = cpu_to_le64(buffer_info->dma); |
2016 | use_tpd->buffer_len = cpu_to_le16(buffer_info->length); | 2114 | use_tpd->buffer_len = cpu_to_le16(buffer_info->length); |
2017 | } | 2115 | } |
@@ -2137,7 +2235,7 @@ static int atl1c_request_irq(struct atl1c_adapter *adapter) | |||
2137 | 2235 | ||
2138 | if (!adapter->have_msi) | 2236 | if (!adapter->have_msi) |
2139 | flags |= IRQF_SHARED; | 2237 | flags |= IRQF_SHARED; |
2140 | err = request_irq(adapter->pdev->irq, &atl1c_intr, flags, | 2238 | err = request_irq(adapter->pdev->irq, atl1c_intr, flags, |
2141 | netdev->name, netdev); | 2239 | netdev->name, netdev); |
2142 | if (err) { | 2240 | if (err) { |
2143 | if (netif_msg_ifup(adapter)) | 2241 | if (netif_msg_ifup(adapter)) |
@@ -2200,8 +2298,7 @@ void atl1c_down(struct atl1c_adapter *adapter) | |||
2200 | struct net_device *netdev = adapter->netdev; | 2298 | struct net_device *netdev = adapter->netdev; |
2201 | 2299 | ||
2202 | atl1c_del_timer(adapter); | 2300 | atl1c_del_timer(adapter); |
2203 | atl1c_cancel_work(adapter); | 2301 | adapter->work_event = 0; /* clear all event */ |
2204 | |||
2205 | /* signal that we're down so the interrupt handler does not | 2302 | /* signal that we're down so the interrupt handler does not |
2206 | * reschedule our watchdog timer */ | 2303 | * reschedule our watchdog timer */ |
2207 | set_bit(__AT_DOWN, &adapter->flags); | 2304 | set_bit(__AT_DOWN, &adapter->flags); |
@@ -2594,15 +2691,12 @@ static int __devinit atl1c_probe(struct pci_dev *pdev, | |||
2594 | memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); | 2691 | memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); |
2595 | memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); | 2692 | memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); |
2596 | if (netif_msg_probe(adapter)) | 2693 | if (netif_msg_probe(adapter)) |
2597 | dev_dbg(&pdev->dev, | 2694 | dev_dbg(&pdev->dev, "mac address : %pM\n", |
2598 | "mac address : %02x-%02x-%02x-%02x-%02x-%02x\n", | 2695 | adapter->hw.mac_addr); |
2599 | adapter->hw.mac_addr[0], adapter->hw.mac_addr[1], | ||
2600 | adapter->hw.mac_addr[2], adapter->hw.mac_addr[3], | ||
2601 | adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]); | ||
2602 | 2696 | ||
2603 | atl1c_hw_set_mac_addr(&adapter->hw); | 2697 | atl1c_hw_set_mac_addr(&adapter->hw); |
2604 | INIT_WORK(&adapter->reset_task, atl1c_reset_task); | 2698 | INIT_WORK(&adapter->common_task, atl1c_common_task); |
2605 | INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task); | 2699 | adapter->work_event = 0; |
2606 | err = register_netdev(netdev); | 2700 | err = register_netdev(netdev); |
2607 | if (err) { | 2701 | if (err) { |
2608 | dev_err(&pdev->dev, "register netdevice failed\n"); | 2702 | dev_err(&pdev->dev, "register netdevice failed\n"); |