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 57ac6653aSJeff Kirsher Copyright (C) 2007-2009 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/module.h> 327ac6653aSJeff Kirsher #include <linux/init.h> 337ac6653aSJeff Kirsher #include <linux/kernel.h> 347ac6653aSJeff Kirsher #include <linux/interrupt.h> 357ac6653aSJeff Kirsher #include <linux/etherdevice.h> 367ac6653aSJeff Kirsher #include <linux/platform_device.h> 377ac6653aSJeff Kirsher #include <linux/ip.h> 387ac6653aSJeff Kirsher #include <linux/tcp.h> 397ac6653aSJeff Kirsher #include <linux/skbuff.h> 407ac6653aSJeff Kirsher #include <linux/ethtool.h> 417ac6653aSJeff Kirsher #include <linux/if_ether.h> 427ac6653aSJeff Kirsher #include <linux/crc32.h> 437ac6653aSJeff Kirsher #include <linux/mii.h> 447ac6653aSJeff Kirsher #include <linux/phy.h> 4501789349SJiri Pirko #include <linux/if.h> 467ac6653aSJeff Kirsher #include <linux/if_vlan.h> 477ac6653aSJeff Kirsher #include <linux/dma-mapping.h> 487ac6653aSJeff Kirsher #include <linux/slab.h> 497ac6653aSJeff Kirsher #include <linux/prefetch.h> 507ac6653aSJeff Kirsher #include "stmmac.h" 517ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 527ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h> 537ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h> 547ac29055SGiuseppe CAVALLARO #endif 557ac6653aSJeff Kirsher 567ac6653aSJeff Kirsher #define STMMAC_RESOURCE_NAME "stmmaceth" 577ac6653aSJeff Kirsher 587ac6653aSJeff Kirsher #undef STMMAC_DEBUG 597ac6653aSJeff Kirsher /*#define STMMAC_DEBUG*/ 607ac6653aSJeff Kirsher #ifdef STMMAC_DEBUG 617ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) \ 627ac6653aSJeff Kirsher ((void)(netif_msg_##nlevel(priv) && \ 637ac6653aSJeff Kirsher printk(KERN_##klevel fmt, ## args))) 647ac6653aSJeff Kirsher #else 657ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) do { } while (0) 667ac6653aSJeff Kirsher #endif 677ac6653aSJeff Kirsher 687ac6653aSJeff Kirsher #undef STMMAC_RX_DEBUG 697ac6653aSJeff Kirsher /*#define STMMAC_RX_DEBUG*/ 707ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 717ac6653aSJeff Kirsher #define RX_DBG(fmt, args...) printk(fmt, ## args) 727ac6653aSJeff Kirsher #else 737ac6653aSJeff Kirsher #define RX_DBG(fmt, args...) do { } while (0) 747ac6653aSJeff Kirsher #endif 757ac6653aSJeff Kirsher 767ac6653aSJeff Kirsher #undef STMMAC_XMIT_DEBUG 777ac6653aSJeff Kirsher /*#define STMMAC_XMIT_DEBUG*/ 787ac6653aSJeff Kirsher #ifdef STMMAC_TX_DEBUG 797ac6653aSJeff Kirsher #define TX_DBG(fmt, args...) printk(fmt, ## args) 807ac6653aSJeff Kirsher #else 817ac6653aSJeff Kirsher #define TX_DBG(fmt, args...) do { } while (0) 827ac6653aSJeff Kirsher #endif 837ac6653aSJeff Kirsher 847ac6653aSJeff Kirsher #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) 857ac6653aSJeff Kirsher #define JUMBO_LEN 9000 867ac6653aSJeff Kirsher 877ac6653aSJeff Kirsher /* Module parameters */ 887ac6653aSJeff Kirsher #define TX_TIMEO 5000 /* default 5 seconds */ 897ac6653aSJeff Kirsher static int watchdog = TX_TIMEO; 907ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR); 917ac6653aSJeff Kirsher MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds"); 927ac6653aSJeff Kirsher 937ac6653aSJeff Kirsher static int debug = -1; /* -1: default, 0: no output, 16: all */ 947ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR); 957ac6653aSJeff Kirsher MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)"); 967ac6653aSJeff Kirsher 977ac6653aSJeff Kirsher static int phyaddr = -1; 987ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO); 997ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address"); 1007ac6653aSJeff Kirsher 1017ac6653aSJeff Kirsher #define DMA_TX_SIZE 256 1027ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE; 1037ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR); 1047ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list"); 1057ac6653aSJeff Kirsher 1067ac6653aSJeff Kirsher #define DMA_RX_SIZE 256 1077ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE; 1087ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR); 1097ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list"); 1107ac6653aSJeff Kirsher 1117ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF; 1127ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); 1137ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); 1147ac6653aSJeff Kirsher 1157ac6653aSJeff Kirsher static int pause = PAUSE_TIME; 1167ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR); 1177ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time"); 1187ac6653aSJeff Kirsher 1197ac6653aSJeff Kirsher #define TC_DEFAULT 64 1207ac6653aSJeff Kirsher static int tc = TC_DEFAULT; 1217ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR); 1227ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value"); 1237ac6653aSJeff Kirsher 1247ac6653aSJeff Kirsher /* Pay attention to tune this parameter; take care of both 1257ac6653aSJeff Kirsher * hardware capability and network stabitily/performance impact. 1267ac6653aSJeff Kirsher * Many tests showed that ~4ms latency seems to be good enough. */ 1277ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 1287ac6653aSJeff Kirsher #define DEFAULT_PERIODIC_RATE 256 1297ac6653aSJeff Kirsher static int tmrate = DEFAULT_PERIODIC_RATE; 1307ac6653aSJeff Kirsher module_param(tmrate, int, S_IRUGO | S_IWUSR); 1317ac6653aSJeff Kirsher MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)"); 1327ac6653aSJeff Kirsher #endif 1337ac6653aSJeff Kirsher 1347ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE BUF_SIZE_2KiB 1357ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE; 1367ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 1377ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 1387ac6653aSJeff Kirsher 1397ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1407ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1417ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1427ac6653aSJeff Kirsher 1437ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1447ac6653aSJeff Kirsher 1457ac6653aSJeff Kirsher /** 1467ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1477ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1487ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1497ac6653aSJeff Kirsher */ 1507ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1517ac6653aSJeff Kirsher { 1527ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1537ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1547ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1557ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1567ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1577ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 1587ac6653aSJeff Kirsher if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) 1597ac6653aSJeff Kirsher buf_sz = DMA_BUFFER_SIZE; 1607ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1617ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1627ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1637ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1647ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1657ac6653aSJeff Kirsher pause = PAUSE_TIME; 1667ac6653aSJeff Kirsher } 1677ac6653aSJeff Kirsher 1687ac6653aSJeff Kirsher #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) 1697ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1707ac6653aSJeff Kirsher { 1717ac6653aSJeff Kirsher int j; 1727ac6653aSJeff Kirsher pr_info("len = %d byte, buf addr: 0x%p", len, buf); 1737ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 1747ac6653aSJeff Kirsher if ((j % 16) == 0) 1757ac6653aSJeff Kirsher pr_info("\n %03x:", j); 1767ac6653aSJeff Kirsher pr_info(" %02x", buf[j]); 1777ac6653aSJeff Kirsher } 1787ac6653aSJeff Kirsher pr_info("\n"); 1797ac6653aSJeff Kirsher } 1807ac6653aSJeff Kirsher #endif 1817ac6653aSJeff Kirsher 1827ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 1837ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 1847ac6653aSJeff Kirsher 1857ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 1867ac6653aSJeff Kirsher { 1877ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 1887ac6653aSJeff Kirsher } 1897ac6653aSJeff Kirsher 1907ac6653aSJeff Kirsher /* On some ST platforms, some HW system configuraton registers have to be 1917ac6653aSJeff Kirsher * set according to the link speed negotiated. 1927ac6653aSJeff Kirsher */ 1937ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 1947ac6653aSJeff Kirsher { 1957ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 1967ac6653aSJeff Kirsher 1977ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 1987ac6653aSJeff Kirsher priv->plat->fix_mac_speed(priv->plat->bsp_priv, 1997ac6653aSJeff Kirsher phydev->speed); 2007ac6653aSJeff Kirsher } 2017ac6653aSJeff Kirsher 2027ac6653aSJeff Kirsher /** 2037ac6653aSJeff Kirsher * stmmac_adjust_link 2047ac6653aSJeff Kirsher * @dev: net device structure 2057ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 2067ac6653aSJeff Kirsher */ 2077ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 2087ac6653aSJeff Kirsher { 2097ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2107ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2117ac6653aSJeff Kirsher unsigned long flags; 2127ac6653aSJeff Kirsher int new_state = 0; 2137ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 2147ac6653aSJeff Kirsher 2157ac6653aSJeff Kirsher if (phydev == NULL) 2167ac6653aSJeff Kirsher return; 2177ac6653aSJeff Kirsher 2187ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n", 2197ac6653aSJeff Kirsher phydev->addr, phydev->link); 2207ac6653aSJeff Kirsher 2217ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 2227ac6653aSJeff Kirsher if (phydev->link) { 2237ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 2247ac6653aSJeff Kirsher 2257ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 2267ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 2277ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 2287ac6653aSJeff Kirsher new_state = 1; 2297ac6653aSJeff Kirsher if (!(phydev->duplex)) 2307ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 2317ac6653aSJeff Kirsher else 2327ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 2337ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 2347ac6653aSJeff Kirsher } 2357ac6653aSJeff Kirsher /* Flow Control operation */ 2367ac6653aSJeff Kirsher if (phydev->pause) 2377ac6653aSJeff Kirsher priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, 2387ac6653aSJeff Kirsher fc, pause_time); 2397ac6653aSJeff Kirsher 2407ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 2417ac6653aSJeff Kirsher new_state = 1; 2427ac6653aSJeff Kirsher switch (phydev->speed) { 2437ac6653aSJeff Kirsher case 1000: 2447ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 2457ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 2467ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 2477ac6653aSJeff Kirsher break; 2487ac6653aSJeff Kirsher case 100: 2497ac6653aSJeff Kirsher case 10: 2507ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 2517ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 2527ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 2537ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 2547ac6653aSJeff Kirsher } else { 2557ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 2567ac6653aSJeff Kirsher } 2577ac6653aSJeff Kirsher } else { 2587ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 2597ac6653aSJeff Kirsher } 2607ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 2617ac6653aSJeff Kirsher break; 2627ac6653aSJeff Kirsher default: 2637ac6653aSJeff Kirsher if (netif_msg_link(priv)) 2647ac6653aSJeff Kirsher pr_warning("%s: Speed (%d) is not 10" 2657ac6653aSJeff Kirsher " or 100!\n", dev->name, phydev->speed); 2667ac6653aSJeff Kirsher break; 2677ac6653aSJeff Kirsher } 2687ac6653aSJeff Kirsher 2697ac6653aSJeff Kirsher priv->speed = phydev->speed; 2707ac6653aSJeff Kirsher } 2717ac6653aSJeff Kirsher 2727ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 2737ac6653aSJeff Kirsher 2747ac6653aSJeff Kirsher if (!priv->oldlink) { 2757ac6653aSJeff Kirsher new_state = 1; 2767ac6653aSJeff Kirsher priv->oldlink = 1; 2777ac6653aSJeff Kirsher } 2787ac6653aSJeff Kirsher } else if (priv->oldlink) { 2797ac6653aSJeff Kirsher new_state = 1; 2807ac6653aSJeff Kirsher priv->oldlink = 0; 2817ac6653aSJeff Kirsher priv->speed = 0; 2827ac6653aSJeff Kirsher priv->oldduplex = -1; 2837ac6653aSJeff Kirsher } 2847ac6653aSJeff Kirsher 2857ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 2867ac6653aSJeff Kirsher phy_print_status(phydev); 2877ac6653aSJeff Kirsher 2887ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 2897ac6653aSJeff Kirsher 2907ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n"); 2917ac6653aSJeff Kirsher } 2927ac6653aSJeff Kirsher 2937ac6653aSJeff Kirsher /** 2947ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 2957ac6653aSJeff Kirsher * @dev: net device structure 2967ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 2977ac6653aSJeff Kirsher * to the mac driver. 2987ac6653aSJeff Kirsher * Return value: 2997ac6653aSJeff Kirsher * 0 on success 3007ac6653aSJeff Kirsher */ 3017ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 3027ac6653aSJeff Kirsher { 3037ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 3047ac6653aSJeff Kirsher struct phy_device *phydev; 3057ac6653aSJeff Kirsher char phy_id[MII_BUS_ID_SIZE + 3]; 3067ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 3077ac6653aSJeff Kirsher 3087ac6653aSJeff Kirsher priv->oldlink = 0; 3097ac6653aSJeff Kirsher priv->speed = 0; 3107ac6653aSJeff Kirsher priv->oldduplex = -1; 3117ac6653aSJeff Kirsher 3127ac6653aSJeff Kirsher snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); 3137ac6653aSJeff Kirsher snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 3147ac6653aSJeff Kirsher priv->plat->phy_addr); 3157ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); 3167ac6653aSJeff Kirsher 3177ac6653aSJeff Kirsher phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, 3187ac6653aSJeff Kirsher priv->plat->interface); 3197ac6653aSJeff Kirsher 3207ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 3217ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 3227ac6653aSJeff Kirsher return PTR_ERR(phydev); 3237ac6653aSJeff Kirsher } 3247ac6653aSJeff Kirsher 3257ac6653aSJeff Kirsher /* 3267ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 3277ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 3287ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 3297ac6653aSJeff Kirsher * device as well. 3307ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 3317ac6653aSJeff Kirsher */ 3327ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 3337ac6653aSJeff Kirsher phy_disconnect(phydev); 3347ac6653aSJeff Kirsher return -ENODEV; 3357ac6653aSJeff Kirsher } 3367ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 3377ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 3387ac6653aSJeff Kirsher 3397ac6653aSJeff Kirsher priv->phydev = phydev; 3407ac6653aSJeff Kirsher 3417ac6653aSJeff Kirsher return 0; 3427ac6653aSJeff Kirsher } 3437ac6653aSJeff Kirsher 3447ac6653aSJeff Kirsher static inline void stmmac_enable_mac(void __iomem *ioaddr) 3457ac6653aSJeff Kirsher { 3467ac6653aSJeff Kirsher u32 value = readl(ioaddr + MAC_CTRL_REG); 3477ac6653aSJeff Kirsher 3487ac6653aSJeff Kirsher value |= MAC_RNABLE_RX | MAC_ENABLE_TX; 3497ac6653aSJeff Kirsher writel(value, ioaddr + MAC_CTRL_REG); 3507ac6653aSJeff Kirsher } 3517ac6653aSJeff Kirsher 3527ac6653aSJeff Kirsher static inline void stmmac_disable_mac(void __iomem *ioaddr) 3537ac6653aSJeff Kirsher { 3547ac6653aSJeff Kirsher u32 value = readl(ioaddr + MAC_CTRL_REG); 3557ac6653aSJeff Kirsher 3567ac6653aSJeff Kirsher value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX); 3577ac6653aSJeff Kirsher writel(value, ioaddr + MAC_CTRL_REG); 3587ac6653aSJeff Kirsher } 3597ac6653aSJeff Kirsher 3607ac6653aSJeff Kirsher /** 3617ac6653aSJeff Kirsher * display_ring 3627ac6653aSJeff Kirsher * @p: pointer to the ring. 3637ac6653aSJeff Kirsher * @size: size of the ring. 3647ac6653aSJeff Kirsher * Description: display all the descriptors within the ring. 3657ac6653aSJeff Kirsher */ 3667ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size) 3677ac6653aSJeff Kirsher { 3687ac6653aSJeff Kirsher struct tmp_s { 3697ac6653aSJeff Kirsher u64 a; 3707ac6653aSJeff Kirsher unsigned int b; 3717ac6653aSJeff Kirsher unsigned int c; 3727ac6653aSJeff Kirsher }; 3737ac6653aSJeff Kirsher int i; 3747ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 3757ac6653aSJeff Kirsher struct tmp_s *x = (struct tmp_s *)(p + i); 3767ac6653aSJeff Kirsher pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 3777ac6653aSJeff Kirsher i, (unsigned int)virt_to_phys(&p[i]), 3787ac6653aSJeff Kirsher (unsigned int)(x->a), (unsigned int)((x->a) >> 32), 3797ac6653aSJeff Kirsher x->b, x->c); 3807ac6653aSJeff Kirsher pr_info("\n"); 3817ac6653aSJeff Kirsher } 3827ac6653aSJeff Kirsher } 3837ac6653aSJeff Kirsher 3847ac6653aSJeff Kirsher /** 3857ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 3867ac6653aSJeff Kirsher * @dev: net device structure 3877ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 3887ac6653aSJeff Kirsher * and allocates the socket buffers. 3897ac6653aSJeff Kirsher */ 3907ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev) 3917ac6653aSJeff Kirsher { 3927ac6653aSJeff Kirsher int i; 3937ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 3947ac6653aSJeff Kirsher struct sk_buff *skb; 3957ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 3967ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 3977ac6653aSJeff Kirsher unsigned int bfsize = priv->dma_buf_sz; 3987ac6653aSJeff Kirsher int buff2_needed = 0, dis_ic = 0; 3997ac6653aSJeff Kirsher 4007ac6653aSJeff Kirsher /* Set the Buffer size according to the MTU; 4017ac6653aSJeff Kirsher * indeed, in case of jumbo we need to bump-up the buffer sizes. 4027ac6653aSJeff Kirsher */ 4037ac6653aSJeff Kirsher if (unlikely(dev->mtu >= BUF_SIZE_8KiB)) 4047ac6653aSJeff Kirsher bfsize = BUF_SIZE_16KiB; 4057ac6653aSJeff Kirsher else if (unlikely(dev->mtu >= BUF_SIZE_4KiB)) 4067ac6653aSJeff Kirsher bfsize = BUF_SIZE_8KiB; 4077ac6653aSJeff Kirsher else if (unlikely(dev->mtu >= BUF_SIZE_2KiB)) 4087ac6653aSJeff Kirsher bfsize = BUF_SIZE_4KiB; 4097ac6653aSJeff Kirsher else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE)) 4107ac6653aSJeff Kirsher bfsize = BUF_SIZE_2KiB; 4117ac6653aSJeff Kirsher else 4127ac6653aSJeff Kirsher bfsize = DMA_BUFFER_SIZE; 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 /* If the MTU exceeds 8k so use the second buffer in the chain */ 4207ac6653aSJeff Kirsher if (bfsize >= BUF_SIZE_8KiB) 4217ac6653aSJeff Kirsher buff2_needed = 1; 4227ac6653aSJeff Kirsher 4237ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n", 4247ac6653aSJeff Kirsher txsize, rxsize, bfsize); 4257ac6653aSJeff Kirsher 4267ac6653aSJeff Kirsher priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL); 4277ac6653aSJeff Kirsher priv->rx_skbuff = 4287ac6653aSJeff Kirsher kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL); 4297ac6653aSJeff Kirsher priv->dma_rx = 4307ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 4317ac6653aSJeff Kirsher rxsize * 4327ac6653aSJeff Kirsher sizeof(struct dma_desc), 4337ac6653aSJeff Kirsher &priv->dma_rx_phy, 4347ac6653aSJeff Kirsher GFP_KERNEL); 4357ac6653aSJeff Kirsher priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize, 4367ac6653aSJeff Kirsher GFP_KERNEL); 4377ac6653aSJeff Kirsher priv->dma_tx = 4387ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 4397ac6653aSJeff Kirsher txsize * 4407ac6653aSJeff Kirsher sizeof(struct dma_desc), 4417ac6653aSJeff Kirsher &priv->dma_tx_phy, 4427ac6653aSJeff Kirsher GFP_KERNEL); 4437ac6653aSJeff Kirsher 4447ac6653aSJeff Kirsher if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) { 4457ac6653aSJeff Kirsher pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__); 4467ac6653aSJeff Kirsher return; 4477ac6653aSJeff Kirsher } 4487ac6653aSJeff Kirsher 4497ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, " 4507ac6653aSJeff Kirsher "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 4517ac6653aSJeff Kirsher dev->name, priv->dma_rx, priv->dma_tx, 4527ac6653aSJeff Kirsher (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 4537ac6653aSJeff Kirsher 4547ac6653aSJeff Kirsher /* RX INITIALIZATION */ 4557ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: SKB addresses:\n" 4567ac6653aSJeff Kirsher "skb\t\tskb data\tdma data\n"); 4577ac6653aSJeff Kirsher 4587ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 4597ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + i; 4607ac6653aSJeff Kirsher 4617ac6653aSJeff Kirsher skb = netdev_alloc_skb_ip_align(dev, bfsize); 4627ac6653aSJeff Kirsher if (unlikely(skb == NULL)) { 4637ac6653aSJeff Kirsher pr_err("%s: Rx init fails; skb is NULL\n", __func__); 4647ac6653aSJeff Kirsher break; 4657ac6653aSJeff Kirsher } 4667ac6653aSJeff Kirsher priv->rx_skbuff[i] = skb; 4677ac6653aSJeff Kirsher priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 4687ac6653aSJeff Kirsher bfsize, DMA_FROM_DEVICE); 4697ac6653aSJeff Kirsher 4707ac6653aSJeff Kirsher p->des2 = priv->rx_skbuff_dma[i]; 4717ac6653aSJeff Kirsher if (unlikely(buff2_needed)) 4727ac6653aSJeff Kirsher p->des3 = p->des2 + BUF_SIZE_8KiB; 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 } 4867ac6653aSJeff Kirsher priv->dirty_tx = 0; 4877ac6653aSJeff Kirsher priv->cur_tx = 0; 4887ac6653aSJeff Kirsher 4897ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 4907ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic); 4917ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, txsize); 4927ac6653aSJeff Kirsher 4937ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 4947ac6653aSJeff Kirsher pr_info("RX descriptor ring:\n"); 4957ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 4967ac6653aSJeff Kirsher pr_info("TX descriptor ring:\n"); 4977ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 4987ac6653aSJeff Kirsher } 4997ac6653aSJeff Kirsher } 5007ac6653aSJeff Kirsher 5017ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 5027ac6653aSJeff Kirsher { 5037ac6653aSJeff Kirsher int i; 5047ac6653aSJeff Kirsher 5057ac6653aSJeff Kirsher for (i = 0; i < priv->dma_rx_size; i++) { 5067ac6653aSJeff Kirsher if (priv->rx_skbuff[i]) { 5077ac6653aSJeff Kirsher dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 5087ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 5097ac6653aSJeff Kirsher dev_kfree_skb_any(priv->rx_skbuff[i]); 5107ac6653aSJeff Kirsher } 5117ac6653aSJeff Kirsher priv->rx_skbuff[i] = NULL; 5127ac6653aSJeff Kirsher } 5137ac6653aSJeff Kirsher } 5147ac6653aSJeff Kirsher 5157ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 5167ac6653aSJeff Kirsher { 5177ac6653aSJeff Kirsher int i; 5187ac6653aSJeff Kirsher 5197ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 5207ac6653aSJeff Kirsher if (priv->tx_skbuff[i] != NULL) { 5217ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + i; 5227ac6653aSJeff Kirsher if (p->des2) 5237ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 5247ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 5257ac6653aSJeff Kirsher DMA_TO_DEVICE); 5267ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 5277ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 5287ac6653aSJeff Kirsher } 5297ac6653aSJeff Kirsher } 5307ac6653aSJeff Kirsher } 5317ac6653aSJeff Kirsher 5327ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 5337ac6653aSJeff Kirsher { 5347ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 5357ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 5367ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 5377ac6653aSJeff Kirsher 5387ac6653aSJeff Kirsher /* Free the region of consistent memory previously allocated for 5397ac6653aSJeff Kirsher * the DMA */ 5407ac6653aSJeff Kirsher dma_free_coherent(priv->device, 5417ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 5427ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 5437ac6653aSJeff Kirsher dma_free_coherent(priv->device, 5447ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 5457ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 5467ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 5477ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 5487ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 5497ac6653aSJeff Kirsher } 5507ac6653aSJeff Kirsher 5517ac6653aSJeff Kirsher /** 5527ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 5537ac6653aSJeff Kirsher * @priv : pointer to the private device structure. 5547ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 5557ac6653aSJeff Kirsher * or Store-And-Forward capability. 5567ac6653aSJeff Kirsher */ 5577ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 5587ac6653aSJeff Kirsher { 5597ac6653aSJeff Kirsher if (likely(priv->plat->force_sf_dma_mode || 5607ac6653aSJeff Kirsher ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) { 5617ac6653aSJeff Kirsher /* 5627ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 5637ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 5647ac6653aSJeff Kirsher * 1) TX COE if actually supported 5657ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 5667ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 5677ac6653aSJeff Kirsher */ 5687ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, 5697ac6653aSJeff Kirsher SF_DMA_MODE, SF_DMA_MODE); 5707ac6653aSJeff Kirsher tc = SF_DMA_MODE; 5717ac6653aSJeff Kirsher } else 5727ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 5737ac6653aSJeff Kirsher } 5747ac6653aSJeff Kirsher 5757ac6653aSJeff Kirsher /** 5767ac6653aSJeff Kirsher * stmmac_tx: 5777ac6653aSJeff Kirsher * @priv: private driver structure 5787ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 5797ac6653aSJeff Kirsher */ 5807ac6653aSJeff Kirsher static void stmmac_tx(struct stmmac_priv *priv) 5817ac6653aSJeff Kirsher { 5827ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 5837ac6653aSJeff Kirsher 5847ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 5857ac6653aSJeff Kirsher int last; 5867ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 5877ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 5887ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + entry; 5897ac6653aSJeff Kirsher 5907ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 5917ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 5927ac6653aSJeff Kirsher break; 5937ac6653aSJeff Kirsher 5947ac6653aSJeff Kirsher /* Verify tx error by looking at the last segment */ 5957ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 5967ac6653aSJeff Kirsher if (likely(last)) { 5977ac6653aSJeff Kirsher int tx_error = 5987ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 5997ac6653aSJeff Kirsher &priv->xstats, p, 6007ac6653aSJeff Kirsher priv->ioaddr); 6017ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 6027ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 6037ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 6047ac6653aSJeff Kirsher } else 6057ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 6067ac6653aSJeff Kirsher } 6077ac6653aSJeff Kirsher TX_DBG("%s: curr %d, dirty %d\n", __func__, 6087ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 6097ac6653aSJeff Kirsher 6107ac6653aSJeff Kirsher if (likely(p->des2)) 6117ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 6127ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 6137ac6653aSJeff Kirsher DMA_TO_DEVICE); 6147ac6653aSJeff Kirsher if (unlikely(p->des3)) 6157ac6653aSJeff Kirsher p->des3 = 0; 6167ac6653aSJeff Kirsher 6177ac6653aSJeff Kirsher if (likely(skb != NULL)) { 6187ac6653aSJeff Kirsher /* 6197ac6653aSJeff Kirsher * If there's room in the queue (limit it to size) 6207ac6653aSJeff Kirsher * we add this skb back into the pool, 6217ac6653aSJeff Kirsher * if it's the right size. 6227ac6653aSJeff Kirsher */ 6237ac6653aSJeff Kirsher if ((skb_queue_len(&priv->rx_recycle) < 6247ac6653aSJeff Kirsher priv->dma_rx_size) && 6257ac6653aSJeff Kirsher skb_recycle_check(skb, priv->dma_buf_sz)) 6267ac6653aSJeff Kirsher __skb_queue_head(&priv->rx_recycle, skb); 6277ac6653aSJeff Kirsher else 6287ac6653aSJeff Kirsher dev_kfree_skb(skb); 6297ac6653aSJeff Kirsher 6307ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 6317ac6653aSJeff Kirsher } 6327ac6653aSJeff Kirsher 6337ac6653aSJeff Kirsher priv->hw->desc->release_tx_desc(p); 6347ac6653aSJeff Kirsher 6357ac6653aSJeff Kirsher entry = (++priv->dirty_tx) % txsize; 6367ac6653aSJeff Kirsher } 6377ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 6387ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 6397ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 6407ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 6417ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 6427ac6653aSJeff Kirsher TX_DBG("%s: restart transmit\n", __func__); 6437ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 6447ac6653aSJeff Kirsher } 6457ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 6467ac6653aSJeff Kirsher } 6477ac6653aSJeff Kirsher } 6487ac6653aSJeff Kirsher 6497ac6653aSJeff Kirsher static inline void stmmac_enable_irq(struct stmmac_priv *priv) 6507ac6653aSJeff Kirsher { 6517ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 6527ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 6537ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 6547ac6653aSJeff Kirsher else 6557ac6653aSJeff Kirsher #endif 6567ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 6577ac6653aSJeff Kirsher } 6587ac6653aSJeff Kirsher 6597ac6653aSJeff Kirsher static inline void stmmac_disable_irq(struct stmmac_priv *priv) 6607ac6653aSJeff Kirsher { 6617ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 6627ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 6637ac6653aSJeff Kirsher priv->tm->timer_stop(); 6647ac6653aSJeff Kirsher else 6657ac6653aSJeff Kirsher #endif 6667ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 6677ac6653aSJeff Kirsher } 6687ac6653aSJeff Kirsher 6697ac6653aSJeff Kirsher static int stmmac_has_work(struct stmmac_priv *priv) 6707ac6653aSJeff Kirsher { 6717ac6653aSJeff Kirsher unsigned int has_work = 0; 6727ac6653aSJeff Kirsher int rxret, tx_work = 0; 6737ac6653aSJeff Kirsher 6747ac6653aSJeff Kirsher rxret = priv->hw->desc->get_rx_owner(priv->dma_rx + 6757ac6653aSJeff Kirsher (priv->cur_rx % priv->dma_rx_size)); 6767ac6653aSJeff Kirsher 6777ac6653aSJeff Kirsher if (priv->dirty_tx != priv->cur_tx) 6787ac6653aSJeff Kirsher tx_work = 1; 6797ac6653aSJeff Kirsher 6807ac6653aSJeff Kirsher if (likely(!rxret || tx_work)) 6817ac6653aSJeff Kirsher has_work = 1; 6827ac6653aSJeff Kirsher 6837ac6653aSJeff Kirsher return has_work; 6847ac6653aSJeff Kirsher } 6857ac6653aSJeff Kirsher 6867ac6653aSJeff Kirsher static inline void _stmmac_schedule(struct stmmac_priv *priv) 6877ac6653aSJeff Kirsher { 6887ac6653aSJeff Kirsher if (likely(stmmac_has_work(priv))) { 6897ac6653aSJeff Kirsher stmmac_disable_irq(priv); 6907ac6653aSJeff Kirsher napi_schedule(&priv->napi); 6917ac6653aSJeff Kirsher } 6927ac6653aSJeff Kirsher } 6937ac6653aSJeff Kirsher 6947ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 6957ac6653aSJeff Kirsher void stmmac_schedule(struct net_device *dev) 6967ac6653aSJeff Kirsher { 6977ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 6987ac6653aSJeff Kirsher 6997ac6653aSJeff Kirsher priv->xstats.sched_timer_n++; 7007ac6653aSJeff Kirsher 7017ac6653aSJeff Kirsher _stmmac_schedule(priv); 7027ac6653aSJeff Kirsher } 7037ac6653aSJeff Kirsher 7047ac6653aSJeff Kirsher static void stmmac_no_timer_started(unsigned int x) 7057ac6653aSJeff Kirsher {; 7067ac6653aSJeff Kirsher }; 7077ac6653aSJeff Kirsher 7087ac6653aSJeff Kirsher static void stmmac_no_timer_stopped(void) 7097ac6653aSJeff Kirsher {; 7107ac6653aSJeff Kirsher }; 7117ac6653aSJeff Kirsher #endif 7127ac6653aSJeff Kirsher 7137ac6653aSJeff Kirsher /** 7147ac6653aSJeff Kirsher * stmmac_tx_err: 7157ac6653aSJeff Kirsher * @priv: pointer to the private device structure 7167ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 7177ac6653aSJeff Kirsher * in case of errors. 7187ac6653aSJeff Kirsher */ 7197ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 7207ac6653aSJeff Kirsher { 7217ac6653aSJeff Kirsher 7227ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 7237ac6653aSJeff Kirsher 7247ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 7257ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 7267ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 7277ac6653aSJeff Kirsher priv->dirty_tx = 0; 7287ac6653aSJeff Kirsher priv->cur_tx = 0; 7297ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 7307ac6653aSJeff Kirsher 7317ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 7327ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 7337ac6653aSJeff Kirsher } 7347ac6653aSJeff Kirsher 7357ac6653aSJeff Kirsher 7367ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 7377ac6653aSJeff Kirsher { 7387ac6653aSJeff Kirsher int status; 7397ac6653aSJeff Kirsher 7407ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 7417ac6653aSJeff Kirsher if (likely(status == handle_tx_rx)) 7427ac6653aSJeff Kirsher _stmmac_schedule(priv); 7437ac6653aSJeff Kirsher 7447ac6653aSJeff Kirsher else if (unlikely(status == tx_hard_error_bump_tc)) { 7457ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 7467ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 7477ac6653aSJeff Kirsher tc += 64; 7487ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 7497ac6653aSJeff Kirsher priv->xstats.threshold = tc; 7507ac6653aSJeff Kirsher } 7517ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 7527ac6653aSJeff Kirsher stmmac_tx_err(priv); 7537ac6653aSJeff Kirsher } 7547ac6653aSJeff Kirsher 7551c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 7561c901a46SGiuseppe CAVALLARO { 7571c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 7581c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 7591c901a46SGiuseppe CAVALLARO 7601c901a46SGiuseppe CAVALLARO /* Do not manage MMC IRQ (FIXME) */ 7611c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 7621c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 7631c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 7641c901a46SGiuseppe CAVALLARO } 7651c901a46SGiuseppe CAVALLARO 766f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 767f0b9d786SGiuseppe CAVALLARO { 768f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 769f0b9d786SGiuseppe CAVALLARO 770f0b9d786SGiuseppe CAVALLARO /* Only check valid Synopsys Id because old MAC chips 771f0b9d786SGiuseppe CAVALLARO * have no HW registers where get the ID */ 772f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 773f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 774f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 775f0b9d786SGiuseppe CAVALLARO 776f0b9d786SGiuseppe CAVALLARO pr_info("STMMAC - user ID: 0x%x, Synopsys ID: 0x%x\n", 777f0b9d786SGiuseppe CAVALLARO uid, synid); 778f0b9d786SGiuseppe CAVALLARO 779f0b9d786SGiuseppe CAVALLARO return synid; 780f0b9d786SGiuseppe CAVALLARO } 781f0b9d786SGiuseppe CAVALLARO return 0; 782f0b9d786SGiuseppe CAVALLARO } 7837ac6653aSJeff Kirsher /** 7847ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 7857ac6653aSJeff Kirsher * @dev : pointer to the device structure. 7867ac6653aSJeff Kirsher * Description: 7877ac6653aSJeff Kirsher * This function is the open entry point of the driver. 7887ac6653aSJeff Kirsher * Return value: 7897ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 7907ac6653aSJeff Kirsher * file on failure. 7917ac6653aSJeff Kirsher */ 7927ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 7937ac6653aSJeff Kirsher { 7947ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 7957ac6653aSJeff Kirsher int ret; 7967ac6653aSJeff Kirsher 7977ac6653aSJeff Kirsher /* Check that the MAC address is valid. If its not, refuse 7987ac6653aSJeff Kirsher * to bring the device up. The user must specify an 7997ac6653aSJeff Kirsher * address using the following linux command: 8007ac6653aSJeff Kirsher * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */ 8017ac6653aSJeff Kirsher if (!is_valid_ether_addr(dev->dev_addr)) { 8027ac6653aSJeff Kirsher random_ether_addr(dev->dev_addr); 8037ac6653aSJeff Kirsher pr_warning("%s: generated random MAC address %pM\n", dev->name, 8047ac6653aSJeff Kirsher dev->dev_addr); 8057ac6653aSJeff Kirsher } 8067ac6653aSJeff Kirsher 8077ac6653aSJeff Kirsher stmmac_verify_args(); 8087ac6653aSJeff Kirsher 8097ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 8107ac6653aSJeff Kirsher priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); 8117ac6653aSJeff Kirsher if (unlikely(priv->tm == NULL)) { 8127ac6653aSJeff Kirsher pr_err("%s: ERROR: timer memory alloc failed\n", __func__); 8137ac6653aSJeff Kirsher return -ENOMEM; 8147ac6653aSJeff Kirsher } 8157ac6653aSJeff Kirsher priv->tm->freq = tmrate; 8167ac6653aSJeff Kirsher 8177ac6653aSJeff Kirsher /* Test if the external timer can be actually used. 8187ac6653aSJeff Kirsher * In case of failure continue without timer. */ 8197ac6653aSJeff Kirsher if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { 8207ac6653aSJeff Kirsher pr_warning("stmmaceth: cannot attach the external timer.\n"); 8217ac6653aSJeff Kirsher priv->tm->freq = 0; 8227ac6653aSJeff Kirsher priv->tm->timer_start = stmmac_no_timer_started; 8237ac6653aSJeff Kirsher priv->tm->timer_stop = stmmac_no_timer_stopped; 8247ac6653aSJeff Kirsher } else 8257ac6653aSJeff Kirsher priv->tm->enable = 1; 8267ac6653aSJeff Kirsher #endif 8277ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 8287ac6653aSJeff Kirsher if (unlikely(ret)) { 8297ac6653aSJeff Kirsher pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); 8307ac6653aSJeff Kirsher goto open_error; 8317ac6653aSJeff Kirsher } 8327ac6653aSJeff Kirsher 8337ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 8347ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 8357ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 8367ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 8377ac6653aSJeff Kirsher init_dma_desc_rings(dev); 8387ac6653aSJeff Kirsher 8397ac6653aSJeff Kirsher /* DMA initialization and SW reset */ 8407ac6653aSJeff Kirsher ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, 8417ac6653aSJeff Kirsher priv->dma_tx_phy, priv->dma_rx_phy); 8427ac6653aSJeff Kirsher if (ret < 0) { 8437ac6653aSJeff Kirsher pr_err("%s: DMA initialization failed\n", __func__); 8447ac6653aSJeff Kirsher goto open_error; 8457ac6653aSJeff Kirsher } 8467ac6653aSJeff Kirsher 8477ac6653aSJeff Kirsher /* Copy the MAC addr into the HW */ 8487ac6653aSJeff Kirsher priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); 8497ac6653aSJeff Kirsher /* If required, perform hw setup of the bus. */ 8507ac6653aSJeff Kirsher if (priv->plat->bus_setup) 8517ac6653aSJeff Kirsher priv->plat->bus_setup(priv->ioaddr); 8527ac6653aSJeff Kirsher /* Initialize the MAC Core */ 8537ac6653aSJeff Kirsher priv->hw->mac->core_init(priv->ioaddr); 8547ac6653aSJeff Kirsher 855f0b9d786SGiuseppe CAVALLARO stmmac_get_synopsys_id(priv); 856f0b9d786SGiuseppe CAVALLARO 8577ac6653aSJeff Kirsher if (priv->rx_coe) 8587ac6653aSJeff Kirsher pr_info("stmmac: Rx Checksum Offload Engine supported\n"); 8597ac6653aSJeff Kirsher if (priv->plat->tx_coe) 8607ac6653aSJeff Kirsher pr_info("\tTX Checksum insertion supported\n"); 8617ac6653aSJeff Kirsher netdev_update_features(dev); 8627ac6653aSJeff Kirsher 8637ac6653aSJeff Kirsher /* Request the IRQ lines */ 8647ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 8657ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 8667ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 8677ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 8687ac6653aSJeff Kirsher __func__, dev->irq, ret); 8697ac6653aSJeff Kirsher goto open_error; 8707ac6653aSJeff Kirsher } 8717ac6653aSJeff Kirsher 8727ac6653aSJeff Kirsher /* Enable the MAC Rx/Tx */ 8737ac6653aSJeff Kirsher stmmac_enable_mac(priv->ioaddr); 8747ac6653aSJeff Kirsher 8757ac6653aSJeff Kirsher /* Set the HW DMA mode and the COE */ 8767ac6653aSJeff Kirsher stmmac_dma_operation_mode(priv); 8777ac6653aSJeff Kirsher 8787ac6653aSJeff Kirsher /* Extra statistics */ 8797ac6653aSJeff Kirsher memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 8807ac6653aSJeff Kirsher priv->xstats.threshold = tc; 8817ac6653aSJeff Kirsher 8821c901a46SGiuseppe CAVALLARO stmmac_mmc_setup(priv); 8831c901a46SGiuseppe CAVALLARO 8847ac6653aSJeff Kirsher /* Start the ball rolling... */ 8857ac6653aSJeff Kirsher DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); 8867ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 8877ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 8887ac6653aSJeff Kirsher 8897ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 8907ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 8917ac6653aSJeff Kirsher #endif 8927ac6653aSJeff Kirsher /* Dump DMA/MAC registers */ 8937ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 8947ac6653aSJeff Kirsher priv->hw->mac->dump_regs(priv->ioaddr); 8957ac6653aSJeff Kirsher priv->hw->dma->dump_regs(priv->ioaddr); 8967ac6653aSJeff Kirsher } 8977ac6653aSJeff Kirsher 8987ac6653aSJeff Kirsher if (priv->phydev) 8997ac6653aSJeff Kirsher phy_start(priv->phydev); 9007ac6653aSJeff Kirsher 9017ac6653aSJeff Kirsher napi_enable(&priv->napi); 9027ac6653aSJeff Kirsher skb_queue_head_init(&priv->rx_recycle); 9037ac6653aSJeff Kirsher netif_start_queue(dev); 9047ac6653aSJeff Kirsher 9057ac6653aSJeff Kirsher return 0; 9067ac6653aSJeff Kirsher 9077ac6653aSJeff Kirsher open_error: 9087ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 9097ac6653aSJeff Kirsher kfree(priv->tm); 9107ac6653aSJeff Kirsher #endif 9117ac6653aSJeff Kirsher if (priv->phydev) 9127ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 9137ac6653aSJeff Kirsher 9147ac6653aSJeff Kirsher return ret; 9157ac6653aSJeff Kirsher } 9167ac6653aSJeff Kirsher 9177ac6653aSJeff Kirsher /** 9187ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 9197ac6653aSJeff Kirsher * @dev : device pointer. 9207ac6653aSJeff Kirsher * Description: 9217ac6653aSJeff Kirsher * This is the stop entry point of the driver. 9227ac6653aSJeff Kirsher */ 9237ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 9247ac6653aSJeff Kirsher { 9257ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 9267ac6653aSJeff Kirsher 9277ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 9287ac6653aSJeff Kirsher if (priv->phydev) { 9297ac6653aSJeff Kirsher phy_stop(priv->phydev); 9307ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 9317ac6653aSJeff Kirsher priv->phydev = NULL; 9327ac6653aSJeff Kirsher } 9337ac6653aSJeff Kirsher 9347ac6653aSJeff Kirsher netif_stop_queue(dev); 9357ac6653aSJeff Kirsher 9367ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 9377ac6653aSJeff Kirsher /* Stop and release the timer */ 9387ac6653aSJeff Kirsher stmmac_close_ext_timer(); 9397ac6653aSJeff Kirsher if (priv->tm != NULL) 9407ac6653aSJeff Kirsher kfree(priv->tm); 9417ac6653aSJeff Kirsher #endif 9427ac6653aSJeff Kirsher napi_disable(&priv->napi); 9437ac6653aSJeff Kirsher skb_queue_purge(&priv->rx_recycle); 9447ac6653aSJeff Kirsher 9457ac6653aSJeff Kirsher /* Free the IRQ lines */ 9467ac6653aSJeff Kirsher free_irq(dev->irq, dev); 9477ac6653aSJeff Kirsher 9487ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 9497ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 9507ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 9517ac6653aSJeff Kirsher 9527ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 9537ac6653aSJeff Kirsher free_dma_desc_resources(priv); 9547ac6653aSJeff Kirsher 9557ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 9567ac6653aSJeff Kirsher stmmac_disable_mac(priv->ioaddr); 9577ac6653aSJeff Kirsher 9587ac6653aSJeff Kirsher netif_carrier_off(dev); 9597ac6653aSJeff Kirsher 9607ac6653aSJeff Kirsher return 0; 9617ac6653aSJeff Kirsher } 9627ac6653aSJeff Kirsher 9637ac6653aSJeff Kirsher static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb, 9647ac6653aSJeff Kirsher struct net_device *dev, 9657ac6653aSJeff Kirsher int csum_insertion) 9667ac6653aSJeff Kirsher { 9677ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 9687ac6653aSJeff Kirsher unsigned int nopaged_len = skb_headlen(skb); 9697ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 9707ac6653aSJeff Kirsher unsigned int entry = priv->cur_tx % txsize; 9717ac6653aSJeff Kirsher struct dma_desc *desc = priv->dma_tx + entry; 9727ac6653aSJeff Kirsher 9737ac6653aSJeff Kirsher if (nopaged_len > BUF_SIZE_8KiB) { 9747ac6653aSJeff Kirsher 9757ac6653aSJeff Kirsher int buf2_size = nopaged_len - BUF_SIZE_8KiB; 9767ac6653aSJeff Kirsher 9777ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 9787ac6653aSJeff Kirsher BUF_SIZE_8KiB, DMA_TO_DEVICE); 9797ac6653aSJeff Kirsher desc->des3 = desc->des2 + BUF_SIZE_4KiB; 9807ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB, 9817ac6653aSJeff Kirsher csum_insertion); 9827ac6653aSJeff Kirsher 9837ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 9847ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 9857ac6653aSJeff Kirsher 9867ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, 9877ac6653aSJeff Kirsher skb->data + BUF_SIZE_8KiB, 9887ac6653aSJeff Kirsher buf2_size, DMA_TO_DEVICE); 9897ac6653aSJeff Kirsher desc->des3 = desc->des2 + BUF_SIZE_4KiB; 9907ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size, 9917ac6653aSJeff Kirsher csum_insertion); 9927ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 9937ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 9947ac6653aSJeff Kirsher } else { 9957ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 9967ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 9977ac6653aSJeff Kirsher desc->des3 = desc->des2 + BUF_SIZE_4KiB; 9987ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 9997ac6653aSJeff Kirsher csum_insertion); 10007ac6653aSJeff Kirsher } 10017ac6653aSJeff Kirsher return entry; 10027ac6653aSJeff Kirsher } 10037ac6653aSJeff Kirsher 10047ac6653aSJeff Kirsher /** 10057ac6653aSJeff Kirsher * stmmac_xmit: 10067ac6653aSJeff Kirsher * @skb : the socket buffer 10077ac6653aSJeff Kirsher * @dev : device pointer 10087ac6653aSJeff Kirsher * Description : Tx entry point of the driver. 10097ac6653aSJeff Kirsher */ 10107ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 10117ac6653aSJeff Kirsher { 10127ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 10137ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 10147ac6653aSJeff Kirsher unsigned int entry; 10157ac6653aSJeff Kirsher int i, csum_insertion = 0; 10167ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 10177ac6653aSJeff Kirsher struct dma_desc *desc, *first; 10187ac6653aSJeff Kirsher 10197ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 10207ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 10217ac6653aSJeff Kirsher netif_stop_queue(dev); 10227ac6653aSJeff Kirsher /* This is a hard error, log it. */ 10237ac6653aSJeff Kirsher pr_err("%s: BUG! Tx Ring full when queue awake\n", 10247ac6653aSJeff Kirsher __func__); 10257ac6653aSJeff Kirsher } 10267ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 10277ac6653aSJeff Kirsher } 10287ac6653aSJeff Kirsher 10297ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 10307ac6653aSJeff Kirsher 10317ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 10327ac6653aSJeff Kirsher if ((skb->len > ETH_FRAME_LEN) || nfrags) 10337ac6653aSJeff Kirsher pr_info("stmmac xmit:\n" 10347ac6653aSJeff Kirsher "\tskb addr %p - len: %d - nopaged_len: %d\n" 10357ac6653aSJeff Kirsher "\tn_frags: %d - ip_summed: %d - %s gso\n", 10367ac6653aSJeff Kirsher skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed, 10377ac6653aSJeff Kirsher !skb_is_gso(skb) ? "isn't" : "is"); 10387ac6653aSJeff Kirsher #endif 10397ac6653aSJeff Kirsher 10407ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 10417ac6653aSJeff Kirsher 10427ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 10437ac6653aSJeff Kirsher first = desc; 10447ac6653aSJeff Kirsher 10457ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 10467ac6653aSJeff Kirsher if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN)) 10477ac6653aSJeff Kirsher pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n" 10487ac6653aSJeff Kirsher "\t\tn_frags: %d, ip_summed: %d\n", 10497ac6653aSJeff Kirsher skb->len, skb_headlen(skb), nfrags, skb->ip_summed); 10507ac6653aSJeff Kirsher #endif 10517ac6653aSJeff Kirsher priv->tx_skbuff[entry] = skb; 10527ac6653aSJeff Kirsher if (unlikely(skb->len >= BUF_SIZE_4KiB)) { 10537ac6653aSJeff Kirsher entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion); 10547ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 10557ac6653aSJeff Kirsher } else { 10567ac6653aSJeff Kirsher unsigned int nopaged_len = skb_headlen(skb); 10577ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 10587ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 10597ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 10607ac6653aSJeff Kirsher csum_insertion); 10617ac6653aSJeff Kirsher } 10627ac6653aSJeff Kirsher 10637ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 10647ac6653aSJeff Kirsher skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 10657ac6653aSJeff Kirsher int len = frag->size; 10667ac6653aSJeff Kirsher 10677ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 10687ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 10697ac6653aSJeff Kirsher 10707ac6653aSJeff Kirsher TX_DBG("\t[entry %d] segment len: %d\n", entry, len); 10717ac6653aSJeff Kirsher desc->des2 = dma_map_page(priv->device, frag->page, 10727ac6653aSJeff Kirsher frag->page_offset, 10737ac6653aSJeff Kirsher len, DMA_TO_DEVICE); 10747ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 10757ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); 10767ac6653aSJeff Kirsher wmb(); 10777ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 10787ac6653aSJeff Kirsher } 10797ac6653aSJeff Kirsher 10807ac6653aSJeff Kirsher /* Interrupt on completition only for the latest segment */ 10817ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 10827ac6653aSJeff Kirsher 10837ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 10847ac6653aSJeff Kirsher /* Clean IC while using timer */ 10857ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 10867ac6653aSJeff Kirsher priv->hw->desc->clear_tx_ic(desc); 10877ac6653aSJeff Kirsher #endif 10887ac6653aSJeff Kirsher 10897ac6653aSJeff Kirsher wmb(); 10907ac6653aSJeff Kirsher 10917ac6653aSJeff Kirsher /* To avoid raise condition */ 10927ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 10937ac6653aSJeff Kirsher 10947ac6653aSJeff Kirsher priv->cur_tx++; 10957ac6653aSJeff Kirsher 10967ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 10977ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 10987ac6653aSJeff Kirsher pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, " 10997ac6653aSJeff Kirsher "first=%p, nfrags=%d\n", 11007ac6653aSJeff Kirsher (priv->cur_tx % txsize), (priv->dirty_tx % txsize), 11017ac6653aSJeff Kirsher entry, first, nfrags); 11027ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 11037ac6653aSJeff Kirsher pr_info(">>> frame to be transmitted: "); 11047ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 11057ac6653aSJeff Kirsher } 11067ac6653aSJeff Kirsher #endif 11077ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 11087ac6653aSJeff Kirsher TX_DBG("%s: stop transmitted packets\n", __func__); 11097ac6653aSJeff Kirsher netif_stop_queue(dev); 11107ac6653aSJeff Kirsher } 11117ac6653aSJeff Kirsher 11127ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 11137ac6653aSJeff Kirsher 11147ac6653aSJeff Kirsher skb_tx_timestamp(skb); 11157ac6653aSJeff Kirsher 11167ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 11177ac6653aSJeff Kirsher 11187ac6653aSJeff Kirsher return NETDEV_TX_OK; 11197ac6653aSJeff Kirsher } 11207ac6653aSJeff Kirsher 11217ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 11227ac6653aSJeff Kirsher { 11237ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 11247ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 11257ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx; 11267ac6653aSJeff Kirsher 11277ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 11287ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 11297ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 11307ac6653aSJeff Kirsher struct sk_buff *skb; 11317ac6653aSJeff Kirsher 11327ac6653aSJeff Kirsher skb = __skb_dequeue(&priv->rx_recycle); 11337ac6653aSJeff Kirsher if (skb == NULL) 11347ac6653aSJeff Kirsher skb = netdev_alloc_skb_ip_align(priv->dev, 11357ac6653aSJeff Kirsher bfsize); 11367ac6653aSJeff Kirsher 11377ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 11387ac6653aSJeff Kirsher break; 11397ac6653aSJeff Kirsher 11407ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 11417ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 11427ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 11437ac6653aSJeff Kirsher DMA_FROM_DEVICE); 11447ac6653aSJeff Kirsher 11457ac6653aSJeff Kirsher (p + entry)->des2 = priv->rx_skbuff_dma[entry]; 11467ac6653aSJeff Kirsher if (unlikely(priv->plat->has_gmac)) { 11477ac6653aSJeff Kirsher if (bfsize >= BUF_SIZE_8KiB) 11487ac6653aSJeff Kirsher (p + entry)->des3 = 11497ac6653aSJeff Kirsher (p + entry)->des2 + BUF_SIZE_8KiB; 11507ac6653aSJeff Kirsher } 11517ac6653aSJeff Kirsher RX_DBG(KERN_INFO "\trefill entry #%d\n", entry); 11527ac6653aSJeff Kirsher } 11537ac6653aSJeff Kirsher wmb(); 11547ac6653aSJeff Kirsher priv->hw->desc->set_rx_owner(p + entry); 11557ac6653aSJeff Kirsher } 11567ac6653aSJeff Kirsher } 11577ac6653aSJeff Kirsher 11587ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 11597ac6653aSJeff Kirsher { 11607ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 11617ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 11627ac6653aSJeff Kirsher unsigned int next_entry; 11637ac6653aSJeff Kirsher unsigned int count = 0; 11647ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + entry; 11657ac6653aSJeff Kirsher struct dma_desc *p_next; 11667ac6653aSJeff Kirsher 11677ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 11687ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 11697ac6653aSJeff Kirsher pr_debug(">>> stmmac_rx: descriptor ring:\n"); 11707ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 11717ac6653aSJeff Kirsher } 11727ac6653aSJeff Kirsher #endif 11737ac6653aSJeff Kirsher count = 0; 11747ac6653aSJeff Kirsher while (!priv->hw->desc->get_rx_owner(p)) { 11757ac6653aSJeff Kirsher int status; 11767ac6653aSJeff Kirsher 11777ac6653aSJeff Kirsher if (count >= limit) 11787ac6653aSJeff Kirsher break; 11797ac6653aSJeff Kirsher 11807ac6653aSJeff Kirsher count++; 11817ac6653aSJeff Kirsher 11827ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 11837ac6653aSJeff Kirsher p_next = priv->dma_rx + next_entry; 11847ac6653aSJeff Kirsher prefetch(p_next); 11857ac6653aSJeff Kirsher 11867ac6653aSJeff Kirsher /* read the status of the incoming frame */ 11877ac6653aSJeff Kirsher status = (priv->hw->desc->rx_status(&priv->dev->stats, 11887ac6653aSJeff Kirsher &priv->xstats, p)); 11897ac6653aSJeff Kirsher if (unlikely(status == discard_frame)) 11907ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 11917ac6653aSJeff Kirsher else { 11927ac6653aSJeff Kirsher struct sk_buff *skb; 11937ac6653aSJeff Kirsher int frame_len; 11947ac6653aSJeff Kirsher 11957ac6653aSJeff Kirsher frame_len = priv->hw->desc->get_rx_frame_len(p); 11967ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 11977ac6653aSJeff Kirsher * Type frames (LLC/LLC-SNAP) */ 11987ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 11997ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 12007ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 12017ac6653aSJeff Kirsher if (frame_len > ETH_FRAME_LEN) 12027ac6653aSJeff Kirsher pr_debug("\tRX frame size %d, COE status: %d\n", 12037ac6653aSJeff Kirsher frame_len, status); 12047ac6653aSJeff Kirsher 12057ac6653aSJeff Kirsher if (netif_msg_hw(priv)) 12067ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 12077ac6653aSJeff Kirsher p, entry, p->des2); 12087ac6653aSJeff Kirsher #endif 12097ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 12107ac6653aSJeff Kirsher if (unlikely(!skb)) { 12117ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 12127ac6653aSJeff Kirsher priv->dev->name); 12137ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 12147ac6653aSJeff Kirsher break; 12157ac6653aSJeff Kirsher } 12167ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 12177ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 12187ac6653aSJeff Kirsher 12197ac6653aSJeff Kirsher skb_put(skb, frame_len); 12207ac6653aSJeff Kirsher dma_unmap_single(priv->device, 12217ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 12227ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 12237ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 12247ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 12257ac6653aSJeff Kirsher pr_info(" frame received (%dbytes)", frame_len); 12267ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 12277ac6653aSJeff Kirsher } 12287ac6653aSJeff Kirsher #endif 12297ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 12307ac6653aSJeff Kirsher 12317ac6653aSJeff Kirsher if (unlikely(status == csum_none)) { 12327ac6653aSJeff Kirsher /* always for the old mac 10/100 */ 12337ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 12347ac6653aSJeff Kirsher netif_receive_skb(skb); 12357ac6653aSJeff Kirsher } else { 12367ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 12377ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 12387ac6653aSJeff Kirsher } 12397ac6653aSJeff Kirsher 12407ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 12417ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 12427ac6653aSJeff Kirsher } 12437ac6653aSJeff Kirsher entry = next_entry; 12447ac6653aSJeff Kirsher p = p_next; /* use prefetched values */ 12457ac6653aSJeff Kirsher } 12467ac6653aSJeff Kirsher 12477ac6653aSJeff Kirsher stmmac_rx_refill(priv); 12487ac6653aSJeff Kirsher 12497ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 12507ac6653aSJeff Kirsher 12517ac6653aSJeff Kirsher return count; 12527ac6653aSJeff Kirsher } 12537ac6653aSJeff Kirsher 12547ac6653aSJeff Kirsher /** 12557ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 12567ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 12577ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 12587ac6653aSJeff Kirsher * all interfaces. 12597ac6653aSJeff Kirsher * Description : 12607ac6653aSJeff Kirsher * This function implements the the reception process. 12617ac6653aSJeff Kirsher * Also it runs the TX completion thread 12627ac6653aSJeff Kirsher */ 12637ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 12647ac6653aSJeff Kirsher { 12657ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 12667ac6653aSJeff Kirsher int work_done = 0; 12677ac6653aSJeff Kirsher 12687ac6653aSJeff Kirsher priv->xstats.poll_n++; 12697ac6653aSJeff Kirsher stmmac_tx(priv); 12707ac6653aSJeff Kirsher work_done = stmmac_rx(priv, budget); 12717ac6653aSJeff Kirsher 12727ac6653aSJeff Kirsher if (work_done < budget) { 12737ac6653aSJeff Kirsher napi_complete(napi); 12747ac6653aSJeff Kirsher stmmac_enable_irq(priv); 12757ac6653aSJeff Kirsher } 12767ac6653aSJeff Kirsher return work_done; 12777ac6653aSJeff Kirsher } 12787ac6653aSJeff Kirsher 12797ac6653aSJeff Kirsher /** 12807ac6653aSJeff Kirsher * stmmac_tx_timeout 12817ac6653aSJeff Kirsher * @dev : Pointer to net device structure 12827ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 12837ac6653aSJeff Kirsher * complete within a reasonable tmrate. The driver will mark the error in the 12847ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 12857ac6653aSJeff Kirsher * in order to transmit a new packet. 12867ac6653aSJeff Kirsher */ 12877ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 12887ac6653aSJeff Kirsher { 12897ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 12907ac6653aSJeff Kirsher 12917ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 12927ac6653aSJeff Kirsher stmmac_tx_err(priv); 12937ac6653aSJeff Kirsher } 12947ac6653aSJeff Kirsher 12957ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */ 12967ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map) 12977ac6653aSJeff Kirsher { 12987ac6653aSJeff Kirsher if (dev->flags & IFF_UP) /* can't act on a running interface */ 12997ac6653aSJeff Kirsher return -EBUSY; 13007ac6653aSJeff Kirsher 13017ac6653aSJeff Kirsher /* Don't allow changing the I/O address */ 13027ac6653aSJeff Kirsher if (map->base_addr != dev->base_addr) { 13037ac6653aSJeff Kirsher pr_warning("%s: can't change I/O address\n", dev->name); 13047ac6653aSJeff Kirsher return -EOPNOTSUPP; 13057ac6653aSJeff Kirsher } 13067ac6653aSJeff Kirsher 13077ac6653aSJeff Kirsher /* Don't allow changing the IRQ */ 13087ac6653aSJeff Kirsher if (map->irq != dev->irq) { 13097ac6653aSJeff Kirsher pr_warning("%s: can't change IRQ number %d\n", 13107ac6653aSJeff Kirsher dev->name, dev->irq); 13117ac6653aSJeff Kirsher return -EOPNOTSUPP; 13127ac6653aSJeff Kirsher } 13137ac6653aSJeff Kirsher 13147ac6653aSJeff Kirsher /* ignore other fields */ 13157ac6653aSJeff Kirsher return 0; 13167ac6653aSJeff Kirsher } 13177ac6653aSJeff Kirsher 13187ac6653aSJeff Kirsher /** 131901789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 13207ac6653aSJeff Kirsher * @dev : pointer to the device structure 13217ac6653aSJeff Kirsher * Description: 13227ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 13237ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 13247ac6653aSJeff Kirsher * Return value: 13257ac6653aSJeff Kirsher * void. 13267ac6653aSJeff Kirsher */ 132701789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 13287ac6653aSJeff Kirsher { 13297ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 13307ac6653aSJeff Kirsher 13317ac6653aSJeff Kirsher spin_lock(&priv->lock); 13327ac6653aSJeff Kirsher priv->hw->mac->set_filter(dev); 13337ac6653aSJeff Kirsher spin_unlock(&priv->lock); 13347ac6653aSJeff Kirsher } 13357ac6653aSJeff Kirsher 13367ac6653aSJeff Kirsher /** 13377ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 13387ac6653aSJeff Kirsher * @dev : device pointer. 13397ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 13407ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 13417ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 13427ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 13437ac6653aSJeff Kirsher * Return value: 13447ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 13457ac6653aSJeff Kirsher * file on failure. 13467ac6653aSJeff Kirsher */ 13477ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 13487ac6653aSJeff Kirsher { 13497ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 13507ac6653aSJeff Kirsher int max_mtu; 13517ac6653aSJeff Kirsher 13527ac6653aSJeff Kirsher if (netif_running(dev)) { 13537ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 13547ac6653aSJeff Kirsher return -EBUSY; 13557ac6653aSJeff Kirsher } 13567ac6653aSJeff Kirsher 13577ac6653aSJeff Kirsher if (priv->plat->has_gmac) 13587ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 13597ac6653aSJeff Kirsher else 13607ac6653aSJeff Kirsher max_mtu = ETH_DATA_LEN; 13617ac6653aSJeff Kirsher 13627ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 13637ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 13647ac6653aSJeff Kirsher return -EINVAL; 13657ac6653aSJeff Kirsher } 13667ac6653aSJeff Kirsher 13677ac6653aSJeff Kirsher dev->mtu = new_mtu; 13687ac6653aSJeff Kirsher netdev_update_features(dev); 13697ac6653aSJeff Kirsher 13707ac6653aSJeff Kirsher return 0; 13717ac6653aSJeff Kirsher } 13727ac6653aSJeff Kirsher 13737ac6653aSJeff Kirsher static u32 stmmac_fix_features(struct net_device *dev, u32 features) 13747ac6653aSJeff Kirsher { 13757ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 13767ac6653aSJeff Kirsher 13777ac6653aSJeff Kirsher if (!priv->rx_coe) 13787ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 13797ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 13807ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 13817ac6653aSJeff Kirsher 13827ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 13837ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 13847ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 13857ac6653aSJeff Kirsher * the TX csum insertionin the TDES and not use SF. */ 13867ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 13877ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 13887ac6653aSJeff Kirsher 13897ac6653aSJeff Kirsher return features; 13907ac6653aSJeff Kirsher } 13917ac6653aSJeff Kirsher 13927ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 13937ac6653aSJeff Kirsher { 13947ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 13957ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 13967ac6653aSJeff Kirsher 13977ac6653aSJeff Kirsher if (unlikely(!dev)) { 13987ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 13997ac6653aSJeff Kirsher return IRQ_NONE; 14007ac6653aSJeff Kirsher } 14017ac6653aSJeff Kirsher 14027ac6653aSJeff Kirsher if (priv->plat->has_gmac) 14037ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 14047ac6653aSJeff Kirsher priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); 14057ac6653aSJeff Kirsher 14067ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 14077ac6653aSJeff Kirsher 14087ac6653aSJeff Kirsher return IRQ_HANDLED; 14097ac6653aSJeff Kirsher } 14107ac6653aSJeff Kirsher 14117ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 14127ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 14137ac6653aSJeff Kirsher * to allow network I/O with interrupts disabled. */ 14147ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 14157ac6653aSJeff Kirsher { 14167ac6653aSJeff Kirsher disable_irq(dev->irq); 14177ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 14187ac6653aSJeff Kirsher enable_irq(dev->irq); 14197ac6653aSJeff Kirsher } 14207ac6653aSJeff Kirsher #endif 14217ac6653aSJeff Kirsher 14227ac6653aSJeff Kirsher /** 14237ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 14247ac6653aSJeff Kirsher * @dev: Device pointer. 14257ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 14267ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 14277ac6653aSJeff Kirsher * @cmd: IOCTL command 14287ac6653aSJeff Kirsher * Description: 14297ac6653aSJeff Kirsher * Currently there are no special functionality supported in IOCTL, just the 14307ac6653aSJeff Kirsher * phy_mii_ioctl(...) can be invoked. 14317ac6653aSJeff Kirsher */ 14327ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 14337ac6653aSJeff Kirsher { 14347ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 14357ac6653aSJeff Kirsher int ret; 14367ac6653aSJeff Kirsher 14377ac6653aSJeff Kirsher if (!netif_running(dev)) 14387ac6653aSJeff Kirsher return -EINVAL; 14397ac6653aSJeff Kirsher 14407ac6653aSJeff Kirsher if (!priv->phydev) 14417ac6653aSJeff Kirsher return -EINVAL; 14427ac6653aSJeff Kirsher 14437ac6653aSJeff Kirsher spin_lock(&priv->lock); 14447ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 14457ac6653aSJeff Kirsher spin_unlock(&priv->lock); 14467ac6653aSJeff Kirsher 14477ac6653aSJeff Kirsher return ret; 14487ac6653aSJeff Kirsher } 14497ac6653aSJeff Kirsher 14507ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 14517ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 14527ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 14537ac29055SGiuseppe CAVALLARO 14547ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 14557ac29055SGiuseppe CAVALLARO { 14567ac29055SGiuseppe CAVALLARO struct tmp_s { 14577ac29055SGiuseppe CAVALLARO u64 a; 14587ac29055SGiuseppe CAVALLARO unsigned int b; 14597ac29055SGiuseppe CAVALLARO unsigned int c; 14607ac29055SGiuseppe CAVALLARO }; 14617ac29055SGiuseppe CAVALLARO int i; 14627ac29055SGiuseppe CAVALLARO struct net_device *dev = seq->private; 14637ac29055SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 14647ac29055SGiuseppe CAVALLARO 14657ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 14667ac29055SGiuseppe CAVALLARO seq_printf(seq, " RX descriptor ring\n"); 14677ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 14687ac29055SGiuseppe CAVALLARO 14697ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_rx_size; i++) { 14707ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i); 14717ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 14727ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 14737ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 14747ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 14757ac29055SGiuseppe CAVALLARO } 14767ac29055SGiuseppe CAVALLARO 14777ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 14787ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 14797ac29055SGiuseppe CAVALLARO seq_printf(seq, " TX descriptor ring\n"); 14807ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 14817ac29055SGiuseppe CAVALLARO 14827ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_tx_size; i++) { 14837ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i); 14847ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 14857ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 14867ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 14877ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 14887ac29055SGiuseppe CAVALLARO } 14897ac29055SGiuseppe CAVALLARO 14907ac29055SGiuseppe CAVALLARO return 0; 14917ac29055SGiuseppe CAVALLARO } 14927ac29055SGiuseppe CAVALLARO 14937ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 14947ac29055SGiuseppe CAVALLARO { 14957ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 14967ac29055SGiuseppe CAVALLARO } 14977ac29055SGiuseppe CAVALLARO 14987ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 14997ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 15007ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 15017ac29055SGiuseppe CAVALLARO .read = seq_read, 15027ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 15037ac29055SGiuseppe CAVALLARO .release = seq_release, 15047ac29055SGiuseppe CAVALLARO }; 15057ac29055SGiuseppe CAVALLARO 15067ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 15077ac29055SGiuseppe CAVALLARO { 15087ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 15097ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 15107ac29055SGiuseppe CAVALLARO 15117ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 15127ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 15137ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 15147ac29055SGiuseppe CAVALLARO 15157ac29055SGiuseppe CAVALLARO return -ENOMEM; 15167ac29055SGiuseppe CAVALLARO } 15177ac29055SGiuseppe CAVALLARO 15187ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 15197ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 15207ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 15217ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 15227ac29055SGiuseppe CAVALLARO 15237ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 15247ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 15257ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 15267ac29055SGiuseppe CAVALLARO 15277ac29055SGiuseppe CAVALLARO return -ENOMEM; 15287ac29055SGiuseppe CAVALLARO } 15297ac29055SGiuseppe CAVALLARO 15307ac29055SGiuseppe CAVALLARO return 0; 15317ac29055SGiuseppe CAVALLARO } 15327ac29055SGiuseppe CAVALLARO 15337ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 15347ac29055SGiuseppe CAVALLARO { 15357ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 15367ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 15377ac29055SGiuseppe CAVALLARO } 15387ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 15397ac29055SGiuseppe CAVALLARO 15407ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 15417ac6653aSJeff Kirsher .ndo_open = stmmac_open, 15427ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 15437ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 15447ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 15457ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 154601789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 15477ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 15487ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 15497ac6653aSJeff Kirsher .ndo_set_config = stmmac_config, 15507ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 15517ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 15527ac6653aSJeff Kirsher #endif 15537ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 15547ac6653aSJeff Kirsher }; 15557ac6653aSJeff Kirsher 15567ac6653aSJeff Kirsher /** 15577ac6653aSJeff Kirsher * stmmac_probe - Initialization of the adapter . 15587ac6653aSJeff Kirsher * @dev : device pointer 15597ac6653aSJeff Kirsher * Description: The function initializes the network device structure for 15607ac6653aSJeff Kirsher * the STMMAC driver. It also calls the low level routines 15617ac6653aSJeff Kirsher * in order to init the HW (i.e. the DMA engine) 15627ac6653aSJeff Kirsher */ 15637ac6653aSJeff Kirsher static int stmmac_probe(struct net_device *dev) 15647ac6653aSJeff Kirsher { 15657ac6653aSJeff Kirsher int ret = 0; 15667ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15677ac6653aSJeff Kirsher 15687ac6653aSJeff Kirsher ether_setup(dev); 15697ac6653aSJeff Kirsher 15707ac6653aSJeff Kirsher dev->netdev_ops = &stmmac_netdev_ops; 15717ac6653aSJeff Kirsher stmmac_set_ethtool_ops(dev); 15727ac6653aSJeff Kirsher 15737ac6653aSJeff Kirsher dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 15747ac6653aSJeff Kirsher dev->features |= dev->hw_features | NETIF_F_HIGHDMA; 15757ac6653aSJeff Kirsher dev->watchdog_timeo = msecs_to_jiffies(watchdog); 15767ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 15777ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 15787ac6653aSJeff Kirsher dev->features |= NETIF_F_HW_VLAN_RX; 15797ac6653aSJeff Kirsher #endif 15807ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 15817ac6653aSJeff Kirsher 15827ac6653aSJeff Kirsher if (flow_ctrl) 15837ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 15847ac6653aSJeff Kirsher 15857ac6653aSJeff Kirsher priv->pause = pause; 15867ac6653aSJeff Kirsher netif_napi_add(dev, &priv->napi, stmmac_poll, 64); 15877ac6653aSJeff Kirsher 15887ac6653aSJeff Kirsher /* Get the MAC address */ 15897ac6653aSJeff Kirsher priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr, 15907ac6653aSJeff Kirsher dev->dev_addr, 0); 15917ac6653aSJeff Kirsher 15927ac6653aSJeff Kirsher if (!is_valid_ether_addr(dev->dev_addr)) 15937ac6653aSJeff Kirsher pr_warning("\tno valid MAC address;" 15947ac6653aSJeff Kirsher "please, use ifconfig or nwhwconfig!\n"); 15957ac6653aSJeff Kirsher 15967ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 15977ac6653aSJeff Kirsher 15987ac6653aSJeff Kirsher ret = register_netdev(dev); 15997ac6653aSJeff Kirsher if (ret) { 16007ac6653aSJeff Kirsher pr_err("%s: ERROR %i registering the device\n", 16017ac6653aSJeff Kirsher __func__, ret); 16027ac6653aSJeff Kirsher return -ENODEV; 16037ac6653aSJeff Kirsher } 16047ac6653aSJeff Kirsher 16057ac6653aSJeff Kirsher DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n", 16067ac6653aSJeff Kirsher dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", 16077ac6653aSJeff Kirsher (dev->features & NETIF_F_IP_CSUM) ? "on" : "off"); 16087ac6653aSJeff Kirsher 16097ac6653aSJeff Kirsher return ret; 16107ac6653aSJeff Kirsher } 16117ac6653aSJeff Kirsher 16127ac6653aSJeff Kirsher /** 16137ac6653aSJeff Kirsher * stmmac_mac_device_setup 16147ac6653aSJeff Kirsher * @dev : device pointer 16157ac6653aSJeff Kirsher * Description: select and initialise the mac device (mac100 or Gmac). 16167ac6653aSJeff Kirsher */ 16177ac6653aSJeff Kirsher static int stmmac_mac_device_setup(struct net_device *dev) 16187ac6653aSJeff Kirsher { 16197ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16207ac6653aSJeff Kirsher 16217ac6653aSJeff Kirsher struct mac_device_info *device; 16227ac6653aSJeff Kirsher 162301789349SJiri Pirko if (priv->plat->has_gmac) { 162401789349SJiri Pirko dev->priv_flags |= IFF_UNICAST_FLT; 16257ac6653aSJeff Kirsher device = dwmac1000_setup(priv->ioaddr); 162601789349SJiri Pirko } else { 16277ac6653aSJeff Kirsher device = dwmac100_setup(priv->ioaddr); 162801789349SJiri Pirko } 16297ac6653aSJeff Kirsher 16307ac6653aSJeff Kirsher if (!device) 16317ac6653aSJeff Kirsher return -ENOMEM; 16327ac6653aSJeff Kirsher 16337ac6653aSJeff Kirsher if (priv->plat->enh_desc) { 16347ac6653aSJeff Kirsher device->desc = &enh_desc_ops; 16357ac6653aSJeff Kirsher pr_info("\tEnhanced descriptor structure\n"); 16367ac6653aSJeff Kirsher } else 16377ac6653aSJeff Kirsher device->desc = &ndesc_ops; 16387ac6653aSJeff Kirsher 16397ac6653aSJeff Kirsher priv->hw = device; 16407ac6653aSJeff Kirsher 16417ac6653aSJeff Kirsher if (device_can_wakeup(priv->device)) { 16427ac6653aSJeff Kirsher priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ 16433172d3afSDeepak Sikri enable_irq_wake(priv->wol_irq); 16447ac6653aSJeff Kirsher } 16457ac6653aSJeff Kirsher 16467ac6653aSJeff Kirsher return 0; 16477ac6653aSJeff Kirsher } 16487ac6653aSJeff Kirsher 16497ac6653aSJeff Kirsher /** 16507ac6653aSJeff Kirsher * stmmac_dvr_probe 16517ac6653aSJeff Kirsher * @pdev: platform device pointer 16527ac6653aSJeff Kirsher * Description: the driver is initialized through platform_device. 16537ac6653aSJeff Kirsher */ 16547ac6653aSJeff Kirsher static int stmmac_dvr_probe(struct platform_device *pdev) 16557ac6653aSJeff Kirsher { 16567ac6653aSJeff Kirsher int ret = 0; 16577ac6653aSJeff Kirsher struct resource *res; 16587ac6653aSJeff Kirsher void __iomem *addr = NULL; 16597ac6653aSJeff Kirsher struct net_device *ndev = NULL; 16607ac6653aSJeff Kirsher struct stmmac_priv *priv = NULL; 16617ac6653aSJeff Kirsher struct plat_stmmacenet_data *plat_dat; 16627ac6653aSJeff Kirsher 16637ac6653aSJeff Kirsher pr_info("STMMAC driver:\n\tplatform registration... "); 16647ac6653aSJeff Kirsher res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 16657ac6653aSJeff Kirsher if (!res) 16667ac6653aSJeff Kirsher return -ENODEV; 16677ac6653aSJeff Kirsher pr_info("\tdone!\n"); 16687ac6653aSJeff Kirsher 16697ac6653aSJeff Kirsher if (!request_mem_region(res->start, resource_size(res), 16707ac6653aSJeff Kirsher pdev->name)) { 16717ac6653aSJeff Kirsher pr_err("%s: ERROR: memory allocation failed" 16727ac6653aSJeff Kirsher "cannot get the I/O addr 0x%x\n", 16737ac6653aSJeff Kirsher __func__, (unsigned int)res->start); 16747ac6653aSJeff Kirsher return -EBUSY; 16757ac6653aSJeff Kirsher } 16767ac6653aSJeff Kirsher 16777ac6653aSJeff Kirsher addr = ioremap(res->start, resource_size(res)); 16787ac6653aSJeff Kirsher if (!addr) { 16797ac6653aSJeff Kirsher pr_err("%s: ERROR: memory mapping failed\n", __func__); 16807ac6653aSJeff Kirsher ret = -ENOMEM; 16817ac6653aSJeff Kirsher goto out_release_region; 16827ac6653aSJeff Kirsher } 16837ac6653aSJeff Kirsher 16847ac6653aSJeff Kirsher ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 16857ac6653aSJeff Kirsher if (!ndev) { 16867ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the device\n", __func__); 16877ac6653aSJeff Kirsher ret = -ENOMEM; 16887ac6653aSJeff Kirsher goto out_unmap; 16897ac6653aSJeff Kirsher } 16907ac6653aSJeff Kirsher 16917ac6653aSJeff Kirsher SET_NETDEV_DEV(ndev, &pdev->dev); 16927ac6653aSJeff Kirsher 16937ac6653aSJeff Kirsher /* Get the MAC information */ 16947ac6653aSJeff Kirsher ndev->irq = platform_get_irq_byname(pdev, "macirq"); 16957ac6653aSJeff Kirsher if (ndev->irq == -ENXIO) { 16967ac6653aSJeff Kirsher pr_err("%s: ERROR: MAC IRQ configuration " 16977ac6653aSJeff Kirsher "information not found\n", __func__); 16987ac6653aSJeff Kirsher ret = -ENXIO; 16997ac6653aSJeff Kirsher goto out_free_ndev; 17007ac6653aSJeff Kirsher } 17017ac6653aSJeff Kirsher 17027ac6653aSJeff Kirsher priv = netdev_priv(ndev); 17037ac6653aSJeff Kirsher priv->device = &(pdev->dev); 17047ac6653aSJeff Kirsher priv->dev = ndev; 17057ac6653aSJeff Kirsher plat_dat = pdev->dev.platform_data; 17067ac6653aSJeff Kirsher 17077ac6653aSJeff Kirsher priv->plat = plat_dat; 17087ac6653aSJeff Kirsher 17097ac6653aSJeff Kirsher priv->ioaddr = addr; 17107ac6653aSJeff Kirsher 17117ac6653aSJeff Kirsher /* PMT module is not integrated in all the MAC devices. */ 17127ac6653aSJeff Kirsher if (plat_dat->pmt) { 17137ac6653aSJeff Kirsher pr_info("\tPMT module supported\n"); 17147ac6653aSJeff Kirsher device_set_wakeup_capable(&pdev->dev, 1); 17157ac6653aSJeff Kirsher } 17163172d3afSDeepak Sikri /* 17173172d3afSDeepak Sikri * On some platforms e.g. SPEAr the wake up irq differs from the mac irq 17183172d3afSDeepak Sikri * The external wake up irq can be passed through the platform code 17193172d3afSDeepak Sikri * named as "eth_wake_irq" 17203172d3afSDeepak Sikri * 17213172d3afSDeepak Sikri * In case the wake up interrupt is not passed from the platform 17223172d3afSDeepak Sikri * so the driver will continue to use the mac irq (ndev->irq) 17233172d3afSDeepak Sikri */ 17243172d3afSDeepak Sikri priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); 17253172d3afSDeepak Sikri if (priv->wol_irq == -ENXIO) 17263172d3afSDeepak Sikri priv->wol_irq = ndev->irq; 17273172d3afSDeepak Sikri 17287ac6653aSJeff Kirsher 17297ac6653aSJeff Kirsher platform_set_drvdata(pdev, ndev); 17307ac6653aSJeff Kirsher 17317ac6653aSJeff Kirsher /* Set the I/O base addr */ 17327ac6653aSJeff Kirsher ndev->base_addr = (unsigned long)addr; 17337ac6653aSJeff Kirsher 17347ac6653aSJeff Kirsher /* Custom initialisation */ 17357ac6653aSJeff Kirsher if (priv->plat->init) { 17367ac6653aSJeff Kirsher ret = priv->plat->init(pdev); 17377ac6653aSJeff Kirsher if (unlikely(ret)) 17387ac6653aSJeff Kirsher goto out_free_ndev; 17397ac6653aSJeff Kirsher } 17407ac6653aSJeff Kirsher 17417ac6653aSJeff Kirsher /* MAC HW revice detection */ 17427ac6653aSJeff Kirsher ret = stmmac_mac_device_setup(ndev); 17437ac6653aSJeff Kirsher if (ret < 0) 17447ac6653aSJeff Kirsher goto out_plat_exit; 17457ac6653aSJeff Kirsher 17467ac6653aSJeff Kirsher /* Network Device Registration */ 17477ac6653aSJeff Kirsher ret = stmmac_probe(ndev); 17487ac6653aSJeff Kirsher if (ret < 0) 17497ac6653aSJeff Kirsher goto out_plat_exit; 17507ac6653aSJeff Kirsher 17517ac6653aSJeff Kirsher /* Override with kernel parameters if supplied XXX CRS XXX 17527ac6653aSJeff Kirsher * this needs to have multiple instances */ 17537ac6653aSJeff Kirsher if ((phyaddr >= 0) && (phyaddr <= 31)) 17547ac6653aSJeff Kirsher priv->plat->phy_addr = phyaddr; 17557ac6653aSJeff Kirsher 17567ac6653aSJeff Kirsher pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" 17577ac6653aSJeff Kirsher "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, 17587ac6653aSJeff Kirsher pdev->id, ndev->irq, addr); 17597ac6653aSJeff Kirsher 17607ac6653aSJeff Kirsher /* MDIO bus Registration */ 17617ac6653aSJeff Kirsher pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id); 17627ac6653aSJeff Kirsher ret = stmmac_mdio_register(ndev); 17637ac6653aSJeff Kirsher if (ret < 0) 17647ac6653aSJeff Kirsher goto out_unregister; 17657ac6653aSJeff Kirsher pr_debug("registered!\n"); 17667ac29055SGiuseppe CAVALLARO 17677ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 17687ac29055SGiuseppe CAVALLARO ret = stmmac_init_fs(ndev); 17697ac29055SGiuseppe CAVALLARO if (ret < 0) 17707ac29055SGiuseppe CAVALLARO pr_warning("\tFailed debugFS registration"); 17717ac29055SGiuseppe CAVALLARO #endif 17727ac29055SGiuseppe CAVALLARO 17737ac6653aSJeff Kirsher return 0; 17747ac6653aSJeff Kirsher 17757ac6653aSJeff Kirsher out_unregister: 17767ac6653aSJeff Kirsher unregister_netdev(ndev); 17777ac6653aSJeff Kirsher out_plat_exit: 17787ac6653aSJeff Kirsher if (priv->plat->exit) 17797ac6653aSJeff Kirsher priv->plat->exit(pdev); 17807ac6653aSJeff Kirsher out_free_ndev: 17817ac6653aSJeff Kirsher free_netdev(ndev); 17827ac6653aSJeff Kirsher platform_set_drvdata(pdev, NULL); 17837ac6653aSJeff Kirsher out_unmap: 17847ac6653aSJeff Kirsher iounmap(addr); 17857ac6653aSJeff Kirsher out_release_region: 17867ac6653aSJeff Kirsher release_mem_region(res->start, resource_size(res)); 17877ac6653aSJeff Kirsher 17887ac6653aSJeff Kirsher return ret; 17897ac6653aSJeff Kirsher } 17907ac6653aSJeff Kirsher 17917ac6653aSJeff Kirsher /** 17927ac6653aSJeff Kirsher * stmmac_dvr_remove 17937ac6653aSJeff Kirsher * @pdev: platform device pointer 17947ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 17957ac6653aSJeff Kirsher * changes the link status, releases the DMA descriptor rings, 17967ac6653aSJeff Kirsher * unregisters the MDIO bus and unmaps the allocated memory. 17977ac6653aSJeff Kirsher */ 17987ac6653aSJeff Kirsher static int stmmac_dvr_remove(struct platform_device *pdev) 17997ac6653aSJeff Kirsher { 18007ac6653aSJeff Kirsher struct net_device *ndev = platform_get_drvdata(pdev); 18017ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 18027ac6653aSJeff Kirsher struct resource *res; 18037ac6653aSJeff Kirsher 18047ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 18057ac6653aSJeff Kirsher 18067ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18077ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18087ac6653aSJeff Kirsher 18097ac6653aSJeff Kirsher stmmac_disable_mac(priv->ioaddr); 18107ac6653aSJeff Kirsher 18117ac6653aSJeff Kirsher netif_carrier_off(ndev); 18127ac6653aSJeff Kirsher 18137ac6653aSJeff Kirsher stmmac_mdio_unregister(ndev); 18147ac6653aSJeff Kirsher 18157ac6653aSJeff Kirsher if (priv->plat->exit) 18167ac6653aSJeff Kirsher priv->plat->exit(pdev); 18177ac6653aSJeff Kirsher 18187ac6653aSJeff Kirsher platform_set_drvdata(pdev, NULL); 18197ac6653aSJeff Kirsher unregister_netdev(ndev); 18207ac6653aSJeff Kirsher 18217ac6653aSJeff Kirsher iounmap((void *)priv->ioaddr); 18227ac6653aSJeff Kirsher res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 18237ac6653aSJeff Kirsher release_mem_region(res->start, resource_size(res)); 18247ac6653aSJeff Kirsher 18257ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 18267ac29055SGiuseppe CAVALLARO stmmac_exit_fs(); 18277ac29055SGiuseppe CAVALLARO #endif 18287ac29055SGiuseppe CAVALLARO 18297ac6653aSJeff Kirsher free_netdev(ndev); 18307ac6653aSJeff Kirsher 18317ac6653aSJeff Kirsher return 0; 18327ac6653aSJeff Kirsher } 18337ac6653aSJeff Kirsher 18347ac6653aSJeff Kirsher #ifdef CONFIG_PM 18357ac6653aSJeff Kirsher static int stmmac_suspend(struct device *dev) 18367ac6653aSJeff Kirsher { 18377ac6653aSJeff Kirsher struct net_device *ndev = dev_get_drvdata(dev); 18387ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 18397ac6653aSJeff Kirsher int dis_ic = 0; 18407ac6653aSJeff Kirsher 18417ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 18427ac6653aSJeff Kirsher return 0; 18437ac6653aSJeff Kirsher 18447ac6653aSJeff Kirsher spin_lock(&priv->lock); 18457ac6653aSJeff Kirsher 18467ac6653aSJeff Kirsher netif_device_detach(ndev); 18477ac6653aSJeff Kirsher netif_stop_queue(ndev); 18487ac6653aSJeff Kirsher if (priv->phydev) 18497ac6653aSJeff Kirsher phy_stop(priv->phydev); 18507ac6653aSJeff Kirsher 18517ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 18527ac6653aSJeff Kirsher priv->tm->timer_stop(); 18537ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 18547ac6653aSJeff Kirsher dis_ic = 1; 18557ac6653aSJeff Kirsher #endif 18567ac6653aSJeff Kirsher napi_disable(&priv->napi); 18577ac6653aSJeff Kirsher 18587ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 18597ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18607ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18617ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 18627ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, 18637ac6653aSJeff Kirsher dis_ic); 18647ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 18657ac6653aSJeff Kirsher 18667ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 18677ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 18687ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 18697ac6653aSJeff Kirsher else 18707ac6653aSJeff Kirsher stmmac_disable_mac(priv->ioaddr); 18717ac6653aSJeff Kirsher 18727ac6653aSJeff Kirsher spin_unlock(&priv->lock); 18737ac6653aSJeff Kirsher return 0; 18747ac6653aSJeff Kirsher } 18757ac6653aSJeff Kirsher 18767ac6653aSJeff Kirsher static int stmmac_resume(struct device *dev) 18777ac6653aSJeff Kirsher { 18787ac6653aSJeff Kirsher struct net_device *ndev = dev_get_drvdata(dev); 18797ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 18807ac6653aSJeff Kirsher 18817ac6653aSJeff Kirsher if (!netif_running(ndev)) 18827ac6653aSJeff Kirsher return 0; 18837ac6653aSJeff Kirsher 18847ac6653aSJeff Kirsher spin_lock(&priv->lock); 18857ac6653aSJeff Kirsher 18867ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 18877ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 18887ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 18897ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 18907ac6653aSJeff Kirsher * from another devices (e.g. serial console). */ 18917ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 18927ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, 0); 18937ac6653aSJeff Kirsher 18947ac6653aSJeff Kirsher netif_device_attach(ndev); 18957ac6653aSJeff Kirsher 18967ac6653aSJeff Kirsher /* Enable the MAC and DMA */ 18977ac6653aSJeff Kirsher stmmac_enable_mac(priv->ioaddr); 18987ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 18997ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 19007ac6653aSJeff Kirsher 19017ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 19027ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 19037ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 19047ac6653aSJeff Kirsher #endif 19057ac6653aSJeff Kirsher napi_enable(&priv->napi); 19067ac6653aSJeff Kirsher 19077ac6653aSJeff Kirsher if (priv->phydev) 19087ac6653aSJeff Kirsher phy_start(priv->phydev); 19097ac6653aSJeff Kirsher 19107ac6653aSJeff Kirsher netif_start_queue(ndev); 19117ac6653aSJeff Kirsher 19127ac6653aSJeff Kirsher spin_unlock(&priv->lock); 19137ac6653aSJeff Kirsher return 0; 19147ac6653aSJeff Kirsher } 19157ac6653aSJeff Kirsher 19167ac6653aSJeff Kirsher static int stmmac_freeze(struct device *dev) 19177ac6653aSJeff Kirsher { 19187ac6653aSJeff Kirsher struct net_device *ndev = dev_get_drvdata(dev); 19197ac6653aSJeff Kirsher 19207ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 19217ac6653aSJeff Kirsher return 0; 19227ac6653aSJeff Kirsher 19237ac6653aSJeff Kirsher return stmmac_release(ndev); 19247ac6653aSJeff Kirsher } 19257ac6653aSJeff Kirsher 19267ac6653aSJeff Kirsher static int stmmac_restore(struct device *dev) 19277ac6653aSJeff Kirsher { 19287ac6653aSJeff Kirsher struct net_device *ndev = dev_get_drvdata(dev); 19297ac6653aSJeff Kirsher 19307ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 19317ac6653aSJeff Kirsher return 0; 19327ac6653aSJeff Kirsher 19337ac6653aSJeff Kirsher return stmmac_open(ndev); 19347ac6653aSJeff Kirsher } 19357ac6653aSJeff Kirsher 19367ac6653aSJeff Kirsher static const struct dev_pm_ops stmmac_pm_ops = { 19377ac6653aSJeff Kirsher .suspend = stmmac_suspend, 19387ac6653aSJeff Kirsher .resume = stmmac_resume, 19397ac6653aSJeff Kirsher .freeze = stmmac_freeze, 19407ac6653aSJeff Kirsher .thaw = stmmac_restore, 19417ac6653aSJeff Kirsher .restore = stmmac_restore, 19427ac6653aSJeff Kirsher }; 19437ac6653aSJeff Kirsher #else 19447ac6653aSJeff Kirsher static const struct dev_pm_ops stmmac_pm_ops; 19457ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 19467ac6653aSJeff Kirsher 19477ac6653aSJeff Kirsher static struct platform_driver stmmac_driver = { 19487ac6653aSJeff Kirsher .probe = stmmac_dvr_probe, 19497ac6653aSJeff Kirsher .remove = stmmac_dvr_remove, 19507ac6653aSJeff Kirsher .driver = { 19517ac6653aSJeff Kirsher .name = STMMAC_RESOURCE_NAME, 19527ac6653aSJeff Kirsher .owner = THIS_MODULE, 19537ac6653aSJeff Kirsher .pm = &stmmac_pm_ops, 19547ac6653aSJeff Kirsher }, 19557ac6653aSJeff Kirsher }; 19567ac6653aSJeff Kirsher 19577ac6653aSJeff Kirsher /** 19587ac6653aSJeff Kirsher * stmmac_init_module - Entry point for the driver 19597ac6653aSJeff Kirsher * Description: This function is the entry point for the driver. 19607ac6653aSJeff Kirsher */ 19617ac6653aSJeff Kirsher static int __init stmmac_init_module(void) 19627ac6653aSJeff Kirsher { 19637ac6653aSJeff Kirsher int ret; 19647ac6653aSJeff Kirsher 19657ac6653aSJeff Kirsher ret = platform_driver_register(&stmmac_driver); 19667ac6653aSJeff Kirsher return ret; 19677ac6653aSJeff Kirsher } 19687ac6653aSJeff Kirsher 19697ac6653aSJeff Kirsher /** 19707ac6653aSJeff Kirsher * stmmac_cleanup_module - Cleanup routine for the driver 19717ac6653aSJeff Kirsher * Description: This function is the cleanup routine for the driver. 19727ac6653aSJeff Kirsher */ 19737ac6653aSJeff Kirsher static void __exit stmmac_cleanup_module(void) 19747ac6653aSJeff Kirsher { 19757ac6653aSJeff Kirsher platform_driver_unregister(&stmmac_driver); 19767ac6653aSJeff Kirsher } 19777ac6653aSJeff Kirsher 19787ac6653aSJeff Kirsher #ifndef MODULE 19797ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 19807ac6653aSJeff Kirsher { 19817ac6653aSJeff Kirsher char *opt; 19827ac6653aSJeff Kirsher 19837ac6653aSJeff Kirsher if (!str || !*str) 19847ac6653aSJeff Kirsher return -EINVAL; 19857ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 19867ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 19877ac6653aSJeff Kirsher if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug)) 19887ac6653aSJeff Kirsher goto err; 19897ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 19907ac6653aSJeff Kirsher if (strict_strtoul(opt + 8, 0, 19917ac6653aSJeff Kirsher (unsigned long *)&phyaddr)) 19927ac6653aSJeff Kirsher goto err; 19937ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 19947ac6653aSJeff Kirsher if (strict_strtoul(opt + 11, 0, 19957ac6653aSJeff Kirsher (unsigned long *)&dma_txsize)) 19967ac6653aSJeff Kirsher goto err; 19977ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 19987ac6653aSJeff Kirsher if (strict_strtoul(opt + 11, 0, 19997ac6653aSJeff Kirsher (unsigned long *)&dma_rxsize)) 20007ac6653aSJeff Kirsher goto err; 20017ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 20027ac6653aSJeff Kirsher if (strict_strtoul(opt + 7, 0, 20037ac6653aSJeff Kirsher (unsigned long *)&buf_sz)) 20047ac6653aSJeff Kirsher goto err; 20057ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 20067ac6653aSJeff Kirsher if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc)) 20077ac6653aSJeff Kirsher goto err; 20087ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 20097ac6653aSJeff Kirsher if (strict_strtoul(opt + 9, 0, 20107ac6653aSJeff Kirsher (unsigned long *)&watchdog)) 20117ac6653aSJeff Kirsher goto err; 20127ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 20137ac6653aSJeff Kirsher if (strict_strtoul(opt + 10, 0, 20147ac6653aSJeff Kirsher (unsigned long *)&flow_ctrl)) 20157ac6653aSJeff Kirsher goto err; 20167ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 20177ac6653aSJeff Kirsher if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause)) 20187ac6653aSJeff Kirsher goto err; 20197ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 20207ac6653aSJeff Kirsher } else if (!strncmp(opt, "tmrate:", 7)) { 20217ac6653aSJeff Kirsher if (strict_strtoul(opt + 7, 0, 20227ac6653aSJeff Kirsher (unsigned long *)&tmrate)) 20237ac6653aSJeff Kirsher goto err; 20247ac6653aSJeff Kirsher #endif 20257ac6653aSJeff Kirsher } 20267ac6653aSJeff Kirsher } 20277ac6653aSJeff Kirsher return 0; 20287ac6653aSJeff Kirsher 20297ac6653aSJeff Kirsher err: 20307ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 20317ac6653aSJeff Kirsher return -EINVAL; 20327ac6653aSJeff Kirsher } 20337ac6653aSJeff Kirsher 20347ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 20357ac6653aSJeff Kirsher #endif 20367ac6653aSJeff Kirsher 20377ac6653aSJeff Kirsher module_init(stmmac_init_module); 20387ac6653aSJeff Kirsher module_exit(stmmac_cleanup_module); 20397ac6653aSJeff Kirsher 20407ac6653aSJeff Kirsher MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver"); 20417ac6653aSJeff Kirsher MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 20427ac6653aSJeff Kirsher MODULE_LICENSE("GPL"); 2043