11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
22b133ad6SJeff Kirsher /*
32b133ad6SJeff Kirsher * Copyright(c) 2007 Atheros Corporation. All rights reserved.
42b133ad6SJeff Kirsher *
52b133ad6SJeff Kirsher * Derived from Intel e1000 driver
62b133ad6SJeff Kirsher * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
72b133ad6SJeff Kirsher */
82b133ad6SJeff Kirsher
92b133ad6SJeff Kirsher #include "atl1e.h"
102b133ad6SJeff Kirsher
112b133ad6SJeff Kirsher char atl1e_driver_name[] = "ATL1E";
122b133ad6SJeff Kirsher #define PCI_DEVICE_ID_ATTANSIC_L1E 0x1026
132b133ad6SJeff Kirsher /*
142b133ad6SJeff Kirsher * atl1e_pci_tbl - PCI Device ID Table
152b133ad6SJeff Kirsher *
162b133ad6SJeff Kirsher * Wildcard entries (PCI_ANY_ID) should come last
172b133ad6SJeff Kirsher * Last entry must be all 0s
182b133ad6SJeff Kirsher *
192b133ad6SJeff Kirsher * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
202b133ad6SJeff Kirsher * Class, Class Mask, private data (not used) }
212b133ad6SJeff Kirsher */
229baa3c34SBenoit Taine static const struct pci_device_id atl1e_pci_tbl[] = {
232b133ad6SJeff Kirsher {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
242b133ad6SJeff Kirsher {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
252b133ad6SJeff Kirsher /* required last entry */
262b133ad6SJeff Kirsher { 0 }
272b133ad6SJeff Kirsher };
282b133ad6SJeff Kirsher MODULE_DEVICE_TABLE(pci, atl1e_pci_tbl);
292b133ad6SJeff Kirsher
302b133ad6SJeff Kirsher MODULE_AUTHOR("Atheros Corporation, <xiong.huang@atheros.com>, Jie Yang <jie.yang@atheros.com>");
312b133ad6SJeff Kirsher MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
322b133ad6SJeff Kirsher MODULE_LICENSE("GPL");
332b133ad6SJeff Kirsher
342b133ad6SJeff Kirsher static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
352b133ad6SJeff Kirsher
362b133ad6SJeff Kirsher static const u16
372b133ad6SJeff Kirsher atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
382b133ad6SJeff Kirsher {
392b133ad6SJeff Kirsher {REG_HOST_RXF0_PAGE0_VLD, REG_HOST_RXF0_PAGE1_VLD},
402b133ad6SJeff Kirsher {REG_HOST_RXF1_PAGE0_VLD, REG_HOST_RXF1_PAGE1_VLD},
412b133ad6SJeff Kirsher {REG_HOST_RXF2_PAGE0_VLD, REG_HOST_RXF2_PAGE1_VLD},
422b133ad6SJeff Kirsher {REG_HOST_RXF3_PAGE0_VLD, REG_HOST_RXF3_PAGE1_VLD}
432b133ad6SJeff Kirsher };
442b133ad6SJeff Kirsher
452b133ad6SJeff Kirsher static const u16 atl1e_rx_page_hi_addr_regs[AT_MAX_RECEIVE_QUEUE] =
462b133ad6SJeff Kirsher {
472b133ad6SJeff Kirsher REG_RXF0_BASE_ADDR_HI,
482b133ad6SJeff Kirsher REG_RXF1_BASE_ADDR_HI,
492b133ad6SJeff Kirsher REG_RXF2_BASE_ADDR_HI,
502b133ad6SJeff Kirsher REG_RXF3_BASE_ADDR_HI
512b133ad6SJeff Kirsher };
522b133ad6SJeff Kirsher
532b133ad6SJeff Kirsher static const u16
542b133ad6SJeff Kirsher atl1e_rx_page_lo_addr_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
552b133ad6SJeff Kirsher {
562b133ad6SJeff Kirsher {REG_HOST_RXF0_PAGE0_LO, REG_HOST_RXF0_PAGE1_LO},
572b133ad6SJeff Kirsher {REG_HOST_RXF1_PAGE0_LO, REG_HOST_RXF1_PAGE1_LO},
582b133ad6SJeff Kirsher {REG_HOST_RXF2_PAGE0_LO, REG_HOST_RXF2_PAGE1_LO},
592b133ad6SJeff Kirsher {REG_HOST_RXF3_PAGE0_LO, REG_HOST_RXF3_PAGE1_LO}
602b133ad6SJeff Kirsher };
612b133ad6SJeff Kirsher
622b133ad6SJeff Kirsher static const u16
632b133ad6SJeff Kirsher atl1e_rx_page_write_offset_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
642b133ad6SJeff Kirsher {
652b133ad6SJeff Kirsher {REG_HOST_RXF0_MB0_LO, REG_HOST_RXF0_MB1_LO},
662b133ad6SJeff Kirsher {REG_HOST_RXF1_MB0_LO, REG_HOST_RXF1_MB1_LO},
672b133ad6SJeff Kirsher {REG_HOST_RXF2_MB0_LO, REG_HOST_RXF2_MB1_LO},
682b133ad6SJeff Kirsher {REG_HOST_RXF3_MB0_LO, REG_HOST_RXF3_MB1_LO}
692b133ad6SJeff Kirsher };
702b133ad6SJeff Kirsher
712b133ad6SJeff Kirsher static const u16 atl1e_pay_load_size[] = {
722b133ad6SJeff Kirsher 128, 256, 512, 1024, 2048, 4096,
732b133ad6SJeff Kirsher };
742b133ad6SJeff Kirsher
7549ce9c2cSBen Hutchings /**
762b133ad6SJeff Kirsher * atl1e_irq_enable - Enable default interrupt generation settings
772b133ad6SJeff Kirsher * @adapter: board private structure
782b133ad6SJeff Kirsher */
atl1e_irq_enable(struct atl1e_adapter * adapter)792b133ad6SJeff Kirsher static inline void atl1e_irq_enable(struct atl1e_adapter *adapter)
802b133ad6SJeff Kirsher {
812b133ad6SJeff Kirsher if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
822b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
832b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK);
842b133ad6SJeff Kirsher AT_WRITE_FLUSH(&adapter->hw);
852b133ad6SJeff Kirsher }
862b133ad6SJeff Kirsher }
872b133ad6SJeff Kirsher
8849ce9c2cSBen Hutchings /**
892b133ad6SJeff Kirsher * atl1e_irq_disable - Mask off interrupt generation on the NIC
902b133ad6SJeff Kirsher * @adapter: board private structure
912b133ad6SJeff Kirsher */
atl1e_irq_disable(struct atl1e_adapter * adapter)922b133ad6SJeff Kirsher static inline void atl1e_irq_disable(struct atl1e_adapter *adapter)
932b133ad6SJeff Kirsher {
942b133ad6SJeff Kirsher atomic_inc(&adapter->irq_sem);
952b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
962b133ad6SJeff Kirsher AT_WRITE_FLUSH(&adapter->hw);
972b133ad6SJeff Kirsher synchronize_irq(adapter->pdev->irq);
982b133ad6SJeff Kirsher }
992b133ad6SJeff Kirsher
10049ce9c2cSBen Hutchings /**
1012b133ad6SJeff Kirsher * atl1e_irq_reset - reset interrupt confiure on the NIC
1022b133ad6SJeff Kirsher * @adapter: board private structure
1032b133ad6SJeff Kirsher */
atl1e_irq_reset(struct atl1e_adapter * adapter)1042b133ad6SJeff Kirsher static inline void atl1e_irq_reset(struct atl1e_adapter *adapter)
1052b133ad6SJeff Kirsher {
1062b133ad6SJeff Kirsher atomic_set(&adapter->irq_sem, 0);
1072b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
1082b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_IMR, 0);
1092b133ad6SJeff Kirsher AT_WRITE_FLUSH(&adapter->hw);
1102b133ad6SJeff Kirsher }
1112b133ad6SJeff Kirsher
11249ce9c2cSBen Hutchings /**
1132b133ad6SJeff Kirsher * atl1e_phy_config - Timer Call-back
114d0ea5cbdSJesse Brandeburg * @t: timer list containing pointer to netdev cast into an unsigned long
1152b133ad6SJeff Kirsher */
atl1e_phy_config(struct timer_list * t)116e99e88a9SKees Cook static void atl1e_phy_config(struct timer_list *t)
1172b133ad6SJeff Kirsher {
118e99e88a9SKees Cook struct atl1e_adapter *adapter = from_timer(adapter, t,
119e99e88a9SKees Cook phy_config_timer);
1202b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
1212b133ad6SJeff Kirsher unsigned long flags;
1222b133ad6SJeff Kirsher
1232b133ad6SJeff Kirsher spin_lock_irqsave(&adapter->mdio_lock, flags);
1242b133ad6SJeff Kirsher atl1e_restart_autoneg(hw);
1252b133ad6SJeff Kirsher spin_unlock_irqrestore(&adapter->mdio_lock, flags);
1262b133ad6SJeff Kirsher }
1272b133ad6SJeff Kirsher
atl1e_reinit_locked(struct atl1e_adapter * adapter)1282b133ad6SJeff Kirsher void atl1e_reinit_locked(struct atl1e_adapter *adapter)
1292b133ad6SJeff Kirsher {
1302b133ad6SJeff Kirsher while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
1312b133ad6SJeff Kirsher msleep(1);
1322b133ad6SJeff Kirsher atl1e_down(adapter);
1332b133ad6SJeff Kirsher atl1e_up(adapter);
1342b133ad6SJeff Kirsher clear_bit(__AT_RESETTING, &adapter->flags);
1352b133ad6SJeff Kirsher }
1362b133ad6SJeff Kirsher
atl1e_reset_task(struct work_struct * work)1372b133ad6SJeff Kirsher static void atl1e_reset_task(struct work_struct *work)
1382b133ad6SJeff Kirsher {
1392b133ad6SJeff Kirsher struct atl1e_adapter *adapter;
1402b133ad6SJeff Kirsher adapter = container_of(work, struct atl1e_adapter, reset_task);
1412b133ad6SJeff Kirsher
1422b133ad6SJeff Kirsher atl1e_reinit_locked(adapter);
1432b133ad6SJeff Kirsher }
1442b133ad6SJeff Kirsher
atl1e_check_link(struct atl1e_adapter * adapter)1452b133ad6SJeff Kirsher static int atl1e_check_link(struct atl1e_adapter *adapter)
1462b133ad6SJeff Kirsher {
1472b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
1482b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
1492b133ad6SJeff Kirsher int err = 0;
1502b133ad6SJeff Kirsher u16 speed, duplex, phy_data;
1512b133ad6SJeff Kirsher
1522b133ad6SJeff Kirsher /* MII_BMSR must read twice */
1532b133ad6SJeff Kirsher atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
1542b133ad6SJeff Kirsher atl1e_read_phy_reg(hw, MII_BMSR, &phy_data);
1552b133ad6SJeff Kirsher if ((phy_data & BMSR_LSTATUS) == 0) {
1562b133ad6SJeff Kirsher /* link down */
1572b133ad6SJeff Kirsher if (netif_carrier_ok(netdev)) { /* old link state: Up */
1582b133ad6SJeff Kirsher u32 value;
1592b133ad6SJeff Kirsher /* disable rx */
1602b133ad6SJeff Kirsher value = AT_READ_REG(hw, REG_MAC_CTRL);
1612b133ad6SJeff Kirsher value &= ~MAC_CTRL_RX_EN;
1622b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_MAC_CTRL, value);
1632b133ad6SJeff Kirsher adapter->link_speed = SPEED_0;
1642b133ad6SJeff Kirsher netif_carrier_off(netdev);
1652b133ad6SJeff Kirsher netif_stop_queue(netdev);
1662b133ad6SJeff Kirsher }
1672b133ad6SJeff Kirsher } else {
1682b133ad6SJeff Kirsher /* Link Up */
1692b133ad6SJeff Kirsher err = atl1e_get_speed_and_duplex(hw, &speed, &duplex);
1702b133ad6SJeff Kirsher if (unlikely(err))
1712b133ad6SJeff Kirsher return err;
1722b133ad6SJeff Kirsher
1732b133ad6SJeff Kirsher /* link result is our setting */
1742b133ad6SJeff Kirsher if (adapter->link_speed != speed ||
1752b133ad6SJeff Kirsher adapter->link_duplex != duplex) {
1762b133ad6SJeff Kirsher adapter->link_speed = speed;
1772b133ad6SJeff Kirsher adapter->link_duplex = duplex;
1782b133ad6SJeff Kirsher atl1e_setup_mac_ctrl(adapter);
1792b133ad6SJeff Kirsher netdev_info(netdev,
1802b133ad6SJeff Kirsher "NIC Link is Up <%d Mbps %s Duplex>\n",
1812b133ad6SJeff Kirsher adapter->link_speed,
1822b133ad6SJeff Kirsher adapter->link_duplex == FULL_DUPLEX ?
1832b133ad6SJeff Kirsher "Full" : "Half");
1842b133ad6SJeff Kirsher }
1852b133ad6SJeff Kirsher
1862b133ad6SJeff Kirsher if (!netif_carrier_ok(netdev)) {
1872b133ad6SJeff Kirsher /* Link down -> Up */
1882b133ad6SJeff Kirsher netif_carrier_on(netdev);
1892b133ad6SJeff Kirsher netif_wake_queue(netdev);
1902b133ad6SJeff Kirsher }
1912b133ad6SJeff Kirsher }
1922b133ad6SJeff Kirsher return 0;
1932b133ad6SJeff Kirsher }
1942b133ad6SJeff Kirsher
19549ce9c2cSBen Hutchings /**
1962b133ad6SJeff Kirsher * atl1e_link_chg_task - deal with link change event Out of interrupt context
197d0ea5cbdSJesse Brandeburg * @work: work struct with driver info
1982b133ad6SJeff Kirsher */
atl1e_link_chg_task(struct work_struct * work)1992b133ad6SJeff Kirsher static void atl1e_link_chg_task(struct work_struct *work)
2002b133ad6SJeff Kirsher {
2012b133ad6SJeff Kirsher struct atl1e_adapter *adapter;
2022b133ad6SJeff Kirsher unsigned long flags;
2032b133ad6SJeff Kirsher
2042b133ad6SJeff Kirsher adapter = container_of(work, struct atl1e_adapter, link_chg_task);
2052b133ad6SJeff Kirsher spin_lock_irqsave(&adapter->mdio_lock, flags);
2062b133ad6SJeff Kirsher atl1e_check_link(adapter);
2072b133ad6SJeff Kirsher spin_unlock_irqrestore(&adapter->mdio_lock, flags);
2082b133ad6SJeff Kirsher }
2092b133ad6SJeff Kirsher
atl1e_link_chg_event(struct atl1e_adapter * adapter)2102b133ad6SJeff Kirsher static void atl1e_link_chg_event(struct atl1e_adapter *adapter)
2112b133ad6SJeff Kirsher {
2122b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
2132b133ad6SJeff Kirsher u16 phy_data = 0;
2142b133ad6SJeff Kirsher u16 link_up = 0;
2152b133ad6SJeff Kirsher
2162b133ad6SJeff Kirsher spin_lock(&adapter->mdio_lock);
2172b133ad6SJeff Kirsher atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
2182b133ad6SJeff Kirsher atl1e_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
2192b133ad6SJeff Kirsher spin_unlock(&adapter->mdio_lock);
2202b133ad6SJeff Kirsher link_up = phy_data & BMSR_LSTATUS;
2212b133ad6SJeff Kirsher /* notify upper layer link down ASAP */
2222b133ad6SJeff Kirsher if (!link_up) {
2232b133ad6SJeff Kirsher if (netif_carrier_ok(netdev)) {
2242b133ad6SJeff Kirsher /* old link state: Up */
2252b133ad6SJeff Kirsher netdev_info(netdev, "NIC Link is Down\n");
2262b133ad6SJeff Kirsher adapter->link_speed = SPEED_0;
2272b133ad6SJeff Kirsher netif_stop_queue(netdev);
2282b133ad6SJeff Kirsher }
2292b133ad6SJeff Kirsher }
2302b133ad6SJeff Kirsher schedule_work(&adapter->link_chg_task);
2312b133ad6SJeff Kirsher }
2322b133ad6SJeff Kirsher
atl1e_del_timer(struct atl1e_adapter * adapter)2332b133ad6SJeff Kirsher static void atl1e_del_timer(struct atl1e_adapter *adapter)
2342b133ad6SJeff Kirsher {
2352b133ad6SJeff Kirsher del_timer_sync(&adapter->phy_config_timer);
2362b133ad6SJeff Kirsher }
2372b133ad6SJeff Kirsher
atl1e_cancel_work(struct atl1e_adapter * adapter)2382b133ad6SJeff Kirsher static void atl1e_cancel_work(struct atl1e_adapter *adapter)
2392b133ad6SJeff Kirsher {
2402b133ad6SJeff Kirsher cancel_work_sync(&adapter->reset_task);
2412b133ad6SJeff Kirsher cancel_work_sync(&adapter->link_chg_task);
2422b133ad6SJeff Kirsher }
2432b133ad6SJeff Kirsher
24449ce9c2cSBen Hutchings /**
2452b133ad6SJeff Kirsher * atl1e_tx_timeout - Respond to a Tx Hang
2462b133ad6SJeff Kirsher * @netdev: network interface device structure
247d0ea5cbdSJesse Brandeburg * @txqueue: the index of the hanging queue
2482b133ad6SJeff Kirsher */
atl1e_tx_timeout(struct net_device * netdev,unsigned int txqueue)2490290bd29SMichael S. Tsirkin static void atl1e_tx_timeout(struct net_device *netdev, unsigned int txqueue)
2502b133ad6SJeff Kirsher {
2512b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
2522b133ad6SJeff Kirsher
2532b133ad6SJeff Kirsher /* Do the reset outside of interrupt context */
2542b133ad6SJeff Kirsher schedule_work(&adapter->reset_task);
2552b133ad6SJeff Kirsher }
2562b133ad6SJeff Kirsher
25749ce9c2cSBen Hutchings /**
2582b133ad6SJeff Kirsher * atl1e_set_multi - Multicast and Promiscuous mode set
2592b133ad6SJeff Kirsher * @netdev: network interface device structure
2602b133ad6SJeff Kirsher *
2612b133ad6SJeff Kirsher * The set_multi entry point is called whenever the multicast address
2622b133ad6SJeff Kirsher * list or the network interface flags are updated. This routine is
2632b133ad6SJeff Kirsher * responsible for configuring the hardware for proper multicast,
2642b133ad6SJeff Kirsher * promiscuous mode, and all-multi behavior.
2652b133ad6SJeff Kirsher */
atl1e_set_multi(struct net_device * netdev)2662b133ad6SJeff Kirsher static void atl1e_set_multi(struct net_device *netdev)
2672b133ad6SJeff Kirsher {
2682b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
2692b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
2702b133ad6SJeff Kirsher struct netdev_hw_addr *ha;
2712b133ad6SJeff Kirsher u32 mac_ctrl_data = 0;
2722b133ad6SJeff Kirsher u32 hash_value;
2732b133ad6SJeff Kirsher
2742b133ad6SJeff Kirsher /* Check for Promiscuous and All Multicast modes */
2752b133ad6SJeff Kirsher mac_ctrl_data = AT_READ_REG(hw, REG_MAC_CTRL);
2762b133ad6SJeff Kirsher
2772b133ad6SJeff Kirsher if (netdev->flags & IFF_PROMISC) {
2782b133ad6SJeff Kirsher mac_ctrl_data |= MAC_CTRL_PROMIS_EN;
2792b133ad6SJeff Kirsher } else if (netdev->flags & IFF_ALLMULTI) {
2802b133ad6SJeff Kirsher mac_ctrl_data |= MAC_CTRL_MC_ALL_EN;
2812b133ad6SJeff Kirsher mac_ctrl_data &= ~MAC_CTRL_PROMIS_EN;
2822b133ad6SJeff Kirsher } else {
2832b133ad6SJeff Kirsher mac_ctrl_data &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
2842b133ad6SJeff Kirsher }
2852b133ad6SJeff Kirsher
2862b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
2872b133ad6SJeff Kirsher
2882b133ad6SJeff Kirsher /* clear the old settings from the multicast hash table */
2892b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0);
2902b133ad6SJeff Kirsher AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0);
2912b133ad6SJeff Kirsher
2922b133ad6SJeff Kirsher /* comoute mc addresses' hash value ,and put it into hash table */
2932b133ad6SJeff Kirsher netdev_for_each_mc_addr(ha, netdev) {
2942b133ad6SJeff Kirsher hash_value = atl1e_hash_mc_addr(hw, ha->addr);
2952b133ad6SJeff Kirsher atl1e_hash_set(hw, hash_value);
2962b133ad6SJeff Kirsher }
2972b133ad6SJeff Kirsher }
2982b133ad6SJeff Kirsher
__atl1e_rx_mode(netdev_features_t features,u32 * mac_ctrl_data)29940dc9ab2SAndrea Merello static void __atl1e_rx_mode(netdev_features_t features, u32 *mac_ctrl_data)
30040dc9ab2SAndrea Merello {
30140dc9ab2SAndrea Merello
30240dc9ab2SAndrea Merello if (features & NETIF_F_RXALL) {
30340dc9ab2SAndrea Merello /* enable RX of ALL frames */
30440dc9ab2SAndrea Merello *mac_ctrl_data |= MAC_CTRL_DBG;
30540dc9ab2SAndrea Merello } else {
30640dc9ab2SAndrea Merello /* disable RX of ALL frames */
30740dc9ab2SAndrea Merello *mac_ctrl_data &= ~MAC_CTRL_DBG;
30840dc9ab2SAndrea Merello }
30940dc9ab2SAndrea Merello }
31040dc9ab2SAndrea Merello
atl1e_rx_mode(struct net_device * netdev,netdev_features_t features)31140dc9ab2SAndrea Merello static void atl1e_rx_mode(struct net_device *netdev,
31240dc9ab2SAndrea Merello netdev_features_t features)
31340dc9ab2SAndrea Merello {
31440dc9ab2SAndrea Merello struct atl1e_adapter *adapter = netdev_priv(netdev);
31540dc9ab2SAndrea Merello u32 mac_ctrl_data = 0;
31640dc9ab2SAndrea Merello
31740dc9ab2SAndrea Merello netdev_dbg(adapter->netdev, "%s\n", __func__);
31840dc9ab2SAndrea Merello
31940dc9ab2SAndrea Merello atl1e_irq_disable(adapter);
32040dc9ab2SAndrea Merello mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
32140dc9ab2SAndrea Merello __atl1e_rx_mode(features, &mac_ctrl_data);
32240dc9ab2SAndrea Merello AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
32340dc9ab2SAndrea Merello atl1e_irq_enable(adapter);
32440dc9ab2SAndrea Merello }
32540dc9ab2SAndrea Merello
32640dc9ab2SAndrea Merello
__atl1e_vlan_mode(netdev_features_t features,u32 * mac_ctrl_data)327c8f44affSMichał Mirosław static void __atl1e_vlan_mode(netdev_features_t features, u32 *mac_ctrl_data)
3282b133ad6SJeff Kirsher {
329f646968fSPatrick McHardy if (features & NETIF_F_HW_VLAN_CTAG_RX) {
3302b133ad6SJeff Kirsher /* enable VLAN tag insert/strip */
3312b133ad6SJeff Kirsher *mac_ctrl_data |= MAC_CTRL_RMV_VLAN;
3322b133ad6SJeff Kirsher } else {
3332b133ad6SJeff Kirsher /* disable VLAN tag insert/strip */
3342b133ad6SJeff Kirsher *mac_ctrl_data &= ~MAC_CTRL_RMV_VLAN;
3352b133ad6SJeff Kirsher }
3362b133ad6SJeff Kirsher }
3372b133ad6SJeff Kirsher
atl1e_vlan_mode(struct net_device * netdev,netdev_features_t features)338c8f44affSMichał Mirosław static void atl1e_vlan_mode(struct net_device *netdev,
339c8f44affSMichał Mirosław netdev_features_t features)
3402b133ad6SJeff Kirsher {
3412b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
3422b133ad6SJeff Kirsher u32 mac_ctrl_data = 0;
3432b133ad6SJeff Kirsher
3442b133ad6SJeff Kirsher netdev_dbg(adapter->netdev, "%s\n", __func__);
3452b133ad6SJeff Kirsher
3462b133ad6SJeff Kirsher atl1e_irq_disable(adapter);
3472b133ad6SJeff Kirsher mac_ctrl_data = AT_READ_REG(&adapter->hw, REG_MAC_CTRL);
3482b133ad6SJeff Kirsher __atl1e_vlan_mode(features, &mac_ctrl_data);
3492b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_MAC_CTRL, mac_ctrl_data);
3502b133ad6SJeff Kirsher atl1e_irq_enable(adapter);
3512b133ad6SJeff Kirsher }
3522b133ad6SJeff Kirsher
atl1e_restore_vlan(struct atl1e_adapter * adapter)3532b133ad6SJeff Kirsher static void atl1e_restore_vlan(struct atl1e_adapter *adapter)
3542b133ad6SJeff Kirsher {
3552b133ad6SJeff Kirsher netdev_dbg(adapter->netdev, "%s\n", __func__);
3562b133ad6SJeff Kirsher atl1e_vlan_mode(adapter->netdev, adapter->netdev->features);
3572b133ad6SJeff Kirsher }
3582b133ad6SJeff Kirsher
35949ce9c2cSBen Hutchings /**
360b43e1554SYang Shen * atl1e_set_mac_addr - Change the Ethernet Address of the NIC
3612b133ad6SJeff Kirsher * @netdev: network interface device structure
3622b133ad6SJeff Kirsher * @p: pointer to an address structure
3632b133ad6SJeff Kirsher *
3642b133ad6SJeff Kirsher * Returns 0 on success, negative on failure
3652b133ad6SJeff Kirsher */
atl1e_set_mac_addr(struct net_device * netdev,void * p)3662b133ad6SJeff Kirsher static int atl1e_set_mac_addr(struct net_device *netdev, void *p)
3672b133ad6SJeff Kirsher {
3682b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
3692b133ad6SJeff Kirsher struct sockaddr *addr = p;
3702b133ad6SJeff Kirsher
3712b133ad6SJeff Kirsher if (!is_valid_ether_addr(addr->sa_data))
3722b133ad6SJeff Kirsher return -EADDRNOTAVAIL;
3732b133ad6SJeff Kirsher
3742b133ad6SJeff Kirsher if (netif_running(netdev))
3752b133ad6SJeff Kirsher return -EBUSY;
3762b133ad6SJeff Kirsher
377a05e4c0aSJakub Kicinski eth_hw_addr_set(netdev, addr->sa_data);
3782b133ad6SJeff Kirsher memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
3792b133ad6SJeff Kirsher
3802b133ad6SJeff Kirsher atl1e_hw_set_mac_addr(&adapter->hw);
3812b133ad6SJeff Kirsher
3822b133ad6SJeff Kirsher return 0;
3832b133ad6SJeff Kirsher }
3842b133ad6SJeff Kirsher
atl1e_fix_features(struct net_device * netdev,netdev_features_t features)385c8f44affSMichał Mirosław static netdev_features_t atl1e_fix_features(struct net_device *netdev,
386c8f44affSMichał Mirosław netdev_features_t features)
3872b133ad6SJeff Kirsher {
3882b133ad6SJeff Kirsher /*
3892b133ad6SJeff Kirsher * Since there is no support for separate rx/tx vlan accel
3902b133ad6SJeff Kirsher * enable/disable make sure tx flag is always in same state as rx.
3912b133ad6SJeff Kirsher */
392f646968fSPatrick McHardy if (features & NETIF_F_HW_VLAN_CTAG_RX)
393f646968fSPatrick McHardy features |= NETIF_F_HW_VLAN_CTAG_TX;
3942b133ad6SJeff Kirsher else
395f646968fSPatrick McHardy features &= ~NETIF_F_HW_VLAN_CTAG_TX;
3962b133ad6SJeff Kirsher
3972b133ad6SJeff Kirsher return features;
3982b133ad6SJeff Kirsher }
3992b133ad6SJeff Kirsher
atl1e_set_features(struct net_device * netdev,netdev_features_t features)400c8f44affSMichał Mirosław static int atl1e_set_features(struct net_device *netdev,
401c8f44affSMichał Mirosław netdev_features_t features)
4022b133ad6SJeff Kirsher {
403c8f44affSMichał Mirosław netdev_features_t changed = netdev->features ^ features;
4042b133ad6SJeff Kirsher
405f646968fSPatrick McHardy if (changed & NETIF_F_HW_VLAN_CTAG_RX)
4062b133ad6SJeff Kirsher atl1e_vlan_mode(netdev, features);
4072b133ad6SJeff Kirsher
40840dc9ab2SAndrea Merello if (changed & NETIF_F_RXALL)
40940dc9ab2SAndrea Merello atl1e_rx_mode(netdev, features);
41040dc9ab2SAndrea Merello
41140dc9ab2SAndrea Merello
4122b133ad6SJeff Kirsher return 0;
4132b133ad6SJeff Kirsher }
4142b133ad6SJeff Kirsher
41549ce9c2cSBen Hutchings /**
4162b133ad6SJeff Kirsher * atl1e_change_mtu - Change the Maximum Transfer Unit
4172b133ad6SJeff Kirsher * @netdev: network interface device structure
4182b133ad6SJeff Kirsher * @new_mtu: new value for maximum frame size
4192b133ad6SJeff Kirsher *
4202b133ad6SJeff Kirsher * Returns 0 on success, negative on failure
4212b133ad6SJeff Kirsher */
atl1e_change_mtu(struct net_device * netdev,int new_mtu)4222b133ad6SJeff Kirsher static int atl1e_change_mtu(struct net_device *netdev, int new_mtu)
4232b133ad6SJeff Kirsher {
4242b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
4252b133ad6SJeff Kirsher int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
4262b133ad6SJeff Kirsher
4272b133ad6SJeff Kirsher /* set MTU */
42867bef942SJarod Wilson if (netif_running(netdev)) {
4292b133ad6SJeff Kirsher while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
4302b133ad6SJeff Kirsher msleep(1);
4312b133ad6SJeff Kirsher netdev->mtu = new_mtu;
4322b133ad6SJeff Kirsher adapter->hw.max_frame_size = new_mtu;
4332b133ad6SJeff Kirsher adapter->hw.rx_jumbo_th = (max_frame + 7) >> 3;
4342b133ad6SJeff Kirsher atl1e_down(adapter);
4352b133ad6SJeff Kirsher atl1e_up(adapter);
4362b133ad6SJeff Kirsher clear_bit(__AT_RESETTING, &adapter->flags);
4372b133ad6SJeff Kirsher }
4382b133ad6SJeff Kirsher return 0;
4392b133ad6SJeff Kirsher }
4402b133ad6SJeff Kirsher
4412b133ad6SJeff Kirsher /*
4422b133ad6SJeff Kirsher * caller should hold mdio_lock
4432b133ad6SJeff Kirsher */
atl1e_mdio_read(struct net_device * netdev,int phy_id,int reg_num)4442b133ad6SJeff Kirsher static int atl1e_mdio_read(struct net_device *netdev, int phy_id, int reg_num)
4452b133ad6SJeff Kirsher {
4462b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
4472b133ad6SJeff Kirsher u16 result;
4482b133ad6SJeff Kirsher
4492b133ad6SJeff Kirsher atl1e_read_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, &result);
4502b133ad6SJeff Kirsher return result;
4512b133ad6SJeff Kirsher }
4522b133ad6SJeff Kirsher
atl1e_mdio_write(struct net_device * netdev,int phy_id,int reg_num,int val)4532b133ad6SJeff Kirsher static void atl1e_mdio_write(struct net_device *netdev, int phy_id,
4542b133ad6SJeff Kirsher int reg_num, int val)
4552b133ad6SJeff Kirsher {
4562b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
4572b133ad6SJeff Kirsher
458ff07d48dSKangjie Lu if (atl1e_write_phy_reg(&adapter->hw,
459ff07d48dSKangjie Lu reg_num & MDIO_REG_ADDR_MASK, val))
460ff07d48dSKangjie Lu netdev_err(netdev, "write phy register failed\n");
4612b133ad6SJeff Kirsher }
4622b133ad6SJeff Kirsher
atl1e_mii_ioctl(struct net_device * netdev,struct ifreq * ifr,int cmd)4632b133ad6SJeff Kirsher static int atl1e_mii_ioctl(struct net_device *netdev,
4642b133ad6SJeff Kirsher struct ifreq *ifr, int cmd)
4652b133ad6SJeff Kirsher {
4662b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
4672b133ad6SJeff Kirsher struct mii_ioctl_data *data = if_mii(ifr);
4682b133ad6SJeff Kirsher unsigned long flags;
4692b133ad6SJeff Kirsher int retval = 0;
4702b133ad6SJeff Kirsher
4712b133ad6SJeff Kirsher if (!netif_running(netdev))
4722b133ad6SJeff Kirsher return -EINVAL;
4732b133ad6SJeff Kirsher
4742b133ad6SJeff Kirsher spin_lock_irqsave(&adapter->mdio_lock, flags);
4752b133ad6SJeff Kirsher switch (cmd) {
4762b133ad6SJeff Kirsher case SIOCGMIIPHY:
4772b133ad6SJeff Kirsher data->phy_id = 0;
4782b133ad6SJeff Kirsher break;
4792b133ad6SJeff Kirsher
4802b133ad6SJeff Kirsher case SIOCGMIIREG:
4812b133ad6SJeff Kirsher if (atl1e_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
4822b133ad6SJeff Kirsher &data->val_out)) {
4832b133ad6SJeff Kirsher retval = -EIO;
4842b133ad6SJeff Kirsher goto out;
4852b133ad6SJeff Kirsher }
4862b133ad6SJeff Kirsher break;
4872b133ad6SJeff Kirsher
4882b133ad6SJeff Kirsher case SIOCSMIIREG:
4892b133ad6SJeff Kirsher if (data->reg_num & ~(0x1F)) {
4902b133ad6SJeff Kirsher retval = -EFAULT;
4912b133ad6SJeff Kirsher goto out;
4922b133ad6SJeff Kirsher }
4932b133ad6SJeff Kirsher
4942b133ad6SJeff Kirsher netdev_dbg(adapter->netdev, "<atl1e_mii_ioctl> write %x %x\n",
4952b133ad6SJeff Kirsher data->reg_num, data->val_in);
4962b133ad6SJeff Kirsher if (atl1e_write_phy_reg(&adapter->hw,
4972b133ad6SJeff Kirsher data->reg_num, data->val_in)) {
4982b133ad6SJeff Kirsher retval = -EIO;
4992b133ad6SJeff Kirsher goto out;
5002b133ad6SJeff Kirsher }
5012b133ad6SJeff Kirsher break;
5022b133ad6SJeff Kirsher
5032b133ad6SJeff Kirsher default:
5042b133ad6SJeff Kirsher retval = -EOPNOTSUPP;
5052b133ad6SJeff Kirsher break;
5062b133ad6SJeff Kirsher }
5072b133ad6SJeff Kirsher out:
5082b133ad6SJeff Kirsher spin_unlock_irqrestore(&adapter->mdio_lock, flags);
5092b133ad6SJeff Kirsher return retval;
5102b133ad6SJeff Kirsher
5112b133ad6SJeff Kirsher }
5122b133ad6SJeff Kirsher
atl1e_ioctl(struct net_device * netdev,struct ifreq * ifr,int cmd)5132b133ad6SJeff Kirsher static int atl1e_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
5142b133ad6SJeff Kirsher {
5152b133ad6SJeff Kirsher switch (cmd) {
5162b133ad6SJeff Kirsher case SIOCGMIIPHY:
5172b133ad6SJeff Kirsher case SIOCGMIIREG:
5182b133ad6SJeff Kirsher case SIOCSMIIREG:
5192b133ad6SJeff Kirsher return atl1e_mii_ioctl(netdev, ifr, cmd);
5202b133ad6SJeff Kirsher default:
5212b133ad6SJeff Kirsher return -EOPNOTSUPP;
5222b133ad6SJeff Kirsher }
5232b133ad6SJeff Kirsher }
5242b133ad6SJeff Kirsher
atl1e_setup_pcicmd(struct pci_dev * pdev)5252b133ad6SJeff Kirsher static void atl1e_setup_pcicmd(struct pci_dev *pdev)
5262b133ad6SJeff Kirsher {
5272b133ad6SJeff Kirsher u16 cmd;
5282b133ad6SJeff Kirsher
5292b133ad6SJeff Kirsher pci_read_config_word(pdev, PCI_COMMAND, &cmd);
5302b133ad6SJeff Kirsher cmd &= ~(PCI_COMMAND_INTX_DISABLE | PCI_COMMAND_IO);
5312b133ad6SJeff Kirsher cmd |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
5322b133ad6SJeff Kirsher pci_write_config_word(pdev, PCI_COMMAND, cmd);
5332b133ad6SJeff Kirsher
5342b133ad6SJeff Kirsher /*
5352b133ad6SJeff Kirsher * some motherboards BIOS(PXE/EFI) driver may set PME
5362b133ad6SJeff Kirsher * while they transfer control to OS (Windows/Linux)
5372b133ad6SJeff Kirsher * so we should clear this bit before NIC work normally
5382b133ad6SJeff Kirsher */
5392b133ad6SJeff Kirsher pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0);
5402b133ad6SJeff Kirsher msleep(1);
5412b133ad6SJeff Kirsher }
5422b133ad6SJeff Kirsher
54349ce9c2cSBen Hutchings /**
5442b133ad6SJeff Kirsher * atl1e_alloc_queues - Allocate memory for all rings
5452b133ad6SJeff Kirsher * @adapter: board private structure to initialize
5462b133ad6SJeff Kirsher *
5472b133ad6SJeff Kirsher */
atl1e_alloc_queues(struct atl1e_adapter * adapter)548093d369dSBill Pemberton static int atl1e_alloc_queues(struct atl1e_adapter *adapter)
5492b133ad6SJeff Kirsher {
5502b133ad6SJeff Kirsher return 0;
5512b133ad6SJeff Kirsher }
5522b133ad6SJeff Kirsher
55349ce9c2cSBen Hutchings /**
5542b133ad6SJeff Kirsher * atl1e_sw_init - Initialize general software structures (struct atl1e_adapter)
5552b133ad6SJeff Kirsher * @adapter: board private structure to initialize
5562b133ad6SJeff Kirsher *
5572b133ad6SJeff Kirsher * atl1e_sw_init initializes the Adapter private data structure.
5582b133ad6SJeff Kirsher * Fields are initialized based on PCI device information and
5592b133ad6SJeff Kirsher * OS network device settings (MTU size).
5602b133ad6SJeff Kirsher */
atl1e_sw_init(struct atl1e_adapter * adapter)561093d369dSBill Pemberton static int atl1e_sw_init(struct atl1e_adapter *adapter)
5622b133ad6SJeff Kirsher {
5632b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
5642b133ad6SJeff Kirsher struct pci_dev *pdev = adapter->pdev;
5652b133ad6SJeff Kirsher u32 phy_status_data = 0;
5662b133ad6SJeff Kirsher
5672b133ad6SJeff Kirsher adapter->wol = 0;
5682b133ad6SJeff Kirsher adapter->link_speed = SPEED_0; /* hardware init */
5692b133ad6SJeff Kirsher adapter->link_duplex = FULL_DUPLEX;
5702b133ad6SJeff Kirsher adapter->num_rx_queues = 1;
5712b133ad6SJeff Kirsher
5722b133ad6SJeff Kirsher /* PCI config space info */
5732b133ad6SJeff Kirsher hw->vendor_id = pdev->vendor;
5742b133ad6SJeff Kirsher hw->device_id = pdev->device;
5752b133ad6SJeff Kirsher hw->subsystem_vendor_id = pdev->subsystem_vendor;
5762b133ad6SJeff Kirsher hw->subsystem_id = pdev->subsystem_device;
5772b133ad6SJeff Kirsher hw->revision_id = pdev->revision;
5782b133ad6SJeff Kirsher
5792b133ad6SJeff Kirsher pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
5802b133ad6SJeff Kirsher
5812b133ad6SJeff Kirsher phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
5822b133ad6SJeff Kirsher /* nic type */
5832b133ad6SJeff Kirsher if (hw->revision_id >= 0xF0) {
5842b133ad6SJeff Kirsher hw->nic_type = athr_l2e_revB;
5852b133ad6SJeff Kirsher } else {
5862b133ad6SJeff Kirsher if (phy_status_data & PHY_STATUS_100M)
5872b133ad6SJeff Kirsher hw->nic_type = athr_l1e;
5882b133ad6SJeff Kirsher else
5892b133ad6SJeff Kirsher hw->nic_type = athr_l2e_revA;
5902b133ad6SJeff Kirsher }
5912b133ad6SJeff Kirsher
5922b133ad6SJeff Kirsher phy_status_data = AT_READ_REG(hw, REG_PHY_STATUS);
5932b133ad6SJeff Kirsher
5942b133ad6SJeff Kirsher if (phy_status_data & PHY_STATUS_EMI_CA)
5952b133ad6SJeff Kirsher hw->emi_ca = true;
5962b133ad6SJeff Kirsher else
5972b133ad6SJeff Kirsher hw->emi_ca = false;
5982b133ad6SJeff Kirsher
5992b133ad6SJeff Kirsher hw->phy_configured = false;
6002b133ad6SJeff Kirsher hw->preamble_len = 7;
6012b133ad6SJeff Kirsher hw->max_frame_size = adapter->netdev->mtu;
6022b133ad6SJeff Kirsher hw->rx_jumbo_th = (hw->max_frame_size + ETH_HLEN +
6032b133ad6SJeff Kirsher VLAN_HLEN + ETH_FCS_LEN + 7) >> 3;
6042b133ad6SJeff Kirsher
6052b133ad6SJeff Kirsher hw->rrs_type = atl1e_rrs_disable;
6062b133ad6SJeff Kirsher hw->indirect_tab = 0;
6072b133ad6SJeff Kirsher hw->base_cpu = 0;
6082b133ad6SJeff Kirsher
6092b133ad6SJeff Kirsher /* need confirm */
6102b133ad6SJeff Kirsher
6112b133ad6SJeff Kirsher hw->ict = 50000; /* 100ms */
6122b133ad6SJeff Kirsher hw->smb_timer = 200000; /* 200ms */
6132b133ad6SJeff Kirsher hw->tpd_burst = 5;
6142b133ad6SJeff Kirsher hw->rrd_thresh = 1;
6152b133ad6SJeff Kirsher hw->tpd_thresh = adapter->tx_ring.count / 2;
6162b133ad6SJeff Kirsher hw->rx_count_down = 4; /* 2us resolution */
6172b133ad6SJeff Kirsher hw->tx_count_down = hw->imt * 4 / 3;
6182b133ad6SJeff Kirsher hw->dmar_block = atl1e_dma_req_1024;
6192b133ad6SJeff Kirsher hw->dmaw_block = atl1e_dma_req_1024;
6202b133ad6SJeff Kirsher hw->dmar_dly_cnt = 15;
6212b133ad6SJeff Kirsher hw->dmaw_dly_cnt = 4;
6222b133ad6SJeff Kirsher
6232b133ad6SJeff Kirsher if (atl1e_alloc_queues(adapter)) {
6242b133ad6SJeff Kirsher netdev_err(adapter->netdev, "Unable to allocate memory for queues\n");
6252b133ad6SJeff Kirsher return -ENOMEM;
6262b133ad6SJeff Kirsher }
6272b133ad6SJeff Kirsher
6282b133ad6SJeff Kirsher atomic_set(&adapter->irq_sem, 1);
6292b133ad6SJeff Kirsher spin_lock_init(&adapter->mdio_lock);
6302b133ad6SJeff Kirsher
6312b133ad6SJeff Kirsher set_bit(__AT_DOWN, &adapter->flags);
6322b133ad6SJeff Kirsher
6332b133ad6SJeff Kirsher return 0;
6342b133ad6SJeff Kirsher }
6352b133ad6SJeff Kirsher
63649ce9c2cSBen Hutchings /**
6372b133ad6SJeff Kirsher * atl1e_clean_tx_ring - Free Tx-skb
6382b133ad6SJeff Kirsher * @adapter: board private structure
6392b133ad6SJeff Kirsher */
atl1e_clean_tx_ring(struct atl1e_adapter * adapter)6402b133ad6SJeff Kirsher static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
6412b133ad6SJeff Kirsher {
64264699336SJoe Perches struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
6432b133ad6SJeff Kirsher struct atl1e_tx_buffer *tx_buffer = NULL;
6442b133ad6SJeff Kirsher struct pci_dev *pdev = adapter->pdev;
6452b133ad6SJeff Kirsher u16 index, ring_count;
6462b133ad6SJeff Kirsher
6472b133ad6SJeff Kirsher if (tx_ring->desc == NULL || tx_ring->tx_buffer == NULL)
6482b133ad6SJeff Kirsher return;
6492b133ad6SJeff Kirsher
6502b133ad6SJeff Kirsher ring_count = tx_ring->count;
6512b133ad6SJeff Kirsher /* first unmmap dma */
6522b133ad6SJeff Kirsher for (index = 0; index < ring_count; index++) {
6532b133ad6SJeff Kirsher tx_buffer = &tx_ring->tx_buffer[index];
6542b133ad6SJeff Kirsher if (tx_buffer->dma) {
6552b133ad6SJeff Kirsher if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
65685eb5bc3SChristophe JAILLET dma_unmap_single(&pdev->dev, tx_buffer->dma,
65785eb5bc3SChristophe JAILLET tx_buffer->length,
65885eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
6592b133ad6SJeff Kirsher else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
66085eb5bc3SChristophe JAILLET dma_unmap_page(&pdev->dev, tx_buffer->dma,
66185eb5bc3SChristophe JAILLET tx_buffer->length,
66285eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
6632b133ad6SJeff Kirsher tx_buffer->dma = 0;
6642b133ad6SJeff Kirsher }
6652b133ad6SJeff Kirsher }
6662b133ad6SJeff Kirsher /* second free skb */
6672b133ad6SJeff Kirsher for (index = 0; index < ring_count; index++) {
6682b133ad6SJeff Kirsher tx_buffer = &tx_ring->tx_buffer[index];
6692b133ad6SJeff Kirsher if (tx_buffer->skb) {
6702b133ad6SJeff Kirsher dev_kfree_skb_any(tx_buffer->skb);
6712b133ad6SJeff Kirsher tx_buffer->skb = NULL;
6722b133ad6SJeff Kirsher }
6732b133ad6SJeff Kirsher }
6742b133ad6SJeff Kirsher /* Zero out Tx-buffers */
6752b133ad6SJeff Kirsher memset(tx_ring->desc, 0, sizeof(struct atl1e_tpd_desc) *
6762b133ad6SJeff Kirsher ring_count);
6772b133ad6SJeff Kirsher memset(tx_ring->tx_buffer, 0, sizeof(struct atl1e_tx_buffer) *
6782b133ad6SJeff Kirsher ring_count);
6792b133ad6SJeff Kirsher }
6802b133ad6SJeff Kirsher
68149ce9c2cSBen Hutchings /**
6822b133ad6SJeff Kirsher * atl1e_clean_rx_ring - Free rx-reservation skbs
6832b133ad6SJeff Kirsher * @adapter: board private structure
6842b133ad6SJeff Kirsher */
atl1e_clean_rx_ring(struct atl1e_adapter * adapter)6852b133ad6SJeff Kirsher static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter)
6862b133ad6SJeff Kirsher {
6872b133ad6SJeff Kirsher struct atl1e_rx_ring *rx_ring =
68864699336SJoe Perches &adapter->rx_ring;
6892b133ad6SJeff Kirsher struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc;
6902b133ad6SJeff Kirsher u16 i, j;
6912b133ad6SJeff Kirsher
6922b133ad6SJeff Kirsher
6932b133ad6SJeff Kirsher if (adapter->ring_vir_addr == NULL)
6942b133ad6SJeff Kirsher return;
6952b133ad6SJeff Kirsher /* Zero out the descriptor ring */
6962b133ad6SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) {
6972b133ad6SJeff Kirsher for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
6982b133ad6SJeff Kirsher if (rx_page_desc[i].rx_page[j].addr != NULL) {
6992b133ad6SJeff Kirsher memset(rx_page_desc[i].rx_page[j].addr, 0,
7002b133ad6SJeff Kirsher rx_ring->real_page_size);
7012b133ad6SJeff Kirsher }
7022b133ad6SJeff Kirsher }
7032b133ad6SJeff Kirsher }
7042b133ad6SJeff Kirsher }
7052b133ad6SJeff Kirsher
atl1e_cal_ring_size(struct atl1e_adapter * adapter,u32 * ring_size)7062b133ad6SJeff Kirsher static void atl1e_cal_ring_size(struct atl1e_adapter *adapter, u32 *ring_size)
7072b133ad6SJeff Kirsher {
7082b133ad6SJeff Kirsher *ring_size = ((u32)(adapter->tx_ring.count *
7092b133ad6SJeff Kirsher sizeof(struct atl1e_tpd_desc) + 7
7102b133ad6SJeff Kirsher /* tx ring, qword align */
7112b133ad6SJeff Kirsher + adapter->rx_ring.real_page_size * AT_PAGE_NUM_PER_QUEUE *
7122b133ad6SJeff Kirsher adapter->num_rx_queues + 31
7132b133ad6SJeff Kirsher /* rx ring, 32 bytes align */
7142b133ad6SJeff Kirsher + (1 + AT_PAGE_NUM_PER_QUEUE * adapter->num_rx_queues) *
7152b133ad6SJeff Kirsher sizeof(u32) + 3));
7162b133ad6SJeff Kirsher /* tx, rx cmd, dword align */
7172b133ad6SJeff Kirsher }
7182b133ad6SJeff Kirsher
atl1e_init_ring_resources(struct atl1e_adapter * adapter)7192b133ad6SJeff Kirsher static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
7202b133ad6SJeff Kirsher {
7212b133ad6SJeff Kirsher struct atl1e_rx_ring *rx_ring = NULL;
7222b133ad6SJeff Kirsher
7232b133ad6SJeff Kirsher rx_ring = &adapter->rx_ring;
7242b133ad6SJeff Kirsher
7252b133ad6SJeff Kirsher rx_ring->real_page_size = adapter->rx_ring.page_size
7262b133ad6SJeff Kirsher + adapter->hw.max_frame_size
7272b133ad6SJeff Kirsher + ETH_HLEN + VLAN_HLEN
7282b133ad6SJeff Kirsher + ETH_FCS_LEN;
7292b133ad6SJeff Kirsher rx_ring->real_page_size = roundup(rx_ring->real_page_size, 32);
7302b133ad6SJeff Kirsher atl1e_cal_ring_size(adapter, &adapter->ring_size);
7312b133ad6SJeff Kirsher
7322b133ad6SJeff Kirsher adapter->ring_vir_addr = NULL;
7332b133ad6SJeff Kirsher adapter->rx_ring.desc = NULL;
7342b133ad6SJeff Kirsher rwlock_init(&adapter->tx_ring.tx_lock);
7352b133ad6SJeff Kirsher }
7362b133ad6SJeff Kirsher
7372b133ad6SJeff Kirsher /*
7382b133ad6SJeff Kirsher * Read / Write Ptr Initialize:
7392b133ad6SJeff Kirsher */
atl1e_init_ring_ptrs(struct atl1e_adapter * adapter)7402b133ad6SJeff Kirsher static void atl1e_init_ring_ptrs(struct atl1e_adapter *adapter)
7412b133ad6SJeff Kirsher {
7422b133ad6SJeff Kirsher struct atl1e_tx_ring *tx_ring = NULL;
7432b133ad6SJeff Kirsher struct atl1e_rx_ring *rx_ring = NULL;
7442b133ad6SJeff Kirsher struct atl1e_rx_page_desc *rx_page_desc = NULL;
7452b133ad6SJeff Kirsher int i, j;
7462b133ad6SJeff Kirsher
7472b133ad6SJeff Kirsher tx_ring = &adapter->tx_ring;
7482b133ad6SJeff Kirsher rx_ring = &adapter->rx_ring;
7492b133ad6SJeff Kirsher rx_page_desc = rx_ring->rx_page_desc;
7502b133ad6SJeff Kirsher
7512b133ad6SJeff Kirsher tx_ring->next_to_use = 0;
7522b133ad6SJeff Kirsher atomic_set(&tx_ring->next_to_clean, 0);
7532b133ad6SJeff Kirsher
7542b133ad6SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) {
7552b133ad6SJeff Kirsher rx_page_desc[i].rx_using = 0;
7562b133ad6SJeff Kirsher rx_page_desc[i].rx_nxseq = 0;
7572b133ad6SJeff Kirsher for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
7582b133ad6SJeff Kirsher *rx_page_desc[i].rx_page[j].write_offset_addr = 0;
7592b133ad6SJeff Kirsher rx_page_desc[i].rx_page[j].read_offset = 0;
7602b133ad6SJeff Kirsher }
7612b133ad6SJeff Kirsher }
7622b133ad6SJeff Kirsher }
7632b133ad6SJeff Kirsher
76449ce9c2cSBen Hutchings /**
7652b133ad6SJeff Kirsher * atl1e_free_ring_resources - Free Tx / RX descriptor Resources
7662b133ad6SJeff Kirsher * @adapter: board private structure
7672b133ad6SJeff Kirsher *
7682b133ad6SJeff Kirsher * Free all transmit software resources
7692b133ad6SJeff Kirsher */
atl1e_free_ring_resources(struct atl1e_adapter * adapter)7702b133ad6SJeff Kirsher static void atl1e_free_ring_resources(struct atl1e_adapter *adapter)
7712b133ad6SJeff Kirsher {
7722b133ad6SJeff Kirsher struct pci_dev *pdev = adapter->pdev;
7732b133ad6SJeff Kirsher
7742b133ad6SJeff Kirsher atl1e_clean_tx_ring(adapter);
7752b133ad6SJeff Kirsher atl1e_clean_rx_ring(adapter);
7762b133ad6SJeff Kirsher
7772b133ad6SJeff Kirsher if (adapter->ring_vir_addr) {
77885eb5bc3SChristophe JAILLET dma_free_coherent(&pdev->dev, adapter->ring_size,
7792b133ad6SJeff Kirsher adapter->ring_vir_addr, adapter->ring_dma);
7802b133ad6SJeff Kirsher adapter->ring_vir_addr = NULL;
7812b133ad6SJeff Kirsher }
7822b133ad6SJeff Kirsher
7832b133ad6SJeff Kirsher if (adapter->tx_ring.tx_buffer) {
7842b133ad6SJeff Kirsher kfree(adapter->tx_ring.tx_buffer);
7852b133ad6SJeff Kirsher adapter->tx_ring.tx_buffer = NULL;
7862b133ad6SJeff Kirsher }
7872b133ad6SJeff Kirsher }
7882b133ad6SJeff Kirsher
78949ce9c2cSBen Hutchings /**
790b43e1554SYang Shen * atl1e_setup_ring_resources - allocate Tx / RX descriptor resources
7912b133ad6SJeff Kirsher * @adapter: board private structure
7922b133ad6SJeff Kirsher *
7932b133ad6SJeff Kirsher * Return 0 on success, negative on failure
7942b133ad6SJeff Kirsher */
atl1e_setup_ring_resources(struct atl1e_adapter * adapter)7952b133ad6SJeff Kirsher static int atl1e_setup_ring_resources(struct atl1e_adapter *adapter)
7962b133ad6SJeff Kirsher {
7972b133ad6SJeff Kirsher struct pci_dev *pdev = adapter->pdev;
7982b133ad6SJeff Kirsher struct atl1e_tx_ring *tx_ring;
7992b133ad6SJeff Kirsher struct atl1e_rx_ring *rx_ring;
8002b133ad6SJeff Kirsher struct atl1e_rx_page_desc *rx_page_desc;
8012b133ad6SJeff Kirsher int size, i, j;
8022b133ad6SJeff Kirsher u32 offset = 0;
8032b133ad6SJeff Kirsher int err = 0;
8042b133ad6SJeff Kirsher
8052b133ad6SJeff Kirsher if (adapter->ring_vir_addr != NULL)
8062b133ad6SJeff Kirsher return 0; /* alloced already */
8072b133ad6SJeff Kirsher
8082b133ad6SJeff Kirsher tx_ring = &adapter->tx_ring;
8092b133ad6SJeff Kirsher rx_ring = &adapter->rx_ring;
8102b133ad6SJeff Kirsher
8112b133ad6SJeff Kirsher /* real ring DMA buffer */
8122b133ad6SJeff Kirsher
8132b133ad6SJeff Kirsher size = adapter->ring_size;
81485eb5bc3SChristophe JAILLET adapter->ring_vir_addr = dma_alloc_coherent(&pdev->dev,
81585eb5bc3SChristophe JAILLET adapter->ring_size,
81685eb5bc3SChristophe JAILLET &adapter->ring_dma, GFP_KERNEL);
8172b133ad6SJeff Kirsher if (adapter->ring_vir_addr == NULL) {
8182b133ad6SJeff Kirsher netdev_err(adapter->netdev,
81985eb5bc3SChristophe JAILLET "dma_alloc_coherent failed, size = D%d\n", size);
8202b133ad6SJeff Kirsher return -ENOMEM;
8212b133ad6SJeff Kirsher }
8222b133ad6SJeff Kirsher
8232b133ad6SJeff Kirsher rx_page_desc = rx_ring->rx_page_desc;
8242b133ad6SJeff Kirsher
8252b133ad6SJeff Kirsher /* Init TPD Ring */
8262b133ad6SJeff Kirsher tx_ring->dma = roundup(adapter->ring_dma, 8);
8272b133ad6SJeff Kirsher offset = tx_ring->dma - adapter->ring_dma;
8282b133ad6SJeff Kirsher tx_ring->desc = adapter->ring_vir_addr + offset;
8292b133ad6SJeff Kirsher size = sizeof(struct atl1e_tx_buffer) * (tx_ring->count);
8302b133ad6SJeff Kirsher tx_ring->tx_buffer = kzalloc(size, GFP_KERNEL);
8312b133ad6SJeff Kirsher if (tx_ring->tx_buffer == NULL) {
8322b133ad6SJeff Kirsher err = -ENOMEM;
8332b133ad6SJeff Kirsher goto failed;
8342b133ad6SJeff Kirsher }
8352b133ad6SJeff Kirsher
8362b133ad6SJeff Kirsher /* Init RXF-Pages */
8372b133ad6SJeff Kirsher offset += (sizeof(struct atl1e_tpd_desc) * tx_ring->count);
8382b133ad6SJeff Kirsher offset = roundup(offset, 32);
8392b133ad6SJeff Kirsher
8402b133ad6SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) {
8412b133ad6SJeff Kirsher for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
8422b133ad6SJeff Kirsher rx_page_desc[i].rx_page[j].dma =
8432b133ad6SJeff Kirsher adapter->ring_dma + offset;
8442b133ad6SJeff Kirsher rx_page_desc[i].rx_page[j].addr =
8452b133ad6SJeff Kirsher adapter->ring_vir_addr + offset;
8462b133ad6SJeff Kirsher offset += rx_ring->real_page_size;
8472b133ad6SJeff Kirsher }
8482b133ad6SJeff Kirsher }
8492b133ad6SJeff Kirsher
8502b133ad6SJeff Kirsher /* Init CMB dma address */
8512b133ad6SJeff Kirsher tx_ring->cmb_dma = adapter->ring_dma + offset;
8522b133ad6SJeff Kirsher tx_ring->cmb = adapter->ring_vir_addr + offset;
8532b133ad6SJeff Kirsher offset += sizeof(u32);
8542b133ad6SJeff Kirsher
8552b133ad6SJeff Kirsher for (i = 0; i < adapter->num_rx_queues; i++) {
8562b133ad6SJeff Kirsher for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
8572b133ad6SJeff Kirsher rx_page_desc[i].rx_page[j].write_offset_dma =
8582b133ad6SJeff Kirsher adapter->ring_dma + offset;
8592b133ad6SJeff Kirsher rx_page_desc[i].rx_page[j].write_offset_addr =
8602b133ad6SJeff Kirsher adapter->ring_vir_addr + offset;
8612b133ad6SJeff Kirsher offset += sizeof(u32);
8622b133ad6SJeff Kirsher }
8632b133ad6SJeff Kirsher }
8642b133ad6SJeff Kirsher
8652b133ad6SJeff Kirsher if (unlikely(offset > adapter->ring_size)) {
8662b133ad6SJeff Kirsher netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n",
8672b133ad6SJeff Kirsher offset, adapter->ring_size);
8682b133ad6SJeff Kirsher err = -1;
869*73e159a2SZhipeng Lu goto free_buffer;
8702b133ad6SJeff Kirsher }
8712b133ad6SJeff Kirsher
8722b133ad6SJeff Kirsher return 0;
873*73e159a2SZhipeng Lu free_buffer:
874*73e159a2SZhipeng Lu kfree(tx_ring->tx_buffer);
875*73e159a2SZhipeng Lu tx_ring->tx_buffer = NULL;
8762b133ad6SJeff Kirsher failed:
8772b133ad6SJeff Kirsher if (adapter->ring_vir_addr != NULL) {
87885eb5bc3SChristophe JAILLET dma_free_coherent(&pdev->dev, adapter->ring_size,
8792b133ad6SJeff Kirsher adapter->ring_vir_addr, adapter->ring_dma);
8802b133ad6SJeff Kirsher adapter->ring_vir_addr = NULL;
8812b133ad6SJeff Kirsher }
8822b133ad6SJeff Kirsher return err;
8832b133ad6SJeff Kirsher }
8842b133ad6SJeff Kirsher
atl1e_configure_des_ring(struct atl1e_adapter * adapter)88564699336SJoe Perches static inline void atl1e_configure_des_ring(struct atl1e_adapter *adapter)
8862b133ad6SJeff Kirsher {
8872b133ad6SJeff Kirsher
88864699336SJoe Perches struct atl1e_hw *hw = &adapter->hw;
88964699336SJoe Perches struct atl1e_rx_ring *rx_ring = &adapter->rx_ring;
89064699336SJoe Perches struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
8912b133ad6SJeff Kirsher struct atl1e_rx_page_desc *rx_page_desc = NULL;
8922b133ad6SJeff Kirsher int i, j;
8932b133ad6SJeff Kirsher
8942b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI,
8952b133ad6SJeff Kirsher (u32)((adapter->ring_dma & AT_DMA_HI_ADDR_MASK) >> 32));
8962b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_TPD_BASE_ADDR_LO,
8972b133ad6SJeff Kirsher (u32)((tx_ring->dma) & AT_DMA_LO_ADDR_MASK));
8982b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_TPD_RING_SIZE, (u16)(tx_ring->count));
8992b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_HOST_TX_CMB_LO,
9002b133ad6SJeff Kirsher (u32)((tx_ring->cmb_dma) & AT_DMA_LO_ADDR_MASK));
9012b133ad6SJeff Kirsher
9022b133ad6SJeff Kirsher rx_page_desc = rx_ring->rx_page_desc;
9032b133ad6SJeff Kirsher /* RXF Page Physical address / Page Length */
9042b133ad6SJeff Kirsher for (i = 0; i < AT_MAX_RECEIVE_QUEUE; i++) {
9052b133ad6SJeff Kirsher AT_WRITE_REG(hw, atl1e_rx_page_hi_addr_regs[i],
9062b133ad6SJeff Kirsher (u32)((adapter->ring_dma &
9072b133ad6SJeff Kirsher AT_DMA_HI_ADDR_MASK) >> 32));
9082b133ad6SJeff Kirsher for (j = 0; j < AT_PAGE_NUM_PER_QUEUE; j++) {
9092b133ad6SJeff Kirsher u32 page_phy_addr;
9102b133ad6SJeff Kirsher u32 offset_phy_addr;
9112b133ad6SJeff Kirsher
9122b133ad6SJeff Kirsher page_phy_addr = rx_page_desc[i].rx_page[j].dma;
9132b133ad6SJeff Kirsher offset_phy_addr =
9142b133ad6SJeff Kirsher rx_page_desc[i].rx_page[j].write_offset_dma;
9152b133ad6SJeff Kirsher
9162b133ad6SJeff Kirsher AT_WRITE_REG(hw, atl1e_rx_page_lo_addr_regs[i][j],
9172b133ad6SJeff Kirsher page_phy_addr & AT_DMA_LO_ADDR_MASK);
9182b133ad6SJeff Kirsher AT_WRITE_REG(hw, atl1e_rx_page_write_offset_regs[i][j],
9192b133ad6SJeff Kirsher offset_phy_addr & AT_DMA_LO_ADDR_MASK);
9202b133ad6SJeff Kirsher AT_WRITE_REGB(hw, atl1e_rx_page_vld_regs[i][j], 1);
9212b133ad6SJeff Kirsher }
9222b133ad6SJeff Kirsher }
9232b133ad6SJeff Kirsher /* Page Length */
9242b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_HOST_RXFPAGE_SIZE, rx_ring->page_size);
9252b133ad6SJeff Kirsher /* Load all of base address above */
9262b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_LOAD_PTR, 1);
9272b133ad6SJeff Kirsher }
9282b133ad6SJeff Kirsher
atl1e_configure_tx(struct atl1e_adapter * adapter)9292b133ad6SJeff Kirsher static inline void atl1e_configure_tx(struct atl1e_adapter *adapter)
9302b133ad6SJeff Kirsher {
93164699336SJoe Perches struct atl1e_hw *hw = &adapter->hw;
9322b133ad6SJeff Kirsher u32 dev_ctrl_data = 0;
9332b133ad6SJeff Kirsher u32 max_pay_load = 0;
9342b133ad6SJeff Kirsher u32 jumbo_thresh = 0;
9352b133ad6SJeff Kirsher u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */
9362b133ad6SJeff Kirsher
9372b133ad6SJeff Kirsher /* configure TXQ param */
9382b133ad6SJeff Kirsher if (hw->nic_type != athr_l2e_revB) {
9392b133ad6SJeff Kirsher extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
9402b133ad6SJeff Kirsher if (hw->max_frame_size <= 1500) {
9412b133ad6SJeff Kirsher jumbo_thresh = hw->max_frame_size + extra_size;
9422b133ad6SJeff Kirsher } else if (hw->max_frame_size < 6*1024) {
9432b133ad6SJeff Kirsher jumbo_thresh =
9442b133ad6SJeff Kirsher (hw->max_frame_size + extra_size) * 2 / 3;
9452b133ad6SJeff Kirsher } else {
9462b133ad6SJeff Kirsher jumbo_thresh = (hw->max_frame_size + extra_size) / 2;
9472b133ad6SJeff Kirsher }
9482b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_TX_EARLY_TH, (jumbo_thresh + 7) >> 3);
9492b133ad6SJeff Kirsher }
9502b133ad6SJeff Kirsher
9512b133ad6SJeff Kirsher dev_ctrl_data = AT_READ_REG(hw, REG_DEVICE_CTRL);
9522b133ad6SJeff Kirsher
9532b133ad6SJeff Kirsher max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT)) &
9542b133ad6SJeff Kirsher DEVICE_CTRL_MAX_PAYLOAD_MASK;
9552b133ad6SJeff Kirsher
9562b133ad6SJeff Kirsher hw->dmaw_block = min_t(u32, max_pay_load, hw->dmaw_block);
9572b133ad6SJeff Kirsher
9582b133ad6SJeff Kirsher max_pay_load = ((dev_ctrl_data >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT)) &
9592b133ad6SJeff Kirsher DEVICE_CTRL_MAX_RREQ_SZ_MASK;
9602b133ad6SJeff Kirsher hw->dmar_block = min_t(u32, max_pay_load, hw->dmar_block);
9612b133ad6SJeff Kirsher
9622b133ad6SJeff Kirsher if (hw->nic_type != athr_l2e_revB)
9632b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_TXQ_CTRL + 2,
9642b133ad6SJeff Kirsher atl1e_pay_load_size[hw->dmar_block]);
9652b133ad6SJeff Kirsher /* enable TXQ */
9662b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_TXQ_CTRL,
9672b133ad6SJeff Kirsher (((u16)hw->tpd_burst & TXQ_CTRL_NUM_TPD_BURST_MASK)
9682b133ad6SJeff Kirsher << TXQ_CTRL_NUM_TPD_BURST_SHIFT)
9692b133ad6SJeff Kirsher | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN);
9702b133ad6SJeff Kirsher }
9712b133ad6SJeff Kirsher
atl1e_configure_rx(struct atl1e_adapter * adapter)9722b133ad6SJeff Kirsher static inline void atl1e_configure_rx(struct atl1e_adapter *adapter)
9732b133ad6SJeff Kirsher {
97464699336SJoe Perches struct atl1e_hw *hw = &adapter->hw;
9752b133ad6SJeff Kirsher u32 rxf_len = 0;
9762b133ad6SJeff Kirsher u32 rxf_low = 0;
9772b133ad6SJeff Kirsher u32 rxf_high = 0;
9782b133ad6SJeff Kirsher u32 rxf_thresh_data = 0;
9792b133ad6SJeff Kirsher u32 rxq_ctrl_data = 0;
9802b133ad6SJeff Kirsher
9812b133ad6SJeff Kirsher if (hw->nic_type != athr_l2e_revB) {
9822b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_RXQ_JMBOSZ_RRDTIM,
9832b133ad6SJeff Kirsher (u16)((hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK) <<
9842b133ad6SJeff Kirsher RXQ_JMBOSZ_TH_SHIFT |
9852b133ad6SJeff Kirsher (1 & RXQ_JMBO_LKAH_MASK) <<
9862b133ad6SJeff Kirsher RXQ_JMBO_LKAH_SHIFT));
9872b133ad6SJeff Kirsher
9882b133ad6SJeff Kirsher rxf_len = AT_READ_REG(hw, REG_SRAM_RXF_LEN);
9892b133ad6SJeff Kirsher rxf_high = rxf_len * 4 / 5;
9902b133ad6SJeff Kirsher rxf_low = rxf_len / 5;
9912b133ad6SJeff Kirsher rxf_thresh_data = ((rxf_high & RXQ_RXF_PAUSE_TH_HI_MASK)
9922b133ad6SJeff Kirsher << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
9932b133ad6SJeff Kirsher ((rxf_low & RXQ_RXF_PAUSE_TH_LO_MASK)
9942b133ad6SJeff Kirsher << RXQ_RXF_PAUSE_TH_LO_SHIFT);
9952b133ad6SJeff Kirsher
9962b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_RXQ_RXF_PAUSE_THRESH, rxf_thresh_data);
9972b133ad6SJeff Kirsher }
9982b133ad6SJeff Kirsher
9992b133ad6SJeff Kirsher /* RRS */
10002b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_IDT_TABLE, hw->indirect_tab);
10012b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_BASE_CPU_NUMBER, hw->base_cpu);
10022b133ad6SJeff Kirsher
10032b133ad6SJeff Kirsher if (hw->rrs_type & atl1e_rrs_ipv4)
10042b133ad6SJeff Kirsher rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4;
10052b133ad6SJeff Kirsher
10062b133ad6SJeff Kirsher if (hw->rrs_type & atl1e_rrs_ipv4_tcp)
10072b133ad6SJeff Kirsher rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV4_TCP;
10082b133ad6SJeff Kirsher
10092b133ad6SJeff Kirsher if (hw->rrs_type & atl1e_rrs_ipv6)
10102b133ad6SJeff Kirsher rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6;
10112b133ad6SJeff Kirsher
10122b133ad6SJeff Kirsher if (hw->rrs_type & atl1e_rrs_ipv6_tcp)
10132b133ad6SJeff Kirsher rxq_ctrl_data |= RXQ_CTRL_HASH_TYPE_IPV6_TCP;
10142b133ad6SJeff Kirsher
10152b133ad6SJeff Kirsher if (hw->rrs_type != atl1e_rrs_disable)
10162b133ad6SJeff Kirsher rxq_ctrl_data |=
10172b133ad6SJeff Kirsher (RXQ_CTRL_HASH_ENABLE | RXQ_CTRL_RSS_MODE_MQUESINT);
10182b133ad6SJeff Kirsher
10192b133ad6SJeff Kirsher rxq_ctrl_data |= RXQ_CTRL_IPV6_XSUM_VERIFY_EN | RXQ_CTRL_PBA_ALIGN_32 |
10202b133ad6SJeff Kirsher RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
10212b133ad6SJeff Kirsher
10222b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data);
10232b133ad6SJeff Kirsher }
10242b133ad6SJeff Kirsher
atl1e_configure_dma(struct atl1e_adapter * adapter)10252b133ad6SJeff Kirsher static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
10262b133ad6SJeff Kirsher {
10272b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
10282b133ad6SJeff Kirsher u32 dma_ctrl_data = 0;
10292b133ad6SJeff Kirsher
10302b133ad6SJeff Kirsher dma_ctrl_data = DMA_CTRL_RXCMB_EN;
10312b133ad6SJeff Kirsher dma_ctrl_data |= (((u32)hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
10322b133ad6SJeff Kirsher << DMA_CTRL_DMAR_BURST_LEN_SHIFT;
10332b133ad6SJeff Kirsher dma_ctrl_data |= (((u32)hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
10342b133ad6SJeff Kirsher << DMA_CTRL_DMAW_BURST_LEN_SHIFT;
10352b133ad6SJeff Kirsher dma_ctrl_data |= DMA_CTRL_DMAR_REQ_PRI | DMA_CTRL_DMAR_OUT_ORDER;
10362b133ad6SJeff Kirsher dma_ctrl_data |= (((u32)hw->dmar_dly_cnt) & DMA_CTRL_DMAR_DLY_CNT_MASK)
10372b133ad6SJeff Kirsher << DMA_CTRL_DMAR_DLY_CNT_SHIFT;
10382b133ad6SJeff Kirsher dma_ctrl_data |= (((u32)hw->dmaw_dly_cnt) & DMA_CTRL_DMAW_DLY_CNT_MASK)
10392b133ad6SJeff Kirsher << DMA_CTRL_DMAW_DLY_CNT_SHIFT;
10402b133ad6SJeff Kirsher
10412b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_DMA_CTRL, dma_ctrl_data);
10422b133ad6SJeff Kirsher }
10432b133ad6SJeff Kirsher
atl1e_setup_mac_ctrl(struct atl1e_adapter * adapter)10442b133ad6SJeff Kirsher static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
10452b133ad6SJeff Kirsher {
10462b133ad6SJeff Kirsher u32 value;
10472b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
10482b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
10492b133ad6SJeff Kirsher
10502b133ad6SJeff Kirsher /* Config MAC CTRL Register */
10512b133ad6SJeff Kirsher value = MAC_CTRL_TX_EN |
10522b133ad6SJeff Kirsher MAC_CTRL_RX_EN ;
10532b133ad6SJeff Kirsher
10542b133ad6SJeff Kirsher if (FULL_DUPLEX == adapter->link_duplex)
10552b133ad6SJeff Kirsher value |= MAC_CTRL_DUPLX;
10562b133ad6SJeff Kirsher
10572b133ad6SJeff Kirsher value |= ((u32)((SPEED_1000 == adapter->link_speed) ?
10582b133ad6SJeff Kirsher MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100) <<
10592b133ad6SJeff Kirsher MAC_CTRL_SPEED_SHIFT);
10602b133ad6SJeff Kirsher value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW);
10612b133ad6SJeff Kirsher
10622b133ad6SJeff Kirsher value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD);
10632b133ad6SJeff Kirsher value |= (((u32)adapter->hw.preamble_len &
10642b133ad6SJeff Kirsher MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT);
10652b133ad6SJeff Kirsher
10662b133ad6SJeff Kirsher __atl1e_vlan_mode(netdev->features, &value);
10672b133ad6SJeff Kirsher
10682b133ad6SJeff Kirsher value |= MAC_CTRL_BC_EN;
10692b133ad6SJeff Kirsher if (netdev->flags & IFF_PROMISC)
10702b133ad6SJeff Kirsher value |= MAC_CTRL_PROMIS_EN;
10712b133ad6SJeff Kirsher if (netdev->flags & IFF_ALLMULTI)
10722b133ad6SJeff Kirsher value |= MAC_CTRL_MC_ALL_EN;
107340dc9ab2SAndrea Merello if (netdev->features & NETIF_F_RXALL)
107440dc9ab2SAndrea Merello value |= MAC_CTRL_DBG;
10752b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_MAC_CTRL, value);
10762b133ad6SJeff Kirsher }
10772b133ad6SJeff Kirsher
107849ce9c2cSBen Hutchings /**
10792b133ad6SJeff Kirsher * atl1e_configure - Configure Transmit&Receive Unit after Reset
10802b133ad6SJeff Kirsher * @adapter: board private structure
10812b133ad6SJeff Kirsher *
10822b133ad6SJeff Kirsher * Configure the Tx /Rx unit of the MAC after a reset.
10832b133ad6SJeff Kirsher */
atl1e_configure(struct atl1e_adapter * adapter)10842b133ad6SJeff Kirsher static int atl1e_configure(struct atl1e_adapter *adapter)
10852b133ad6SJeff Kirsher {
10862b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
10872b133ad6SJeff Kirsher
10882b133ad6SJeff Kirsher u32 intr_status_data = 0;
10892b133ad6SJeff Kirsher
10902b133ad6SJeff Kirsher /* clear interrupt status */
10912b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_ISR, ~0);
10922b133ad6SJeff Kirsher
10932b133ad6SJeff Kirsher /* 1. set MAC Address */
10942b133ad6SJeff Kirsher atl1e_hw_set_mac_addr(hw);
10952b133ad6SJeff Kirsher
10962b133ad6SJeff Kirsher /* 2. Init the Multicast HASH table done by set_muti */
10972b133ad6SJeff Kirsher
10982b133ad6SJeff Kirsher /* 3. Clear any WOL status */
10992b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
11002b133ad6SJeff Kirsher
11012b133ad6SJeff Kirsher /* 4. Descripter Ring BaseMem/Length/Read ptr/Write ptr
11022b133ad6SJeff Kirsher * TPD Ring/SMB/RXF0 Page CMBs, they use the same
11032b133ad6SJeff Kirsher * High 32bits memory */
11042b133ad6SJeff Kirsher atl1e_configure_des_ring(adapter);
11052b133ad6SJeff Kirsher
11062b133ad6SJeff Kirsher /* 5. set Interrupt Moderator Timer */
11072b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, hw->imt);
11082b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER2_INIT, hw->imt);
11092b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_LED_MODE |
11102b133ad6SJeff Kirsher MASTER_CTRL_ITIMER_EN | MASTER_CTRL_ITIMER2_EN);
11112b133ad6SJeff Kirsher
11122b133ad6SJeff Kirsher /* 6. rx/tx threshold to trig interrupt */
11132b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_TRIG_RRD_THRESH, hw->rrd_thresh);
11142b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_TRIG_TPD_THRESH, hw->tpd_thresh);
11152b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_TRIG_RXTIMER, hw->rx_count_down);
11162b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_TRIG_TXTIMER, hw->tx_count_down);
11172b133ad6SJeff Kirsher
11182b133ad6SJeff Kirsher /* 7. set Interrupt Clear Timer */
11192b133ad6SJeff Kirsher AT_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, hw->ict);
11202b133ad6SJeff Kirsher
11212b133ad6SJeff Kirsher /* 8. set MTU */
11222b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ETH_HLEN +
11232b133ad6SJeff Kirsher VLAN_HLEN + ETH_FCS_LEN);
11242b133ad6SJeff Kirsher
11252b133ad6SJeff Kirsher /* 9. config TXQ early tx threshold */
11262b133ad6SJeff Kirsher atl1e_configure_tx(adapter);
11272b133ad6SJeff Kirsher
11282b133ad6SJeff Kirsher /* 10. config RXQ */
11292b133ad6SJeff Kirsher atl1e_configure_rx(adapter);
11302b133ad6SJeff Kirsher
11312b133ad6SJeff Kirsher /* 11. config DMA Engine */
11322b133ad6SJeff Kirsher atl1e_configure_dma(adapter);
11332b133ad6SJeff Kirsher
11342b133ad6SJeff Kirsher /* 12. smb timer to trig interrupt */
11352b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_SMB_STAT_TIMER, hw->smb_timer);
11362b133ad6SJeff Kirsher
11372b133ad6SJeff Kirsher intr_status_data = AT_READ_REG(hw, REG_ISR);
11382b133ad6SJeff Kirsher if (unlikely((intr_status_data & ISR_PHY_LINKDOWN) != 0)) {
11392b133ad6SJeff Kirsher netdev_err(adapter->netdev,
11402b133ad6SJeff Kirsher "atl1e_configure failed, PCIE phy link down\n");
11412b133ad6SJeff Kirsher return -1;
11422b133ad6SJeff Kirsher }
11432b133ad6SJeff Kirsher
11442b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_ISR, 0x7fffffff);
11452b133ad6SJeff Kirsher return 0;
11462b133ad6SJeff Kirsher }
11472b133ad6SJeff Kirsher
114849ce9c2cSBen Hutchings /**
11492b133ad6SJeff Kirsher * atl1e_get_stats - Get System Network Statistics
11502b133ad6SJeff Kirsher * @netdev: network interface device structure
11512b133ad6SJeff Kirsher *
11522b133ad6SJeff Kirsher * Returns the address of the device statistics structure.
11532b133ad6SJeff Kirsher * The statistics are actually updated from the timer callback.
11542b133ad6SJeff Kirsher */
atl1e_get_stats(struct net_device * netdev)11552b133ad6SJeff Kirsher static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
11562b133ad6SJeff Kirsher {
11572b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
11582b133ad6SJeff Kirsher struct atl1e_hw_stats *hw_stats = &adapter->hw_stats;
11592b133ad6SJeff Kirsher struct net_device_stats *net_stats = &netdev->stats;
11602b133ad6SJeff Kirsher
11612b133ad6SJeff Kirsher net_stats->rx_bytes = hw_stats->rx_byte_cnt;
11622b133ad6SJeff Kirsher net_stats->tx_bytes = hw_stats->tx_byte_cnt;
11632b133ad6SJeff Kirsher net_stats->multicast = hw_stats->rx_mcast;
11642b133ad6SJeff Kirsher net_stats->collisions = hw_stats->tx_1_col +
1165fb3a42fcSSabrina Dubroca hw_stats->tx_2_col +
1166fb3a42fcSSabrina Dubroca hw_stats->tx_late_col +
1167fb3a42fcSSabrina Dubroca hw_stats->tx_abort_col;
11682b133ad6SJeff Kirsher
1169fb3a42fcSSabrina Dubroca net_stats->rx_errors = hw_stats->rx_frag +
1170fb3a42fcSSabrina Dubroca hw_stats->rx_fcs_err +
1171fb3a42fcSSabrina Dubroca hw_stats->rx_len_err +
1172fb3a42fcSSabrina Dubroca hw_stats->rx_sz_ov +
1173fb3a42fcSSabrina Dubroca hw_stats->rx_rrd_ov +
1174fb3a42fcSSabrina Dubroca hw_stats->rx_align_err +
1175fb3a42fcSSabrina Dubroca hw_stats->rx_rxf_ov;
1176fb3a42fcSSabrina Dubroca
11772b133ad6SJeff Kirsher net_stats->rx_fifo_errors = hw_stats->rx_rxf_ov;
11782b133ad6SJeff Kirsher net_stats->rx_length_errors = hw_stats->rx_len_err;
11792b133ad6SJeff Kirsher net_stats->rx_crc_errors = hw_stats->rx_fcs_err;
11802b133ad6SJeff Kirsher net_stats->rx_frame_errors = hw_stats->rx_align_err;
1181fb3a42fcSSabrina Dubroca net_stats->rx_dropped = hw_stats->rx_rrd_ov;
11822b133ad6SJeff Kirsher
1183fb3a42fcSSabrina Dubroca net_stats->tx_errors = hw_stats->tx_late_col +
1184fb3a42fcSSabrina Dubroca hw_stats->tx_abort_col +
1185fb3a42fcSSabrina Dubroca hw_stats->tx_underrun +
1186fb3a42fcSSabrina Dubroca hw_stats->tx_trunc;
11872b133ad6SJeff Kirsher
11882b133ad6SJeff Kirsher net_stats->tx_fifo_errors = hw_stats->tx_underrun;
11892b133ad6SJeff Kirsher net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
11902b133ad6SJeff Kirsher net_stats->tx_window_errors = hw_stats->tx_late_col;
11912b133ad6SJeff Kirsher
1192fb3a42fcSSabrina Dubroca net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors;
1193fb3a42fcSSabrina Dubroca net_stats->tx_packets = hw_stats->tx_ok + net_stats->tx_errors;
1194fb3a42fcSSabrina Dubroca
11952b133ad6SJeff Kirsher return net_stats;
11962b133ad6SJeff Kirsher }
11972b133ad6SJeff Kirsher
atl1e_update_hw_stats(struct atl1e_adapter * adapter)11982b133ad6SJeff Kirsher static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
11992b133ad6SJeff Kirsher {
12002b133ad6SJeff Kirsher u16 hw_reg_addr = 0;
12012b133ad6SJeff Kirsher unsigned long *stats_item = NULL;
12022b133ad6SJeff Kirsher
12032b133ad6SJeff Kirsher /* update rx status */
12042b133ad6SJeff Kirsher hw_reg_addr = REG_MAC_RX_STATUS_BIN;
12052b133ad6SJeff Kirsher stats_item = &adapter->hw_stats.rx_ok;
12062b133ad6SJeff Kirsher while (hw_reg_addr <= REG_MAC_RX_STATUS_END) {
12072b133ad6SJeff Kirsher *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
12082b133ad6SJeff Kirsher stats_item++;
12092b133ad6SJeff Kirsher hw_reg_addr += 4;
12102b133ad6SJeff Kirsher }
12112b133ad6SJeff Kirsher /* update tx status */
12122b133ad6SJeff Kirsher hw_reg_addr = REG_MAC_TX_STATUS_BIN;
12132b133ad6SJeff Kirsher stats_item = &adapter->hw_stats.tx_ok;
12142b133ad6SJeff Kirsher while (hw_reg_addr <= REG_MAC_TX_STATUS_END) {
12152b133ad6SJeff Kirsher *stats_item += AT_READ_REG(&adapter->hw, hw_reg_addr);
12162b133ad6SJeff Kirsher stats_item++;
12172b133ad6SJeff Kirsher hw_reg_addr += 4;
12182b133ad6SJeff Kirsher }
12192b133ad6SJeff Kirsher }
12202b133ad6SJeff Kirsher
atl1e_clear_phy_int(struct atl1e_adapter * adapter)12212b133ad6SJeff Kirsher static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter)
12222b133ad6SJeff Kirsher {
12232b133ad6SJeff Kirsher u16 phy_data;
12242b133ad6SJeff Kirsher
12252b133ad6SJeff Kirsher spin_lock(&adapter->mdio_lock);
12262b133ad6SJeff Kirsher atl1e_read_phy_reg(&adapter->hw, MII_INT_STATUS, &phy_data);
12272b133ad6SJeff Kirsher spin_unlock(&adapter->mdio_lock);
12282b133ad6SJeff Kirsher }
12292b133ad6SJeff Kirsher
atl1e_clean_tx_irq(struct atl1e_adapter * adapter)12302b133ad6SJeff Kirsher static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
12312b133ad6SJeff Kirsher {
123264699336SJoe Perches struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
12332b133ad6SJeff Kirsher struct atl1e_tx_buffer *tx_buffer = NULL;
12342b133ad6SJeff Kirsher u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
12352b133ad6SJeff Kirsher u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
12362b133ad6SJeff Kirsher
12372b133ad6SJeff Kirsher while (next_to_clean != hw_next_to_clean) {
12382b133ad6SJeff Kirsher tx_buffer = &tx_ring->tx_buffer[next_to_clean];
12392b133ad6SJeff Kirsher if (tx_buffer->dma) {
12402b133ad6SJeff Kirsher if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
124185eb5bc3SChristophe JAILLET dma_unmap_single(&adapter->pdev->dev,
124285eb5bc3SChristophe JAILLET tx_buffer->dma,
124385eb5bc3SChristophe JAILLET tx_buffer->length,
124485eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
12452b133ad6SJeff Kirsher else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
124685eb5bc3SChristophe JAILLET dma_unmap_page(&adapter->pdev->dev,
124785eb5bc3SChristophe JAILLET tx_buffer->dma,
124885eb5bc3SChristophe JAILLET tx_buffer->length,
124985eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
12502b133ad6SJeff Kirsher tx_buffer->dma = 0;
12512b133ad6SJeff Kirsher }
12522b133ad6SJeff Kirsher
12532b133ad6SJeff Kirsher if (tx_buffer->skb) {
1254d270f67dSYang Wei dev_consume_skb_irq(tx_buffer->skb);
12552b133ad6SJeff Kirsher tx_buffer->skb = NULL;
12562b133ad6SJeff Kirsher }
12572b133ad6SJeff Kirsher
12582b133ad6SJeff Kirsher if (++next_to_clean == tx_ring->count)
12592b133ad6SJeff Kirsher next_to_clean = 0;
12602b133ad6SJeff Kirsher }
12612b133ad6SJeff Kirsher
12622b133ad6SJeff Kirsher atomic_set(&tx_ring->next_to_clean, next_to_clean);
12632b133ad6SJeff Kirsher
12642b133ad6SJeff Kirsher if (netif_queue_stopped(adapter->netdev) &&
12652b133ad6SJeff Kirsher netif_carrier_ok(adapter->netdev)) {
12662b133ad6SJeff Kirsher netif_wake_queue(adapter->netdev);
12672b133ad6SJeff Kirsher }
12682b133ad6SJeff Kirsher
12692b133ad6SJeff Kirsher return true;
12702b133ad6SJeff Kirsher }
12712b133ad6SJeff Kirsher
127249ce9c2cSBen Hutchings /**
12732b133ad6SJeff Kirsher * atl1e_intr - Interrupt Handler
12742b133ad6SJeff Kirsher * @irq: interrupt number
12752b133ad6SJeff Kirsher * @data: pointer to a network interface device structure
12762b133ad6SJeff Kirsher */
atl1e_intr(int irq,void * data)12772b133ad6SJeff Kirsher static irqreturn_t atl1e_intr(int irq, void *data)
12782b133ad6SJeff Kirsher {
12792b133ad6SJeff Kirsher struct net_device *netdev = data;
12802b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
12812b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
12822b133ad6SJeff Kirsher int max_ints = AT_MAX_INT_WORK;
12832b133ad6SJeff Kirsher int handled = IRQ_NONE;
12842b133ad6SJeff Kirsher u32 status;
12852b133ad6SJeff Kirsher
12862b133ad6SJeff Kirsher do {
12872b133ad6SJeff Kirsher status = AT_READ_REG(hw, REG_ISR);
12882b133ad6SJeff Kirsher if ((status & IMR_NORMAL_MASK) == 0 ||
12892b133ad6SJeff Kirsher (status & ISR_DIS_INT) != 0) {
12902b133ad6SJeff Kirsher if (max_ints != AT_MAX_INT_WORK)
12912b133ad6SJeff Kirsher handled = IRQ_HANDLED;
12922b133ad6SJeff Kirsher break;
12932b133ad6SJeff Kirsher }
12942b133ad6SJeff Kirsher /* link event */
12952b133ad6SJeff Kirsher if (status & ISR_GPHY)
12962b133ad6SJeff Kirsher atl1e_clear_phy_int(adapter);
12972b133ad6SJeff Kirsher /* Ack ISR */
12982b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT);
12992b133ad6SJeff Kirsher
13002b133ad6SJeff Kirsher handled = IRQ_HANDLED;
13012b133ad6SJeff Kirsher /* check if PCIE PHY Link down */
13022b133ad6SJeff Kirsher if (status & ISR_PHY_LINKDOWN) {
13032b133ad6SJeff Kirsher netdev_err(adapter->netdev,
13042b133ad6SJeff Kirsher "pcie phy linkdown %x\n", status);
13052b133ad6SJeff Kirsher if (netif_running(adapter->netdev)) {
13062b133ad6SJeff Kirsher /* reset MAC */
13072b133ad6SJeff Kirsher atl1e_irq_reset(adapter);
13082b133ad6SJeff Kirsher schedule_work(&adapter->reset_task);
13092b133ad6SJeff Kirsher break;
13102b133ad6SJeff Kirsher }
13112b133ad6SJeff Kirsher }
13122b133ad6SJeff Kirsher
13132b133ad6SJeff Kirsher /* check if DMA read/write error */
13142b133ad6SJeff Kirsher if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
13152b133ad6SJeff Kirsher netdev_err(adapter->netdev,
13162b133ad6SJeff Kirsher "PCIE DMA RW error (status = 0x%x)\n",
13172b133ad6SJeff Kirsher status);
13182b133ad6SJeff Kirsher atl1e_irq_reset(adapter);
13192b133ad6SJeff Kirsher schedule_work(&adapter->reset_task);
13202b133ad6SJeff Kirsher break;
13212b133ad6SJeff Kirsher }
13222b133ad6SJeff Kirsher
13232b133ad6SJeff Kirsher if (status & ISR_SMB)
13242b133ad6SJeff Kirsher atl1e_update_hw_stats(adapter);
13252b133ad6SJeff Kirsher
13262b133ad6SJeff Kirsher /* link event */
13272b133ad6SJeff Kirsher if (status & (ISR_GPHY | ISR_MANUAL)) {
13282b133ad6SJeff Kirsher netdev->stats.tx_carrier_errors++;
13292b133ad6SJeff Kirsher atl1e_link_chg_event(adapter);
13302b133ad6SJeff Kirsher break;
13312b133ad6SJeff Kirsher }
13322b133ad6SJeff Kirsher
13332b133ad6SJeff Kirsher /* transmit event */
13342b133ad6SJeff Kirsher if (status & ISR_TX_EVENT)
13352b133ad6SJeff Kirsher atl1e_clean_tx_irq(adapter);
13362b133ad6SJeff Kirsher
13372b133ad6SJeff Kirsher if (status & ISR_RX_EVENT) {
13382b133ad6SJeff Kirsher /*
13392b133ad6SJeff Kirsher * disable rx interrupts, without
13402b133ad6SJeff Kirsher * the synchronize_irq bit
13412b133ad6SJeff Kirsher */
13422b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_IMR,
13432b133ad6SJeff Kirsher IMR_NORMAL_MASK & ~ISR_RX_EVENT);
13442b133ad6SJeff Kirsher AT_WRITE_FLUSH(hw);
13452b133ad6SJeff Kirsher if (likely(napi_schedule_prep(
13462b133ad6SJeff Kirsher &adapter->napi)))
13472b133ad6SJeff Kirsher __napi_schedule(&adapter->napi);
13482b133ad6SJeff Kirsher }
13492b133ad6SJeff Kirsher } while (--max_ints > 0);
13502b133ad6SJeff Kirsher /* re-enable Interrupt*/
13512b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_ISR, 0);
13522b133ad6SJeff Kirsher
13532b133ad6SJeff Kirsher return handled;
13542b133ad6SJeff Kirsher }
13552b133ad6SJeff Kirsher
atl1e_rx_checksum(struct atl1e_adapter * adapter,struct sk_buff * skb,struct atl1e_recv_ret_status * prrs)13562b133ad6SJeff Kirsher static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter,
13572b133ad6SJeff Kirsher struct sk_buff *skb, struct atl1e_recv_ret_status *prrs)
13582b133ad6SJeff Kirsher {
13592b133ad6SJeff Kirsher u8 *packet = (u8 *)(prrs + 1);
13602b133ad6SJeff Kirsher struct iphdr *iph;
13612b133ad6SJeff Kirsher u16 head_len = ETH_HLEN;
13622b133ad6SJeff Kirsher u16 pkt_flags;
13632b133ad6SJeff Kirsher u16 err_flags;
13642b133ad6SJeff Kirsher
13652b133ad6SJeff Kirsher skb_checksum_none_assert(skb);
13662b133ad6SJeff Kirsher pkt_flags = prrs->pkt_flag;
13672b133ad6SJeff Kirsher err_flags = prrs->err_flag;
13682b133ad6SJeff Kirsher if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) &&
13692b133ad6SJeff Kirsher ((pkt_flags & RRS_IS_TCP) || (pkt_flags & RRS_IS_UDP))) {
13702b133ad6SJeff Kirsher if (pkt_flags & RRS_IS_IPV4) {
13712b133ad6SJeff Kirsher if (pkt_flags & RRS_IS_802_3)
13722b133ad6SJeff Kirsher head_len += 8;
13732b133ad6SJeff Kirsher iph = (struct iphdr *) (packet + head_len);
13742b133ad6SJeff Kirsher if (iph->frag_off != 0 && !(pkt_flags & RRS_IS_IP_DF))
13752b133ad6SJeff Kirsher goto hw_xsum;
13762b133ad6SJeff Kirsher }
13772b133ad6SJeff Kirsher if (!(err_flags & (RRS_ERR_IP_CSUM | RRS_ERR_L4_CSUM))) {
13782b133ad6SJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY;
13792b133ad6SJeff Kirsher return;
13802b133ad6SJeff Kirsher }
13812b133ad6SJeff Kirsher }
13822b133ad6SJeff Kirsher
13832b133ad6SJeff Kirsher hw_xsum :
13842b133ad6SJeff Kirsher return;
13852b133ad6SJeff Kirsher }
13862b133ad6SJeff Kirsher
atl1e_get_rx_page(struct atl1e_adapter * adapter,u8 que)13872b133ad6SJeff Kirsher static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter,
13882b133ad6SJeff Kirsher u8 que)
13892b133ad6SJeff Kirsher {
13902b133ad6SJeff Kirsher struct atl1e_rx_page_desc *rx_page_desc =
13912b133ad6SJeff Kirsher (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc;
13922b133ad6SJeff Kirsher u8 rx_using = rx_page_desc[que].rx_using;
13932b133ad6SJeff Kirsher
139464699336SJoe Perches return &(rx_page_desc[que].rx_page[rx_using]);
13952b133ad6SJeff Kirsher }
13962b133ad6SJeff Kirsher
atl1e_clean_rx_irq(struct atl1e_adapter * adapter,u8 que,int * work_done,int work_to_do)13972b133ad6SJeff Kirsher static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
13982b133ad6SJeff Kirsher int *work_done, int work_to_do)
13992b133ad6SJeff Kirsher {
14002b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
140164699336SJoe Perches struct atl1e_rx_ring *rx_ring = &adapter->rx_ring;
14022b133ad6SJeff Kirsher struct atl1e_rx_page_desc *rx_page_desc =
14032b133ad6SJeff Kirsher (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc;
14042b133ad6SJeff Kirsher struct sk_buff *skb = NULL;
14052b133ad6SJeff Kirsher struct atl1e_rx_page *rx_page = atl1e_get_rx_page(adapter, que);
14062b133ad6SJeff Kirsher u32 packet_size, write_offset;
14072b133ad6SJeff Kirsher struct atl1e_recv_ret_status *prrs;
14082b133ad6SJeff Kirsher
14092b133ad6SJeff Kirsher write_offset = *(rx_page->write_offset_addr);
14102b133ad6SJeff Kirsher if (likely(rx_page->read_offset < write_offset)) {
14112b133ad6SJeff Kirsher do {
14122b133ad6SJeff Kirsher if (*work_done >= work_to_do)
14132b133ad6SJeff Kirsher break;
14142b133ad6SJeff Kirsher (*work_done)++;
14152b133ad6SJeff Kirsher /* get new packet's rrs */
14162b133ad6SJeff Kirsher prrs = (struct atl1e_recv_ret_status *) (rx_page->addr +
14172b133ad6SJeff Kirsher rx_page->read_offset);
14182b133ad6SJeff Kirsher /* check sequence number */
14192b133ad6SJeff Kirsher if (prrs->seq_num != rx_page_desc[que].rx_nxseq) {
14202b133ad6SJeff Kirsher netdev_err(netdev,
14212b133ad6SJeff Kirsher "rx sequence number error (rx=%d) (expect=%d)\n",
14222b133ad6SJeff Kirsher prrs->seq_num,
14232b133ad6SJeff Kirsher rx_page_desc[que].rx_nxseq);
14242b133ad6SJeff Kirsher rx_page_desc[que].rx_nxseq++;
14252b133ad6SJeff Kirsher /* just for debug use */
14262b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_DEBUG_DATA0,
14272b133ad6SJeff Kirsher (((u32)prrs->seq_num) << 16) |
14282b133ad6SJeff Kirsher rx_page_desc[que].rx_nxseq);
14292b133ad6SJeff Kirsher goto fatal_err;
14302b133ad6SJeff Kirsher }
14312b133ad6SJeff Kirsher rx_page_desc[que].rx_nxseq++;
14322b133ad6SJeff Kirsher
14332b133ad6SJeff Kirsher /* error packet */
143440dc9ab2SAndrea Merello if ((prrs->pkt_flag & RRS_IS_ERR_FRAME) &&
143540dc9ab2SAndrea Merello !(netdev->features & NETIF_F_RXALL)) {
14362b133ad6SJeff Kirsher if (prrs->err_flag & (RRS_ERR_BAD_CRC |
14372b133ad6SJeff Kirsher RRS_ERR_DRIBBLE | RRS_ERR_CODE |
14382b133ad6SJeff Kirsher RRS_ERR_TRUNC)) {
14392b133ad6SJeff Kirsher /* hardware error, discard this packet*/
14402b133ad6SJeff Kirsher netdev_err(netdev,
14412b133ad6SJeff Kirsher "rx packet desc error %x\n",
14422b133ad6SJeff Kirsher *((u32 *)prrs + 1));
14432b133ad6SJeff Kirsher goto skip_pkt;
14442b133ad6SJeff Kirsher }
14452b133ad6SJeff Kirsher }
14462b133ad6SJeff Kirsher
14472b133ad6SJeff Kirsher packet_size = ((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
144840dc9ab2SAndrea Merello RRS_PKT_SIZE_MASK);
144940dc9ab2SAndrea Merello if (likely(!(netdev->features & NETIF_F_RXFCS)))
145040dc9ab2SAndrea Merello packet_size -= 4; /* CRC */
145140dc9ab2SAndrea Merello
14522b133ad6SJeff Kirsher skb = netdev_alloc_skb_ip_align(netdev, packet_size);
1453720a43efSJoe Perches if (skb == NULL)
14542b133ad6SJeff Kirsher goto skip_pkt;
1455720a43efSJoe Perches
14562b133ad6SJeff Kirsher memcpy(skb->data, (u8 *)(prrs + 1), packet_size);
14572b133ad6SJeff Kirsher skb_put(skb, packet_size);
14582b133ad6SJeff Kirsher skb->protocol = eth_type_trans(skb, netdev);
14592b133ad6SJeff Kirsher atl1e_rx_checksum(adapter, skb, prrs);
14602b133ad6SJeff Kirsher
14612b133ad6SJeff Kirsher if (prrs->pkt_flag & RRS_IS_VLAN_TAG) {
14622b133ad6SJeff Kirsher u16 vlan_tag = (prrs->vtag >> 4) |
14632b133ad6SJeff Kirsher ((prrs->vtag & 7) << 13) |
14642b133ad6SJeff Kirsher ((prrs->vtag & 8) << 9);
14652b133ad6SJeff Kirsher netdev_dbg(netdev,
14662b133ad6SJeff Kirsher "RXD VLAN TAG<RRD>=0x%04x\n",
14672b133ad6SJeff Kirsher prrs->vtag);
146886a9bad3SPatrick McHardy __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
14692b133ad6SJeff Kirsher }
1470c45f8e10SEric Dumazet napi_gro_receive(&adapter->napi, skb);
14712b133ad6SJeff Kirsher
14722b133ad6SJeff Kirsher skip_pkt:
14732b133ad6SJeff Kirsher /* skip current packet whether it's ok or not. */
14742b133ad6SJeff Kirsher rx_page->read_offset +=
14752b133ad6SJeff Kirsher (((u32)((prrs->word1 >> RRS_PKT_SIZE_SHIFT) &
14762b133ad6SJeff Kirsher RRS_PKT_SIZE_MASK) +
14772b133ad6SJeff Kirsher sizeof(struct atl1e_recv_ret_status) + 31) &
14782b133ad6SJeff Kirsher 0xFFFFFFE0);
14792b133ad6SJeff Kirsher
14802b133ad6SJeff Kirsher if (rx_page->read_offset >= rx_ring->page_size) {
14812b133ad6SJeff Kirsher /* mark this page clean */
14822b133ad6SJeff Kirsher u16 reg_addr;
14832b133ad6SJeff Kirsher u8 rx_using;
14842b133ad6SJeff Kirsher
14852b133ad6SJeff Kirsher rx_page->read_offset =
14862b133ad6SJeff Kirsher *(rx_page->write_offset_addr) = 0;
14872b133ad6SJeff Kirsher rx_using = rx_page_desc[que].rx_using;
14882b133ad6SJeff Kirsher reg_addr =
14892b133ad6SJeff Kirsher atl1e_rx_page_vld_regs[que][rx_using];
14902b133ad6SJeff Kirsher AT_WRITE_REGB(&adapter->hw, reg_addr, 1);
14912b133ad6SJeff Kirsher rx_page_desc[que].rx_using ^= 1;
14922b133ad6SJeff Kirsher rx_page = atl1e_get_rx_page(adapter, que);
14932b133ad6SJeff Kirsher }
14942b133ad6SJeff Kirsher write_offset = *(rx_page->write_offset_addr);
14952b133ad6SJeff Kirsher } while (rx_page->read_offset < write_offset);
14962b133ad6SJeff Kirsher }
14972b133ad6SJeff Kirsher
14982b133ad6SJeff Kirsher return;
14992b133ad6SJeff Kirsher
15002b133ad6SJeff Kirsher fatal_err:
15012b133ad6SJeff Kirsher if (!test_bit(__AT_DOWN, &adapter->flags))
15022b133ad6SJeff Kirsher schedule_work(&adapter->reset_task);
15032b133ad6SJeff Kirsher }
15042b133ad6SJeff Kirsher
150549ce9c2cSBen Hutchings /**
15062b133ad6SJeff Kirsher * atl1e_clean - NAPI Rx polling callback
1507d0ea5cbdSJesse Brandeburg * @napi: napi info
1508d0ea5cbdSJesse Brandeburg * @budget: number of packets to clean
15092b133ad6SJeff Kirsher */
atl1e_clean(struct napi_struct * napi,int budget)15102b133ad6SJeff Kirsher static int atl1e_clean(struct napi_struct *napi, int budget)
15112b133ad6SJeff Kirsher {
15122b133ad6SJeff Kirsher struct atl1e_adapter *adapter =
15132b133ad6SJeff Kirsher container_of(napi, struct atl1e_adapter, napi);
15142b133ad6SJeff Kirsher u32 imr_data;
15152b133ad6SJeff Kirsher int work_done = 0;
15162b133ad6SJeff Kirsher
15172b133ad6SJeff Kirsher /* Keep link state information with original netdev */
15182b133ad6SJeff Kirsher if (!netif_carrier_ok(adapter->netdev))
15192b133ad6SJeff Kirsher goto quit_polling;
15202b133ad6SJeff Kirsher
15212b133ad6SJeff Kirsher atl1e_clean_rx_irq(adapter, 0, &work_done, budget);
15222b133ad6SJeff Kirsher
15232b133ad6SJeff Kirsher /* If no Tx and not enough Rx work done, exit the polling mode */
15242b133ad6SJeff Kirsher if (work_done < budget) {
15252b133ad6SJeff Kirsher quit_polling:
15266ad20165SEric Dumazet napi_complete_done(napi, work_done);
15272b133ad6SJeff Kirsher imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
15282b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
15292b133ad6SJeff Kirsher /* test debug */
15302b133ad6SJeff Kirsher if (test_bit(__AT_DOWN, &adapter->flags)) {
15312b133ad6SJeff Kirsher atomic_dec(&adapter->irq_sem);
15322b133ad6SJeff Kirsher netdev_err(adapter->netdev,
15332b133ad6SJeff Kirsher "atl1e_clean is called when AT_DOWN\n");
15342b133ad6SJeff Kirsher }
15352b133ad6SJeff Kirsher /* reenable RX intr */
15362b133ad6SJeff Kirsher /*atl1e_irq_enable(adapter); */
15372b133ad6SJeff Kirsher
15382b133ad6SJeff Kirsher }
15392b133ad6SJeff Kirsher return work_done;
15402b133ad6SJeff Kirsher }
15412b133ad6SJeff Kirsher
15422b133ad6SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
15432b133ad6SJeff Kirsher
15442b133ad6SJeff Kirsher /*
15452b133ad6SJeff Kirsher * Polling 'interrupt' - used by things like netconsole to send skbs
15462b133ad6SJeff Kirsher * without having to re-enable interrupts. It's not called while
15472b133ad6SJeff Kirsher * the interrupt routine is executing.
15482b133ad6SJeff Kirsher */
atl1e_netpoll(struct net_device * netdev)15492b133ad6SJeff Kirsher static void atl1e_netpoll(struct net_device *netdev)
15502b133ad6SJeff Kirsher {
15512b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
15522b133ad6SJeff Kirsher
15532b133ad6SJeff Kirsher disable_irq(adapter->pdev->irq);
15542b133ad6SJeff Kirsher atl1e_intr(adapter->pdev->irq, netdev);
15552b133ad6SJeff Kirsher enable_irq(adapter->pdev->irq);
15562b133ad6SJeff Kirsher }
15572b133ad6SJeff Kirsher #endif
15582b133ad6SJeff Kirsher
atl1e_tpd_avail(struct atl1e_adapter * adapter)15592b133ad6SJeff Kirsher static inline u16 atl1e_tpd_avail(struct atl1e_adapter *adapter)
15602b133ad6SJeff Kirsher {
15612b133ad6SJeff Kirsher struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
15622b133ad6SJeff Kirsher u16 next_to_use = 0;
15632b133ad6SJeff Kirsher u16 next_to_clean = 0;
15642b133ad6SJeff Kirsher
15652b133ad6SJeff Kirsher next_to_clean = atomic_read(&tx_ring->next_to_clean);
15662b133ad6SJeff Kirsher next_to_use = tx_ring->next_to_use;
15672b133ad6SJeff Kirsher
15682b133ad6SJeff Kirsher return (u16)(next_to_clean > next_to_use) ?
15692b133ad6SJeff Kirsher (next_to_clean - next_to_use - 1) :
15702b133ad6SJeff Kirsher (tx_ring->count + next_to_clean - next_to_use - 1);
15712b133ad6SJeff Kirsher }
15722b133ad6SJeff Kirsher
15732b133ad6SJeff Kirsher /*
15742b133ad6SJeff Kirsher * get next usable tpd
15752b133ad6SJeff Kirsher * Note: should call atl1e_tdp_avail to make sure
15762b133ad6SJeff Kirsher * there is enough tpd to use
15772b133ad6SJeff Kirsher */
atl1e_get_tpd(struct atl1e_adapter * adapter)15782b133ad6SJeff Kirsher static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter)
15792b133ad6SJeff Kirsher {
15802b133ad6SJeff Kirsher struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
15812b133ad6SJeff Kirsher u16 next_to_use = 0;
15822b133ad6SJeff Kirsher
15832b133ad6SJeff Kirsher next_to_use = tx_ring->next_to_use;
15842b133ad6SJeff Kirsher if (++tx_ring->next_to_use == tx_ring->count)
15852b133ad6SJeff Kirsher tx_ring->next_to_use = 0;
15862b133ad6SJeff Kirsher
15872b133ad6SJeff Kirsher memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc));
158864699336SJoe Perches return &tx_ring->desc[next_to_use];
15892b133ad6SJeff Kirsher }
15902b133ad6SJeff Kirsher
15912b133ad6SJeff Kirsher static struct atl1e_tx_buffer *
atl1e_get_tx_buffer(struct atl1e_adapter * adapter,struct atl1e_tpd_desc * tpd)15922b133ad6SJeff Kirsher atl1e_get_tx_buffer(struct atl1e_adapter *adapter, struct atl1e_tpd_desc *tpd)
15932b133ad6SJeff Kirsher {
15942b133ad6SJeff Kirsher struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
15952b133ad6SJeff Kirsher
15962b133ad6SJeff Kirsher return &tx_ring->tx_buffer[tpd - tx_ring->desc];
15972b133ad6SJeff Kirsher }
15982b133ad6SJeff Kirsher
15992b133ad6SJeff Kirsher /* Calculate the transmit packet descript needed*/
atl1e_cal_tdp_req(const struct sk_buff * skb)16002b133ad6SJeff Kirsher static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
16012b133ad6SJeff Kirsher {
16022b133ad6SJeff Kirsher int i = 0;
16032b133ad6SJeff Kirsher u16 tpd_req = 1;
16042b133ad6SJeff Kirsher u16 fg_size = 0;
16052b133ad6SJeff Kirsher u16 proto_hdr_len = 0;
16062b133ad6SJeff Kirsher
16072b133ad6SJeff Kirsher for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
16089e903e08SEric Dumazet fg_size = skb_frag_size(&skb_shinfo(skb)->frags[i]);
16092b133ad6SJeff Kirsher tpd_req += ((fg_size + MAX_TX_BUF_LEN - 1) >> MAX_TX_BUF_SHIFT);
16102b133ad6SJeff Kirsher }
16112b133ad6SJeff Kirsher
16122b133ad6SJeff Kirsher if (skb_is_gso(skb)) {
16132b133ad6SJeff Kirsher if (skb->protocol == htons(ETH_P_IP) ||
16142b133ad6SJeff Kirsher (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
1615504148feSEric Dumazet proto_hdr_len = skb_tcp_all_headers(skb);
16162b133ad6SJeff Kirsher if (proto_hdr_len < skb_headlen(skb)) {
16172b133ad6SJeff Kirsher tpd_req += ((skb_headlen(skb) - proto_hdr_len +
16182b133ad6SJeff Kirsher MAX_TX_BUF_LEN - 1) >>
16192b133ad6SJeff Kirsher MAX_TX_BUF_SHIFT);
16202b133ad6SJeff Kirsher }
16212b133ad6SJeff Kirsher }
16222b133ad6SJeff Kirsher
16232b133ad6SJeff Kirsher }
16242b133ad6SJeff Kirsher return tpd_req;
16252b133ad6SJeff Kirsher }
16262b133ad6SJeff Kirsher
atl1e_tso_csum(struct atl1e_adapter * adapter,struct sk_buff * skb,struct atl1e_tpd_desc * tpd)16272b133ad6SJeff Kirsher static int atl1e_tso_csum(struct atl1e_adapter *adapter,
16282b133ad6SJeff Kirsher struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
16292b133ad6SJeff Kirsher {
1630d8e4435eSfrançois romieu unsigned short offload_type;
16312b133ad6SJeff Kirsher u8 hdr_len;
16322b133ad6SJeff Kirsher u32 real_len;
16332b133ad6SJeff Kirsher
16342b133ad6SJeff Kirsher if (skb_is_gso(skb)) {
1635d8e4435eSfrançois romieu int err;
1636d8e4435eSfrançois romieu
1637d8e4435eSfrançois romieu err = skb_cow_head(skb, 0);
1638d8e4435eSfrançois romieu if (err < 0)
1639d8e4435eSfrançois romieu return err;
1640d8e4435eSfrançois romieu
16412b133ad6SJeff Kirsher offload_type = skb_shinfo(skb)->gso_type;
16422b133ad6SJeff Kirsher
16432b133ad6SJeff Kirsher if (offload_type & SKB_GSO_TCPV4) {
16442b133ad6SJeff Kirsher real_len = (((unsigned char *)ip_hdr(skb) - skb->data)
16452b133ad6SJeff Kirsher + ntohs(ip_hdr(skb)->tot_len));
16462b133ad6SJeff Kirsher
164769a184f7SYuanjun Gong if (real_len < skb->len) {
164869a184f7SYuanjun Gong err = pskb_trim(skb, real_len);
164969a184f7SYuanjun Gong if (err)
165069a184f7SYuanjun Gong return err;
165169a184f7SYuanjun Gong }
16522b133ad6SJeff Kirsher
1653504148feSEric Dumazet hdr_len = skb_tcp_all_headers(skb);
16542b133ad6SJeff Kirsher if (unlikely(skb->len == hdr_len)) {
16552b133ad6SJeff Kirsher /* only xsum need */
16562b133ad6SJeff Kirsher netdev_warn(adapter->netdev,
16572b133ad6SJeff Kirsher "IPV4 tso with zero data??\n");
16582b133ad6SJeff Kirsher goto check_sum;
16592b133ad6SJeff Kirsher } else {
16602b133ad6SJeff Kirsher ip_hdr(skb)->check = 0;
16612b133ad6SJeff Kirsher ip_hdr(skb)->tot_len = 0;
16622b133ad6SJeff Kirsher tcp_hdr(skb)->check = ~csum_tcpudp_magic(
16632b133ad6SJeff Kirsher ip_hdr(skb)->saddr,
16642b133ad6SJeff Kirsher ip_hdr(skb)->daddr,
16652b133ad6SJeff Kirsher 0, IPPROTO_TCP, 0);
16662b133ad6SJeff Kirsher tpd->word3 |= (ip_hdr(skb)->ihl &
16672b133ad6SJeff Kirsher TDP_V4_IPHL_MASK) <<
16682b133ad6SJeff Kirsher TPD_V4_IPHL_SHIFT;
16692b133ad6SJeff Kirsher tpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
16702b133ad6SJeff Kirsher TPD_TCPHDRLEN_MASK) <<
16712b133ad6SJeff Kirsher TPD_TCPHDRLEN_SHIFT;
16722b133ad6SJeff Kirsher tpd->word3 |= ((skb_shinfo(skb)->gso_size) &
16732b133ad6SJeff Kirsher TPD_MSS_MASK) << TPD_MSS_SHIFT;
16742b133ad6SJeff Kirsher tpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
16752b133ad6SJeff Kirsher }
16762b133ad6SJeff Kirsher return 0;
16772b133ad6SJeff Kirsher }
16782b133ad6SJeff Kirsher }
16792b133ad6SJeff Kirsher
16802b133ad6SJeff Kirsher check_sum:
16812b133ad6SJeff Kirsher if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
16822b133ad6SJeff Kirsher u8 css, cso;
16832b133ad6SJeff Kirsher
16842b133ad6SJeff Kirsher cso = skb_checksum_start_offset(skb);
16852b133ad6SJeff Kirsher if (unlikely(cso & 0x1)) {
16862b133ad6SJeff Kirsher netdev_err(adapter->netdev,
16872b133ad6SJeff Kirsher "payload offset should not ant event number\n");
16882b133ad6SJeff Kirsher return -1;
16892b133ad6SJeff Kirsher } else {
16902b133ad6SJeff Kirsher css = cso + skb->csum_offset;
16912b133ad6SJeff Kirsher tpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
16922b133ad6SJeff Kirsher TPD_PLOADOFFSET_SHIFT;
16932b133ad6SJeff Kirsher tpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
16942b133ad6SJeff Kirsher TPD_CCSUMOFFSET_SHIFT;
16952b133ad6SJeff Kirsher tpd->word3 |= 1 << TPD_CC_SEGMENT_EN_SHIFT;
16962b133ad6SJeff Kirsher }
16972b133ad6SJeff Kirsher }
16982b133ad6SJeff Kirsher
16992b133ad6SJeff Kirsher return 0;
17002b133ad6SJeff Kirsher }
17012b133ad6SJeff Kirsher
atl1e_tx_map(struct atl1e_adapter * adapter,struct sk_buff * skb,struct atl1e_tpd_desc * tpd)1702352900b5SNeil Horman static int atl1e_tx_map(struct atl1e_adapter *adapter,
17032b133ad6SJeff Kirsher struct sk_buff *skb, struct atl1e_tpd_desc *tpd)
17042b133ad6SJeff Kirsher {
17052b133ad6SJeff Kirsher struct atl1e_tpd_desc *use_tpd = NULL;
17062b133ad6SJeff Kirsher struct atl1e_tx_buffer *tx_buffer = NULL;
17072b133ad6SJeff Kirsher u16 buf_len = skb_headlen(skb);
17082b133ad6SJeff Kirsher u16 map_len = 0;
17092b133ad6SJeff Kirsher u16 mapped_len = 0;
17102b133ad6SJeff Kirsher u16 hdr_len = 0;
17112b133ad6SJeff Kirsher u16 nr_frags;
17122b133ad6SJeff Kirsher u16 f;
17132b133ad6SJeff Kirsher int segment;
1714352900b5SNeil Horman int ring_start = adapter->tx_ring.next_to_use;
1715584ec435SNeil Horman int ring_end;
17162b133ad6SJeff Kirsher
17172b133ad6SJeff Kirsher nr_frags = skb_shinfo(skb)->nr_frags;
17182b133ad6SJeff Kirsher segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
17192b133ad6SJeff Kirsher if (segment) {
17202b133ad6SJeff Kirsher /* TSO */
1721504148feSEric Dumazet hdr_len = skb_tcp_all_headers(skb);
1722504148feSEric Dumazet map_len = hdr_len;
17232b133ad6SJeff Kirsher use_tpd = tpd;
17242b133ad6SJeff Kirsher
17252b133ad6SJeff Kirsher tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
17262b133ad6SJeff Kirsher tx_buffer->length = map_len;
172785eb5bc3SChristophe JAILLET tx_buffer->dma = dma_map_single(&adapter->pdev->dev,
172885eb5bc3SChristophe JAILLET skb->data, hdr_len,
172985eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
1730352900b5SNeil Horman if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma))
1731352900b5SNeil Horman return -ENOSPC;
1732352900b5SNeil Horman
17332b133ad6SJeff Kirsher ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
17342b133ad6SJeff Kirsher mapped_len += map_len;
17352b133ad6SJeff Kirsher use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
17362b133ad6SJeff Kirsher use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
17372b133ad6SJeff Kirsher ((cpu_to_le32(tx_buffer->length) &
17382b133ad6SJeff Kirsher TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
17392b133ad6SJeff Kirsher }
17402b133ad6SJeff Kirsher
17412b133ad6SJeff Kirsher while (mapped_len < buf_len) {
17422b133ad6SJeff Kirsher /* mapped_len == 0, means we should use the first tpd,
17432b133ad6SJeff Kirsher which is given by caller */
17442b133ad6SJeff Kirsher if (mapped_len == 0) {
17452b133ad6SJeff Kirsher use_tpd = tpd;
17462b133ad6SJeff Kirsher } else {
17472b133ad6SJeff Kirsher use_tpd = atl1e_get_tpd(adapter);
17482b133ad6SJeff Kirsher memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
17492b133ad6SJeff Kirsher }
17502b133ad6SJeff Kirsher tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
17512b133ad6SJeff Kirsher tx_buffer->skb = NULL;
17522b133ad6SJeff Kirsher
17532b133ad6SJeff Kirsher tx_buffer->length = map_len =
17542b133ad6SJeff Kirsher ((buf_len - mapped_len) >= MAX_TX_BUF_LEN) ?
17552b133ad6SJeff Kirsher MAX_TX_BUF_LEN : (buf_len - mapped_len);
17562b133ad6SJeff Kirsher tx_buffer->dma =
175785eb5bc3SChristophe JAILLET dma_map_single(&adapter->pdev->dev,
175885eb5bc3SChristophe JAILLET skb->data + mapped_len, map_len,
175985eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
1760352900b5SNeil Horman
1761352900b5SNeil Horman if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) {
1762584ec435SNeil Horman /* We need to unwind the mappings we've done */
1763584ec435SNeil Horman ring_end = adapter->tx_ring.next_to_use;
1764584ec435SNeil Horman adapter->tx_ring.next_to_use = ring_start;
1765584ec435SNeil Horman while (adapter->tx_ring.next_to_use != ring_end) {
1766584ec435SNeil Horman tpd = atl1e_get_tpd(adapter);
1767584ec435SNeil Horman tx_buffer = atl1e_get_tx_buffer(adapter, tpd);
176885eb5bc3SChristophe JAILLET dma_unmap_single(&adapter->pdev->dev,
176985eb5bc3SChristophe JAILLET tx_buffer->dma,
177085eb5bc3SChristophe JAILLET tx_buffer->length,
177185eb5bc3SChristophe JAILLET DMA_TO_DEVICE);
1772584ec435SNeil Horman }
1773352900b5SNeil Horman /* Reset the tx rings next pointer */
1774352900b5SNeil Horman adapter->tx_ring.next_to_use = ring_start;
1775352900b5SNeil Horman return -ENOSPC;
1776352900b5SNeil Horman }
1777352900b5SNeil Horman
17782b133ad6SJeff Kirsher ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
17792b133ad6SJeff Kirsher mapped_len += map_len;
17802b133ad6SJeff Kirsher use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
17812b133ad6SJeff Kirsher use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
17822b133ad6SJeff Kirsher ((cpu_to_le32(tx_buffer->length) &
17832b133ad6SJeff Kirsher TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
17842b133ad6SJeff Kirsher }
17852b133ad6SJeff Kirsher
17862b133ad6SJeff Kirsher for (f = 0; f < nr_frags; f++) {
1787d7840976SMatthew Wilcox (Oracle) const skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
17882b133ad6SJeff Kirsher u16 i;
17892b133ad6SJeff Kirsher u16 seg_num;
17902b133ad6SJeff Kirsher
17919e903e08SEric Dumazet buf_len = skb_frag_size(frag);
17922b133ad6SJeff Kirsher
17932b133ad6SJeff Kirsher seg_num = (buf_len + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
17942b133ad6SJeff Kirsher for (i = 0; i < seg_num; i++) {
17952b133ad6SJeff Kirsher use_tpd = atl1e_get_tpd(adapter);
17962b133ad6SJeff Kirsher memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
17972b133ad6SJeff Kirsher
17982b133ad6SJeff Kirsher tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
17992b133ad6SJeff Kirsher BUG_ON(tx_buffer->skb);
18002b133ad6SJeff Kirsher
18012b133ad6SJeff Kirsher tx_buffer->skb = NULL;
18022b133ad6SJeff Kirsher tx_buffer->length =
18032b133ad6SJeff Kirsher (buf_len > MAX_TX_BUF_LEN) ?
18042b133ad6SJeff Kirsher MAX_TX_BUF_LEN : buf_len;
18052b133ad6SJeff Kirsher buf_len -= tx_buffer->length;
18062b133ad6SJeff Kirsher
18076adaaac7SIan Campbell tx_buffer->dma = skb_frag_dma_map(&adapter->pdev->dev,
18086adaaac7SIan Campbell frag,
18092b133ad6SJeff Kirsher (i * MAX_TX_BUF_LEN),
18102b133ad6SJeff Kirsher tx_buffer->length,
18115d6bcdfeSIan Campbell DMA_TO_DEVICE);
1812352900b5SNeil Horman
1813352900b5SNeil Horman if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) {
1814584ec435SNeil Horman /* We need to unwind the mappings we've done */
1815584ec435SNeil Horman ring_end = adapter->tx_ring.next_to_use;
1816584ec435SNeil Horman adapter->tx_ring.next_to_use = ring_start;
1817584ec435SNeil Horman while (adapter->tx_ring.next_to_use != ring_end) {
1818584ec435SNeil Horman tpd = atl1e_get_tpd(adapter);
1819584ec435SNeil Horman tx_buffer = atl1e_get_tx_buffer(adapter, tpd);
1820584ec435SNeil Horman dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma,
1821584ec435SNeil Horman tx_buffer->length, DMA_TO_DEVICE);
1822584ec435SNeil Horman }
1823584ec435SNeil Horman
1824352900b5SNeil Horman /* Reset the ring next to use pointer */
1825352900b5SNeil Horman adapter->tx_ring.next_to_use = ring_start;
1826352900b5SNeil Horman return -ENOSPC;
1827352900b5SNeil Horman }
1828352900b5SNeil Horman
18292b133ad6SJeff Kirsher ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
18302b133ad6SJeff Kirsher use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
18312b133ad6SJeff Kirsher use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
18322b133ad6SJeff Kirsher ((cpu_to_le32(tx_buffer->length) &
18332b133ad6SJeff Kirsher TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT);
18342b133ad6SJeff Kirsher }
18352b133ad6SJeff Kirsher }
18362b133ad6SJeff Kirsher
18372b133ad6SJeff Kirsher if ((tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK)
18382b133ad6SJeff Kirsher /* note this one is a tcp header */
18392b133ad6SJeff Kirsher tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
18402b133ad6SJeff Kirsher /* The last tpd */
18412b133ad6SJeff Kirsher
18422b133ad6SJeff Kirsher use_tpd->word3 |= 1 << TPD_EOP_SHIFT;
18432b133ad6SJeff Kirsher /* The last buffer info contain the skb address,
18442b133ad6SJeff Kirsher so it will be free after unmap */
18452b133ad6SJeff Kirsher tx_buffer->skb = skb;
1846352900b5SNeil Horman return 0;
18472b133ad6SJeff Kirsher }
18482b133ad6SJeff Kirsher
atl1e_tx_queue(struct atl1e_adapter * adapter,u16 count,struct atl1e_tpd_desc * tpd)18492b133ad6SJeff Kirsher static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
18502b133ad6SJeff Kirsher struct atl1e_tpd_desc *tpd)
18512b133ad6SJeff Kirsher {
18522b133ad6SJeff Kirsher struct atl1e_tx_ring *tx_ring = &adapter->tx_ring;
18532b133ad6SJeff Kirsher /* Force memory writes to complete before letting h/w
18542b133ad6SJeff Kirsher * know there are new descriptors to fetch. (Only
18552b133ad6SJeff Kirsher * applicable for weak-ordered memory model archs,
18562b133ad6SJeff Kirsher * such as IA-64). */
18572b133ad6SJeff Kirsher wmb();
18582b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use);
18592b133ad6SJeff Kirsher }
18602b133ad6SJeff Kirsher
atl1e_xmit_frame(struct sk_buff * skb,struct net_device * netdev)18612b133ad6SJeff Kirsher static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
18622b133ad6SJeff Kirsher struct net_device *netdev)
18632b133ad6SJeff Kirsher {
18642b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
18652b133ad6SJeff Kirsher u16 tpd_req = 1;
18662b133ad6SJeff Kirsher struct atl1e_tpd_desc *tpd;
18672b133ad6SJeff Kirsher
18682b133ad6SJeff Kirsher if (test_bit(__AT_DOWN, &adapter->flags)) {
18692b133ad6SJeff Kirsher dev_kfree_skb_any(skb);
18702b133ad6SJeff Kirsher return NETDEV_TX_OK;
18712b133ad6SJeff Kirsher }
18722b133ad6SJeff Kirsher
18732b133ad6SJeff Kirsher if (unlikely(skb->len <= 0)) {
18742b133ad6SJeff Kirsher dev_kfree_skb_any(skb);
18752b133ad6SJeff Kirsher return NETDEV_TX_OK;
18762b133ad6SJeff Kirsher }
18772b133ad6SJeff Kirsher tpd_req = atl1e_cal_tdp_req(skb);
18782b133ad6SJeff Kirsher
18792b133ad6SJeff Kirsher if (atl1e_tpd_avail(adapter) < tpd_req) {
18802b133ad6SJeff Kirsher /* no enough descriptor, just stop queue */
18812b133ad6SJeff Kirsher netif_stop_queue(netdev);
18822b133ad6SJeff Kirsher return NETDEV_TX_BUSY;
18832b133ad6SJeff Kirsher }
18842b133ad6SJeff Kirsher
18852b133ad6SJeff Kirsher tpd = atl1e_get_tpd(adapter);
18862b133ad6SJeff Kirsher
1887df8a39deSJiri Pirko if (skb_vlan_tag_present(skb)) {
1888df8a39deSJiri Pirko u16 vlan_tag = skb_vlan_tag_get(skb);
18892b133ad6SJeff Kirsher u16 atl1e_vlan_tag;
18902b133ad6SJeff Kirsher
18912b133ad6SJeff Kirsher tpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
18922b133ad6SJeff Kirsher AT_VLAN_TAG_TO_TPD_TAG(vlan_tag, atl1e_vlan_tag);
18932b133ad6SJeff Kirsher tpd->word2 |= (atl1e_vlan_tag & TPD_VLANTAG_MASK) <<
18942b133ad6SJeff Kirsher TPD_VLAN_SHIFT;
18952b133ad6SJeff Kirsher }
18962b133ad6SJeff Kirsher
18972b133ad6SJeff Kirsher if (skb->protocol == htons(ETH_P_8021Q))
18982b133ad6SJeff Kirsher tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
18992b133ad6SJeff Kirsher
19002b133ad6SJeff Kirsher if (skb_network_offset(skb) != ETH_HLEN)
19012b133ad6SJeff Kirsher tpd->word3 |= 1 << TPD_ETHTYPE_SHIFT; /* 802.3 frame */
19022b133ad6SJeff Kirsher
19032b133ad6SJeff Kirsher /* do TSO and check sum */
19042b133ad6SJeff Kirsher if (atl1e_tso_csum(adapter, skb, tpd) != 0) {
19052b133ad6SJeff Kirsher dev_kfree_skb_any(skb);
19062b133ad6SJeff Kirsher return NETDEV_TX_OK;
19072b133ad6SJeff Kirsher }
19082b133ad6SJeff Kirsher
1909584ec435SNeil Horman if (atl1e_tx_map(adapter, skb, tpd)) {
1910584ec435SNeil Horman dev_kfree_skb_any(skb);
1911352900b5SNeil Horman goto out;
1912584ec435SNeil Horman }
1913352900b5SNeil Horman
19142b133ad6SJeff Kirsher atl1e_tx_queue(adapter, tpd_req, tpd);
1915352900b5SNeil Horman out:
19162b133ad6SJeff Kirsher return NETDEV_TX_OK;
19172b133ad6SJeff Kirsher }
19182b133ad6SJeff Kirsher
atl1e_free_irq(struct atl1e_adapter * adapter)19192b133ad6SJeff Kirsher static void atl1e_free_irq(struct atl1e_adapter *adapter)
19202b133ad6SJeff Kirsher {
19212b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
19222b133ad6SJeff Kirsher
19232b133ad6SJeff Kirsher free_irq(adapter->pdev->irq, netdev);
19242b133ad6SJeff Kirsher }
19252b133ad6SJeff Kirsher
atl1e_request_irq(struct atl1e_adapter * adapter)19262b133ad6SJeff Kirsher static int atl1e_request_irq(struct atl1e_adapter *adapter)
19272b133ad6SJeff Kirsher {
19282b133ad6SJeff Kirsher struct pci_dev *pdev = adapter->pdev;
19292b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
19302b133ad6SJeff Kirsher int err = 0;
19312b133ad6SJeff Kirsher
1932188ab1b1SHannes Frederic Sowa err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name,
1933188ab1b1SHannes Frederic Sowa netdev);
19342b133ad6SJeff Kirsher if (err) {
19352b133ad6SJeff Kirsher netdev_dbg(adapter->netdev,
19362b133ad6SJeff Kirsher "Unable to allocate interrupt Error: %d\n", err);
19372b133ad6SJeff Kirsher return err;
19382b133ad6SJeff Kirsher }
1939b5efab99SFrancois Romieu netdev_dbg(netdev, "atl1e_request_irq OK\n");
19402b133ad6SJeff Kirsher return err;
19412b133ad6SJeff Kirsher }
19422b133ad6SJeff Kirsher
atl1e_up(struct atl1e_adapter * adapter)19432b133ad6SJeff Kirsher int atl1e_up(struct atl1e_adapter *adapter)
19442b133ad6SJeff Kirsher {
19452b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
19462b133ad6SJeff Kirsher int err = 0;
19472b133ad6SJeff Kirsher u32 val;
19482b133ad6SJeff Kirsher
19492b133ad6SJeff Kirsher /* hardware has been reset, we need to reload some things */
19502b133ad6SJeff Kirsher err = atl1e_init_hw(&adapter->hw);
19512b133ad6SJeff Kirsher if (err) {
19522b133ad6SJeff Kirsher err = -EIO;
19532b133ad6SJeff Kirsher return err;
19542b133ad6SJeff Kirsher }
19552b133ad6SJeff Kirsher atl1e_init_ring_ptrs(adapter);
19562b133ad6SJeff Kirsher atl1e_set_multi(netdev);
19572b133ad6SJeff Kirsher atl1e_restore_vlan(adapter);
19582b133ad6SJeff Kirsher
19592b133ad6SJeff Kirsher if (atl1e_configure(adapter)) {
19602b133ad6SJeff Kirsher err = -EIO;
19612b133ad6SJeff Kirsher goto err_up;
19622b133ad6SJeff Kirsher }
19632b133ad6SJeff Kirsher
19642b133ad6SJeff Kirsher clear_bit(__AT_DOWN, &adapter->flags);
19652b133ad6SJeff Kirsher napi_enable(&adapter->napi);
19662b133ad6SJeff Kirsher atl1e_irq_enable(adapter);
19672b133ad6SJeff Kirsher val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL);
19682b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
19692b133ad6SJeff Kirsher val | MASTER_CTRL_MANUAL_INT);
19702b133ad6SJeff Kirsher
19712b133ad6SJeff Kirsher err_up:
19722b133ad6SJeff Kirsher return err;
19732b133ad6SJeff Kirsher }
19742b133ad6SJeff Kirsher
atl1e_down(struct atl1e_adapter * adapter)19752b133ad6SJeff Kirsher void atl1e_down(struct atl1e_adapter *adapter)
19762b133ad6SJeff Kirsher {
19772b133ad6SJeff Kirsher struct net_device *netdev = adapter->netdev;
19782b133ad6SJeff Kirsher
19792b133ad6SJeff Kirsher /* signal that we're down so the interrupt handler does not
19802b133ad6SJeff Kirsher * reschedule our watchdog timer */
19812b133ad6SJeff Kirsher set_bit(__AT_DOWN, &adapter->flags);
19822b133ad6SJeff Kirsher
19832b133ad6SJeff Kirsher netif_stop_queue(netdev);
19842b133ad6SJeff Kirsher
19852b133ad6SJeff Kirsher /* reset MAC to disable all RX/TX */
19862b133ad6SJeff Kirsher atl1e_reset_hw(&adapter->hw);
19872b133ad6SJeff Kirsher msleep(1);
19882b133ad6SJeff Kirsher
19892b133ad6SJeff Kirsher napi_disable(&adapter->napi);
19902b133ad6SJeff Kirsher atl1e_del_timer(adapter);
19912b133ad6SJeff Kirsher atl1e_irq_disable(adapter);
19922b133ad6SJeff Kirsher
19932b133ad6SJeff Kirsher netif_carrier_off(netdev);
19942b133ad6SJeff Kirsher adapter->link_speed = SPEED_0;
19952b133ad6SJeff Kirsher adapter->link_duplex = -1;
19962b133ad6SJeff Kirsher atl1e_clean_tx_ring(adapter);
19972b133ad6SJeff Kirsher atl1e_clean_rx_ring(adapter);
19982b133ad6SJeff Kirsher }
19992b133ad6SJeff Kirsher
200049ce9c2cSBen Hutchings /**
20012b133ad6SJeff Kirsher * atl1e_open - Called when a network interface is made active
20022b133ad6SJeff Kirsher * @netdev: network interface device structure
20032b133ad6SJeff Kirsher *
20042b133ad6SJeff Kirsher * Returns 0 on success, negative value on failure
20052b133ad6SJeff Kirsher *
20062b133ad6SJeff Kirsher * The open entry point is called when a network interface is made
20072b133ad6SJeff Kirsher * active by the system (IFF_UP). At this point all resources needed
20082b133ad6SJeff Kirsher * for transmit and receive operations are allocated, the interrupt
20092b133ad6SJeff Kirsher * handler is registered with the OS, the watchdog timer is started,
20102b133ad6SJeff Kirsher * and the stack is notified that the interface is ready.
20112b133ad6SJeff Kirsher */
atl1e_open(struct net_device * netdev)20122b133ad6SJeff Kirsher static int atl1e_open(struct net_device *netdev)
20132b133ad6SJeff Kirsher {
20142b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
20152b133ad6SJeff Kirsher int err;
20162b133ad6SJeff Kirsher
20172b133ad6SJeff Kirsher /* disallow open during test */
20182b133ad6SJeff Kirsher if (test_bit(__AT_TESTING, &adapter->flags))
20192b133ad6SJeff Kirsher return -EBUSY;
20202b133ad6SJeff Kirsher
20212b133ad6SJeff Kirsher /* allocate rx/tx dma buffer & descriptors */
20222b133ad6SJeff Kirsher atl1e_init_ring_resources(adapter);
20232b133ad6SJeff Kirsher err = atl1e_setup_ring_resources(adapter);
20242b133ad6SJeff Kirsher if (unlikely(err))
20252b133ad6SJeff Kirsher return err;
20262b133ad6SJeff Kirsher
20272b133ad6SJeff Kirsher err = atl1e_request_irq(adapter);
20282b133ad6SJeff Kirsher if (unlikely(err))
20292b133ad6SJeff Kirsher goto err_req_irq;
20302b133ad6SJeff Kirsher
20312b133ad6SJeff Kirsher err = atl1e_up(adapter);
20322b133ad6SJeff Kirsher if (unlikely(err))
20332b133ad6SJeff Kirsher goto err_up;
20342b133ad6SJeff Kirsher
20352b133ad6SJeff Kirsher return 0;
20362b133ad6SJeff Kirsher
20372b133ad6SJeff Kirsher err_up:
20382b133ad6SJeff Kirsher atl1e_free_irq(adapter);
20392b133ad6SJeff Kirsher err_req_irq:
20402b133ad6SJeff Kirsher atl1e_free_ring_resources(adapter);
20412b133ad6SJeff Kirsher atl1e_reset_hw(&adapter->hw);
20422b133ad6SJeff Kirsher
20432b133ad6SJeff Kirsher return err;
20442b133ad6SJeff Kirsher }
20452b133ad6SJeff Kirsher
204649ce9c2cSBen Hutchings /**
20472b133ad6SJeff Kirsher * atl1e_close - Disables a network interface
20482b133ad6SJeff Kirsher * @netdev: network interface device structure
20492b133ad6SJeff Kirsher *
20502b133ad6SJeff Kirsher * Returns 0, this is not allowed to fail
20512b133ad6SJeff Kirsher *
20522b133ad6SJeff Kirsher * The close entry point is called when an interface is de-activated
20532b133ad6SJeff Kirsher * by the OS. The hardware is still under the drivers control, but
20542b133ad6SJeff Kirsher * needs to be disabled. A global MAC reset is issued to stop the
20552b133ad6SJeff Kirsher * hardware, and all transmit and receive resources are freed.
20562b133ad6SJeff Kirsher */
atl1e_close(struct net_device * netdev)20572b133ad6SJeff Kirsher static int atl1e_close(struct net_device *netdev)
20582b133ad6SJeff Kirsher {
20592b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
20602b133ad6SJeff Kirsher
20612b133ad6SJeff Kirsher WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
20622b133ad6SJeff Kirsher atl1e_down(adapter);
20632b133ad6SJeff Kirsher atl1e_free_irq(adapter);
20642b133ad6SJeff Kirsher atl1e_free_ring_resources(adapter);
20652b133ad6SJeff Kirsher
20662b133ad6SJeff Kirsher return 0;
20672b133ad6SJeff Kirsher }
20682b133ad6SJeff Kirsher
atl1e_suspend(struct pci_dev * pdev,pm_message_t state)20692b133ad6SJeff Kirsher static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state)
20702b133ad6SJeff Kirsher {
20712b133ad6SJeff Kirsher struct net_device *netdev = pci_get_drvdata(pdev);
20722b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
20732b133ad6SJeff Kirsher struct atl1e_hw *hw = &adapter->hw;
20742b133ad6SJeff Kirsher u32 ctrl = 0;
20752b133ad6SJeff Kirsher u32 mac_ctrl_data = 0;
20762b133ad6SJeff Kirsher u32 wol_ctrl_data = 0;
20772b133ad6SJeff Kirsher u16 mii_advertise_data = 0;
20782b133ad6SJeff Kirsher u16 mii_bmsr_data = 0;
20792b133ad6SJeff Kirsher u16 mii_intr_status_data = 0;
20802b133ad6SJeff Kirsher u32 wufc = adapter->wol;
20812b133ad6SJeff Kirsher u32 i;
20822b133ad6SJeff Kirsher #ifdef CONFIG_PM
20832b133ad6SJeff Kirsher int retval = 0;
20842b133ad6SJeff Kirsher #endif
20852b133ad6SJeff Kirsher
20862b133ad6SJeff Kirsher if (netif_running(netdev)) {
20872b133ad6SJeff Kirsher WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
20882b133ad6SJeff Kirsher atl1e_down(adapter);
20892b133ad6SJeff Kirsher }
20902b133ad6SJeff Kirsher netif_device_detach(netdev);
20912b133ad6SJeff Kirsher
20922b133ad6SJeff Kirsher #ifdef CONFIG_PM
20932b133ad6SJeff Kirsher retval = pci_save_state(pdev);
20942b133ad6SJeff Kirsher if (retval)
20952b133ad6SJeff Kirsher return retval;
20962b133ad6SJeff Kirsher #endif
20972b133ad6SJeff Kirsher
20982b133ad6SJeff Kirsher if (wufc) {
20992b133ad6SJeff Kirsher /* get link status */
210064699336SJoe Perches atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data);
210164699336SJoe Perches atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data);
21022b133ad6SJeff Kirsher
21032b133ad6SJeff Kirsher mii_advertise_data = ADVERTISE_10HALF;
21042b133ad6SJeff Kirsher
21052b133ad6SJeff Kirsher if ((atl1e_write_phy_reg(hw, MII_CTRL1000, 0) != 0) ||
21062b133ad6SJeff Kirsher (atl1e_write_phy_reg(hw,
21072b133ad6SJeff Kirsher MII_ADVERTISE, mii_advertise_data) != 0) ||
21082b133ad6SJeff Kirsher (atl1e_phy_commit(hw)) != 0) {
21092b133ad6SJeff Kirsher netdev_dbg(adapter->netdev, "set phy register failed\n");
21102b133ad6SJeff Kirsher goto wol_dis;
21112b133ad6SJeff Kirsher }
21122b133ad6SJeff Kirsher
21132b133ad6SJeff Kirsher hw->phy_configured = false; /* re-init PHY when resume */
21142b133ad6SJeff Kirsher
21152b133ad6SJeff Kirsher /* turn on magic packet wol */
21162b133ad6SJeff Kirsher if (wufc & AT_WUFC_MAG)
21172b133ad6SJeff Kirsher wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
21182b133ad6SJeff Kirsher
21192b133ad6SJeff Kirsher if (wufc & AT_WUFC_LNKC) {
21202b133ad6SJeff Kirsher /* if orignal link status is link, just wait for retrive link */
21212b133ad6SJeff Kirsher if (mii_bmsr_data & BMSR_LSTATUS) {
21222b133ad6SJeff Kirsher for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
21232b133ad6SJeff Kirsher msleep(100);
21242b133ad6SJeff Kirsher atl1e_read_phy_reg(hw, MII_BMSR,
212564699336SJoe Perches &mii_bmsr_data);
21262b133ad6SJeff Kirsher if (mii_bmsr_data & BMSR_LSTATUS)
21272b133ad6SJeff Kirsher break;
21282b133ad6SJeff Kirsher }
21292b133ad6SJeff Kirsher
21302b133ad6SJeff Kirsher if ((mii_bmsr_data & BMSR_LSTATUS) == 0)
21312b133ad6SJeff Kirsher netdev_dbg(adapter->netdev,
21322b133ad6SJeff Kirsher "Link may change when suspend\n");
21332b133ad6SJeff Kirsher }
21342b133ad6SJeff Kirsher wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
21352b133ad6SJeff Kirsher /* only link up can wake up */
21362b133ad6SJeff Kirsher if (atl1e_write_phy_reg(hw, MII_INT_CTRL, 0x400) != 0) {
21372b133ad6SJeff Kirsher netdev_dbg(adapter->netdev,
21382b133ad6SJeff Kirsher "read write phy register failed\n");
21392b133ad6SJeff Kirsher goto wol_dis;
21402b133ad6SJeff Kirsher }
21412b133ad6SJeff Kirsher }
21422b133ad6SJeff Kirsher /* clear phy interrupt */
21432b133ad6SJeff Kirsher atl1e_read_phy_reg(hw, MII_INT_STATUS, &mii_intr_status_data);
21442b133ad6SJeff Kirsher /* Config MAC Ctrl register */
21452b133ad6SJeff Kirsher mac_ctrl_data = MAC_CTRL_RX_EN;
21462b133ad6SJeff Kirsher /* set to 10/100M halt duplex */
21472b133ad6SJeff Kirsher mac_ctrl_data |= MAC_CTRL_SPEED_10_100 << MAC_CTRL_SPEED_SHIFT;
21482b133ad6SJeff Kirsher mac_ctrl_data |= (((u32)adapter->hw.preamble_len &
21492b133ad6SJeff Kirsher MAC_CTRL_PRMLEN_MASK) <<
21502b133ad6SJeff Kirsher MAC_CTRL_PRMLEN_SHIFT);
21512b133ad6SJeff Kirsher
21522b133ad6SJeff Kirsher __atl1e_vlan_mode(netdev->features, &mac_ctrl_data);
21532b133ad6SJeff Kirsher
21542b133ad6SJeff Kirsher /* magic packet maybe Broadcast&multicast&Unicast frame */
21552b133ad6SJeff Kirsher if (wufc & AT_WUFC_MAG)
21562b133ad6SJeff Kirsher mac_ctrl_data |= MAC_CTRL_BC_EN;
21572b133ad6SJeff Kirsher
21582b133ad6SJeff Kirsher netdev_dbg(adapter->netdev, "suspend MAC=0x%x\n",
21592b133ad6SJeff Kirsher mac_ctrl_data);
21602b133ad6SJeff Kirsher
21612b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data);
21622b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data);
21632b133ad6SJeff Kirsher /* pcie patch */
21642b133ad6SJeff Kirsher ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
21652b133ad6SJeff Kirsher ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
21662b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
21672b133ad6SJeff Kirsher pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
21682b133ad6SJeff Kirsher goto suspend_exit;
21692b133ad6SJeff Kirsher }
21702b133ad6SJeff Kirsher wol_dis:
21712b133ad6SJeff Kirsher
21722b133ad6SJeff Kirsher /* WOL disabled */
21732b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
21742b133ad6SJeff Kirsher
21752b133ad6SJeff Kirsher /* pcie patch */
21762b133ad6SJeff Kirsher ctrl = AT_READ_REG(hw, REG_PCIE_PHYMISC);
21772b133ad6SJeff Kirsher ctrl |= PCIE_PHYMISC_FORCE_RCV_DET;
21782b133ad6SJeff Kirsher AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl);
21792b133ad6SJeff Kirsher
21802b133ad6SJeff Kirsher atl1e_force_ps(hw);
21812b133ad6SJeff Kirsher hw->phy_configured = false; /* re-init PHY when resume */
21822b133ad6SJeff Kirsher
21832b133ad6SJeff Kirsher pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
21842b133ad6SJeff Kirsher
21852b133ad6SJeff Kirsher suspend_exit:
21862b133ad6SJeff Kirsher
21872b133ad6SJeff Kirsher if (netif_running(netdev))
21882b133ad6SJeff Kirsher atl1e_free_irq(adapter);
21892b133ad6SJeff Kirsher
21902b133ad6SJeff Kirsher pci_disable_device(pdev);
21912b133ad6SJeff Kirsher
21922b133ad6SJeff Kirsher pci_set_power_state(pdev, pci_choose_state(pdev, state));
21932b133ad6SJeff Kirsher
21942b133ad6SJeff Kirsher return 0;
21952b133ad6SJeff Kirsher }
21962b133ad6SJeff Kirsher
21972b133ad6SJeff Kirsher #ifdef CONFIG_PM
atl1e_resume(struct pci_dev * pdev)21982b133ad6SJeff Kirsher static int atl1e_resume(struct pci_dev *pdev)
21992b133ad6SJeff Kirsher {
22002b133ad6SJeff Kirsher struct net_device *netdev = pci_get_drvdata(pdev);
22012b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
22022b133ad6SJeff Kirsher u32 err;
22032b133ad6SJeff Kirsher
22042b133ad6SJeff Kirsher pci_set_power_state(pdev, PCI_D0);
22052b133ad6SJeff Kirsher pci_restore_state(pdev);
22062b133ad6SJeff Kirsher
22072b133ad6SJeff Kirsher err = pci_enable_device(pdev);
22082b133ad6SJeff Kirsher if (err) {
22092b133ad6SJeff Kirsher netdev_err(adapter->netdev,
22102b133ad6SJeff Kirsher "Cannot enable PCI device from suspend\n");
22112b133ad6SJeff Kirsher return err;
22122b133ad6SJeff Kirsher }
22132b133ad6SJeff Kirsher
22142b133ad6SJeff Kirsher pci_set_master(pdev);
22152b133ad6SJeff Kirsher
22162b133ad6SJeff Kirsher AT_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */
22172b133ad6SJeff Kirsher
22182b133ad6SJeff Kirsher pci_enable_wake(pdev, PCI_D3hot, 0);
22192b133ad6SJeff Kirsher pci_enable_wake(pdev, PCI_D3cold, 0);
22202b133ad6SJeff Kirsher
22212b133ad6SJeff Kirsher AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0);
22222b133ad6SJeff Kirsher
22232b133ad6SJeff Kirsher if (netif_running(netdev)) {
22242b133ad6SJeff Kirsher err = atl1e_request_irq(adapter);
22252b133ad6SJeff Kirsher if (err)
22262b133ad6SJeff Kirsher return err;
22272b133ad6SJeff Kirsher }
22282b133ad6SJeff Kirsher
22292b133ad6SJeff Kirsher atl1e_reset_hw(&adapter->hw);
22302b133ad6SJeff Kirsher
22312b133ad6SJeff Kirsher if (netif_running(netdev))
22322b133ad6SJeff Kirsher atl1e_up(adapter);
22332b133ad6SJeff Kirsher
22342b133ad6SJeff Kirsher netif_device_attach(netdev);
22352b133ad6SJeff Kirsher
22362b133ad6SJeff Kirsher return 0;
22372b133ad6SJeff Kirsher }
22382b133ad6SJeff Kirsher #endif
22392b133ad6SJeff Kirsher
atl1e_shutdown(struct pci_dev * pdev)22402b133ad6SJeff Kirsher static void atl1e_shutdown(struct pci_dev *pdev)
22412b133ad6SJeff Kirsher {
22422b133ad6SJeff Kirsher atl1e_suspend(pdev, PMSG_SUSPEND);
22432b133ad6SJeff Kirsher }
22442b133ad6SJeff Kirsher
22452b133ad6SJeff Kirsher static const struct net_device_ops atl1e_netdev_ops = {
22462b133ad6SJeff Kirsher .ndo_open = atl1e_open,
22472b133ad6SJeff Kirsher .ndo_stop = atl1e_close,
22482b133ad6SJeff Kirsher .ndo_start_xmit = atl1e_xmit_frame,
22492b133ad6SJeff Kirsher .ndo_get_stats = atl1e_get_stats,
2250afc4b13dSJiri Pirko .ndo_set_rx_mode = atl1e_set_multi,
22512b133ad6SJeff Kirsher .ndo_validate_addr = eth_validate_addr,
22522b133ad6SJeff Kirsher .ndo_set_mac_address = atl1e_set_mac_addr,
22532b133ad6SJeff Kirsher .ndo_fix_features = atl1e_fix_features,
22542b133ad6SJeff Kirsher .ndo_set_features = atl1e_set_features,
22552b133ad6SJeff Kirsher .ndo_change_mtu = atl1e_change_mtu,
2256a7605370SArnd Bergmann .ndo_eth_ioctl = atl1e_ioctl,
22572b133ad6SJeff Kirsher .ndo_tx_timeout = atl1e_tx_timeout,
22582b133ad6SJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
22592b133ad6SJeff Kirsher .ndo_poll_controller = atl1e_netpoll,
22602b133ad6SJeff Kirsher #endif
22612b133ad6SJeff Kirsher
22622b133ad6SJeff Kirsher };
22632b133ad6SJeff Kirsher
atl1e_init_netdev(struct net_device * netdev,struct pci_dev * pdev)22642b133ad6SJeff Kirsher static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
22652b133ad6SJeff Kirsher {
22662b133ad6SJeff Kirsher SET_NETDEV_DEV(netdev, &pdev->dev);
22672b133ad6SJeff Kirsher pci_set_drvdata(pdev, netdev);
22682b133ad6SJeff Kirsher
22692b133ad6SJeff Kirsher netdev->netdev_ops = &atl1e_netdev_ops;
22702b133ad6SJeff Kirsher
22712b133ad6SJeff Kirsher netdev->watchdog_timeo = AT_TX_WATCHDOG;
227267bef942SJarod Wilson /* MTU range: 42 - 8170 */
227367bef942SJarod Wilson netdev->min_mtu = ETH_ZLEN - (ETH_HLEN + VLAN_HLEN);
227467bef942SJarod Wilson netdev->max_mtu = MAX_JUMBO_FRAME_SIZE -
227567bef942SJarod Wilson (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
22762b133ad6SJeff Kirsher atl1e_set_ethtool_ops(netdev);
22772b133ad6SJeff Kirsher
22782b133ad6SJeff Kirsher netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
2279f646968fSPatrick McHardy NETIF_F_HW_VLAN_CTAG_RX;
22804acff371SFlorian Westphal netdev->features = netdev->hw_features | NETIF_F_HW_VLAN_CTAG_TX;
228140dc9ab2SAndrea Merello /* not enabled by default */
228240dc9ab2SAndrea Merello netdev->hw_features |= NETIF_F_RXALL | NETIF_F_RXFCS;
22832b133ad6SJeff Kirsher return 0;
22842b133ad6SJeff Kirsher }
22852b133ad6SJeff Kirsher
228649ce9c2cSBen Hutchings /**
22872b133ad6SJeff Kirsher * atl1e_probe - Device Initialization Routine
22882b133ad6SJeff Kirsher * @pdev: PCI device information struct
22892b133ad6SJeff Kirsher * @ent: entry in atl1e_pci_tbl
22902b133ad6SJeff Kirsher *
22912b133ad6SJeff Kirsher * Returns 0 on success, negative on failure
22922b133ad6SJeff Kirsher *
22932b133ad6SJeff Kirsher * atl1e_probe initializes an adapter identified by a pci_dev structure.
22942b133ad6SJeff Kirsher * The OS initialization, configuring of the adapter private structure,
22952b133ad6SJeff Kirsher * and a hardware reset occur.
22962b133ad6SJeff Kirsher */
atl1e_probe(struct pci_dev * pdev,const struct pci_device_id * ent)22971dd06ae8SGreg Kroah-Hartman static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
22982b133ad6SJeff Kirsher {
22992b133ad6SJeff Kirsher struct net_device *netdev;
23002b133ad6SJeff Kirsher struct atl1e_adapter *adapter = NULL;
23012b133ad6SJeff Kirsher static int cards_found;
23022b133ad6SJeff Kirsher
23032b133ad6SJeff Kirsher int err = 0;
23042b133ad6SJeff Kirsher
23052b133ad6SJeff Kirsher err = pci_enable_device(pdev);
2306b0ab7096SCai Huoqing if (err)
2307b0ab7096SCai Huoqing return dev_err_probe(&pdev->dev, err, "cannot enable PCI device\n");
23082b133ad6SJeff Kirsher
23092b133ad6SJeff Kirsher /*
23102b133ad6SJeff Kirsher * The atl1e chip can DMA to 64-bit addresses, but it uses a single
23112b133ad6SJeff Kirsher * shared register for the high 32 bits, so only a single, aligned,
23122b133ad6SJeff Kirsher * 4 GB physical address range can be used at a time.
23132b133ad6SJeff Kirsher *
23142b133ad6SJeff Kirsher * Supporting 64-bit DMA on this hardware is more trouble than it's
23152b133ad6SJeff Kirsher * worth. It is far easier to limit to 32-bit DMA than update
23162b133ad6SJeff Kirsher * various kernel subsystems to support the mechanics required by a
23172b133ad6SJeff Kirsher * fixed-high-32-bit system.
23182b133ad6SJeff Kirsher */
23193a36060bSZhang Changzhong err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
23203a36060bSZhang Changzhong if (err) {
23212b133ad6SJeff Kirsher dev_err(&pdev->dev, "No usable DMA configuration,aborting\n");
23222b133ad6SJeff Kirsher goto err_dma;
23232b133ad6SJeff Kirsher }
23242b133ad6SJeff Kirsher
23252b133ad6SJeff Kirsher err = pci_request_regions(pdev, atl1e_driver_name);
23262b133ad6SJeff Kirsher if (err) {
23272b133ad6SJeff Kirsher dev_err(&pdev->dev, "cannot obtain PCI resources\n");
23282b133ad6SJeff Kirsher goto err_pci_reg;
23292b133ad6SJeff Kirsher }
23302b133ad6SJeff Kirsher
23312b133ad6SJeff Kirsher pci_set_master(pdev);
23322b133ad6SJeff Kirsher
23332b133ad6SJeff Kirsher netdev = alloc_etherdev(sizeof(struct atl1e_adapter));
23342b133ad6SJeff Kirsher if (netdev == NULL) {
23352b133ad6SJeff Kirsher err = -ENOMEM;
23362b133ad6SJeff Kirsher goto err_alloc_etherdev;
23372b133ad6SJeff Kirsher }
23382b133ad6SJeff Kirsher
23392b133ad6SJeff Kirsher err = atl1e_init_netdev(netdev, pdev);
23402b133ad6SJeff Kirsher if (err) {
23412b133ad6SJeff Kirsher netdev_err(netdev, "init netdevice failed\n");
23422b133ad6SJeff Kirsher goto err_init_netdev;
23432b133ad6SJeff Kirsher }
23442b133ad6SJeff Kirsher adapter = netdev_priv(netdev);
23452b133ad6SJeff Kirsher adapter->bd_number = cards_found;
23462b133ad6SJeff Kirsher adapter->netdev = netdev;
23472b133ad6SJeff Kirsher adapter->pdev = pdev;
23482b133ad6SJeff Kirsher adapter->hw.adapter = adapter;
23492b133ad6SJeff Kirsher adapter->hw.hw_addr = pci_iomap(pdev, BAR_0, 0);
23502b133ad6SJeff Kirsher if (!adapter->hw.hw_addr) {
23512b133ad6SJeff Kirsher err = -EIO;
23522b133ad6SJeff Kirsher netdev_err(netdev, "cannot map device registers\n");
23532b133ad6SJeff Kirsher goto err_ioremap;
23542b133ad6SJeff Kirsher }
23552b133ad6SJeff Kirsher
23562b133ad6SJeff Kirsher /* init mii data */
23572b133ad6SJeff Kirsher adapter->mii.dev = netdev;
23582b133ad6SJeff Kirsher adapter->mii.mdio_read = atl1e_mdio_read;
23592b133ad6SJeff Kirsher adapter->mii.mdio_write = atl1e_mdio_write;
23602b133ad6SJeff Kirsher adapter->mii.phy_id_mask = 0x1f;
23612b133ad6SJeff Kirsher adapter->mii.reg_num_mask = MDIO_REG_ADDR_MASK;
23622b133ad6SJeff Kirsher
2363b48b89f9SJakub Kicinski netif_napi_add(netdev, &adapter->napi, atl1e_clean);
23642b133ad6SJeff Kirsher
2365e99e88a9SKees Cook timer_setup(&adapter->phy_config_timer, atl1e_phy_config, 0);
23662b133ad6SJeff Kirsher
23672b133ad6SJeff Kirsher /* get user settings */
23682b133ad6SJeff Kirsher atl1e_check_options(adapter);
23692b133ad6SJeff Kirsher /*
23702b133ad6SJeff Kirsher * Mark all PCI regions associated with PCI device
23712b133ad6SJeff Kirsher * pdev as being reserved by owner atl1e_driver_name
23722b133ad6SJeff Kirsher * Enables bus-mastering on the device and calls
23732b133ad6SJeff Kirsher * pcibios_set_master to do the needed arch specific settings
23742b133ad6SJeff Kirsher */
23752b133ad6SJeff Kirsher atl1e_setup_pcicmd(pdev);
23762b133ad6SJeff Kirsher /* setup the private structure */
23772b133ad6SJeff Kirsher err = atl1e_sw_init(adapter);
23782b133ad6SJeff Kirsher if (err) {
23792b133ad6SJeff Kirsher netdev_err(netdev, "net device private data init failed\n");
23802b133ad6SJeff Kirsher goto err_sw_init;
23812b133ad6SJeff Kirsher }
23822b133ad6SJeff Kirsher
23832b133ad6SJeff Kirsher /* Init GPHY as early as possible due to power saving issue */
23842b133ad6SJeff Kirsher atl1e_phy_init(&adapter->hw);
23852b133ad6SJeff Kirsher /* reset the controller to
23862b133ad6SJeff Kirsher * put the device in a known good starting state */
23872b133ad6SJeff Kirsher err = atl1e_reset_hw(&adapter->hw);
23882b133ad6SJeff Kirsher if (err) {
23892b133ad6SJeff Kirsher err = -EIO;
23902b133ad6SJeff Kirsher goto err_reset;
23912b133ad6SJeff Kirsher }
23922b133ad6SJeff Kirsher
23932b133ad6SJeff Kirsher if (atl1e_read_mac_addr(&adapter->hw) != 0) {
23942b133ad6SJeff Kirsher err = -EIO;
23952b133ad6SJeff Kirsher netdev_err(netdev, "get mac address failed\n");
23962b133ad6SJeff Kirsher goto err_eeprom;
23972b133ad6SJeff Kirsher }
23982b133ad6SJeff Kirsher
2399a05e4c0aSJakub Kicinski eth_hw_addr_set(netdev, adapter->hw.mac_addr);
24002b133ad6SJeff Kirsher netdev_dbg(netdev, "mac address : %pM\n", adapter->hw.mac_addr);
24012b133ad6SJeff Kirsher
24022b133ad6SJeff Kirsher INIT_WORK(&adapter->reset_task, atl1e_reset_task);
24032b133ad6SJeff Kirsher INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
2404ee8b7a11SJakub Kicinski netif_set_tso_max_size(netdev, MAX_TSO_SEG_SIZE);
24052b133ad6SJeff Kirsher err = register_netdev(netdev);
24062b133ad6SJeff Kirsher if (err) {
24072b133ad6SJeff Kirsher netdev_err(netdev, "register netdevice failed\n");
24082b133ad6SJeff Kirsher goto err_register;
24092b133ad6SJeff Kirsher }
24102b133ad6SJeff Kirsher
24112b133ad6SJeff Kirsher /* assume we have no link for now */
24122b133ad6SJeff Kirsher netif_stop_queue(netdev);
24132b133ad6SJeff Kirsher netif_carrier_off(netdev);
24142b133ad6SJeff Kirsher
24152b133ad6SJeff Kirsher cards_found++;
24162b133ad6SJeff Kirsher
24172b133ad6SJeff Kirsher return 0;
24182b133ad6SJeff Kirsher
24192b133ad6SJeff Kirsher err_reset:
24202b133ad6SJeff Kirsher err_register:
24212b133ad6SJeff Kirsher err_sw_init:
24222b133ad6SJeff Kirsher err_eeprom:
24233e3d3540SPeter Senna Tschudin pci_iounmap(pdev, adapter->hw.hw_addr);
24242b133ad6SJeff Kirsher err_init_netdev:
24252b133ad6SJeff Kirsher err_ioremap:
24262b133ad6SJeff Kirsher free_netdev(netdev);
24272b133ad6SJeff Kirsher err_alloc_etherdev:
24282b133ad6SJeff Kirsher pci_release_regions(pdev);
24292b133ad6SJeff Kirsher err_pci_reg:
24302b133ad6SJeff Kirsher err_dma:
24312b133ad6SJeff Kirsher pci_disable_device(pdev);
24322b133ad6SJeff Kirsher return err;
24332b133ad6SJeff Kirsher }
24342b133ad6SJeff Kirsher
243549ce9c2cSBen Hutchings /**
24362b133ad6SJeff Kirsher * atl1e_remove - Device Removal Routine
24372b133ad6SJeff Kirsher * @pdev: PCI device information struct
24382b133ad6SJeff Kirsher *
24392b133ad6SJeff Kirsher * atl1e_remove is called by the PCI subsystem to alert the driver
24402b133ad6SJeff Kirsher * that it should release a PCI device. The could be caused by a
24412b133ad6SJeff Kirsher * Hot-Plug event, or because the driver is going to be removed from
24422b133ad6SJeff Kirsher * memory.
24432b133ad6SJeff Kirsher */
atl1e_remove(struct pci_dev * pdev)2444093d369dSBill Pemberton static void atl1e_remove(struct pci_dev *pdev)
24452b133ad6SJeff Kirsher {
24462b133ad6SJeff Kirsher struct net_device *netdev = pci_get_drvdata(pdev);
24472b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
24482b133ad6SJeff Kirsher
24492b133ad6SJeff Kirsher /*
24502b133ad6SJeff Kirsher * flush_scheduled work may reschedule our watchdog task, so
24512b133ad6SJeff Kirsher * explicitly disable watchdog tasks from being rescheduled
24522b133ad6SJeff Kirsher */
24532b133ad6SJeff Kirsher set_bit(__AT_DOWN, &adapter->flags);
24542b133ad6SJeff Kirsher
24552b133ad6SJeff Kirsher atl1e_del_timer(adapter);
24562b133ad6SJeff Kirsher atl1e_cancel_work(adapter);
24572b133ad6SJeff Kirsher
24582b133ad6SJeff Kirsher unregister_netdev(netdev);
24592b133ad6SJeff Kirsher atl1e_free_ring_resources(adapter);
24602b133ad6SJeff Kirsher atl1e_force_ps(&adapter->hw);
24613e3d3540SPeter Senna Tschudin pci_iounmap(pdev, adapter->hw.hw_addr);
24622b133ad6SJeff Kirsher pci_release_regions(pdev);
24632b133ad6SJeff Kirsher free_netdev(netdev);
24642b133ad6SJeff Kirsher pci_disable_device(pdev);
24652b133ad6SJeff Kirsher }
24662b133ad6SJeff Kirsher
246749ce9c2cSBen Hutchings /**
24682b133ad6SJeff Kirsher * atl1e_io_error_detected - called when PCI error is detected
24692b133ad6SJeff Kirsher * @pdev: Pointer to PCI device
24702b133ad6SJeff Kirsher * @state: The current pci connection state
24712b133ad6SJeff Kirsher *
24722b133ad6SJeff Kirsher * This function is called after a PCI bus error affecting
24732b133ad6SJeff Kirsher * this device has been detected.
24742b133ad6SJeff Kirsher */
24752b133ad6SJeff Kirsher static pci_ers_result_t
atl1e_io_error_detected(struct pci_dev * pdev,pci_channel_state_t state)24762b133ad6SJeff Kirsher atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
24772b133ad6SJeff Kirsher {
24782b133ad6SJeff Kirsher struct net_device *netdev = pci_get_drvdata(pdev);
24792b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
24802b133ad6SJeff Kirsher
24812b133ad6SJeff Kirsher netif_device_detach(netdev);
24822b133ad6SJeff Kirsher
24832b133ad6SJeff Kirsher if (state == pci_channel_io_perm_failure)
24842b133ad6SJeff Kirsher return PCI_ERS_RESULT_DISCONNECT;
24852b133ad6SJeff Kirsher
24862b133ad6SJeff Kirsher if (netif_running(netdev))
24872b133ad6SJeff Kirsher atl1e_down(adapter);
24882b133ad6SJeff Kirsher
24892b133ad6SJeff Kirsher pci_disable_device(pdev);
24902b133ad6SJeff Kirsher
24918dcc8ab8SJilin Yuan /* Request a slot reset. */
24922b133ad6SJeff Kirsher return PCI_ERS_RESULT_NEED_RESET;
24932b133ad6SJeff Kirsher }
24942b133ad6SJeff Kirsher
249549ce9c2cSBen Hutchings /**
24962b133ad6SJeff Kirsher * atl1e_io_slot_reset - called after the pci bus has been reset.
24972b133ad6SJeff Kirsher * @pdev: Pointer to PCI device
24982b133ad6SJeff Kirsher *
24992b133ad6SJeff Kirsher * Restart the card from scratch, as if from a cold-boot. Implementation
25002b133ad6SJeff Kirsher * resembles the first-half of the e1000_resume routine.
25012b133ad6SJeff Kirsher */
atl1e_io_slot_reset(struct pci_dev * pdev)25022b133ad6SJeff Kirsher static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
25032b133ad6SJeff Kirsher {
25042b133ad6SJeff Kirsher struct net_device *netdev = pci_get_drvdata(pdev);
25052b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
25062b133ad6SJeff Kirsher
25072b133ad6SJeff Kirsher if (pci_enable_device(pdev)) {
25082b133ad6SJeff Kirsher netdev_err(adapter->netdev,
25092b133ad6SJeff Kirsher "Cannot re-enable PCI device after reset\n");
25102b133ad6SJeff Kirsher return PCI_ERS_RESULT_DISCONNECT;
25112b133ad6SJeff Kirsher }
25122b133ad6SJeff Kirsher pci_set_master(pdev);
25132b133ad6SJeff Kirsher
25142b133ad6SJeff Kirsher pci_enable_wake(pdev, PCI_D3hot, 0);
25152b133ad6SJeff Kirsher pci_enable_wake(pdev, PCI_D3cold, 0);
25162b133ad6SJeff Kirsher
25172b133ad6SJeff Kirsher atl1e_reset_hw(&adapter->hw);
25182b133ad6SJeff Kirsher
25192b133ad6SJeff Kirsher return PCI_ERS_RESULT_RECOVERED;
25202b133ad6SJeff Kirsher }
25212b133ad6SJeff Kirsher
252249ce9c2cSBen Hutchings /**
25232b133ad6SJeff Kirsher * atl1e_io_resume - called when traffic can start flowing again.
25242b133ad6SJeff Kirsher * @pdev: Pointer to PCI device
25252b133ad6SJeff Kirsher *
25262b133ad6SJeff Kirsher * This callback is called when the error recovery driver tells us that
25272b133ad6SJeff Kirsher * its OK to resume normal operation. Implementation resembles the
25282b133ad6SJeff Kirsher * second-half of the atl1e_resume routine.
25292b133ad6SJeff Kirsher */
atl1e_io_resume(struct pci_dev * pdev)25302b133ad6SJeff Kirsher static void atl1e_io_resume(struct pci_dev *pdev)
25312b133ad6SJeff Kirsher {
25322b133ad6SJeff Kirsher struct net_device *netdev = pci_get_drvdata(pdev);
25332b133ad6SJeff Kirsher struct atl1e_adapter *adapter = netdev_priv(netdev);
25342b133ad6SJeff Kirsher
25352b133ad6SJeff Kirsher if (netif_running(netdev)) {
25362b133ad6SJeff Kirsher if (atl1e_up(adapter)) {
25372b133ad6SJeff Kirsher netdev_err(adapter->netdev,
25382b133ad6SJeff Kirsher "can't bring device back up after reset\n");
25392b133ad6SJeff Kirsher return;
25402b133ad6SJeff Kirsher }
25412b133ad6SJeff Kirsher }
25422b133ad6SJeff Kirsher
25432b133ad6SJeff Kirsher netif_device_attach(netdev);
25442b133ad6SJeff Kirsher }
25452b133ad6SJeff Kirsher
25463646f0e5SStephen Hemminger static const struct pci_error_handlers atl1e_err_handler = {
25472b133ad6SJeff Kirsher .error_detected = atl1e_io_error_detected,
25482b133ad6SJeff Kirsher .slot_reset = atl1e_io_slot_reset,
25492b133ad6SJeff Kirsher .resume = atl1e_io_resume,
25502b133ad6SJeff Kirsher };
25512b133ad6SJeff Kirsher
25522b133ad6SJeff Kirsher static struct pci_driver atl1e_driver = {
25532b133ad6SJeff Kirsher .name = atl1e_driver_name,
25542b133ad6SJeff Kirsher .id_table = atl1e_pci_tbl,
25552b133ad6SJeff Kirsher .probe = atl1e_probe,
2556093d369dSBill Pemberton .remove = atl1e_remove,
25572b133ad6SJeff Kirsher /* Power Management Hooks */
25582b133ad6SJeff Kirsher #ifdef CONFIG_PM
25592b133ad6SJeff Kirsher .suspend = atl1e_suspend,
25602b133ad6SJeff Kirsher .resume = atl1e_resume,
25612b133ad6SJeff Kirsher #endif
25622b133ad6SJeff Kirsher .shutdown = atl1e_shutdown,
25632b133ad6SJeff Kirsher .err_handler = &atl1e_err_handler
25642b133ad6SJeff Kirsher };
25652b133ad6SJeff Kirsher
2566687df5d4SPeter Hüwe module_pci_driver(atl1e_driver);
2567