17ac6653aSJeff Kirsher /******************************************************************************* 27ac6653aSJeff Kirsher This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers. 37ac6653aSJeff Kirsher ST Ethernet IPs are built around a Synopsys IP Core. 47ac6653aSJeff Kirsher 5286a8372SGiuseppe CAVALLARO Copyright(C) 2007-2011 STMicroelectronics Ltd 67ac6653aSJeff Kirsher 77ac6653aSJeff Kirsher This program is free software; you can redistribute it and/or modify it 87ac6653aSJeff Kirsher under the terms and conditions of the GNU General Public License, 97ac6653aSJeff Kirsher version 2, as published by the Free Software Foundation. 107ac6653aSJeff Kirsher 117ac6653aSJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 127ac6653aSJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137ac6653aSJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 147ac6653aSJeff Kirsher more details. 157ac6653aSJeff Kirsher 167ac6653aSJeff Kirsher You should have received a copy of the GNU General Public License along with 177ac6653aSJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 187ac6653aSJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 197ac6653aSJeff Kirsher 207ac6653aSJeff Kirsher The full GNU General Public License is included in this distribution in 217ac6653aSJeff Kirsher the file called "COPYING". 227ac6653aSJeff Kirsher 237ac6653aSJeff Kirsher Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 247ac6653aSJeff Kirsher 257ac6653aSJeff Kirsher Documentation available at: 267ac6653aSJeff Kirsher http://www.stlinux.com 277ac6653aSJeff Kirsher Support available at: 287ac6653aSJeff Kirsher https://bugzilla.stlinux.com/ 297ac6653aSJeff Kirsher *******************************************************************************/ 307ac6653aSJeff Kirsher 317ac6653aSJeff Kirsher #include <linux/kernel.h> 327ac6653aSJeff Kirsher #include <linux/interrupt.h> 337ac6653aSJeff Kirsher #include <linux/ip.h> 347ac6653aSJeff Kirsher #include <linux/tcp.h> 357ac6653aSJeff Kirsher #include <linux/skbuff.h> 367ac6653aSJeff Kirsher #include <linux/ethtool.h> 377ac6653aSJeff Kirsher #include <linux/if_ether.h> 387ac6653aSJeff Kirsher #include <linux/crc32.h> 397ac6653aSJeff Kirsher #include <linux/mii.h> 4001789349SJiri Pirko #include <linux/if.h> 417ac6653aSJeff Kirsher #include <linux/if_vlan.h> 427ac6653aSJeff Kirsher #include <linux/dma-mapping.h> 437ac6653aSJeff Kirsher #include <linux/slab.h> 447ac6653aSJeff Kirsher #include <linux/prefetch.h> 457ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 467ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h> 477ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h> 487ac29055SGiuseppe CAVALLARO #endif 49286a8372SGiuseppe CAVALLARO #include "stmmac.h" 507ac6653aSJeff Kirsher 517ac6653aSJeff Kirsher #undef STMMAC_DEBUG 527ac6653aSJeff Kirsher /*#define STMMAC_DEBUG*/ 537ac6653aSJeff Kirsher #ifdef STMMAC_DEBUG 547ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) \ 557ac6653aSJeff Kirsher ((void)(netif_msg_##nlevel(priv) && \ 567ac6653aSJeff Kirsher printk(KERN_##klevel fmt, ## args))) 577ac6653aSJeff Kirsher #else 587ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) do { } while (0) 597ac6653aSJeff Kirsher #endif 607ac6653aSJeff Kirsher 617ac6653aSJeff Kirsher #undef STMMAC_RX_DEBUG 627ac6653aSJeff Kirsher /*#define STMMAC_RX_DEBUG*/ 637ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 647ac6653aSJeff Kirsher #define RX_DBG(fmt, args...) printk(fmt, ## args) 657ac6653aSJeff Kirsher #else 667ac6653aSJeff Kirsher #define RX_DBG(fmt, args...) do { } while (0) 677ac6653aSJeff Kirsher #endif 687ac6653aSJeff Kirsher 697ac6653aSJeff Kirsher #undef STMMAC_XMIT_DEBUG 707ac6653aSJeff Kirsher /*#define STMMAC_XMIT_DEBUG*/ 717ac6653aSJeff Kirsher #ifdef STMMAC_TX_DEBUG 727ac6653aSJeff Kirsher #define TX_DBG(fmt, args...) printk(fmt, ## args) 737ac6653aSJeff Kirsher #else 747ac6653aSJeff Kirsher #define TX_DBG(fmt, args...) do { } while (0) 757ac6653aSJeff Kirsher #endif 767ac6653aSJeff Kirsher 777ac6653aSJeff Kirsher #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) 787ac6653aSJeff Kirsher #define JUMBO_LEN 9000 797ac6653aSJeff Kirsher 807ac6653aSJeff Kirsher /* Module parameters */ 817ac6653aSJeff Kirsher #define TX_TIMEO 5000 /* default 5 seconds */ 827ac6653aSJeff Kirsher static int watchdog = TX_TIMEO; 837ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR); 847ac6653aSJeff Kirsher MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds"); 857ac6653aSJeff Kirsher 867ac6653aSJeff Kirsher static int debug = -1; /* -1: default, 0: no output, 16: all */ 877ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR); 887ac6653aSJeff Kirsher MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)"); 897ac6653aSJeff Kirsher 90bfab27a1SGiuseppe CAVALLARO int phyaddr = -1; 917ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO); 927ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address"); 937ac6653aSJeff Kirsher 947ac6653aSJeff Kirsher #define DMA_TX_SIZE 256 957ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE; 967ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR); 977ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list"); 987ac6653aSJeff Kirsher 997ac6653aSJeff Kirsher #define DMA_RX_SIZE 256 1007ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE; 1017ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR); 1027ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list"); 1037ac6653aSJeff Kirsher 1047ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF; 1057ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); 1067ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); 1077ac6653aSJeff Kirsher 1087ac6653aSJeff Kirsher static int pause = PAUSE_TIME; 1097ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR); 1107ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time"); 1117ac6653aSJeff Kirsher 1127ac6653aSJeff Kirsher #define TC_DEFAULT 64 1137ac6653aSJeff Kirsher static int tc = TC_DEFAULT; 1147ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR); 1157ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value"); 1167ac6653aSJeff Kirsher 1177ac6653aSJeff Kirsher /* Pay attention to tune this parameter; take care of both 1187ac6653aSJeff Kirsher * hardware capability and network stabitily/performance impact. 1197ac6653aSJeff Kirsher * Many tests showed that ~4ms latency seems to be good enough. */ 1207ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 1217ac6653aSJeff Kirsher #define DEFAULT_PERIODIC_RATE 256 1227ac6653aSJeff Kirsher static int tmrate = DEFAULT_PERIODIC_RATE; 1237ac6653aSJeff Kirsher module_param(tmrate, int, S_IRUGO | S_IWUSR); 1247ac6653aSJeff Kirsher MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)"); 1257ac6653aSJeff Kirsher #endif 1267ac6653aSJeff Kirsher 1277ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE BUF_SIZE_2KiB 1287ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE; 1297ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 1307ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 1317ac6653aSJeff Kirsher 1327ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1337ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1347ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1357ac6653aSJeff Kirsher 1367ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1377ac6653aSJeff Kirsher 138bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 139bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev); 140bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void); 141bfab27a1SGiuseppe CAVALLARO #endif 142bfab27a1SGiuseppe CAVALLARO 1437ac6653aSJeff Kirsher /** 1447ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1457ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1467ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1477ac6653aSJeff Kirsher */ 1487ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1497ac6653aSJeff Kirsher { 1507ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1517ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1527ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1537ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1547ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1557ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 1567ac6653aSJeff Kirsher if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) 1577ac6653aSJeff Kirsher buf_sz = DMA_BUFFER_SIZE; 1587ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1597ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1607ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1617ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1627ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1637ac6653aSJeff Kirsher pause = PAUSE_TIME; 1647ac6653aSJeff Kirsher } 1657ac6653aSJeff Kirsher 1667ac6653aSJeff Kirsher #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) 1677ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1687ac6653aSJeff Kirsher { 1697ac6653aSJeff Kirsher int j; 1707ac6653aSJeff Kirsher pr_info("len = %d byte, buf addr: 0x%p", len, buf); 1717ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 1727ac6653aSJeff Kirsher if ((j % 16) == 0) 1737ac6653aSJeff Kirsher pr_info("\n %03x:", j); 1747ac6653aSJeff Kirsher pr_info(" %02x", buf[j]); 1757ac6653aSJeff Kirsher } 1767ac6653aSJeff Kirsher pr_info("\n"); 1777ac6653aSJeff Kirsher } 1787ac6653aSJeff Kirsher #endif 1797ac6653aSJeff Kirsher 1807ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 1817ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 1827ac6653aSJeff Kirsher 1837ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 1847ac6653aSJeff Kirsher { 1857ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 1867ac6653aSJeff Kirsher } 1877ac6653aSJeff Kirsher 1887ac6653aSJeff Kirsher /* On some ST platforms, some HW system configuraton registers have to be 1897ac6653aSJeff Kirsher * set according to the link speed negotiated. 1907ac6653aSJeff Kirsher */ 1917ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 1927ac6653aSJeff Kirsher { 1937ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 1947ac6653aSJeff Kirsher 1957ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 1967ac6653aSJeff Kirsher priv->plat->fix_mac_speed(priv->plat->bsp_priv, 1977ac6653aSJeff Kirsher phydev->speed); 1987ac6653aSJeff Kirsher } 1997ac6653aSJeff Kirsher 2007ac6653aSJeff Kirsher /** 2017ac6653aSJeff Kirsher * stmmac_adjust_link 2027ac6653aSJeff Kirsher * @dev: net device structure 2037ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 2047ac6653aSJeff Kirsher */ 2057ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 2067ac6653aSJeff Kirsher { 2077ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2087ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2097ac6653aSJeff Kirsher unsigned long flags; 2107ac6653aSJeff Kirsher int new_state = 0; 2117ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 2127ac6653aSJeff Kirsher 2137ac6653aSJeff Kirsher if (phydev == NULL) 2147ac6653aSJeff Kirsher return; 2157ac6653aSJeff Kirsher 2167ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n", 2177ac6653aSJeff Kirsher phydev->addr, phydev->link); 2187ac6653aSJeff Kirsher 2197ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 2207ac6653aSJeff Kirsher if (phydev->link) { 2217ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 2227ac6653aSJeff Kirsher 2237ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 2247ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 2257ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 2267ac6653aSJeff Kirsher new_state = 1; 2277ac6653aSJeff Kirsher if (!(phydev->duplex)) 2287ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 2297ac6653aSJeff Kirsher else 2307ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 2317ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 2327ac6653aSJeff Kirsher } 2337ac6653aSJeff Kirsher /* Flow Control operation */ 2347ac6653aSJeff Kirsher if (phydev->pause) 2357ac6653aSJeff Kirsher priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, 2367ac6653aSJeff Kirsher fc, pause_time); 2377ac6653aSJeff Kirsher 2387ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 2397ac6653aSJeff Kirsher new_state = 1; 2407ac6653aSJeff Kirsher switch (phydev->speed) { 2417ac6653aSJeff Kirsher case 1000: 2427ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 2437ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 2447ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 2457ac6653aSJeff Kirsher break; 2467ac6653aSJeff Kirsher case 100: 2477ac6653aSJeff Kirsher case 10: 2487ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 2497ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 2507ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 2517ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 2527ac6653aSJeff Kirsher } else { 2537ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 2547ac6653aSJeff Kirsher } 2557ac6653aSJeff Kirsher } else { 2567ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 2577ac6653aSJeff Kirsher } 2587ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 2597ac6653aSJeff Kirsher break; 2607ac6653aSJeff Kirsher default: 2617ac6653aSJeff Kirsher if (netif_msg_link(priv)) 2627ac6653aSJeff Kirsher pr_warning("%s: Speed (%d) is not 10" 2637ac6653aSJeff Kirsher " or 100!\n", dev->name, phydev->speed); 2647ac6653aSJeff Kirsher break; 2657ac6653aSJeff Kirsher } 2667ac6653aSJeff Kirsher 2677ac6653aSJeff Kirsher priv->speed = phydev->speed; 2687ac6653aSJeff Kirsher } 2697ac6653aSJeff Kirsher 2707ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 2717ac6653aSJeff Kirsher 2727ac6653aSJeff Kirsher if (!priv->oldlink) { 2737ac6653aSJeff Kirsher new_state = 1; 2747ac6653aSJeff Kirsher priv->oldlink = 1; 2757ac6653aSJeff Kirsher } 2767ac6653aSJeff Kirsher } else if (priv->oldlink) { 2777ac6653aSJeff Kirsher new_state = 1; 2787ac6653aSJeff Kirsher priv->oldlink = 0; 2797ac6653aSJeff Kirsher priv->speed = 0; 2807ac6653aSJeff Kirsher priv->oldduplex = -1; 2817ac6653aSJeff Kirsher } 2827ac6653aSJeff Kirsher 2837ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 2847ac6653aSJeff Kirsher phy_print_status(phydev); 2857ac6653aSJeff Kirsher 2867ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 2877ac6653aSJeff Kirsher 2887ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n"); 2897ac6653aSJeff Kirsher } 2907ac6653aSJeff Kirsher 2917ac6653aSJeff Kirsher /** 2927ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 2937ac6653aSJeff Kirsher * @dev: net device structure 2947ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 2957ac6653aSJeff Kirsher * to the mac driver. 2967ac6653aSJeff Kirsher * Return value: 2977ac6653aSJeff Kirsher * 0 on success 2987ac6653aSJeff Kirsher */ 2997ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 3007ac6653aSJeff Kirsher { 3017ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 3027ac6653aSJeff Kirsher struct phy_device *phydev; 3037ac6653aSJeff Kirsher char phy_id[MII_BUS_ID_SIZE + 3]; 3047ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 30579ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 3067ac6653aSJeff Kirsher priv->oldlink = 0; 3077ac6653aSJeff Kirsher priv->speed = 0; 3087ac6653aSJeff Kirsher priv->oldduplex = -1; 3097ac6653aSJeff Kirsher 310db8857bfSFlorian Fainelli snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id); 3117ac6653aSJeff Kirsher snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 3127ac6653aSJeff Kirsher priv->plat->phy_addr); 3137ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); 3147ac6653aSJeff Kirsher 31579ee1dc3SSrinivas Kandagatla phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface); 3167ac6653aSJeff Kirsher 3177ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 3187ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 3197ac6653aSJeff Kirsher return PTR_ERR(phydev); 3207ac6653aSJeff Kirsher } 3217ac6653aSJeff Kirsher 32279ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 323c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 324c5b9b4e4SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII)) 325c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 326c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 32779ee1dc3SSrinivas Kandagatla 3287ac6653aSJeff Kirsher /* 3297ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 3307ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 3317ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 3327ac6653aSJeff Kirsher * device as well. 3337ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 3347ac6653aSJeff Kirsher */ 3357ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 3367ac6653aSJeff Kirsher phy_disconnect(phydev); 3377ac6653aSJeff Kirsher return -ENODEV; 3387ac6653aSJeff Kirsher } 3397ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 3407ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 3417ac6653aSJeff Kirsher 3427ac6653aSJeff Kirsher priv->phydev = phydev; 3437ac6653aSJeff Kirsher 3447ac6653aSJeff Kirsher return 0; 3457ac6653aSJeff Kirsher } 3467ac6653aSJeff Kirsher 3477ac6653aSJeff Kirsher /** 3487ac6653aSJeff Kirsher * display_ring 3497ac6653aSJeff Kirsher * @p: pointer to the ring. 3507ac6653aSJeff Kirsher * @size: size of the ring. 3517ac6653aSJeff Kirsher * Description: display all the descriptors within the ring. 3527ac6653aSJeff Kirsher */ 3537ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size) 3547ac6653aSJeff Kirsher { 3557ac6653aSJeff Kirsher struct tmp_s { 3567ac6653aSJeff Kirsher u64 a; 3577ac6653aSJeff Kirsher unsigned int b; 3587ac6653aSJeff Kirsher unsigned int c; 3597ac6653aSJeff Kirsher }; 3607ac6653aSJeff Kirsher int i; 3617ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 3627ac6653aSJeff Kirsher struct tmp_s *x = (struct tmp_s *)(p + i); 3637ac6653aSJeff Kirsher pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 3647ac6653aSJeff Kirsher i, (unsigned int)virt_to_phys(&p[i]), 3657ac6653aSJeff Kirsher (unsigned int)(x->a), (unsigned int)((x->a) >> 32), 3667ac6653aSJeff Kirsher x->b, x->c); 3677ac6653aSJeff Kirsher pr_info("\n"); 3687ac6653aSJeff Kirsher } 3697ac6653aSJeff Kirsher } 3707ac6653aSJeff Kirsher 371286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 372286a8372SGiuseppe CAVALLARO { 373286a8372SGiuseppe CAVALLARO int ret = bufsize; 374286a8372SGiuseppe CAVALLARO 375286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 376286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 377286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 378286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 379286a8372SGiuseppe CAVALLARO else if (mtu >= DMA_BUFFER_SIZE) 380286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 381286a8372SGiuseppe CAVALLARO else 382286a8372SGiuseppe CAVALLARO ret = DMA_BUFFER_SIZE; 383286a8372SGiuseppe CAVALLARO 384286a8372SGiuseppe CAVALLARO return ret; 385286a8372SGiuseppe CAVALLARO } 386286a8372SGiuseppe CAVALLARO 3877ac6653aSJeff Kirsher /** 3887ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 3897ac6653aSJeff Kirsher * @dev: net device structure 3907ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 391286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 392286a8372SGiuseppe CAVALLARO * modes. 3937ac6653aSJeff Kirsher */ 3947ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev) 3957ac6653aSJeff Kirsher { 3967ac6653aSJeff Kirsher int i; 3977ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 3987ac6653aSJeff Kirsher struct sk_buff *skb; 3997ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 4007ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 401286a8372SGiuseppe CAVALLARO unsigned int bfsize; 402286a8372SGiuseppe CAVALLARO int dis_ic = 0; 403286a8372SGiuseppe CAVALLARO int des3_as_data_buf = 0; 4047ac6653aSJeff Kirsher 405286a8372SGiuseppe CAVALLARO /* Set the max buffer size according to the DESC mode 406286a8372SGiuseppe CAVALLARO * and the MTU. Note that RING mode allows 16KiB bsize. */ 407286a8372SGiuseppe CAVALLARO bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu); 408286a8372SGiuseppe CAVALLARO 409286a8372SGiuseppe CAVALLARO if (bfsize == BUF_SIZE_16KiB) 410286a8372SGiuseppe CAVALLARO des3_as_data_buf = 1; 4117ac6653aSJeff Kirsher else 412286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 4137ac6653aSJeff Kirsher 4147ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 4157ac6653aSJeff Kirsher /* Disable interrupts on completion for the reception if timer is on */ 4167ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 4177ac6653aSJeff Kirsher dis_ic = 1; 4187ac6653aSJeff Kirsher #endif 4197ac6653aSJeff Kirsher 4207ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n", 4217ac6653aSJeff Kirsher txsize, rxsize, bfsize); 4227ac6653aSJeff Kirsher 4237ac6653aSJeff Kirsher priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL); 4247ac6653aSJeff Kirsher priv->rx_skbuff = 4257ac6653aSJeff Kirsher kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL); 4267ac6653aSJeff Kirsher priv->dma_rx = 4277ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 4287ac6653aSJeff Kirsher rxsize * 4297ac6653aSJeff Kirsher sizeof(struct dma_desc), 4307ac6653aSJeff Kirsher &priv->dma_rx_phy, 4317ac6653aSJeff Kirsher GFP_KERNEL); 4327ac6653aSJeff Kirsher priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize, 4337ac6653aSJeff Kirsher GFP_KERNEL); 4347ac6653aSJeff Kirsher priv->dma_tx = 4357ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 4367ac6653aSJeff Kirsher txsize * 4377ac6653aSJeff Kirsher sizeof(struct dma_desc), 4387ac6653aSJeff Kirsher &priv->dma_tx_phy, 4397ac6653aSJeff Kirsher GFP_KERNEL); 4407ac6653aSJeff Kirsher 4417ac6653aSJeff Kirsher if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) { 4427ac6653aSJeff Kirsher pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__); 4437ac6653aSJeff Kirsher return; 4447ac6653aSJeff Kirsher } 4457ac6653aSJeff Kirsher 446286a8372SGiuseppe CAVALLARO DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, " 4477ac6653aSJeff Kirsher "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 4487ac6653aSJeff Kirsher dev->name, priv->dma_rx, priv->dma_tx, 4497ac6653aSJeff Kirsher (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 4507ac6653aSJeff Kirsher 4517ac6653aSJeff Kirsher /* RX INITIALIZATION */ 4527ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: SKB addresses:\n" 4537ac6653aSJeff Kirsher "skb\t\tskb data\tdma data\n"); 4547ac6653aSJeff Kirsher 4557ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 4567ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + i; 4577ac6653aSJeff Kirsher 45845db81e1SGiuseppe CAVALLARO skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN, 45945db81e1SGiuseppe CAVALLARO GFP_KERNEL); 4607ac6653aSJeff Kirsher if (unlikely(skb == NULL)) { 4617ac6653aSJeff Kirsher pr_err("%s: Rx init fails; skb is NULL\n", __func__); 4627ac6653aSJeff Kirsher break; 4637ac6653aSJeff Kirsher } 46445db81e1SGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 4657ac6653aSJeff Kirsher priv->rx_skbuff[i] = skb; 4667ac6653aSJeff Kirsher priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 4677ac6653aSJeff Kirsher bfsize, DMA_FROM_DEVICE); 4687ac6653aSJeff Kirsher 4697ac6653aSJeff Kirsher p->des2 = priv->rx_skbuff_dma[i]; 470286a8372SGiuseppe CAVALLARO 471286a8372SGiuseppe CAVALLARO priv->hw->ring->init_desc3(des3_as_data_buf, p); 472286a8372SGiuseppe CAVALLARO 4737ac6653aSJeff Kirsher DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 4747ac6653aSJeff Kirsher priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]); 4757ac6653aSJeff Kirsher } 4767ac6653aSJeff Kirsher priv->cur_rx = 0; 4777ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 4787ac6653aSJeff Kirsher priv->dma_buf_sz = bfsize; 4797ac6653aSJeff Kirsher buf_sz = bfsize; 4807ac6653aSJeff Kirsher 4817ac6653aSJeff Kirsher /* TX INITIALIZATION */ 4827ac6653aSJeff Kirsher for (i = 0; i < txsize; i++) { 4837ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 4847ac6653aSJeff Kirsher priv->dma_tx[i].des2 = 0; 4857ac6653aSJeff Kirsher } 486286a8372SGiuseppe CAVALLARO 487286a8372SGiuseppe CAVALLARO /* In case of Chained mode this sets the des3 to the next 488286a8372SGiuseppe CAVALLARO * element in the chain */ 489286a8372SGiuseppe CAVALLARO priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize); 490286a8372SGiuseppe CAVALLARO priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize); 491286a8372SGiuseppe CAVALLARO 4927ac6653aSJeff Kirsher priv->dirty_tx = 0; 4937ac6653aSJeff Kirsher priv->cur_tx = 0; 4947ac6653aSJeff Kirsher 4957ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 4967ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic); 4977ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, txsize); 4987ac6653aSJeff Kirsher 4997ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 5007ac6653aSJeff Kirsher pr_info("RX descriptor ring:\n"); 5017ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 5027ac6653aSJeff Kirsher pr_info("TX descriptor ring:\n"); 5037ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 5047ac6653aSJeff Kirsher } 5057ac6653aSJeff Kirsher } 5067ac6653aSJeff Kirsher 5077ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 5087ac6653aSJeff Kirsher { 5097ac6653aSJeff Kirsher int i; 5107ac6653aSJeff Kirsher 5117ac6653aSJeff Kirsher for (i = 0; i < priv->dma_rx_size; i++) { 5127ac6653aSJeff Kirsher if (priv->rx_skbuff[i]) { 5137ac6653aSJeff Kirsher dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 5147ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 5157ac6653aSJeff Kirsher dev_kfree_skb_any(priv->rx_skbuff[i]); 5167ac6653aSJeff Kirsher } 5177ac6653aSJeff Kirsher priv->rx_skbuff[i] = NULL; 5187ac6653aSJeff Kirsher } 5197ac6653aSJeff Kirsher } 5207ac6653aSJeff Kirsher 5217ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 5227ac6653aSJeff Kirsher { 5237ac6653aSJeff Kirsher int i; 5247ac6653aSJeff Kirsher 5257ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 5267ac6653aSJeff Kirsher if (priv->tx_skbuff[i] != NULL) { 5277ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + i; 5287ac6653aSJeff Kirsher if (p->des2) 5297ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 5307ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 5317ac6653aSJeff Kirsher DMA_TO_DEVICE); 5327ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 5337ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 5347ac6653aSJeff Kirsher } 5357ac6653aSJeff Kirsher } 5367ac6653aSJeff Kirsher } 5377ac6653aSJeff Kirsher 5387ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 5397ac6653aSJeff Kirsher { 5407ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 5417ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 5427ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 5437ac6653aSJeff Kirsher 5447ac6653aSJeff Kirsher /* Free the region of consistent memory previously allocated for 5457ac6653aSJeff Kirsher * the DMA */ 5467ac6653aSJeff Kirsher dma_free_coherent(priv->device, 5477ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 5487ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 5497ac6653aSJeff Kirsher dma_free_coherent(priv->device, 5507ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 5517ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 5527ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 5537ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 5547ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 5557ac6653aSJeff Kirsher } 5567ac6653aSJeff Kirsher 5577ac6653aSJeff Kirsher /** 5587ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 5597ac6653aSJeff Kirsher * @priv : pointer to the private device structure. 5607ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 5617ac6653aSJeff Kirsher * or Store-And-Forward capability. 5627ac6653aSJeff Kirsher */ 5637ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 5647ac6653aSJeff Kirsher { 5657ac6653aSJeff Kirsher if (likely(priv->plat->force_sf_dma_mode || 5667ac6653aSJeff Kirsher ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) { 5677ac6653aSJeff Kirsher /* 5687ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 5697ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 5707ac6653aSJeff Kirsher * 1) TX COE if actually supported 5717ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 5727ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 5737ac6653aSJeff Kirsher */ 5747ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, 5757ac6653aSJeff Kirsher SF_DMA_MODE, SF_DMA_MODE); 5767ac6653aSJeff Kirsher tc = SF_DMA_MODE; 5777ac6653aSJeff Kirsher } else 5787ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 5797ac6653aSJeff Kirsher } 5807ac6653aSJeff Kirsher 5817ac6653aSJeff Kirsher /** 5827ac6653aSJeff Kirsher * stmmac_tx: 5837ac6653aSJeff Kirsher * @priv: private driver structure 5847ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 5857ac6653aSJeff Kirsher */ 5867ac6653aSJeff Kirsher static void stmmac_tx(struct stmmac_priv *priv) 5877ac6653aSJeff Kirsher { 5887ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 5897ac6653aSJeff Kirsher 590a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 591a9097a96SGiuseppe CAVALLARO 5927ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 5937ac6653aSJeff Kirsher int last; 5947ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 5957ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 5967ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + entry; 5977ac6653aSJeff Kirsher 5987ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 5997ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 6007ac6653aSJeff Kirsher break; 6017ac6653aSJeff Kirsher 6027ac6653aSJeff Kirsher /* Verify tx error by looking at the last segment */ 6037ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 6047ac6653aSJeff Kirsher if (likely(last)) { 6057ac6653aSJeff Kirsher int tx_error = 6067ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 6077ac6653aSJeff Kirsher &priv->xstats, p, 6087ac6653aSJeff Kirsher priv->ioaddr); 6097ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 6107ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 6117ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 6127ac6653aSJeff Kirsher } else 6137ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 6147ac6653aSJeff Kirsher } 6157ac6653aSJeff Kirsher TX_DBG("%s: curr %d, dirty %d\n", __func__, 6167ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 6177ac6653aSJeff Kirsher 6187ac6653aSJeff Kirsher if (likely(p->des2)) 6197ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 6207ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 6217ac6653aSJeff Kirsher DMA_TO_DEVICE); 622286a8372SGiuseppe CAVALLARO priv->hw->ring->clean_desc3(p); 6237ac6653aSJeff Kirsher 6247ac6653aSJeff Kirsher if (likely(skb != NULL)) { 6257ac6653aSJeff Kirsher /* 6267ac6653aSJeff Kirsher * If there's room in the queue (limit it to size) 6277ac6653aSJeff Kirsher * we add this skb back into the pool, 6287ac6653aSJeff Kirsher * if it's the right size. 6297ac6653aSJeff Kirsher */ 6307ac6653aSJeff Kirsher if ((skb_queue_len(&priv->rx_recycle) < 6317ac6653aSJeff Kirsher priv->dma_rx_size) && 6327ac6653aSJeff Kirsher skb_recycle_check(skb, priv->dma_buf_sz)) 6337ac6653aSJeff Kirsher __skb_queue_head(&priv->rx_recycle, skb); 6347ac6653aSJeff Kirsher else 6357ac6653aSJeff Kirsher dev_kfree_skb(skb); 6367ac6653aSJeff Kirsher 6377ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 6387ac6653aSJeff Kirsher } 6397ac6653aSJeff Kirsher 6407ac6653aSJeff Kirsher priv->hw->desc->release_tx_desc(p); 6417ac6653aSJeff Kirsher 6427ac6653aSJeff Kirsher entry = (++priv->dirty_tx) % txsize; 6437ac6653aSJeff Kirsher } 6447ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 6457ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 6467ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 6477ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 6487ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 6497ac6653aSJeff Kirsher TX_DBG("%s: restart transmit\n", __func__); 6507ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 6517ac6653aSJeff Kirsher } 6527ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 6537ac6653aSJeff Kirsher } 654a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 6557ac6653aSJeff Kirsher } 6567ac6653aSJeff Kirsher 6577ac6653aSJeff Kirsher static inline void stmmac_enable_irq(struct stmmac_priv *priv) 6587ac6653aSJeff Kirsher { 6597ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 6607ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 6617ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 6627ac6653aSJeff Kirsher else 6637ac6653aSJeff Kirsher #endif 6647ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 6657ac6653aSJeff Kirsher } 6667ac6653aSJeff Kirsher 6677ac6653aSJeff Kirsher static inline void stmmac_disable_irq(struct stmmac_priv *priv) 6687ac6653aSJeff Kirsher { 6697ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 6707ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 6717ac6653aSJeff Kirsher priv->tm->timer_stop(); 6727ac6653aSJeff Kirsher else 6737ac6653aSJeff Kirsher #endif 6747ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 6757ac6653aSJeff Kirsher } 6767ac6653aSJeff Kirsher 6777ac6653aSJeff Kirsher static int stmmac_has_work(struct stmmac_priv *priv) 6787ac6653aSJeff Kirsher { 6797ac6653aSJeff Kirsher unsigned int has_work = 0; 6807ac6653aSJeff Kirsher int rxret, tx_work = 0; 6817ac6653aSJeff Kirsher 6827ac6653aSJeff Kirsher rxret = priv->hw->desc->get_rx_owner(priv->dma_rx + 6837ac6653aSJeff Kirsher (priv->cur_rx % priv->dma_rx_size)); 6847ac6653aSJeff Kirsher 6857ac6653aSJeff Kirsher if (priv->dirty_tx != priv->cur_tx) 6867ac6653aSJeff Kirsher tx_work = 1; 6877ac6653aSJeff Kirsher 6887ac6653aSJeff Kirsher if (likely(!rxret || tx_work)) 6897ac6653aSJeff Kirsher has_work = 1; 6907ac6653aSJeff Kirsher 6917ac6653aSJeff Kirsher return has_work; 6927ac6653aSJeff Kirsher } 6937ac6653aSJeff Kirsher 6947ac6653aSJeff Kirsher static inline void _stmmac_schedule(struct stmmac_priv *priv) 6957ac6653aSJeff Kirsher { 6967ac6653aSJeff Kirsher if (likely(stmmac_has_work(priv))) { 6977ac6653aSJeff Kirsher stmmac_disable_irq(priv); 6987ac6653aSJeff Kirsher napi_schedule(&priv->napi); 6997ac6653aSJeff Kirsher } 7007ac6653aSJeff Kirsher } 7017ac6653aSJeff Kirsher 7027ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 7037ac6653aSJeff Kirsher void stmmac_schedule(struct net_device *dev) 7047ac6653aSJeff Kirsher { 7057ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 7067ac6653aSJeff Kirsher 7077ac6653aSJeff Kirsher priv->xstats.sched_timer_n++; 7087ac6653aSJeff Kirsher 7097ac6653aSJeff Kirsher _stmmac_schedule(priv); 7107ac6653aSJeff Kirsher } 7117ac6653aSJeff Kirsher 7127ac6653aSJeff Kirsher static void stmmac_no_timer_started(unsigned int x) 7137ac6653aSJeff Kirsher {; 7147ac6653aSJeff Kirsher }; 7157ac6653aSJeff Kirsher 7167ac6653aSJeff Kirsher static void stmmac_no_timer_stopped(void) 7177ac6653aSJeff Kirsher {; 7187ac6653aSJeff Kirsher }; 7197ac6653aSJeff Kirsher #endif 7207ac6653aSJeff Kirsher 7217ac6653aSJeff Kirsher /** 7227ac6653aSJeff Kirsher * stmmac_tx_err: 7237ac6653aSJeff Kirsher * @priv: pointer to the private device structure 7247ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 7257ac6653aSJeff Kirsher * in case of errors. 7267ac6653aSJeff Kirsher */ 7277ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 7287ac6653aSJeff Kirsher { 7297ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 7307ac6653aSJeff Kirsher 7317ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 7327ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 7337ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 7347ac6653aSJeff Kirsher priv->dirty_tx = 0; 7357ac6653aSJeff Kirsher priv->cur_tx = 0; 7367ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 7377ac6653aSJeff Kirsher 7387ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 7397ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 7407ac6653aSJeff Kirsher } 7417ac6653aSJeff Kirsher 7427ac6653aSJeff Kirsher 7437ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 7447ac6653aSJeff Kirsher { 7457ac6653aSJeff Kirsher int status; 7467ac6653aSJeff Kirsher 7477ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 7487ac6653aSJeff Kirsher if (likely(status == handle_tx_rx)) 7497ac6653aSJeff Kirsher _stmmac_schedule(priv); 7507ac6653aSJeff Kirsher 7517ac6653aSJeff Kirsher else if (unlikely(status == tx_hard_error_bump_tc)) { 7527ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 7537ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 7547ac6653aSJeff Kirsher tc += 64; 7557ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 7567ac6653aSJeff Kirsher priv->xstats.threshold = tc; 7577ac6653aSJeff Kirsher } 7587ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 7597ac6653aSJeff Kirsher stmmac_tx_err(priv); 7607ac6653aSJeff Kirsher } 7617ac6653aSJeff Kirsher 7621c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 7631c901a46SGiuseppe CAVALLARO { 7641c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 7651c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 7661c901a46SGiuseppe CAVALLARO 7674f795b25SGiuseppe CAVALLARO /* Mask MMC irq, counters are managed in SW and registers 7684f795b25SGiuseppe CAVALLARO * are cleared on each READ eventually. */ 7691c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 7704f795b25SGiuseppe CAVALLARO 7714f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 7721c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 7731c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 7744f795b25SGiuseppe CAVALLARO } else 775aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 7761c901a46SGiuseppe CAVALLARO } 7771c901a46SGiuseppe CAVALLARO 778f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 779f0b9d786SGiuseppe CAVALLARO { 780f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 781f0b9d786SGiuseppe CAVALLARO 782f0b9d786SGiuseppe CAVALLARO /* Only check valid Synopsys Id because old MAC chips 783f0b9d786SGiuseppe CAVALLARO * have no HW registers where get the ID */ 784f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 785f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 786f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 787f0b9d786SGiuseppe CAVALLARO 788f0b9d786SGiuseppe CAVALLARO pr_info("STMMAC - user ID: 0x%x, Synopsys ID: 0x%x\n", 789f0b9d786SGiuseppe CAVALLARO uid, synid); 790f0b9d786SGiuseppe CAVALLARO 791f0b9d786SGiuseppe CAVALLARO return synid; 792f0b9d786SGiuseppe CAVALLARO } 793f0b9d786SGiuseppe CAVALLARO return 0; 794f0b9d786SGiuseppe CAVALLARO } 795e7434821SGiuseppe CAVALLARO 79619e30c14SGiuseppe CAVALLARO /** 79719e30c14SGiuseppe CAVALLARO * stmmac_selec_desc_mode 79819e30c14SGiuseppe CAVALLARO * @dev : device pointer 79919e30c14SGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors */ 80019e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 80119e30c14SGiuseppe CAVALLARO { 80219e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 80319e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 80419e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 80519e30c14SGiuseppe CAVALLARO } else { 80619e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 80719e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 80819e30c14SGiuseppe CAVALLARO } 80919e30c14SGiuseppe CAVALLARO } 81019e30c14SGiuseppe CAVALLARO 81119e30c14SGiuseppe CAVALLARO /** 81219e30c14SGiuseppe CAVALLARO * stmmac_get_hw_features 81319e30c14SGiuseppe CAVALLARO * @priv : private device pointer 81419e30c14SGiuseppe CAVALLARO * Description: 81519e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 816e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 81719e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 81819e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 819e7434821SGiuseppe CAVALLARO */ 820e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 821e7434821SGiuseppe CAVALLARO { 8225e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 8233c20f72fSGiuseppe CAVALLARO 8245e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 8255e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 826e7434821SGiuseppe CAVALLARO 8271db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 8281db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 8291db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 8301db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 8311db123fbSRayagond Kokatanur priv->dma_cap.multi_addr = 8321db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_ADDMACADRSEL) >> 5; 8331db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 8341db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 8351db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 8361db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 8371db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 8381db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 8391db123fbSRayagond Kokatanur /* MMC */ 8401db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 841e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002*/ 8421db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 8431db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 844e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008*/ 8451db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 8461db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 847e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 8481db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 8491db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 850e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 8511db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 8521db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 8531db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 8541db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 8551db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 8561db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 8571db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 858e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 8591db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 8601db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 8611db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 8621db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 863e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode*/ 8641db123fbSRayagond Kokatanur priv->dma_cap.enh_desc = 8651db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 866e7434821SGiuseppe CAVALLARO 86719e30c14SGiuseppe CAVALLARO } 868e7434821SGiuseppe CAVALLARO 869e7434821SGiuseppe CAVALLARO return hw_cap; 870e7434821SGiuseppe CAVALLARO } 871e7434821SGiuseppe CAVALLARO 8727ac6653aSJeff Kirsher /** 873bfab27a1SGiuseppe CAVALLARO * stmmac_mac_device_setup 874bfab27a1SGiuseppe CAVALLARO * @dev : device pointer 875bfab27a1SGiuseppe CAVALLARO * Description: this is to attach the GMAC or MAC 10/100 876bfab27a1SGiuseppe CAVALLARO * main core structures that will be completed during the 877bfab27a1SGiuseppe CAVALLARO * open step. 878bfab27a1SGiuseppe CAVALLARO */ 879bfab27a1SGiuseppe CAVALLARO static int stmmac_mac_device_setup(struct net_device *dev) 880bfab27a1SGiuseppe CAVALLARO { 881bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 882bfab27a1SGiuseppe CAVALLARO 883bfab27a1SGiuseppe CAVALLARO struct mac_device_info *device; 884bfab27a1SGiuseppe CAVALLARO 885bfab27a1SGiuseppe CAVALLARO if (priv->plat->has_gmac) 886bfab27a1SGiuseppe CAVALLARO device = dwmac1000_setup(priv->ioaddr); 887bfab27a1SGiuseppe CAVALLARO else 888bfab27a1SGiuseppe CAVALLARO device = dwmac100_setup(priv->ioaddr); 889bfab27a1SGiuseppe CAVALLARO 890bfab27a1SGiuseppe CAVALLARO if (!device) 891bfab27a1SGiuseppe CAVALLARO return -ENOMEM; 892bfab27a1SGiuseppe CAVALLARO 893bfab27a1SGiuseppe CAVALLARO priv->hw = device; 894bfab27a1SGiuseppe CAVALLARO priv->hw->ring = &ring_mode_ops; 895bfab27a1SGiuseppe CAVALLARO 896bfab27a1SGiuseppe CAVALLARO if (device_can_wakeup(priv->device)) { 897bfab27a1SGiuseppe CAVALLARO priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ 898bfab27a1SGiuseppe CAVALLARO enable_irq_wake(priv->wol_irq); 899bfab27a1SGiuseppe CAVALLARO } 900bfab27a1SGiuseppe CAVALLARO 901bfab27a1SGiuseppe CAVALLARO return 0; 902bfab27a1SGiuseppe CAVALLARO } 903bfab27a1SGiuseppe CAVALLARO 904bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 905bfab27a1SGiuseppe CAVALLARO { 906bfab27a1SGiuseppe CAVALLARO /* verify if the MAC address is valid, in case of failures it 907bfab27a1SGiuseppe CAVALLARO * generates a random MAC address */ 908bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 909bfab27a1SGiuseppe CAVALLARO priv->hw->mac->get_umac_addr((void __iomem *) 910bfab27a1SGiuseppe CAVALLARO priv->dev->base_addr, 911bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 912bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 913f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 914bfab27a1SGiuseppe CAVALLARO } 915bfab27a1SGiuseppe CAVALLARO pr_warning("%s: device MAC address %pM\n", priv->dev->name, 916bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 917bfab27a1SGiuseppe CAVALLARO } 918bfab27a1SGiuseppe CAVALLARO 919bfab27a1SGiuseppe CAVALLARO /** 9207ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 9217ac6653aSJeff Kirsher * @dev : pointer to the device structure. 9227ac6653aSJeff Kirsher * Description: 9237ac6653aSJeff Kirsher * This function is the open entry point of the driver. 9247ac6653aSJeff Kirsher * Return value: 9257ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 9267ac6653aSJeff Kirsher * file on failure. 9277ac6653aSJeff Kirsher */ 9287ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 9297ac6653aSJeff Kirsher { 9307ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 9317ac6653aSJeff Kirsher int ret; 9327ac6653aSJeff Kirsher 933bfab27a1SGiuseppe CAVALLARO /* MAC HW device setup */ 934bfab27a1SGiuseppe CAVALLARO ret = stmmac_mac_device_setup(dev); 935bfab27a1SGiuseppe CAVALLARO if (ret < 0) 936bfab27a1SGiuseppe CAVALLARO return ret; 937bfab27a1SGiuseppe CAVALLARO 938bfab27a1SGiuseppe CAVALLARO stmmac_check_ether_addr(priv); 9397ac6653aSJeff Kirsher 9407ac6653aSJeff Kirsher stmmac_verify_args(); 9417ac6653aSJeff Kirsher 942bfab27a1SGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 943bfab27a1SGiuseppe CAVALLARO * this needs to have multiple instances */ 944bfab27a1SGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 945bfab27a1SGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 946bfab27a1SGiuseppe CAVALLARO 947bfab27a1SGiuseppe CAVALLARO /* MDIO bus Registration */ 948bfab27a1SGiuseppe CAVALLARO ret = stmmac_mdio_register(dev); 949bfab27a1SGiuseppe CAVALLARO if (ret < 0) { 950bfab27a1SGiuseppe CAVALLARO pr_debug("%s: MDIO bus (id: %d) registration failed", 951bfab27a1SGiuseppe CAVALLARO __func__, priv->plat->bus_id); 952bfab27a1SGiuseppe CAVALLARO return ret; 953bfab27a1SGiuseppe CAVALLARO } 954bfab27a1SGiuseppe CAVALLARO 9557ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 9567ac6653aSJeff Kirsher priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); 957e404decbSJoe Perches if (unlikely(priv->tm == NULL)) 9587ac6653aSJeff Kirsher return -ENOMEM; 959e404decbSJoe Perches 9607ac6653aSJeff Kirsher priv->tm->freq = tmrate; 9617ac6653aSJeff Kirsher 9627ac6653aSJeff Kirsher /* Test if the external timer can be actually used. 9637ac6653aSJeff Kirsher * In case of failure continue without timer. */ 9647ac6653aSJeff Kirsher if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { 9657ac6653aSJeff Kirsher pr_warning("stmmaceth: cannot attach the external timer.\n"); 9667ac6653aSJeff Kirsher priv->tm->freq = 0; 9677ac6653aSJeff Kirsher priv->tm->timer_start = stmmac_no_timer_started; 9687ac6653aSJeff Kirsher priv->tm->timer_stop = stmmac_no_timer_stopped; 9697ac6653aSJeff Kirsher } else 9707ac6653aSJeff Kirsher priv->tm->enable = 1; 9717ac6653aSJeff Kirsher #endif 9727ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 9737ac6653aSJeff Kirsher if (unlikely(ret)) { 9747ac6653aSJeff Kirsher pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); 9757ac6653aSJeff Kirsher goto open_error; 9767ac6653aSJeff Kirsher } 9777ac6653aSJeff Kirsher 97819e30c14SGiuseppe CAVALLARO stmmac_get_synopsys_id(priv); 97919e30c14SGiuseppe CAVALLARO 98019e30c14SGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 98119e30c14SGiuseppe CAVALLARO 98219e30c14SGiuseppe CAVALLARO if (priv->hw_cap_support) { 98319e30c14SGiuseppe CAVALLARO pr_info(" Support DMA HW capability register"); 98419e30c14SGiuseppe CAVALLARO 98519e30c14SGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 98619e30c14SGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 98719e30c14SGiuseppe CAVALLARO * platform) with the values from the HW capability 98819e30c14SGiuseppe CAVALLARO * register (if supported). 98919e30c14SGiuseppe CAVALLARO */ 99019e30c14SGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 99119e30c14SGiuseppe CAVALLARO priv->plat->tx_coe = priv->dma_cap.tx_coe; 99219e30c14SGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 99319e30c14SGiuseppe CAVALLARO 99419e30c14SGiuseppe CAVALLARO /* By default disable wol on magic frame if not supported */ 99519e30c14SGiuseppe CAVALLARO if (!priv->dma_cap.pmt_magic_frame) 99619e30c14SGiuseppe CAVALLARO priv->wolopts &= ~WAKE_MAGIC; 99719e30c14SGiuseppe CAVALLARO 99819e30c14SGiuseppe CAVALLARO } else 99919e30c14SGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 100019e30c14SGiuseppe CAVALLARO 100119e30c14SGiuseppe CAVALLARO /* Select the enhnaced/normal descriptor structures */ 100219e30c14SGiuseppe CAVALLARO stmmac_selec_desc_mode(priv); 100319e30c14SGiuseppe CAVALLARO 100419e30c14SGiuseppe CAVALLARO /* PMT module is not integrated in all the MAC devices. */ 100519e30c14SGiuseppe CAVALLARO if (priv->plat->pmt) { 100619e30c14SGiuseppe CAVALLARO pr_info(" Remote wake-up capable\n"); 100719e30c14SGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 100819e30c14SGiuseppe CAVALLARO } 100919e30c14SGiuseppe CAVALLARO 101019e30c14SGiuseppe CAVALLARO priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); 101119e30c14SGiuseppe CAVALLARO if (priv->rx_coe) 101219e30c14SGiuseppe CAVALLARO pr_info(" Checksum Offload Engine supported\n"); 101319e30c14SGiuseppe CAVALLARO if (priv->plat->tx_coe) 101419e30c14SGiuseppe CAVALLARO pr_info(" Checksum insertion supported\n"); 101519e30c14SGiuseppe CAVALLARO 10167ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 10177ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 10187ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 10197ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 10207ac6653aSJeff Kirsher init_dma_desc_rings(dev); 10217ac6653aSJeff Kirsher 10227ac6653aSJeff Kirsher /* DMA initialization and SW reset */ 10237ac6653aSJeff Kirsher ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, 10247ac6653aSJeff Kirsher priv->dma_tx_phy, priv->dma_rx_phy); 10257ac6653aSJeff Kirsher if (ret < 0) { 10267ac6653aSJeff Kirsher pr_err("%s: DMA initialization failed\n", __func__); 10277ac6653aSJeff Kirsher goto open_error; 10287ac6653aSJeff Kirsher } 10297ac6653aSJeff Kirsher 10307ac6653aSJeff Kirsher /* Copy the MAC addr into the HW */ 10317ac6653aSJeff Kirsher priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); 10327ac6653aSJeff Kirsher /* If required, perform hw setup of the bus. */ 10337ac6653aSJeff Kirsher if (priv->plat->bus_setup) 10347ac6653aSJeff Kirsher priv->plat->bus_setup(priv->ioaddr); 10357ac6653aSJeff Kirsher /* Initialize the MAC Core */ 10367ac6653aSJeff Kirsher priv->hw->mac->core_init(priv->ioaddr); 10377ac6653aSJeff Kirsher 10387ac6653aSJeff Kirsher netdev_update_features(dev); 10397ac6653aSJeff Kirsher 10407ac6653aSJeff Kirsher /* Request the IRQ lines */ 10417ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 10427ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 10437ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 10447ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 10457ac6653aSJeff Kirsher __func__, dev->irq, ret); 10467ac6653aSJeff Kirsher goto open_error; 10477ac6653aSJeff Kirsher } 10487ac6653aSJeff Kirsher 10497ac6653aSJeff Kirsher /* Enable the MAC Rx/Tx */ 1050bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, true); 10517ac6653aSJeff Kirsher 10527ac6653aSJeff Kirsher /* Set the HW DMA mode and the COE */ 10537ac6653aSJeff Kirsher stmmac_dma_operation_mode(priv); 10547ac6653aSJeff Kirsher 10557ac6653aSJeff Kirsher /* Extra statistics */ 10567ac6653aSJeff Kirsher memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 10577ac6653aSJeff Kirsher priv->xstats.threshold = tc; 10587ac6653aSJeff Kirsher 10591c901a46SGiuseppe CAVALLARO stmmac_mmc_setup(priv); 10601c901a46SGiuseppe CAVALLARO 1061bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1062bfab27a1SGiuseppe CAVALLARO ret = stmmac_init_fs(dev); 1063bfab27a1SGiuseppe CAVALLARO if (ret < 0) 1064bfab27a1SGiuseppe CAVALLARO pr_warning("\tFailed debugFS registration"); 1065bfab27a1SGiuseppe CAVALLARO #endif 10667ac6653aSJeff Kirsher /* Start the ball rolling... */ 10677ac6653aSJeff Kirsher DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); 10687ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 10697ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 10707ac6653aSJeff Kirsher 10717ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 10727ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 10737ac6653aSJeff Kirsher #endif 10747ac6653aSJeff Kirsher /* Dump DMA/MAC registers */ 10757ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 10767ac6653aSJeff Kirsher priv->hw->mac->dump_regs(priv->ioaddr); 10777ac6653aSJeff Kirsher priv->hw->dma->dump_regs(priv->ioaddr); 10787ac6653aSJeff Kirsher } 10797ac6653aSJeff Kirsher 10807ac6653aSJeff Kirsher if (priv->phydev) 10817ac6653aSJeff Kirsher phy_start(priv->phydev); 10827ac6653aSJeff Kirsher 10837ac6653aSJeff Kirsher napi_enable(&priv->napi); 10847ac6653aSJeff Kirsher skb_queue_head_init(&priv->rx_recycle); 10857ac6653aSJeff Kirsher netif_start_queue(dev); 10867ac6653aSJeff Kirsher 10877ac6653aSJeff Kirsher return 0; 10887ac6653aSJeff Kirsher 10897ac6653aSJeff Kirsher open_error: 10907ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 10917ac6653aSJeff Kirsher kfree(priv->tm); 10927ac6653aSJeff Kirsher #endif 10937ac6653aSJeff Kirsher if (priv->phydev) 10947ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 10957ac6653aSJeff Kirsher 10967ac6653aSJeff Kirsher return ret; 10977ac6653aSJeff Kirsher } 10987ac6653aSJeff Kirsher 10997ac6653aSJeff Kirsher /** 11007ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 11017ac6653aSJeff Kirsher * @dev : device pointer. 11027ac6653aSJeff Kirsher * Description: 11037ac6653aSJeff Kirsher * This is the stop entry point of the driver. 11047ac6653aSJeff Kirsher */ 11057ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 11067ac6653aSJeff Kirsher { 11077ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 11087ac6653aSJeff Kirsher 11097ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 11107ac6653aSJeff Kirsher if (priv->phydev) { 11117ac6653aSJeff Kirsher phy_stop(priv->phydev); 11127ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 11137ac6653aSJeff Kirsher priv->phydev = NULL; 11147ac6653aSJeff Kirsher } 11157ac6653aSJeff Kirsher 11167ac6653aSJeff Kirsher netif_stop_queue(dev); 11177ac6653aSJeff Kirsher 11187ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 11197ac6653aSJeff Kirsher /* Stop and release the timer */ 11207ac6653aSJeff Kirsher stmmac_close_ext_timer(); 11217ac6653aSJeff Kirsher if (priv->tm != NULL) 11227ac6653aSJeff Kirsher kfree(priv->tm); 11237ac6653aSJeff Kirsher #endif 11247ac6653aSJeff Kirsher napi_disable(&priv->napi); 11257ac6653aSJeff Kirsher skb_queue_purge(&priv->rx_recycle); 11267ac6653aSJeff Kirsher 11277ac6653aSJeff Kirsher /* Free the IRQ lines */ 11287ac6653aSJeff Kirsher free_irq(dev->irq, dev); 11297ac6653aSJeff Kirsher 11307ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 11317ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 11327ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 11337ac6653aSJeff Kirsher 11347ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 11357ac6653aSJeff Kirsher free_dma_desc_resources(priv); 11367ac6653aSJeff Kirsher 11377ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1138bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 11397ac6653aSJeff Kirsher 11407ac6653aSJeff Kirsher netif_carrier_off(dev); 11417ac6653aSJeff Kirsher 1142bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1143bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1144bfab27a1SGiuseppe CAVALLARO #endif 1145bfab27a1SGiuseppe CAVALLARO stmmac_mdio_unregister(dev); 1146bfab27a1SGiuseppe CAVALLARO 11477ac6653aSJeff Kirsher return 0; 11487ac6653aSJeff Kirsher } 11497ac6653aSJeff Kirsher 11507ac6653aSJeff Kirsher /** 11517ac6653aSJeff Kirsher * stmmac_xmit: 11527ac6653aSJeff Kirsher * @skb : the socket buffer 11537ac6653aSJeff Kirsher * @dev : device pointer 11547ac6653aSJeff Kirsher * Description : Tx entry point of the driver. 11557ac6653aSJeff Kirsher */ 11567ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 11577ac6653aSJeff Kirsher { 11587ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 11597ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 11607ac6653aSJeff Kirsher unsigned int entry; 11617ac6653aSJeff Kirsher int i, csum_insertion = 0; 11627ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 11637ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1164286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 11657ac6653aSJeff Kirsher 11667ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 11677ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 11687ac6653aSJeff Kirsher netif_stop_queue(dev); 11697ac6653aSJeff Kirsher /* This is a hard error, log it. */ 11707ac6653aSJeff Kirsher pr_err("%s: BUG! Tx Ring full when queue awake\n", 11717ac6653aSJeff Kirsher __func__); 11727ac6653aSJeff Kirsher } 11737ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 11747ac6653aSJeff Kirsher } 11757ac6653aSJeff Kirsher 1176a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1177a9097a96SGiuseppe CAVALLARO 11787ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 11797ac6653aSJeff Kirsher 11807ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 11817ac6653aSJeff Kirsher if ((skb->len > ETH_FRAME_LEN) || nfrags) 11827ac6653aSJeff Kirsher pr_info("stmmac xmit:\n" 11837ac6653aSJeff Kirsher "\tskb addr %p - len: %d - nopaged_len: %d\n" 11847ac6653aSJeff Kirsher "\tn_frags: %d - ip_summed: %d - %s gso\n", 1185286a8372SGiuseppe CAVALLARO skb, skb->len, nopaged_len, nfrags, skb->ip_summed, 11867ac6653aSJeff Kirsher !skb_is_gso(skb) ? "isn't" : "is"); 11877ac6653aSJeff Kirsher #endif 11887ac6653aSJeff Kirsher 11897ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 11907ac6653aSJeff Kirsher 11917ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 11927ac6653aSJeff Kirsher first = desc; 11937ac6653aSJeff Kirsher 11947ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 11957ac6653aSJeff Kirsher if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN)) 11967ac6653aSJeff Kirsher pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n" 11977ac6653aSJeff Kirsher "\t\tn_frags: %d, ip_summed: %d\n", 1198286a8372SGiuseppe CAVALLARO skb->len, nopaged_len, nfrags, skb->ip_summed); 11997ac6653aSJeff Kirsher #endif 12007ac6653aSJeff Kirsher priv->tx_skbuff[entry] = skb; 1201286a8372SGiuseppe CAVALLARO 1202286a8372SGiuseppe CAVALLARO if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) { 1203286a8372SGiuseppe CAVALLARO entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion); 12047ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 12057ac6653aSJeff Kirsher } else { 12067ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 12077ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 12087ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 12097ac6653aSJeff Kirsher csum_insertion); 12107ac6653aSJeff Kirsher } 12117ac6653aSJeff Kirsher 12127ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 12139e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 12149e903e08SEric Dumazet int len = skb_frag_size(frag); 12157ac6653aSJeff Kirsher 12167ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 12177ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 12187ac6653aSJeff Kirsher 12197ac6653aSJeff Kirsher TX_DBG("\t[entry %d] segment len: %d\n", entry, len); 1220f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1221f722380dSIan Campbell DMA_TO_DEVICE); 12227ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 12237ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); 12247ac6653aSJeff Kirsher wmb(); 12257ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 12267ac6653aSJeff Kirsher } 12277ac6653aSJeff Kirsher 12287ac6653aSJeff Kirsher /* Interrupt on completition only for the latest segment */ 12297ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 12307ac6653aSJeff Kirsher 12317ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 12327ac6653aSJeff Kirsher /* Clean IC while using timer */ 12337ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 12347ac6653aSJeff Kirsher priv->hw->desc->clear_tx_ic(desc); 12357ac6653aSJeff Kirsher #endif 12367ac6653aSJeff Kirsher 12377ac6653aSJeff Kirsher wmb(); 12387ac6653aSJeff Kirsher 12397ac6653aSJeff Kirsher /* To avoid raise condition */ 12407ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 12417ac6653aSJeff Kirsher 12427ac6653aSJeff Kirsher priv->cur_tx++; 12437ac6653aSJeff Kirsher 12447ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 12457ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 12467ac6653aSJeff Kirsher pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, " 12477ac6653aSJeff Kirsher "first=%p, nfrags=%d\n", 12487ac6653aSJeff Kirsher (priv->cur_tx % txsize), (priv->dirty_tx % txsize), 12497ac6653aSJeff Kirsher entry, first, nfrags); 12507ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 12517ac6653aSJeff Kirsher pr_info(">>> frame to be transmitted: "); 12527ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 12537ac6653aSJeff Kirsher } 12547ac6653aSJeff Kirsher #endif 12557ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 12567ac6653aSJeff Kirsher TX_DBG("%s: stop transmitted packets\n", __func__); 12577ac6653aSJeff Kirsher netif_stop_queue(dev); 12587ac6653aSJeff Kirsher } 12597ac6653aSJeff Kirsher 12607ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 12617ac6653aSJeff Kirsher 12627ac6653aSJeff Kirsher skb_tx_timestamp(skb); 12637ac6653aSJeff Kirsher 12647ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 12657ac6653aSJeff Kirsher 1266a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 1267a9097a96SGiuseppe CAVALLARO 12687ac6653aSJeff Kirsher return NETDEV_TX_OK; 12697ac6653aSJeff Kirsher } 12707ac6653aSJeff Kirsher 12717ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 12727ac6653aSJeff Kirsher { 12737ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 12747ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 12757ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx; 12767ac6653aSJeff Kirsher 12777ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 12787ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 12797ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 12807ac6653aSJeff Kirsher struct sk_buff *skb; 12817ac6653aSJeff Kirsher 12827ac6653aSJeff Kirsher skb = __skb_dequeue(&priv->rx_recycle); 12837ac6653aSJeff Kirsher if (skb == NULL) 12847ac6653aSJeff Kirsher skb = netdev_alloc_skb_ip_align(priv->dev, 12857ac6653aSJeff Kirsher bfsize); 12867ac6653aSJeff Kirsher 12877ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 12887ac6653aSJeff Kirsher break; 12897ac6653aSJeff Kirsher 12907ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 12917ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 12927ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 12937ac6653aSJeff Kirsher DMA_FROM_DEVICE); 12947ac6653aSJeff Kirsher 12957ac6653aSJeff Kirsher (p + entry)->des2 = priv->rx_skbuff_dma[entry]; 1296286a8372SGiuseppe CAVALLARO 1297286a8372SGiuseppe CAVALLARO if (unlikely(priv->plat->has_gmac)) 1298286a8372SGiuseppe CAVALLARO priv->hw->ring->refill_desc3(bfsize, p + entry); 1299286a8372SGiuseppe CAVALLARO 13007ac6653aSJeff Kirsher RX_DBG(KERN_INFO "\trefill entry #%d\n", entry); 13017ac6653aSJeff Kirsher } 13027ac6653aSJeff Kirsher wmb(); 13037ac6653aSJeff Kirsher priv->hw->desc->set_rx_owner(p + entry); 13047ac6653aSJeff Kirsher } 13057ac6653aSJeff Kirsher } 13067ac6653aSJeff Kirsher 13077ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 13087ac6653aSJeff Kirsher { 13097ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 13107ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 13117ac6653aSJeff Kirsher unsigned int next_entry; 13127ac6653aSJeff Kirsher unsigned int count = 0; 13137ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + entry; 13147ac6653aSJeff Kirsher struct dma_desc *p_next; 13157ac6653aSJeff Kirsher 13167ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 13177ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 13187ac6653aSJeff Kirsher pr_debug(">>> stmmac_rx: descriptor ring:\n"); 13197ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 13207ac6653aSJeff Kirsher } 13217ac6653aSJeff Kirsher #endif 13227ac6653aSJeff Kirsher count = 0; 13237ac6653aSJeff Kirsher while (!priv->hw->desc->get_rx_owner(p)) { 13247ac6653aSJeff Kirsher int status; 13257ac6653aSJeff Kirsher 13267ac6653aSJeff Kirsher if (count >= limit) 13277ac6653aSJeff Kirsher break; 13287ac6653aSJeff Kirsher 13297ac6653aSJeff Kirsher count++; 13307ac6653aSJeff Kirsher 13317ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 13327ac6653aSJeff Kirsher p_next = priv->dma_rx + next_entry; 13337ac6653aSJeff Kirsher prefetch(p_next); 13347ac6653aSJeff Kirsher 13357ac6653aSJeff Kirsher /* read the status of the incoming frame */ 13367ac6653aSJeff Kirsher status = (priv->hw->desc->rx_status(&priv->dev->stats, 13377ac6653aSJeff Kirsher &priv->xstats, p)); 13387ac6653aSJeff Kirsher if (unlikely(status == discard_frame)) 13397ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 13407ac6653aSJeff Kirsher else { 13417ac6653aSJeff Kirsher struct sk_buff *skb; 13427ac6653aSJeff Kirsher int frame_len; 13437ac6653aSJeff Kirsher 13447ac6653aSJeff Kirsher frame_len = priv->hw->desc->get_rx_frame_len(p); 13457ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 13467ac6653aSJeff Kirsher * Type frames (LLC/LLC-SNAP) */ 13477ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 13487ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 13497ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 13507ac6653aSJeff Kirsher if (frame_len > ETH_FRAME_LEN) 13517ac6653aSJeff Kirsher pr_debug("\tRX frame size %d, COE status: %d\n", 13527ac6653aSJeff Kirsher frame_len, status); 13537ac6653aSJeff Kirsher 13547ac6653aSJeff Kirsher if (netif_msg_hw(priv)) 13557ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 13567ac6653aSJeff Kirsher p, entry, p->des2); 13577ac6653aSJeff Kirsher #endif 13587ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 13597ac6653aSJeff Kirsher if (unlikely(!skb)) { 13607ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 13617ac6653aSJeff Kirsher priv->dev->name); 13627ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 13637ac6653aSJeff Kirsher break; 13647ac6653aSJeff Kirsher } 13657ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 13667ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 13677ac6653aSJeff Kirsher 13687ac6653aSJeff Kirsher skb_put(skb, frame_len); 13697ac6653aSJeff Kirsher dma_unmap_single(priv->device, 13707ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 13717ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 13727ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 13737ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 13747ac6653aSJeff Kirsher pr_info(" frame received (%dbytes)", frame_len); 13757ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 13767ac6653aSJeff Kirsher } 13777ac6653aSJeff Kirsher #endif 13787ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 13797ac6653aSJeff Kirsher 13803c20f72fSGiuseppe CAVALLARO if (unlikely(!priv->rx_coe)) { 13813c20f72fSGiuseppe CAVALLARO /* No RX COE for old mac10/100 devices */ 13827ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 13837ac6653aSJeff Kirsher netif_receive_skb(skb); 13847ac6653aSJeff Kirsher } else { 13857ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 13867ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 13877ac6653aSJeff Kirsher } 13887ac6653aSJeff Kirsher 13897ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 13907ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 13917ac6653aSJeff Kirsher } 13927ac6653aSJeff Kirsher entry = next_entry; 13937ac6653aSJeff Kirsher p = p_next; /* use prefetched values */ 13947ac6653aSJeff Kirsher } 13957ac6653aSJeff Kirsher 13967ac6653aSJeff Kirsher stmmac_rx_refill(priv); 13977ac6653aSJeff Kirsher 13987ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 13997ac6653aSJeff Kirsher 14007ac6653aSJeff Kirsher return count; 14017ac6653aSJeff Kirsher } 14027ac6653aSJeff Kirsher 14037ac6653aSJeff Kirsher /** 14047ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 14057ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 14067ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 14077ac6653aSJeff Kirsher * all interfaces. 14087ac6653aSJeff Kirsher * Description : 14097ac6653aSJeff Kirsher * This function implements the the reception process. 14107ac6653aSJeff Kirsher * Also it runs the TX completion thread 14117ac6653aSJeff Kirsher */ 14127ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 14137ac6653aSJeff Kirsher { 14147ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 14157ac6653aSJeff Kirsher int work_done = 0; 14167ac6653aSJeff Kirsher 14177ac6653aSJeff Kirsher priv->xstats.poll_n++; 14187ac6653aSJeff Kirsher stmmac_tx(priv); 14197ac6653aSJeff Kirsher work_done = stmmac_rx(priv, budget); 14207ac6653aSJeff Kirsher 14217ac6653aSJeff Kirsher if (work_done < budget) { 14227ac6653aSJeff Kirsher napi_complete(napi); 14237ac6653aSJeff Kirsher stmmac_enable_irq(priv); 14247ac6653aSJeff Kirsher } 14257ac6653aSJeff Kirsher return work_done; 14267ac6653aSJeff Kirsher } 14277ac6653aSJeff Kirsher 14287ac6653aSJeff Kirsher /** 14297ac6653aSJeff Kirsher * stmmac_tx_timeout 14307ac6653aSJeff Kirsher * @dev : Pointer to net device structure 14317ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 14327ac6653aSJeff Kirsher * complete within a reasonable tmrate. The driver will mark the error in the 14337ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 14347ac6653aSJeff Kirsher * in order to transmit a new packet. 14357ac6653aSJeff Kirsher */ 14367ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 14377ac6653aSJeff Kirsher { 14387ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 14397ac6653aSJeff Kirsher 14407ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 14417ac6653aSJeff Kirsher stmmac_tx_err(priv); 14427ac6653aSJeff Kirsher } 14437ac6653aSJeff Kirsher 14447ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */ 14457ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map) 14467ac6653aSJeff Kirsher { 14477ac6653aSJeff Kirsher if (dev->flags & IFF_UP) /* can't act on a running interface */ 14487ac6653aSJeff Kirsher return -EBUSY; 14497ac6653aSJeff Kirsher 14507ac6653aSJeff Kirsher /* Don't allow changing the I/O address */ 14517ac6653aSJeff Kirsher if (map->base_addr != dev->base_addr) { 14527ac6653aSJeff Kirsher pr_warning("%s: can't change I/O address\n", dev->name); 14537ac6653aSJeff Kirsher return -EOPNOTSUPP; 14547ac6653aSJeff Kirsher } 14557ac6653aSJeff Kirsher 14567ac6653aSJeff Kirsher /* Don't allow changing the IRQ */ 14577ac6653aSJeff Kirsher if (map->irq != dev->irq) { 14587ac6653aSJeff Kirsher pr_warning("%s: can't change IRQ number %d\n", 14597ac6653aSJeff Kirsher dev->name, dev->irq); 14607ac6653aSJeff Kirsher return -EOPNOTSUPP; 14617ac6653aSJeff Kirsher } 14627ac6653aSJeff Kirsher 14637ac6653aSJeff Kirsher /* ignore other fields */ 14647ac6653aSJeff Kirsher return 0; 14657ac6653aSJeff Kirsher } 14667ac6653aSJeff Kirsher 14677ac6653aSJeff Kirsher /** 146801789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 14697ac6653aSJeff Kirsher * @dev : pointer to the device structure 14707ac6653aSJeff Kirsher * Description: 14717ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 14727ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 14737ac6653aSJeff Kirsher * Return value: 14747ac6653aSJeff Kirsher * void. 14757ac6653aSJeff Kirsher */ 147601789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 14777ac6653aSJeff Kirsher { 14787ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 14797ac6653aSJeff Kirsher 14807ac6653aSJeff Kirsher spin_lock(&priv->lock); 14817ac6653aSJeff Kirsher priv->hw->mac->set_filter(dev); 14827ac6653aSJeff Kirsher spin_unlock(&priv->lock); 14837ac6653aSJeff Kirsher } 14847ac6653aSJeff Kirsher 14857ac6653aSJeff Kirsher /** 14867ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 14877ac6653aSJeff Kirsher * @dev : device pointer. 14887ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 14897ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 14907ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 14917ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 14927ac6653aSJeff Kirsher * Return value: 14937ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 14947ac6653aSJeff Kirsher * file on failure. 14957ac6653aSJeff Kirsher */ 14967ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 14977ac6653aSJeff Kirsher { 14987ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 14997ac6653aSJeff Kirsher int max_mtu; 15007ac6653aSJeff Kirsher 15017ac6653aSJeff Kirsher if (netif_running(dev)) { 15027ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 15037ac6653aSJeff Kirsher return -EBUSY; 15047ac6653aSJeff Kirsher } 15057ac6653aSJeff Kirsher 150648febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 15077ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 15087ac6653aSJeff Kirsher else 150945db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 15107ac6653aSJeff Kirsher 15117ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 15127ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 15137ac6653aSJeff Kirsher return -EINVAL; 15147ac6653aSJeff Kirsher } 15157ac6653aSJeff Kirsher 15167ac6653aSJeff Kirsher dev->mtu = new_mtu; 15177ac6653aSJeff Kirsher netdev_update_features(dev); 15187ac6653aSJeff Kirsher 15197ac6653aSJeff Kirsher return 0; 15207ac6653aSJeff Kirsher } 15217ac6653aSJeff Kirsher 1522c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 1523c8f44affSMichał Mirosław netdev_features_t features) 15247ac6653aSJeff Kirsher { 15257ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15267ac6653aSJeff Kirsher 15277ac6653aSJeff Kirsher if (!priv->rx_coe) 15287ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 15297ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 15307ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 15317ac6653aSJeff Kirsher 15327ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 15337ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 15347ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 15357ac6653aSJeff Kirsher * the TX csum insertionin the TDES and not use SF. */ 15367ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 15377ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 15387ac6653aSJeff Kirsher 15397ac6653aSJeff Kirsher return features; 15407ac6653aSJeff Kirsher } 15417ac6653aSJeff Kirsher 15427ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 15437ac6653aSJeff Kirsher { 15447ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 15457ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15467ac6653aSJeff Kirsher 15477ac6653aSJeff Kirsher if (unlikely(!dev)) { 15487ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 15497ac6653aSJeff Kirsher return IRQ_NONE; 15507ac6653aSJeff Kirsher } 15517ac6653aSJeff Kirsher 15527ac6653aSJeff Kirsher if (priv->plat->has_gmac) 15537ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 15547ac6653aSJeff Kirsher priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); 15557ac6653aSJeff Kirsher 15567ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 15577ac6653aSJeff Kirsher 15587ac6653aSJeff Kirsher return IRQ_HANDLED; 15597ac6653aSJeff Kirsher } 15607ac6653aSJeff Kirsher 15617ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 15627ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 15637ac6653aSJeff Kirsher * to allow network I/O with interrupts disabled. */ 15647ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 15657ac6653aSJeff Kirsher { 15667ac6653aSJeff Kirsher disable_irq(dev->irq); 15677ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 15687ac6653aSJeff Kirsher enable_irq(dev->irq); 15697ac6653aSJeff Kirsher } 15707ac6653aSJeff Kirsher #endif 15717ac6653aSJeff Kirsher 15727ac6653aSJeff Kirsher /** 15737ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 15747ac6653aSJeff Kirsher * @dev: Device pointer. 15757ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 15767ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 15777ac6653aSJeff Kirsher * @cmd: IOCTL command 15787ac6653aSJeff Kirsher * Description: 15797ac6653aSJeff Kirsher * Currently there are no special functionality supported in IOCTL, just the 15807ac6653aSJeff Kirsher * phy_mii_ioctl(...) can be invoked. 15817ac6653aSJeff Kirsher */ 15827ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 15837ac6653aSJeff Kirsher { 15847ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15857ac6653aSJeff Kirsher int ret; 15867ac6653aSJeff Kirsher 15877ac6653aSJeff Kirsher if (!netif_running(dev)) 15887ac6653aSJeff Kirsher return -EINVAL; 15897ac6653aSJeff Kirsher 15907ac6653aSJeff Kirsher if (!priv->phydev) 15917ac6653aSJeff Kirsher return -EINVAL; 15927ac6653aSJeff Kirsher 15937ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 15947ac6653aSJeff Kirsher 15957ac6653aSJeff Kirsher return ret; 15967ac6653aSJeff Kirsher } 15977ac6653aSJeff Kirsher 15987ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 15997ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 16007ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 1601e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 16027ac29055SGiuseppe CAVALLARO 16037ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 16047ac29055SGiuseppe CAVALLARO { 16057ac29055SGiuseppe CAVALLARO struct tmp_s { 16067ac29055SGiuseppe CAVALLARO u64 a; 16077ac29055SGiuseppe CAVALLARO unsigned int b; 16087ac29055SGiuseppe CAVALLARO unsigned int c; 16097ac29055SGiuseppe CAVALLARO }; 16107ac29055SGiuseppe CAVALLARO int i; 16117ac29055SGiuseppe CAVALLARO struct net_device *dev = seq->private; 16127ac29055SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 16137ac29055SGiuseppe CAVALLARO 16147ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 16157ac29055SGiuseppe CAVALLARO seq_printf(seq, " RX descriptor ring\n"); 16167ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 16177ac29055SGiuseppe CAVALLARO 16187ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_rx_size; i++) { 16197ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i); 16207ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 16217ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 16227ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 16237ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 16247ac29055SGiuseppe CAVALLARO } 16257ac29055SGiuseppe CAVALLARO 16267ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 16277ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 16287ac29055SGiuseppe CAVALLARO seq_printf(seq, " TX descriptor ring\n"); 16297ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 16307ac29055SGiuseppe CAVALLARO 16317ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_tx_size; i++) { 16327ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i); 16337ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 16347ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 16357ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 16367ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 16377ac29055SGiuseppe CAVALLARO } 16387ac29055SGiuseppe CAVALLARO 16397ac29055SGiuseppe CAVALLARO return 0; 16407ac29055SGiuseppe CAVALLARO } 16417ac29055SGiuseppe CAVALLARO 16427ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 16437ac29055SGiuseppe CAVALLARO { 16447ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 16457ac29055SGiuseppe CAVALLARO } 16467ac29055SGiuseppe CAVALLARO 16477ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 16487ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 16497ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 16507ac29055SGiuseppe CAVALLARO .read = seq_read, 16517ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 16527ac29055SGiuseppe CAVALLARO .release = seq_release, 16537ac29055SGiuseppe CAVALLARO }; 16547ac29055SGiuseppe CAVALLARO 1655e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 1656e7434821SGiuseppe CAVALLARO { 1657e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 1658e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 1659e7434821SGiuseppe CAVALLARO 166019e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 1661e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 1662e7434821SGiuseppe CAVALLARO return 0; 1663e7434821SGiuseppe CAVALLARO } 1664e7434821SGiuseppe CAVALLARO 1665e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 1666e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 1667e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 1668e7434821SGiuseppe CAVALLARO 1669e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 1670e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 1671e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 1672e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 1673e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 1674e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 1675e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 1676e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 1677e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 1678e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 1679e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 1680e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 1681e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 1682e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 1683e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 1684e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 1685e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 1686e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 1687e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 1688e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 1689e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 1690e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 1691e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 1692e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 1693e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 1694e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 1695e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 1696e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 1697e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 1698e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 1699e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 1700e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 1701e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 1702e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 1703e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 1704e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 1705e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 1706e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 1707e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 1708e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 1709e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 1710e7434821SGiuseppe CAVALLARO 1711e7434821SGiuseppe CAVALLARO return 0; 1712e7434821SGiuseppe CAVALLARO } 1713e7434821SGiuseppe CAVALLARO 1714e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 1715e7434821SGiuseppe CAVALLARO { 1716e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 1717e7434821SGiuseppe CAVALLARO } 1718e7434821SGiuseppe CAVALLARO 1719e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 1720e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 1721e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 1722e7434821SGiuseppe CAVALLARO .read = seq_read, 1723e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 1724e7434821SGiuseppe CAVALLARO .release = seq_release, 1725e7434821SGiuseppe CAVALLARO }; 1726e7434821SGiuseppe CAVALLARO 17277ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 17287ac29055SGiuseppe CAVALLARO { 17297ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 17307ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 17317ac29055SGiuseppe CAVALLARO 17327ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 17337ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 17347ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 17357ac29055SGiuseppe CAVALLARO 17367ac29055SGiuseppe CAVALLARO return -ENOMEM; 17377ac29055SGiuseppe CAVALLARO } 17387ac29055SGiuseppe CAVALLARO 17397ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 17407ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 17417ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 17427ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 17437ac29055SGiuseppe CAVALLARO 17447ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 17457ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 17467ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 17477ac29055SGiuseppe CAVALLARO 17487ac29055SGiuseppe CAVALLARO return -ENOMEM; 17497ac29055SGiuseppe CAVALLARO } 17507ac29055SGiuseppe CAVALLARO 1751e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 1752e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 1753e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 1754e7434821SGiuseppe CAVALLARO 1755e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 1756e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 1757e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 1758e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 1759e7434821SGiuseppe CAVALLARO 1760e7434821SGiuseppe CAVALLARO return -ENOMEM; 1761e7434821SGiuseppe CAVALLARO } 1762e7434821SGiuseppe CAVALLARO 17637ac29055SGiuseppe CAVALLARO return 0; 17647ac29055SGiuseppe CAVALLARO } 17657ac29055SGiuseppe CAVALLARO 17667ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 17677ac29055SGiuseppe CAVALLARO { 17687ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 1769e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 17707ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 17717ac29055SGiuseppe CAVALLARO } 17727ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 17737ac29055SGiuseppe CAVALLARO 17747ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 17757ac6653aSJeff Kirsher .ndo_open = stmmac_open, 17767ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 17777ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 17787ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 17797ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 178001789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 17817ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 17827ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 17837ac6653aSJeff Kirsher .ndo_set_config = stmmac_config, 17847ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 17857ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 17867ac6653aSJeff Kirsher #endif 17877ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 17887ac6653aSJeff Kirsher }; 17897ac6653aSJeff Kirsher 17907ac6653aSJeff Kirsher /** 1791bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 1792bfab27a1SGiuseppe CAVALLARO * @device: device pointer 1793bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 1794bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 17957ac6653aSJeff Kirsher */ 1796bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 1797bfab27a1SGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat) 17987ac6653aSJeff Kirsher { 17997ac6653aSJeff Kirsher int ret = 0; 1800bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 1801bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 18027ac6653aSJeff Kirsher 1803bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 180441de8d4cSJoe Perches if (!ndev) 1805bfab27a1SGiuseppe CAVALLARO return NULL; 18067ac6653aSJeff Kirsher 1807bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 18087ac6653aSJeff Kirsher 1809bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 1810bfab27a1SGiuseppe CAVALLARO priv->device = device; 1811bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 1812bfab27a1SGiuseppe CAVALLARO 1813bfab27a1SGiuseppe CAVALLARO ether_setup(ndev); 1814bfab27a1SGiuseppe CAVALLARO 1815bfab27a1SGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 1816bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 1817bfab27a1SGiuseppe CAVALLARO 1818bfab27a1SGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 1819bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 1820bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 18217ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 18227ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 1823bfab27a1SGiuseppe CAVALLARO ndev->features |= NETIF_F_HW_VLAN_RX; 18247ac6653aSJeff Kirsher #endif 18257ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 18267ac6653aSJeff Kirsher 18277ac6653aSJeff Kirsher if (flow_ctrl) 18287ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 18297ac6653aSJeff Kirsher 18307ac6653aSJeff Kirsher priv->pause = pause; 1831bfab27a1SGiuseppe CAVALLARO priv->plat = plat_dat; 1832bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 18337ac6653aSJeff Kirsher 18347ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 1835a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 18367ac6653aSJeff Kirsher 1837bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 18387ac6653aSJeff Kirsher if (ret) { 18397ac6653aSJeff Kirsher pr_err("%s: ERROR %i registering the device\n", 18407ac6653aSJeff Kirsher __func__, ret); 1841bfab27a1SGiuseppe CAVALLARO goto error; 18427ac6653aSJeff Kirsher } 18437ac6653aSJeff Kirsher 18447ac6653aSJeff Kirsher DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n", 1845bfab27a1SGiuseppe CAVALLARO ndev->name, (ndev->features & NETIF_F_SG) ? "on" : "off", 1846bfab27a1SGiuseppe CAVALLARO (ndev->features & NETIF_F_IP_CSUM) ? "on" : "off"); 18477ac6653aSJeff Kirsher 1848bfab27a1SGiuseppe CAVALLARO return priv; 18497ac6653aSJeff Kirsher 1850bfab27a1SGiuseppe CAVALLARO error: 1851bfab27a1SGiuseppe CAVALLARO netif_napi_del(&priv->napi); 18527ac6653aSJeff Kirsher 18537ac6653aSJeff Kirsher unregister_netdev(ndev); 18547ac6653aSJeff Kirsher free_netdev(ndev); 18557ac6653aSJeff Kirsher 1856bfab27a1SGiuseppe CAVALLARO return NULL; 18577ac6653aSJeff Kirsher } 18587ac6653aSJeff Kirsher 18597ac6653aSJeff Kirsher /** 18607ac6653aSJeff Kirsher * stmmac_dvr_remove 1861bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 18627ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 1863bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 18647ac6653aSJeff Kirsher */ 1865bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 18667ac6653aSJeff Kirsher { 18677ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 18687ac6653aSJeff Kirsher 18697ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 18707ac6653aSJeff Kirsher 18717ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18727ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18737ac6653aSJeff Kirsher 1874bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 18757ac6653aSJeff Kirsher netif_carrier_off(ndev); 18767ac6653aSJeff Kirsher unregister_netdev(ndev); 18777ac6653aSJeff Kirsher free_netdev(ndev); 18787ac6653aSJeff Kirsher 18797ac6653aSJeff Kirsher return 0; 18807ac6653aSJeff Kirsher } 18817ac6653aSJeff Kirsher 18827ac6653aSJeff Kirsher #ifdef CONFIG_PM 1883bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 18847ac6653aSJeff Kirsher { 18857ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 18867ac6653aSJeff Kirsher int dis_ic = 0; 18877ac6653aSJeff Kirsher 18887ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 18897ac6653aSJeff Kirsher return 0; 18907ac6653aSJeff Kirsher 1891102463b1SFrancesco Virlinzi if (priv->phydev) 1892102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 1893102463b1SFrancesco Virlinzi 18947ac6653aSJeff Kirsher spin_lock(&priv->lock); 18957ac6653aSJeff Kirsher 18967ac6653aSJeff Kirsher netif_device_detach(ndev); 18977ac6653aSJeff Kirsher netif_stop_queue(ndev); 18987ac6653aSJeff Kirsher 18997ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 19007ac6653aSJeff Kirsher priv->tm->timer_stop(); 19017ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 19027ac6653aSJeff Kirsher dis_ic = 1; 19037ac6653aSJeff Kirsher #endif 19047ac6653aSJeff Kirsher napi_disable(&priv->napi); 19057ac6653aSJeff Kirsher 19067ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 19077ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 19087ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 19097ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 19107ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, 19117ac6653aSJeff Kirsher dis_ic); 19127ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 19137ac6653aSJeff Kirsher 19147ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 19157ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 19167ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 19177ac6653aSJeff Kirsher else 1918bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 19197ac6653aSJeff Kirsher 19207ac6653aSJeff Kirsher spin_unlock(&priv->lock); 19217ac6653aSJeff Kirsher return 0; 19227ac6653aSJeff Kirsher } 19237ac6653aSJeff Kirsher 1924bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 19257ac6653aSJeff Kirsher { 19267ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 19277ac6653aSJeff Kirsher 19287ac6653aSJeff Kirsher if (!netif_running(ndev)) 19297ac6653aSJeff Kirsher return 0; 19307ac6653aSJeff Kirsher 19317ac6653aSJeff Kirsher spin_lock(&priv->lock); 19327ac6653aSJeff Kirsher 19337ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 19347ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 19357ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 19367ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 19377ac6653aSJeff Kirsher * from another devices (e.g. serial console). */ 19387ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 19397ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, 0); 19407ac6653aSJeff Kirsher 19417ac6653aSJeff Kirsher netif_device_attach(ndev); 19427ac6653aSJeff Kirsher 19437ac6653aSJeff Kirsher /* Enable the MAC and DMA */ 1944bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, true); 19457ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 19467ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 19477ac6653aSJeff Kirsher 19487ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 19497ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 19507ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 19517ac6653aSJeff Kirsher #endif 19527ac6653aSJeff Kirsher napi_enable(&priv->napi); 19537ac6653aSJeff Kirsher 19547ac6653aSJeff Kirsher netif_start_queue(ndev); 19557ac6653aSJeff Kirsher 19567ac6653aSJeff Kirsher spin_unlock(&priv->lock); 1957102463b1SFrancesco Virlinzi 1958102463b1SFrancesco Virlinzi if (priv->phydev) 1959102463b1SFrancesco Virlinzi phy_start(priv->phydev); 1960102463b1SFrancesco Virlinzi 19617ac6653aSJeff Kirsher return 0; 19627ac6653aSJeff Kirsher } 19637ac6653aSJeff Kirsher 1964bfab27a1SGiuseppe CAVALLARO int stmmac_freeze(struct net_device *ndev) 19657ac6653aSJeff Kirsher { 19667ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 19677ac6653aSJeff Kirsher return 0; 19687ac6653aSJeff Kirsher 19697ac6653aSJeff Kirsher return stmmac_release(ndev); 19707ac6653aSJeff Kirsher } 19717ac6653aSJeff Kirsher 1972bfab27a1SGiuseppe CAVALLARO int stmmac_restore(struct net_device *ndev) 19737ac6653aSJeff Kirsher { 19747ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 19757ac6653aSJeff Kirsher return 0; 19767ac6653aSJeff Kirsher 19777ac6653aSJeff Kirsher return stmmac_open(ndev); 19787ac6653aSJeff Kirsher } 19797ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 19807ac6653aSJeff Kirsher 19817ac6653aSJeff Kirsher #ifndef MODULE 19827ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 19837ac6653aSJeff Kirsher { 19847ac6653aSJeff Kirsher char *opt; 19857ac6653aSJeff Kirsher 19867ac6653aSJeff Kirsher if (!str || !*str) 19877ac6653aSJeff Kirsher return -EINVAL; 19887ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 19897ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 19907ac6653aSJeff Kirsher if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug)) 19917ac6653aSJeff Kirsher goto err; 19927ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 19937ac6653aSJeff Kirsher if (strict_strtoul(opt + 8, 0, 19947ac6653aSJeff Kirsher (unsigned long *)&phyaddr)) 19957ac6653aSJeff Kirsher goto err; 19967ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 19977ac6653aSJeff Kirsher if (strict_strtoul(opt + 11, 0, 19987ac6653aSJeff Kirsher (unsigned long *)&dma_txsize)) 19997ac6653aSJeff Kirsher goto err; 20007ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 20017ac6653aSJeff Kirsher if (strict_strtoul(opt + 11, 0, 20027ac6653aSJeff Kirsher (unsigned long *)&dma_rxsize)) 20037ac6653aSJeff Kirsher goto err; 20047ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 20057ac6653aSJeff Kirsher if (strict_strtoul(opt + 7, 0, 20067ac6653aSJeff Kirsher (unsigned long *)&buf_sz)) 20077ac6653aSJeff Kirsher goto err; 20087ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 20097ac6653aSJeff Kirsher if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc)) 20107ac6653aSJeff Kirsher goto err; 20117ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 20127ac6653aSJeff Kirsher if (strict_strtoul(opt + 9, 0, 20137ac6653aSJeff Kirsher (unsigned long *)&watchdog)) 20147ac6653aSJeff Kirsher goto err; 20157ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 20167ac6653aSJeff Kirsher if (strict_strtoul(opt + 10, 0, 20177ac6653aSJeff Kirsher (unsigned long *)&flow_ctrl)) 20187ac6653aSJeff Kirsher goto err; 20197ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 20207ac6653aSJeff Kirsher if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause)) 20217ac6653aSJeff Kirsher goto err; 20227ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 20237ac6653aSJeff Kirsher } else if (!strncmp(opt, "tmrate:", 7)) { 20247ac6653aSJeff Kirsher if (strict_strtoul(opt + 7, 0, 20257ac6653aSJeff Kirsher (unsigned long *)&tmrate)) 20267ac6653aSJeff Kirsher goto err; 20277ac6653aSJeff Kirsher #endif 20287ac6653aSJeff Kirsher } 20297ac6653aSJeff Kirsher } 20307ac6653aSJeff Kirsher return 0; 20317ac6653aSJeff Kirsher 20327ac6653aSJeff Kirsher err: 20337ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 20347ac6653aSJeff Kirsher return -EINVAL; 20357ac6653aSJeff Kirsher } 20367ac6653aSJeff Kirsher 20377ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 20387ac6653aSJeff Kirsher #endif 20396fc0d0f2SGiuseppe Cavallaro 20406fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 20416fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 20426fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 2043