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];
30779ee1dc3SSrinivas Kandagatla 	int interface = priv->plat->interface;
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 
31779ee1dc3SSrinivas Kandagatla 	phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0, interface);
3187ac6653aSJeff Kirsher 
3197ac6653aSJeff Kirsher 	if (IS_ERR(phydev)) {
3207ac6653aSJeff Kirsher 		pr_err("%s: Could not attach to PHY\n", dev->name);
3217ac6653aSJeff Kirsher 		return PTR_ERR(phydev);
3227ac6653aSJeff Kirsher 	}
3237ac6653aSJeff Kirsher 
32479ee1dc3SSrinivas Kandagatla 	/* Stop Advertising 1000BASE Capability if interface is not GMII */
32579ee1dc3SSrinivas Kandagatla 	if ((interface) && ((interface == PHY_INTERFACE_MODE_MII) ||
32679ee1dc3SSrinivas Kandagatla 	    (interface == PHY_INTERFACE_MODE_RMII))) {
32779ee1dc3SSrinivas Kandagatla 		phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
32879ee1dc3SSrinivas Kandagatla 				      SUPPORTED_Asym_Pause);
32979ee1dc3SSrinivas Kandagatla 		priv->phydev->advertising = priv->phydev->supported;
33079ee1dc3SSrinivas Kandagatla 	}
33179ee1dc3SSrinivas Kandagatla 
3327ac6653aSJeff Kirsher 	/*
3337ac6653aSJeff Kirsher 	 * Broken HW is sometimes missing the pull-up resistor on the
3347ac6653aSJeff Kirsher 	 * MDIO line, which results in reads to non-existent devices returning
3357ac6653aSJeff Kirsher 	 * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
3367ac6653aSJeff Kirsher 	 * device as well.
3377ac6653aSJeff Kirsher 	 * Note: phydev->phy_id is the result of reading the UID PHY registers.
3387ac6653aSJeff Kirsher 	 */
3397ac6653aSJeff Kirsher 	if (phydev->phy_id == 0) {
3407ac6653aSJeff Kirsher 		phy_disconnect(phydev);
3417ac6653aSJeff Kirsher 		return -ENODEV;
3427ac6653aSJeff Kirsher 	}
3437ac6653aSJeff Kirsher 	pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
3447ac6653aSJeff Kirsher 		 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
3457ac6653aSJeff Kirsher 
3467ac6653aSJeff Kirsher 	priv->phydev = phydev;
3477ac6653aSJeff Kirsher 
3487ac6653aSJeff Kirsher 	return 0;
3497ac6653aSJeff Kirsher }
3507ac6653aSJeff Kirsher 
3517ac6653aSJeff Kirsher static inline void stmmac_enable_mac(void __iomem *ioaddr)
3527ac6653aSJeff Kirsher {
3537ac6653aSJeff Kirsher 	u32 value = readl(ioaddr + MAC_CTRL_REG);
3547ac6653aSJeff Kirsher 
3557ac6653aSJeff Kirsher 	value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
3567ac6653aSJeff Kirsher 	writel(value, ioaddr + MAC_CTRL_REG);
3577ac6653aSJeff Kirsher }
3587ac6653aSJeff Kirsher 
3597ac6653aSJeff Kirsher static inline void stmmac_disable_mac(void __iomem *ioaddr)
3607ac6653aSJeff Kirsher {
3617ac6653aSJeff Kirsher 	u32 value = readl(ioaddr + MAC_CTRL_REG);
3627ac6653aSJeff Kirsher 
3637ac6653aSJeff Kirsher 	value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
3647ac6653aSJeff Kirsher 	writel(value, ioaddr + MAC_CTRL_REG);
3657ac6653aSJeff Kirsher }
3667ac6653aSJeff Kirsher 
3677ac6653aSJeff Kirsher /**
3687ac6653aSJeff Kirsher  * display_ring
3697ac6653aSJeff Kirsher  * @p: pointer to the ring.
3707ac6653aSJeff Kirsher  * @size: size of the ring.
3717ac6653aSJeff Kirsher  * Description: display all the descriptors within the ring.
3727ac6653aSJeff Kirsher  */
3737ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size)
3747ac6653aSJeff Kirsher {
3757ac6653aSJeff Kirsher 	struct tmp_s {
3767ac6653aSJeff Kirsher 		u64 a;
3777ac6653aSJeff Kirsher 		unsigned int b;
3787ac6653aSJeff Kirsher 		unsigned int c;
3797ac6653aSJeff Kirsher 	};
3807ac6653aSJeff Kirsher 	int i;
3817ac6653aSJeff Kirsher 	for (i = 0; i < size; i++) {
3827ac6653aSJeff Kirsher 		struct tmp_s *x = (struct tmp_s *)(p + i);
3837ac6653aSJeff Kirsher 		pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
3847ac6653aSJeff Kirsher 		       i, (unsigned int)virt_to_phys(&p[i]),
3857ac6653aSJeff Kirsher 		       (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
3867ac6653aSJeff Kirsher 		       x->b, x->c);
3877ac6653aSJeff Kirsher 		pr_info("\n");
3887ac6653aSJeff Kirsher 	}
3897ac6653aSJeff Kirsher }
3907ac6653aSJeff Kirsher 
3917ac6653aSJeff Kirsher /**
3927ac6653aSJeff Kirsher  * init_dma_desc_rings - init the RX/TX descriptor rings
3937ac6653aSJeff Kirsher  * @dev: net device structure
3947ac6653aSJeff Kirsher  * Description:  this function initializes the DMA RX/TX descriptors
3957ac6653aSJeff Kirsher  * and allocates the socket buffers.
3967ac6653aSJeff Kirsher  */
3977ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev)
3987ac6653aSJeff Kirsher {
3997ac6653aSJeff Kirsher 	int i;
4007ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
4017ac6653aSJeff Kirsher 	struct sk_buff *skb;
4027ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
4037ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
4047ac6653aSJeff Kirsher 	unsigned int bfsize = priv->dma_buf_sz;
4057ac6653aSJeff Kirsher 	int buff2_needed = 0, dis_ic = 0;
4067ac6653aSJeff Kirsher 
4077ac6653aSJeff Kirsher 	/* Set the Buffer size according to the MTU;
4087ac6653aSJeff Kirsher 	 * indeed, in case of jumbo we need to bump-up the buffer sizes.
4097ac6653aSJeff Kirsher 	 */
4107ac6653aSJeff Kirsher 	if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
4117ac6653aSJeff Kirsher 		bfsize = BUF_SIZE_16KiB;
4127ac6653aSJeff Kirsher 	else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
4137ac6653aSJeff Kirsher 		bfsize = BUF_SIZE_8KiB;
4147ac6653aSJeff Kirsher 	else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
4157ac6653aSJeff Kirsher 		bfsize = BUF_SIZE_4KiB;
4167ac6653aSJeff Kirsher 	else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
4177ac6653aSJeff Kirsher 		bfsize = BUF_SIZE_2KiB;
4187ac6653aSJeff Kirsher 	else
4197ac6653aSJeff Kirsher 		bfsize = DMA_BUFFER_SIZE;
4207ac6653aSJeff Kirsher 
4217ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
4227ac6653aSJeff Kirsher 	/* Disable interrupts on completion for the reception if timer is on */
4237ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
4247ac6653aSJeff Kirsher 		dis_ic = 1;
4257ac6653aSJeff Kirsher #endif
4267ac6653aSJeff Kirsher 	/* If the MTU exceeds 8k so use the second buffer in the chain */
4277ac6653aSJeff Kirsher 	if (bfsize >= BUF_SIZE_8KiB)
4287ac6653aSJeff Kirsher 		buff2_needed = 1;
4297ac6653aSJeff Kirsher 
4307ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
4317ac6653aSJeff Kirsher 	    txsize, rxsize, bfsize);
4327ac6653aSJeff Kirsher 
4337ac6653aSJeff Kirsher 	priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
4347ac6653aSJeff Kirsher 	priv->rx_skbuff =
4357ac6653aSJeff Kirsher 	    kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
4367ac6653aSJeff Kirsher 	priv->dma_rx =
4377ac6653aSJeff Kirsher 	    (struct dma_desc *)dma_alloc_coherent(priv->device,
4387ac6653aSJeff Kirsher 						  rxsize *
4397ac6653aSJeff Kirsher 						  sizeof(struct dma_desc),
4407ac6653aSJeff Kirsher 						  &priv->dma_rx_phy,
4417ac6653aSJeff Kirsher 						  GFP_KERNEL);
4427ac6653aSJeff Kirsher 	priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
4437ac6653aSJeff Kirsher 				       GFP_KERNEL);
4447ac6653aSJeff Kirsher 	priv->dma_tx =
4457ac6653aSJeff Kirsher 	    (struct dma_desc *)dma_alloc_coherent(priv->device,
4467ac6653aSJeff Kirsher 						  txsize *
4477ac6653aSJeff Kirsher 						  sizeof(struct dma_desc),
4487ac6653aSJeff Kirsher 						  &priv->dma_tx_phy,
4497ac6653aSJeff Kirsher 						  GFP_KERNEL);
4507ac6653aSJeff Kirsher 
4517ac6653aSJeff Kirsher 	if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
4527ac6653aSJeff Kirsher 		pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
4537ac6653aSJeff Kirsher 		return;
4547ac6653aSJeff Kirsher 	}
4557ac6653aSJeff Kirsher 
4567ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
4577ac6653aSJeff Kirsher 	    "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
4587ac6653aSJeff Kirsher 	    dev->name, priv->dma_rx, priv->dma_tx,
4597ac6653aSJeff Kirsher 	    (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
4607ac6653aSJeff Kirsher 
4617ac6653aSJeff Kirsher 	/* RX INITIALIZATION */
4627ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac: SKB addresses:\n"
4637ac6653aSJeff Kirsher 			 "skb\t\tskb data\tdma data\n");
4647ac6653aSJeff Kirsher 
4657ac6653aSJeff Kirsher 	for (i = 0; i < rxsize; i++) {
4667ac6653aSJeff Kirsher 		struct dma_desc *p = priv->dma_rx + i;
4677ac6653aSJeff Kirsher 
4687ac6653aSJeff Kirsher 		skb = netdev_alloc_skb_ip_align(dev, bfsize);
4697ac6653aSJeff Kirsher 		if (unlikely(skb == NULL)) {
4707ac6653aSJeff Kirsher 			pr_err("%s: Rx init fails; skb is NULL\n", __func__);
4717ac6653aSJeff Kirsher 			break;
4727ac6653aSJeff Kirsher 		}
4737ac6653aSJeff Kirsher 		priv->rx_skbuff[i] = skb;
4747ac6653aSJeff Kirsher 		priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
4757ac6653aSJeff Kirsher 						bfsize, DMA_FROM_DEVICE);
4767ac6653aSJeff Kirsher 
4777ac6653aSJeff Kirsher 		p->des2 = priv->rx_skbuff_dma[i];
4787ac6653aSJeff Kirsher 		if (unlikely(buff2_needed))
4797ac6653aSJeff Kirsher 			p->des3 = p->des2 + BUF_SIZE_8KiB;
4807ac6653aSJeff Kirsher 		DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
4817ac6653aSJeff Kirsher 			priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
4827ac6653aSJeff Kirsher 	}
4837ac6653aSJeff Kirsher 	priv->cur_rx = 0;
4847ac6653aSJeff Kirsher 	priv->dirty_rx = (unsigned int)(i - rxsize);
4857ac6653aSJeff Kirsher 	priv->dma_buf_sz = bfsize;
4867ac6653aSJeff Kirsher 	buf_sz = bfsize;
4877ac6653aSJeff Kirsher 
4887ac6653aSJeff Kirsher 	/* TX INITIALIZATION */
4897ac6653aSJeff Kirsher 	for (i = 0; i < txsize; i++) {
4907ac6653aSJeff Kirsher 		priv->tx_skbuff[i] = NULL;
4917ac6653aSJeff Kirsher 		priv->dma_tx[i].des2 = 0;
4927ac6653aSJeff Kirsher 	}
4937ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
4947ac6653aSJeff Kirsher 	priv->cur_tx = 0;
4957ac6653aSJeff Kirsher 
4967ac6653aSJeff Kirsher 	/* Clear the Rx/Tx descriptors */
4977ac6653aSJeff Kirsher 	priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
4987ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
4997ac6653aSJeff Kirsher 
5007ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
5017ac6653aSJeff Kirsher 		pr_info("RX descriptor ring:\n");
5027ac6653aSJeff Kirsher 		display_ring(priv->dma_rx, rxsize);
5037ac6653aSJeff Kirsher 		pr_info("TX descriptor ring:\n");
5047ac6653aSJeff Kirsher 		display_ring(priv->dma_tx, txsize);
5057ac6653aSJeff Kirsher 	}
5067ac6653aSJeff Kirsher }
5077ac6653aSJeff Kirsher 
5087ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv)
5097ac6653aSJeff Kirsher {
5107ac6653aSJeff Kirsher 	int i;
5117ac6653aSJeff Kirsher 
5127ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_rx_size; i++) {
5137ac6653aSJeff Kirsher 		if (priv->rx_skbuff[i]) {
5147ac6653aSJeff Kirsher 			dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
5157ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
5167ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->rx_skbuff[i]);
5177ac6653aSJeff Kirsher 		}
5187ac6653aSJeff Kirsher 		priv->rx_skbuff[i] = NULL;
5197ac6653aSJeff Kirsher 	}
5207ac6653aSJeff Kirsher }
5217ac6653aSJeff Kirsher 
5227ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv)
5237ac6653aSJeff Kirsher {
5247ac6653aSJeff Kirsher 	int i;
5257ac6653aSJeff Kirsher 
5267ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_tx_size; i++) {
5277ac6653aSJeff Kirsher 		if (priv->tx_skbuff[i] != NULL) {
5287ac6653aSJeff Kirsher 			struct dma_desc *p = priv->dma_tx + i;
5297ac6653aSJeff Kirsher 			if (p->des2)
5307ac6653aSJeff Kirsher 				dma_unmap_single(priv->device, p->des2,
5317ac6653aSJeff Kirsher 						 priv->hw->desc->get_tx_len(p),
5327ac6653aSJeff Kirsher 						 DMA_TO_DEVICE);
5337ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->tx_skbuff[i]);
5347ac6653aSJeff Kirsher 			priv->tx_skbuff[i] = NULL;
5357ac6653aSJeff Kirsher 		}
5367ac6653aSJeff Kirsher 	}
5377ac6653aSJeff Kirsher }
5387ac6653aSJeff Kirsher 
5397ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv)
5407ac6653aSJeff Kirsher {
5417ac6653aSJeff Kirsher 	/* Release the DMA TX/RX socket buffers */
5427ac6653aSJeff Kirsher 	dma_free_rx_skbufs(priv);
5437ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
5447ac6653aSJeff Kirsher 
5457ac6653aSJeff Kirsher 	/* Free the region of consistent memory previously allocated for
5467ac6653aSJeff Kirsher 	 * the DMA */
5477ac6653aSJeff Kirsher 	dma_free_coherent(priv->device,
5487ac6653aSJeff Kirsher 			  priv->dma_tx_size * sizeof(struct dma_desc),
5497ac6653aSJeff Kirsher 			  priv->dma_tx, priv->dma_tx_phy);
5507ac6653aSJeff Kirsher 	dma_free_coherent(priv->device,
5517ac6653aSJeff Kirsher 			  priv->dma_rx_size * sizeof(struct dma_desc),
5527ac6653aSJeff Kirsher 			  priv->dma_rx, priv->dma_rx_phy);
5537ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff_dma);
5547ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff);
5557ac6653aSJeff Kirsher 	kfree(priv->tx_skbuff);
5567ac6653aSJeff Kirsher }
5577ac6653aSJeff Kirsher 
5587ac6653aSJeff Kirsher /**
5597ac6653aSJeff Kirsher  *  stmmac_dma_operation_mode - HW DMA operation mode
5607ac6653aSJeff Kirsher  *  @priv : pointer to the private device structure.
5617ac6653aSJeff Kirsher  *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
5627ac6653aSJeff Kirsher  *  or Store-And-Forward capability.
5637ac6653aSJeff Kirsher  */
5647ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
5657ac6653aSJeff Kirsher {
5667ac6653aSJeff Kirsher 	if (likely(priv->plat->force_sf_dma_mode ||
5677ac6653aSJeff Kirsher 		((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) {
5687ac6653aSJeff Kirsher 		/*
5697ac6653aSJeff Kirsher 		 * In case of GMAC, SF mode can be enabled
5707ac6653aSJeff Kirsher 		 * to perform the TX COE in HW. This depends on:
5717ac6653aSJeff Kirsher 		 * 1) TX COE if actually supported
5727ac6653aSJeff Kirsher 		 * 2) There is no bugged Jumbo frame support
5737ac6653aSJeff Kirsher 		 *    that needs to not insert csum in the TDES.
5747ac6653aSJeff Kirsher 		 */
5757ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr,
5767ac6653aSJeff Kirsher 					SF_DMA_MODE, SF_DMA_MODE);
5777ac6653aSJeff Kirsher 		tc = SF_DMA_MODE;
5787ac6653aSJeff Kirsher 	} else
5797ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
5807ac6653aSJeff Kirsher }
5817ac6653aSJeff Kirsher 
5827ac6653aSJeff Kirsher /**
5837ac6653aSJeff Kirsher  * stmmac_tx:
5847ac6653aSJeff Kirsher  * @priv: private driver structure
5857ac6653aSJeff Kirsher  * Description: it reclaims resources after transmission completes.
5867ac6653aSJeff Kirsher  */
5877ac6653aSJeff Kirsher static void stmmac_tx(struct stmmac_priv *priv)
5887ac6653aSJeff Kirsher {
5897ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
5907ac6653aSJeff Kirsher 
591a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
592a9097a96SGiuseppe CAVALLARO 
5937ac6653aSJeff Kirsher 	while (priv->dirty_tx != priv->cur_tx) {
5947ac6653aSJeff Kirsher 		int last;
5957ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_tx % txsize;
5967ac6653aSJeff Kirsher 		struct sk_buff *skb = priv->tx_skbuff[entry];
5977ac6653aSJeff Kirsher 		struct dma_desc *p = priv->dma_tx + entry;
5987ac6653aSJeff Kirsher 
5997ac6653aSJeff Kirsher 		/* Check if the descriptor is owned by the DMA. */
6007ac6653aSJeff Kirsher 		if (priv->hw->desc->get_tx_owner(p))
6017ac6653aSJeff Kirsher 			break;
6027ac6653aSJeff Kirsher 
6037ac6653aSJeff Kirsher 		/* Verify tx error by looking at the last segment */
6047ac6653aSJeff Kirsher 		last = priv->hw->desc->get_tx_ls(p);
6057ac6653aSJeff Kirsher 		if (likely(last)) {
6067ac6653aSJeff Kirsher 			int tx_error =
6077ac6653aSJeff Kirsher 				priv->hw->desc->tx_status(&priv->dev->stats,
6087ac6653aSJeff Kirsher 							  &priv->xstats, p,
6097ac6653aSJeff Kirsher 							  priv->ioaddr);
6107ac6653aSJeff Kirsher 			if (likely(tx_error == 0)) {
6117ac6653aSJeff Kirsher 				priv->dev->stats.tx_packets++;
6127ac6653aSJeff Kirsher 				priv->xstats.tx_pkt_n++;
6137ac6653aSJeff Kirsher 			} else
6147ac6653aSJeff Kirsher 				priv->dev->stats.tx_errors++;
6157ac6653aSJeff Kirsher 		}
6167ac6653aSJeff Kirsher 		TX_DBG("%s: curr %d, dirty %d\n", __func__,
6177ac6653aSJeff Kirsher 			priv->cur_tx, priv->dirty_tx);
6187ac6653aSJeff Kirsher 
6197ac6653aSJeff Kirsher 		if (likely(p->des2))
6207ac6653aSJeff Kirsher 			dma_unmap_single(priv->device, p->des2,
6217ac6653aSJeff Kirsher 					 priv->hw->desc->get_tx_len(p),
6227ac6653aSJeff Kirsher 					 DMA_TO_DEVICE);
6237ac6653aSJeff Kirsher 		if (unlikely(p->des3))
6247ac6653aSJeff Kirsher 			p->des3 = 0;
6257ac6653aSJeff Kirsher 
6267ac6653aSJeff Kirsher 		if (likely(skb != NULL)) {
6277ac6653aSJeff Kirsher 			/*
6287ac6653aSJeff Kirsher 			 * If there's room in the queue (limit it to size)
6297ac6653aSJeff Kirsher 			 * we add this skb back into the pool,
6307ac6653aSJeff Kirsher 			 * if it's the right size.
6317ac6653aSJeff Kirsher 			 */
6327ac6653aSJeff Kirsher 			if ((skb_queue_len(&priv->rx_recycle) <
6337ac6653aSJeff Kirsher 				priv->dma_rx_size) &&
6347ac6653aSJeff Kirsher 				skb_recycle_check(skb, priv->dma_buf_sz))
6357ac6653aSJeff Kirsher 				__skb_queue_head(&priv->rx_recycle, skb);
6367ac6653aSJeff Kirsher 			else
6377ac6653aSJeff Kirsher 				dev_kfree_skb(skb);
6387ac6653aSJeff Kirsher 
6397ac6653aSJeff Kirsher 			priv->tx_skbuff[entry] = NULL;
6407ac6653aSJeff Kirsher 		}
6417ac6653aSJeff Kirsher 
6427ac6653aSJeff Kirsher 		priv->hw->desc->release_tx_desc(p);
6437ac6653aSJeff Kirsher 
6447ac6653aSJeff Kirsher 		entry = (++priv->dirty_tx) % txsize;
6457ac6653aSJeff Kirsher 	}
6467ac6653aSJeff Kirsher 	if (unlikely(netif_queue_stopped(priv->dev) &&
6477ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
6487ac6653aSJeff Kirsher 		netif_tx_lock(priv->dev);
6497ac6653aSJeff Kirsher 		if (netif_queue_stopped(priv->dev) &&
6507ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
6517ac6653aSJeff Kirsher 			TX_DBG("%s: restart transmit\n", __func__);
6527ac6653aSJeff Kirsher 			netif_wake_queue(priv->dev);
6537ac6653aSJeff Kirsher 		}
6547ac6653aSJeff Kirsher 		netif_tx_unlock(priv->dev);
6557ac6653aSJeff Kirsher 	}
656a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
6577ac6653aSJeff Kirsher }
6587ac6653aSJeff Kirsher 
6597ac6653aSJeff Kirsher static inline void stmmac_enable_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_start(tmrate);
6647ac6653aSJeff Kirsher 	else
6657ac6653aSJeff Kirsher #endif
6667ac6653aSJeff Kirsher 		priv->hw->dma->enable_dma_irq(priv->ioaddr);
6677ac6653aSJeff Kirsher }
6687ac6653aSJeff Kirsher 
6697ac6653aSJeff Kirsher static inline void stmmac_disable_irq(struct stmmac_priv *priv)
6707ac6653aSJeff Kirsher {
6717ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
6727ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
6737ac6653aSJeff Kirsher 		priv->tm->timer_stop();
6747ac6653aSJeff Kirsher 	else
6757ac6653aSJeff Kirsher #endif
6767ac6653aSJeff Kirsher 		priv->hw->dma->disable_dma_irq(priv->ioaddr);
6777ac6653aSJeff Kirsher }
6787ac6653aSJeff Kirsher 
6797ac6653aSJeff Kirsher static int stmmac_has_work(struct stmmac_priv *priv)
6807ac6653aSJeff Kirsher {
6817ac6653aSJeff Kirsher 	unsigned int has_work = 0;
6827ac6653aSJeff Kirsher 	int rxret, tx_work = 0;
6837ac6653aSJeff Kirsher 
6847ac6653aSJeff Kirsher 	rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
6857ac6653aSJeff Kirsher 		(priv->cur_rx % priv->dma_rx_size));
6867ac6653aSJeff Kirsher 
6877ac6653aSJeff Kirsher 	if (priv->dirty_tx != priv->cur_tx)
6887ac6653aSJeff Kirsher 		tx_work = 1;
6897ac6653aSJeff Kirsher 
6907ac6653aSJeff Kirsher 	if (likely(!rxret || tx_work))
6917ac6653aSJeff Kirsher 		has_work = 1;
6927ac6653aSJeff Kirsher 
6937ac6653aSJeff Kirsher 	return has_work;
6947ac6653aSJeff Kirsher }
6957ac6653aSJeff Kirsher 
6967ac6653aSJeff Kirsher static inline void _stmmac_schedule(struct stmmac_priv *priv)
6977ac6653aSJeff Kirsher {
6987ac6653aSJeff Kirsher 	if (likely(stmmac_has_work(priv))) {
6997ac6653aSJeff Kirsher 		stmmac_disable_irq(priv);
7007ac6653aSJeff Kirsher 		napi_schedule(&priv->napi);
7017ac6653aSJeff Kirsher 	}
7027ac6653aSJeff Kirsher }
7037ac6653aSJeff Kirsher 
7047ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
7057ac6653aSJeff Kirsher void stmmac_schedule(struct net_device *dev)
7067ac6653aSJeff Kirsher {
7077ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
7087ac6653aSJeff Kirsher 
7097ac6653aSJeff Kirsher 	priv->xstats.sched_timer_n++;
7107ac6653aSJeff Kirsher 
7117ac6653aSJeff Kirsher 	_stmmac_schedule(priv);
7127ac6653aSJeff Kirsher }
7137ac6653aSJeff Kirsher 
7147ac6653aSJeff Kirsher static void stmmac_no_timer_started(unsigned int x)
7157ac6653aSJeff Kirsher {;
7167ac6653aSJeff Kirsher };
7177ac6653aSJeff Kirsher 
7187ac6653aSJeff Kirsher static void stmmac_no_timer_stopped(void)
7197ac6653aSJeff Kirsher {;
7207ac6653aSJeff Kirsher };
7217ac6653aSJeff Kirsher #endif
7227ac6653aSJeff Kirsher 
7237ac6653aSJeff Kirsher /**
7247ac6653aSJeff Kirsher  * stmmac_tx_err:
7257ac6653aSJeff Kirsher  * @priv: pointer to the private device structure
7267ac6653aSJeff Kirsher  * Description: it cleans the descriptors and restarts the transmission
7277ac6653aSJeff Kirsher  * in case of errors.
7287ac6653aSJeff Kirsher  */
7297ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv)
7307ac6653aSJeff Kirsher {
7317ac6653aSJeff Kirsher 
7327ac6653aSJeff Kirsher 	netif_stop_queue(priv->dev);
7337ac6653aSJeff Kirsher 
7347ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
7357ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
7367ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
7377ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
7387ac6653aSJeff Kirsher 	priv->cur_tx = 0;
7397ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
7407ac6653aSJeff Kirsher 
7417ac6653aSJeff Kirsher 	priv->dev->stats.tx_errors++;
7427ac6653aSJeff Kirsher 	netif_wake_queue(priv->dev);
7437ac6653aSJeff Kirsher }
7447ac6653aSJeff Kirsher 
7457ac6653aSJeff Kirsher 
7467ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv)
7477ac6653aSJeff Kirsher {
7487ac6653aSJeff Kirsher 	int status;
7497ac6653aSJeff Kirsher 
7507ac6653aSJeff Kirsher 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
7517ac6653aSJeff Kirsher 	if (likely(status == handle_tx_rx))
7527ac6653aSJeff Kirsher 		_stmmac_schedule(priv);
7537ac6653aSJeff Kirsher 
7547ac6653aSJeff Kirsher 	else if (unlikely(status == tx_hard_error_bump_tc)) {
7557ac6653aSJeff Kirsher 		/* Try to bump up the dma threshold on this failure */
7567ac6653aSJeff Kirsher 		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
7577ac6653aSJeff Kirsher 			tc += 64;
7587ac6653aSJeff Kirsher 			priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
7597ac6653aSJeff Kirsher 			priv->xstats.threshold = tc;
7607ac6653aSJeff Kirsher 		}
7617ac6653aSJeff Kirsher 	} else if (unlikely(status == tx_hard_error))
7627ac6653aSJeff Kirsher 		stmmac_tx_err(priv);
7637ac6653aSJeff Kirsher }
7647ac6653aSJeff Kirsher 
7651c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv)
7661c901a46SGiuseppe CAVALLARO {
7671c901a46SGiuseppe CAVALLARO 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
7681c901a46SGiuseppe CAVALLARO 			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
7691c901a46SGiuseppe CAVALLARO 
7701c901a46SGiuseppe CAVALLARO 	/* Do not manage MMC IRQ (FIXME) */
7711c901a46SGiuseppe CAVALLARO 	dwmac_mmc_intr_all_mask(priv->ioaddr);
7721c901a46SGiuseppe CAVALLARO 	dwmac_mmc_ctrl(priv->ioaddr, mode);
7731c901a46SGiuseppe CAVALLARO 	memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
7741c901a46SGiuseppe CAVALLARO }
7751c901a46SGiuseppe CAVALLARO 
776f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
777f0b9d786SGiuseppe CAVALLARO {
778f0b9d786SGiuseppe CAVALLARO 	u32 hwid = priv->hw->synopsys_uid;
779f0b9d786SGiuseppe CAVALLARO 
780f0b9d786SGiuseppe CAVALLARO 	/* Only check valid Synopsys Id because old MAC chips
781f0b9d786SGiuseppe CAVALLARO 	 * have no HW registers where get the ID */
782f0b9d786SGiuseppe CAVALLARO 	if (likely(hwid)) {
783f0b9d786SGiuseppe CAVALLARO 		u32 uid = ((hwid & 0x0000ff00) >> 8);
784f0b9d786SGiuseppe CAVALLARO 		u32 synid = (hwid & 0x000000ff);
785f0b9d786SGiuseppe CAVALLARO 
786f0b9d786SGiuseppe CAVALLARO 		pr_info("STMMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
787f0b9d786SGiuseppe CAVALLARO 			uid, synid);
788f0b9d786SGiuseppe CAVALLARO 
789f0b9d786SGiuseppe CAVALLARO 		return synid;
790f0b9d786SGiuseppe CAVALLARO 	}
791f0b9d786SGiuseppe CAVALLARO 	return 0;
792f0b9d786SGiuseppe CAVALLARO }
793e7434821SGiuseppe CAVALLARO 
794e7434821SGiuseppe CAVALLARO /* New GMAC chips support a new register to indicate the
795e7434821SGiuseppe CAVALLARO  * presence of the optional feature/functions.
796e7434821SGiuseppe CAVALLARO  */
797e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv)
798e7434821SGiuseppe CAVALLARO {
799e7434821SGiuseppe CAVALLARO 	u32 hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
800e7434821SGiuseppe CAVALLARO 
801e7434821SGiuseppe CAVALLARO 	if (likely(hw_cap)) {
802e7434821SGiuseppe CAVALLARO 		priv->dma_cap.mbps_10_100 = (hw_cap & 0x1);
803e7434821SGiuseppe CAVALLARO 		priv->dma_cap.mbps_1000 = (hw_cap & 0x2) >> 1;
804e7434821SGiuseppe CAVALLARO 		priv->dma_cap.half_duplex = (hw_cap & 0x4) >> 2;
805e7434821SGiuseppe CAVALLARO 		priv->dma_cap.hash_filter = (hw_cap & 0x10) >> 4;
806e7434821SGiuseppe CAVALLARO 		priv->dma_cap.multi_addr = (hw_cap & 0x20) >> 5;
807e7434821SGiuseppe CAVALLARO 		priv->dma_cap.pcs = (hw_cap & 0x40) >> 6;
808e7434821SGiuseppe CAVALLARO 		priv->dma_cap.sma_mdio = (hw_cap & 0x100) >> 8;
809e7434821SGiuseppe CAVALLARO 		priv->dma_cap.pmt_remote_wake_up = (hw_cap & 0x200) >> 9;
810e7434821SGiuseppe CAVALLARO 		priv->dma_cap.pmt_magic_frame = (hw_cap & 0x400) >> 10;
811e7434821SGiuseppe CAVALLARO 		priv->dma_cap.rmon = (hw_cap & 0x800) >> 11; /* MMC */
812e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2002*/
813e7434821SGiuseppe CAVALLARO 		priv->dma_cap.time_stamp = (hw_cap & 0x1000) >> 12;
814e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2008*/
815e7434821SGiuseppe CAVALLARO 		priv->dma_cap.atime_stamp = (hw_cap & 0x2000) >> 13;
816e7434821SGiuseppe CAVALLARO 		/* 802.3az - Energy-Efficient Ethernet (EEE) */
817e7434821SGiuseppe CAVALLARO 		priv->dma_cap.eee = (hw_cap & 0x4000) >> 14;
818e7434821SGiuseppe CAVALLARO 		priv->dma_cap.av = (hw_cap & 0x8000) >> 15;
819e7434821SGiuseppe CAVALLARO 		/* TX and RX csum */
820e7434821SGiuseppe CAVALLARO 		priv->dma_cap.tx_coe = (hw_cap & 0x10000) >> 16;
821e7434821SGiuseppe CAVALLARO 		priv->dma_cap.rx_coe_type1 = (hw_cap & 0x20000) >> 17;
822e7434821SGiuseppe CAVALLARO 		priv->dma_cap.rx_coe_type2 = (hw_cap & 0x40000) >> 18;
823e7434821SGiuseppe CAVALLARO 		priv->dma_cap.rxfifo_over_2048 = (hw_cap & 0x80000) >> 19;
824e7434821SGiuseppe CAVALLARO 		/* TX and RX number of channels */
825e7434821SGiuseppe CAVALLARO 		priv->dma_cap.number_rx_channel = (hw_cap & 0x300000) >> 20;
826e7434821SGiuseppe CAVALLARO 		priv->dma_cap.number_tx_channel = (hw_cap & 0xc00000) >> 22;
827e7434821SGiuseppe CAVALLARO 		/* Alternate (enhanced) DESC mode*/
828e7434821SGiuseppe CAVALLARO 		priv->dma_cap.enh_desc = (hw_cap & 0x1000000) >> 24;
829e7434821SGiuseppe CAVALLARO 
830e7434821SGiuseppe CAVALLARO 	} else
831e7434821SGiuseppe CAVALLARO 		pr_debug("\tNo HW DMA feature register supported");
832e7434821SGiuseppe CAVALLARO 
833e7434821SGiuseppe CAVALLARO 	return hw_cap;
834e7434821SGiuseppe CAVALLARO }
835e7434821SGiuseppe CAVALLARO 
8367ac6653aSJeff Kirsher /**
8377ac6653aSJeff Kirsher  *  stmmac_open - open entry point of the driver
8387ac6653aSJeff Kirsher  *  @dev : pointer to the device structure.
8397ac6653aSJeff Kirsher  *  Description:
8407ac6653aSJeff Kirsher  *  This function is the open entry point of the driver.
8417ac6653aSJeff Kirsher  *  Return value:
8427ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
8437ac6653aSJeff Kirsher  *  file on failure.
8447ac6653aSJeff Kirsher  */
8457ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev)
8467ac6653aSJeff Kirsher {
8477ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
8487ac6653aSJeff Kirsher 	int ret;
8497ac6653aSJeff Kirsher 
8507ac6653aSJeff Kirsher 	/* Check that the MAC address is valid.  If its not, refuse
8517ac6653aSJeff Kirsher 	 * to bring the device up. The user must specify an
8527ac6653aSJeff Kirsher 	 * address using the following linux command:
8537ac6653aSJeff Kirsher 	 *      ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx  */
8547ac6653aSJeff Kirsher 	if (!is_valid_ether_addr(dev->dev_addr)) {
8557ac6653aSJeff Kirsher 		random_ether_addr(dev->dev_addr);
8567ac6653aSJeff Kirsher 		pr_warning("%s: generated random MAC address %pM\n", dev->name,
8577ac6653aSJeff Kirsher 			dev->dev_addr);
8587ac6653aSJeff Kirsher 	}
8597ac6653aSJeff Kirsher 
8607ac6653aSJeff Kirsher 	stmmac_verify_args();
8617ac6653aSJeff Kirsher 
8627ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
8637ac6653aSJeff Kirsher 	priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
8647ac6653aSJeff Kirsher 	if (unlikely(priv->tm == NULL)) {
8657ac6653aSJeff Kirsher 		pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
8667ac6653aSJeff Kirsher 		return -ENOMEM;
8677ac6653aSJeff Kirsher 	}
8687ac6653aSJeff Kirsher 	priv->tm->freq = tmrate;
8697ac6653aSJeff Kirsher 
8707ac6653aSJeff Kirsher 	/* Test if the external timer can be actually used.
8717ac6653aSJeff Kirsher 	 * In case of failure continue without timer. */
8727ac6653aSJeff Kirsher 	if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
8737ac6653aSJeff Kirsher 		pr_warning("stmmaceth: cannot attach the external timer.\n");
8747ac6653aSJeff Kirsher 		priv->tm->freq = 0;
8757ac6653aSJeff Kirsher 		priv->tm->timer_start = stmmac_no_timer_started;
8767ac6653aSJeff Kirsher 		priv->tm->timer_stop = stmmac_no_timer_stopped;
8777ac6653aSJeff Kirsher 	} else
8787ac6653aSJeff Kirsher 		priv->tm->enable = 1;
8797ac6653aSJeff Kirsher #endif
8807ac6653aSJeff Kirsher 	ret = stmmac_init_phy(dev);
8817ac6653aSJeff Kirsher 	if (unlikely(ret)) {
8827ac6653aSJeff Kirsher 		pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
8837ac6653aSJeff Kirsher 		goto open_error;
8847ac6653aSJeff Kirsher 	}
8857ac6653aSJeff Kirsher 
8867ac6653aSJeff Kirsher 	/* Create and initialize the TX/RX descriptors chains. */
8877ac6653aSJeff Kirsher 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
8887ac6653aSJeff Kirsher 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
8897ac6653aSJeff Kirsher 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
8907ac6653aSJeff Kirsher 	init_dma_desc_rings(dev);
8917ac6653aSJeff Kirsher 
8927ac6653aSJeff Kirsher 	/* DMA initialization and SW reset */
8937ac6653aSJeff Kirsher 	ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
8947ac6653aSJeff Kirsher 				  priv->dma_tx_phy, priv->dma_rx_phy);
8957ac6653aSJeff Kirsher 	if (ret < 0) {
8967ac6653aSJeff Kirsher 		pr_err("%s: DMA initialization failed\n", __func__);
8977ac6653aSJeff Kirsher 		goto open_error;
8987ac6653aSJeff Kirsher 	}
8997ac6653aSJeff Kirsher 
9007ac6653aSJeff Kirsher 	/* Copy the MAC addr into the HW  */
9017ac6653aSJeff Kirsher 	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
9027ac6653aSJeff Kirsher 	/* If required, perform hw setup of the bus. */
9037ac6653aSJeff Kirsher 	if (priv->plat->bus_setup)
9047ac6653aSJeff Kirsher 		priv->plat->bus_setup(priv->ioaddr);
9057ac6653aSJeff Kirsher 	/* Initialize the MAC Core */
9067ac6653aSJeff Kirsher 	priv->hw->mac->core_init(priv->ioaddr);
9077ac6653aSJeff Kirsher 
908f0b9d786SGiuseppe CAVALLARO 	stmmac_get_synopsys_id(priv);
909f0b9d786SGiuseppe CAVALLARO 
910e7434821SGiuseppe CAVALLARO 	stmmac_get_hw_features(priv);
911e7434821SGiuseppe CAVALLARO 
9127ac6653aSJeff Kirsher 	if (priv->rx_coe)
9137ac6653aSJeff Kirsher 		pr_info("stmmac: Rx Checksum Offload Engine supported\n");
9147ac6653aSJeff Kirsher 	if (priv->plat->tx_coe)
9157ac6653aSJeff Kirsher 		pr_info("\tTX Checksum insertion supported\n");
9167ac6653aSJeff Kirsher 	netdev_update_features(dev);
9177ac6653aSJeff Kirsher 
9187ac6653aSJeff Kirsher 	/* Request the IRQ lines */
9197ac6653aSJeff Kirsher 	ret = request_irq(dev->irq, stmmac_interrupt,
9207ac6653aSJeff Kirsher 			 IRQF_SHARED, dev->name, dev);
9217ac6653aSJeff Kirsher 	if (unlikely(ret < 0)) {
9227ac6653aSJeff Kirsher 		pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
9237ac6653aSJeff Kirsher 		       __func__, dev->irq, ret);
9247ac6653aSJeff Kirsher 		goto open_error;
9257ac6653aSJeff Kirsher 	}
9267ac6653aSJeff Kirsher 
9277ac6653aSJeff Kirsher 	/* Enable the MAC Rx/Tx */
9287ac6653aSJeff Kirsher 	stmmac_enable_mac(priv->ioaddr);
9297ac6653aSJeff Kirsher 
9307ac6653aSJeff Kirsher 	/* Set the HW DMA mode and the COE */
9317ac6653aSJeff Kirsher 	stmmac_dma_operation_mode(priv);
9327ac6653aSJeff Kirsher 
9337ac6653aSJeff Kirsher 	/* Extra statistics */
9347ac6653aSJeff Kirsher 	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
9357ac6653aSJeff Kirsher 	priv->xstats.threshold = tc;
9367ac6653aSJeff Kirsher 
9371c901a46SGiuseppe CAVALLARO 	stmmac_mmc_setup(priv);
9381c901a46SGiuseppe CAVALLARO 
9397ac6653aSJeff Kirsher 	/* Start the ball rolling... */
9407ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
9417ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
9427ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
9437ac6653aSJeff Kirsher 
9447ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
9457ac6653aSJeff Kirsher 	priv->tm->timer_start(tmrate);
9467ac6653aSJeff Kirsher #endif
9477ac6653aSJeff Kirsher 	/* Dump DMA/MAC registers */
9487ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
9497ac6653aSJeff Kirsher 		priv->hw->mac->dump_regs(priv->ioaddr);
9507ac6653aSJeff Kirsher 		priv->hw->dma->dump_regs(priv->ioaddr);
9517ac6653aSJeff Kirsher 	}
9527ac6653aSJeff Kirsher 
9537ac6653aSJeff Kirsher 	if (priv->phydev)
9547ac6653aSJeff Kirsher 		phy_start(priv->phydev);
9557ac6653aSJeff Kirsher 
9567ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
9577ac6653aSJeff Kirsher 	skb_queue_head_init(&priv->rx_recycle);
9587ac6653aSJeff Kirsher 	netif_start_queue(dev);
9597ac6653aSJeff Kirsher 
9607ac6653aSJeff Kirsher 	return 0;
9617ac6653aSJeff Kirsher 
9627ac6653aSJeff Kirsher open_error:
9637ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
9647ac6653aSJeff Kirsher 	kfree(priv->tm);
9657ac6653aSJeff Kirsher #endif
9667ac6653aSJeff Kirsher 	if (priv->phydev)
9677ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
9687ac6653aSJeff Kirsher 
9697ac6653aSJeff Kirsher 	return ret;
9707ac6653aSJeff Kirsher }
9717ac6653aSJeff Kirsher 
9727ac6653aSJeff Kirsher /**
9737ac6653aSJeff Kirsher  *  stmmac_release - close entry point of the driver
9747ac6653aSJeff Kirsher  *  @dev : device pointer.
9757ac6653aSJeff Kirsher  *  Description:
9767ac6653aSJeff Kirsher  *  This is the stop entry point of the driver.
9777ac6653aSJeff Kirsher  */
9787ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev)
9797ac6653aSJeff Kirsher {
9807ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
9817ac6653aSJeff Kirsher 
9827ac6653aSJeff Kirsher 	/* Stop and disconnect the PHY */
9837ac6653aSJeff Kirsher 	if (priv->phydev) {
9847ac6653aSJeff Kirsher 		phy_stop(priv->phydev);
9857ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
9867ac6653aSJeff Kirsher 		priv->phydev = NULL;
9877ac6653aSJeff Kirsher 	}
9887ac6653aSJeff Kirsher 
9897ac6653aSJeff Kirsher 	netif_stop_queue(dev);
9907ac6653aSJeff Kirsher 
9917ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
9927ac6653aSJeff Kirsher 	/* Stop and release the timer */
9937ac6653aSJeff Kirsher 	stmmac_close_ext_timer();
9947ac6653aSJeff Kirsher 	if (priv->tm != NULL)
9957ac6653aSJeff Kirsher 		kfree(priv->tm);
9967ac6653aSJeff Kirsher #endif
9977ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
9987ac6653aSJeff Kirsher 	skb_queue_purge(&priv->rx_recycle);
9997ac6653aSJeff Kirsher 
10007ac6653aSJeff Kirsher 	/* Free the IRQ lines */
10017ac6653aSJeff Kirsher 	free_irq(dev->irq, dev);
10027ac6653aSJeff Kirsher 
10037ac6653aSJeff Kirsher 	/* Stop TX/RX DMA and clear the descriptors */
10047ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
10057ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
10067ac6653aSJeff Kirsher 
10077ac6653aSJeff Kirsher 	/* Release and free the Rx/Tx resources */
10087ac6653aSJeff Kirsher 	free_dma_desc_resources(priv);
10097ac6653aSJeff Kirsher 
10107ac6653aSJeff Kirsher 	/* Disable the MAC Rx/Tx */
10117ac6653aSJeff Kirsher 	stmmac_disable_mac(priv->ioaddr);
10127ac6653aSJeff Kirsher 
10137ac6653aSJeff Kirsher 	netif_carrier_off(dev);
10147ac6653aSJeff Kirsher 
10157ac6653aSJeff Kirsher 	return 0;
10167ac6653aSJeff Kirsher }
10177ac6653aSJeff Kirsher 
10187ac6653aSJeff Kirsher static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
10197ac6653aSJeff Kirsher 					       struct net_device *dev,
10207ac6653aSJeff Kirsher 					       int csum_insertion)
10217ac6653aSJeff Kirsher {
10227ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
10237ac6653aSJeff Kirsher 	unsigned int nopaged_len = skb_headlen(skb);
10247ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
10257ac6653aSJeff Kirsher 	unsigned int entry = priv->cur_tx % txsize;
10267ac6653aSJeff Kirsher 	struct dma_desc *desc = priv->dma_tx + entry;
10277ac6653aSJeff Kirsher 
10287ac6653aSJeff Kirsher 	if (nopaged_len > BUF_SIZE_8KiB) {
10297ac6653aSJeff Kirsher 
10307ac6653aSJeff Kirsher 		int buf2_size = nopaged_len - BUF_SIZE_8KiB;
10317ac6653aSJeff Kirsher 
10327ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device, skb->data,
10337ac6653aSJeff Kirsher 					    BUF_SIZE_8KiB, DMA_TO_DEVICE);
10347ac6653aSJeff Kirsher 		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
10357ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
10367ac6653aSJeff Kirsher 						csum_insertion);
10377ac6653aSJeff Kirsher 
10387ac6653aSJeff Kirsher 		entry = (++priv->cur_tx) % txsize;
10397ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
10407ac6653aSJeff Kirsher 
10417ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device,
10427ac6653aSJeff Kirsher 					skb->data + BUF_SIZE_8KiB,
10437ac6653aSJeff Kirsher 					buf2_size, DMA_TO_DEVICE);
10447ac6653aSJeff Kirsher 		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
10457ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
10467ac6653aSJeff Kirsher 						csum_insertion);
10477ac6653aSJeff Kirsher 		priv->hw->desc->set_tx_owner(desc);
10487ac6653aSJeff Kirsher 		priv->tx_skbuff[entry] = NULL;
10497ac6653aSJeff Kirsher 	} else {
10507ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device, skb->data,
10517ac6653aSJeff Kirsher 					nopaged_len, DMA_TO_DEVICE);
10527ac6653aSJeff Kirsher 		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
10537ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
10547ac6653aSJeff Kirsher 						csum_insertion);
10557ac6653aSJeff Kirsher 	}
10567ac6653aSJeff Kirsher 	return entry;
10577ac6653aSJeff Kirsher }
10587ac6653aSJeff Kirsher 
10597ac6653aSJeff Kirsher /**
10607ac6653aSJeff Kirsher  *  stmmac_xmit:
10617ac6653aSJeff Kirsher  *  @skb : the socket buffer
10627ac6653aSJeff Kirsher  *  @dev : device pointer
10637ac6653aSJeff Kirsher  *  Description : Tx entry point of the driver.
10647ac6653aSJeff Kirsher  */
10657ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
10667ac6653aSJeff Kirsher {
10677ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
10687ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
10697ac6653aSJeff Kirsher 	unsigned int entry;
10707ac6653aSJeff Kirsher 	int i, csum_insertion = 0;
10717ac6653aSJeff Kirsher 	int nfrags = skb_shinfo(skb)->nr_frags;
10727ac6653aSJeff Kirsher 	struct dma_desc *desc, *first;
10737ac6653aSJeff Kirsher 
10747ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
10757ac6653aSJeff Kirsher 		if (!netif_queue_stopped(dev)) {
10767ac6653aSJeff Kirsher 			netif_stop_queue(dev);
10777ac6653aSJeff Kirsher 			/* This is a hard error, log it. */
10787ac6653aSJeff Kirsher 			pr_err("%s: BUG! Tx Ring full when queue awake\n",
10797ac6653aSJeff Kirsher 				__func__);
10807ac6653aSJeff Kirsher 		}
10817ac6653aSJeff Kirsher 		return NETDEV_TX_BUSY;
10827ac6653aSJeff Kirsher 	}
10837ac6653aSJeff Kirsher 
1084a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
1085a9097a96SGiuseppe CAVALLARO 
10867ac6653aSJeff Kirsher 	entry = priv->cur_tx % txsize;
10877ac6653aSJeff Kirsher 
10887ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
10897ac6653aSJeff Kirsher 	if ((skb->len > ETH_FRAME_LEN) || nfrags)
10907ac6653aSJeff Kirsher 		pr_info("stmmac xmit:\n"
10917ac6653aSJeff Kirsher 		       "\tskb addr %p - len: %d - nopaged_len: %d\n"
10927ac6653aSJeff Kirsher 		       "\tn_frags: %d - ip_summed: %d - %s gso\n",
10937ac6653aSJeff Kirsher 		       skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
10947ac6653aSJeff Kirsher 		       !skb_is_gso(skb) ? "isn't" : "is");
10957ac6653aSJeff Kirsher #endif
10967ac6653aSJeff Kirsher 
10977ac6653aSJeff Kirsher 	csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
10987ac6653aSJeff Kirsher 
10997ac6653aSJeff Kirsher 	desc = priv->dma_tx + entry;
11007ac6653aSJeff Kirsher 	first = desc;
11017ac6653aSJeff Kirsher 
11027ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
11037ac6653aSJeff Kirsher 	if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
11047ac6653aSJeff Kirsher 		pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
11057ac6653aSJeff Kirsher 		       "\t\tn_frags: %d, ip_summed: %d\n",
11067ac6653aSJeff Kirsher 		       skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
11077ac6653aSJeff Kirsher #endif
11087ac6653aSJeff Kirsher 	priv->tx_skbuff[entry] = skb;
11097ac6653aSJeff Kirsher 	if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
11107ac6653aSJeff Kirsher 		entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
11117ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
11127ac6653aSJeff Kirsher 	} else {
11137ac6653aSJeff Kirsher 		unsigned int nopaged_len = skb_headlen(skb);
11147ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device, skb->data,
11157ac6653aSJeff Kirsher 					nopaged_len, DMA_TO_DEVICE);
11167ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
11177ac6653aSJeff Kirsher 						csum_insertion);
11187ac6653aSJeff Kirsher 	}
11197ac6653aSJeff Kirsher 
11207ac6653aSJeff Kirsher 	for (i = 0; i < nfrags; i++) {
11219e903e08SEric Dumazet 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
11229e903e08SEric Dumazet 		int len = skb_frag_size(frag);
11237ac6653aSJeff Kirsher 
11247ac6653aSJeff Kirsher 		entry = (++priv->cur_tx) % txsize;
11257ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
11267ac6653aSJeff Kirsher 
11277ac6653aSJeff Kirsher 		TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
1128f722380dSIan Campbell 		desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
1129f722380dSIan Campbell 					      DMA_TO_DEVICE);
11307ac6653aSJeff Kirsher 		priv->tx_skbuff[entry] = NULL;
11317ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
11327ac6653aSJeff Kirsher 		wmb();
11337ac6653aSJeff Kirsher 		priv->hw->desc->set_tx_owner(desc);
11347ac6653aSJeff Kirsher 	}
11357ac6653aSJeff Kirsher 
11367ac6653aSJeff Kirsher 	/* Interrupt on completition only for the latest segment */
11377ac6653aSJeff Kirsher 	priv->hw->desc->close_tx_desc(desc);
11387ac6653aSJeff Kirsher 
11397ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
11407ac6653aSJeff Kirsher 	/* Clean IC while using timer */
11417ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
11427ac6653aSJeff Kirsher 		priv->hw->desc->clear_tx_ic(desc);
11437ac6653aSJeff Kirsher #endif
11447ac6653aSJeff Kirsher 
11457ac6653aSJeff Kirsher 	wmb();
11467ac6653aSJeff Kirsher 
11477ac6653aSJeff Kirsher 	/* To avoid raise condition */
11487ac6653aSJeff Kirsher 	priv->hw->desc->set_tx_owner(first);
11497ac6653aSJeff Kirsher 
11507ac6653aSJeff Kirsher 	priv->cur_tx++;
11517ac6653aSJeff Kirsher 
11527ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
11537ac6653aSJeff Kirsher 	if (netif_msg_pktdata(priv)) {
11547ac6653aSJeff Kirsher 		pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
11557ac6653aSJeff Kirsher 		       "first=%p, nfrags=%d\n",
11567ac6653aSJeff Kirsher 		       (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
11577ac6653aSJeff Kirsher 		       entry, first, nfrags);
11587ac6653aSJeff Kirsher 		display_ring(priv->dma_tx, txsize);
11597ac6653aSJeff Kirsher 		pr_info(">>> frame to be transmitted: ");
11607ac6653aSJeff Kirsher 		print_pkt(skb->data, skb->len);
11617ac6653aSJeff Kirsher 	}
11627ac6653aSJeff Kirsher #endif
11637ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
11647ac6653aSJeff Kirsher 		TX_DBG("%s: stop transmitted packets\n", __func__);
11657ac6653aSJeff Kirsher 		netif_stop_queue(dev);
11667ac6653aSJeff Kirsher 	}
11677ac6653aSJeff Kirsher 
11687ac6653aSJeff Kirsher 	dev->stats.tx_bytes += skb->len;
11697ac6653aSJeff Kirsher 
11707ac6653aSJeff Kirsher 	skb_tx_timestamp(skb);
11717ac6653aSJeff Kirsher 
11727ac6653aSJeff Kirsher 	priv->hw->dma->enable_dma_transmission(priv->ioaddr);
11737ac6653aSJeff Kirsher 
1174a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
1175a9097a96SGiuseppe CAVALLARO 
11767ac6653aSJeff Kirsher 	return NETDEV_TX_OK;
11777ac6653aSJeff Kirsher }
11787ac6653aSJeff Kirsher 
11797ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv)
11807ac6653aSJeff Kirsher {
11817ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
11827ac6653aSJeff Kirsher 	int bfsize = priv->dma_buf_sz;
11837ac6653aSJeff Kirsher 	struct dma_desc *p = priv->dma_rx;
11847ac6653aSJeff Kirsher 
11857ac6653aSJeff Kirsher 	for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
11867ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_rx % rxsize;
11877ac6653aSJeff Kirsher 		if (likely(priv->rx_skbuff[entry] == NULL)) {
11887ac6653aSJeff Kirsher 			struct sk_buff *skb;
11897ac6653aSJeff Kirsher 
11907ac6653aSJeff Kirsher 			skb = __skb_dequeue(&priv->rx_recycle);
11917ac6653aSJeff Kirsher 			if (skb == NULL)
11927ac6653aSJeff Kirsher 				skb = netdev_alloc_skb_ip_align(priv->dev,
11937ac6653aSJeff Kirsher 								bfsize);
11947ac6653aSJeff Kirsher 
11957ac6653aSJeff Kirsher 			if (unlikely(skb == NULL))
11967ac6653aSJeff Kirsher 				break;
11977ac6653aSJeff Kirsher 
11987ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = skb;
11997ac6653aSJeff Kirsher 			priv->rx_skbuff_dma[entry] =
12007ac6653aSJeff Kirsher 			    dma_map_single(priv->device, skb->data, bfsize,
12017ac6653aSJeff Kirsher 					   DMA_FROM_DEVICE);
12027ac6653aSJeff Kirsher 
12037ac6653aSJeff Kirsher 			(p + entry)->des2 = priv->rx_skbuff_dma[entry];
12047ac6653aSJeff Kirsher 			if (unlikely(priv->plat->has_gmac)) {
12057ac6653aSJeff Kirsher 				if (bfsize >= BUF_SIZE_8KiB)
12067ac6653aSJeff Kirsher 					(p + entry)->des3 =
12077ac6653aSJeff Kirsher 					    (p + entry)->des2 + BUF_SIZE_8KiB;
12087ac6653aSJeff Kirsher 			}
12097ac6653aSJeff Kirsher 			RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
12107ac6653aSJeff Kirsher 		}
12117ac6653aSJeff Kirsher 		wmb();
12127ac6653aSJeff Kirsher 		priv->hw->desc->set_rx_owner(p + entry);
12137ac6653aSJeff Kirsher 	}
12147ac6653aSJeff Kirsher }
12157ac6653aSJeff Kirsher 
12167ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit)
12177ac6653aSJeff Kirsher {
12187ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
12197ac6653aSJeff Kirsher 	unsigned int entry = priv->cur_rx % rxsize;
12207ac6653aSJeff Kirsher 	unsigned int next_entry;
12217ac6653aSJeff Kirsher 	unsigned int count = 0;
12227ac6653aSJeff Kirsher 	struct dma_desc *p = priv->dma_rx + entry;
12237ac6653aSJeff Kirsher 	struct dma_desc *p_next;
12247ac6653aSJeff Kirsher 
12257ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
12267ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
12277ac6653aSJeff Kirsher 		pr_debug(">>> stmmac_rx: descriptor ring:\n");
12287ac6653aSJeff Kirsher 		display_ring(priv->dma_rx, rxsize);
12297ac6653aSJeff Kirsher 	}
12307ac6653aSJeff Kirsher #endif
12317ac6653aSJeff Kirsher 	count = 0;
12327ac6653aSJeff Kirsher 	while (!priv->hw->desc->get_rx_owner(p)) {
12337ac6653aSJeff Kirsher 		int status;
12347ac6653aSJeff Kirsher 
12357ac6653aSJeff Kirsher 		if (count >= limit)
12367ac6653aSJeff Kirsher 			break;
12377ac6653aSJeff Kirsher 
12387ac6653aSJeff Kirsher 		count++;
12397ac6653aSJeff Kirsher 
12407ac6653aSJeff Kirsher 		next_entry = (++priv->cur_rx) % rxsize;
12417ac6653aSJeff Kirsher 		p_next = priv->dma_rx + next_entry;
12427ac6653aSJeff Kirsher 		prefetch(p_next);
12437ac6653aSJeff Kirsher 
12447ac6653aSJeff Kirsher 		/* read the status of the incoming frame */
12457ac6653aSJeff Kirsher 		status = (priv->hw->desc->rx_status(&priv->dev->stats,
12467ac6653aSJeff Kirsher 						    &priv->xstats, p));
12477ac6653aSJeff Kirsher 		if (unlikely(status == discard_frame))
12487ac6653aSJeff Kirsher 			priv->dev->stats.rx_errors++;
12497ac6653aSJeff Kirsher 		else {
12507ac6653aSJeff Kirsher 			struct sk_buff *skb;
12517ac6653aSJeff Kirsher 			int frame_len;
12527ac6653aSJeff Kirsher 
12537ac6653aSJeff Kirsher 			frame_len = priv->hw->desc->get_rx_frame_len(p);
12547ac6653aSJeff Kirsher 			/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
12557ac6653aSJeff Kirsher 			 * Type frames (LLC/LLC-SNAP) */
12567ac6653aSJeff Kirsher 			if (unlikely(status != llc_snap))
12577ac6653aSJeff Kirsher 				frame_len -= ETH_FCS_LEN;
12587ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
12597ac6653aSJeff Kirsher 			if (frame_len > ETH_FRAME_LEN)
12607ac6653aSJeff Kirsher 				pr_debug("\tRX frame size %d, COE status: %d\n",
12617ac6653aSJeff Kirsher 					frame_len, status);
12627ac6653aSJeff Kirsher 
12637ac6653aSJeff Kirsher 			if (netif_msg_hw(priv))
12647ac6653aSJeff Kirsher 				pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
12657ac6653aSJeff Kirsher 					p, entry, p->des2);
12667ac6653aSJeff Kirsher #endif
12677ac6653aSJeff Kirsher 			skb = priv->rx_skbuff[entry];
12687ac6653aSJeff Kirsher 			if (unlikely(!skb)) {
12697ac6653aSJeff Kirsher 				pr_err("%s: Inconsistent Rx descriptor chain\n",
12707ac6653aSJeff Kirsher 					priv->dev->name);
12717ac6653aSJeff Kirsher 				priv->dev->stats.rx_dropped++;
12727ac6653aSJeff Kirsher 				break;
12737ac6653aSJeff Kirsher 			}
12747ac6653aSJeff Kirsher 			prefetch(skb->data - NET_IP_ALIGN);
12757ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = NULL;
12767ac6653aSJeff Kirsher 
12777ac6653aSJeff Kirsher 			skb_put(skb, frame_len);
12787ac6653aSJeff Kirsher 			dma_unmap_single(priv->device,
12797ac6653aSJeff Kirsher 					 priv->rx_skbuff_dma[entry],
12807ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
12817ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
12827ac6653aSJeff Kirsher 			if (netif_msg_pktdata(priv)) {
12837ac6653aSJeff Kirsher 				pr_info(" frame received (%dbytes)", frame_len);
12847ac6653aSJeff Kirsher 				print_pkt(skb->data, frame_len);
12857ac6653aSJeff Kirsher 			}
12867ac6653aSJeff Kirsher #endif
12877ac6653aSJeff Kirsher 			skb->protocol = eth_type_trans(skb, priv->dev);
12887ac6653aSJeff Kirsher 
12897ac6653aSJeff Kirsher 			if (unlikely(status == csum_none)) {
12907ac6653aSJeff Kirsher 				/* always for the old mac 10/100 */
12917ac6653aSJeff Kirsher 				skb_checksum_none_assert(skb);
12927ac6653aSJeff Kirsher 				netif_receive_skb(skb);
12937ac6653aSJeff Kirsher 			} else {
12947ac6653aSJeff Kirsher 				skb->ip_summed = CHECKSUM_UNNECESSARY;
12957ac6653aSJeff Kirsher 				napi_gro_receive(&priv->napi, skb);
12967ac6653aSJeff Kirsher 			}
12977ac6653aSJeff Kirsher 
12987ac6653aSJeff Kirsher 			priv->dev->stats.rx_packets++;
12997ac6653aSJeff Kirsher 			priv->dev->stats.rx_bytes += frame_len;
13007ac6653aSJeff Kirsher 		}
13017ac6653aSJeff Kirsher 		entry = next_entry;
13027ac6653aSJeff Kirsher 		p = p_next;	/* use prefetched values */
13037ac6653aSJeff Kirsher 	}
13047ac6653aSJeff Kirsher 
13057ac6653aSJeff Kirsher 	stmmac_rx_refill(priv);
13067ac6653aSJeff Kirsher 
13077ac6653aSJeff Kirsher 	priv->xstats.rx_pkt_n += count;
13087ac6653aSJeff Kirsher 
13097ac6653aSJeff Kirsher 	return count;
13107ac6653aSJeff Kirsher }
13117ac6653aSJeff Kirsher 
13127ac6653aSJeff Kirsher /**
13137ac6653aSJeff Kirsher  *  stmmac_poll - stmmac poll method (NAPI)
13147ac6653aSJeff Kirsher  *  @napi : pointer to the napi structure.
13157ac6653aSJeff Kirsher  *  @budget : maximum number of packets that the current CPU can receive from
13167ac6653aSJeff Kirsher  *	      all interfaces.
13177ac6653aSJeff Kirsher  *  Description :
13187ac6653aSJeff Kirsher  *   This function implements the the reception process.
13197ac6653aSJeff Kirsher  *   Also it runs the TX completion thread
13207ac6653aSJeff Kirsher  */
13217ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget)
13227ac6653aSJeff Kirsher {
13237ac6653aSJeff Kirsher 	struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
13247ac6653aSJeff Kirsher 	int work_done = 0;
13257ac6653aSJeff Kirsher 
13267ac6653aSJeff Kirsher 	priv->xstats.poll_n++;
13277ac6653aSJeff Kirsher 	stmmac_tx(priv);
13287ac6653aSJeff Kirsher 	work_done = stmmac_rx(priv, budget);
13297ac6653aSJeff Kirsher 
13307ac6653aSJeff Kirsher 	if (work_done < budget) {
13317ac6653aSJeff Kirsher 		napi_complete(napi);
13327ac6653aSJeff Kirsher 		stmmac_enable_irq(priv);
13337ac6653aSJeff Kirsher 	}
13347ac6653aSJeff Kirsher 	return work_done;
13357ac6653aSJeff Kirsher }
13367ac6653aSJeff Kirsher 
13377ac6653aSJeff Kirsher /**
13387ac6653aSJeff Kirsher  *  stmmac_tx_timeout
13397ac6653aSJeff Kirsher  *  @dev : Pointer to net device structure
13407ac6653aSJeff Kirsher  *  Description: this function is called when a packet transmission fails to
13417ac6653aSJeff Kirsher  *   complete within a reasonable tmrate. The driver will mark the error in the
13427ac6653aSJeff Kirsher  *   netdev structure and arrange for the device to be reset to a sane state
13437ac6653aSJeff Kirsher  *   in order to transmit a new packet.
13447ac6653aSJeff Kirsher  */
13457ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev)
13467ac6653aSJeff Kirsher {
13477ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
13487ac6653aSJeff Kirsher 
13497ac6653aSJeff Kirsher 	/* Clear Tx resources and restart transmitting again */
13507ac6653aSJeff Kirsher 	stmmac_tx_err(priv);
13517ac6653aSJeff Kirsher }
13527ac6653aSJeff Kirsher 
13537ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */
13547ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map)
13557ac6653aSJeff Kirsher {
13567ac6653aSJeff Kirsher 	if (dev->flags & IFF_UP)	/* can't act on a running interface */
13577ac6653aSJeff Kirsher 		return -EBUSY;
13587ac6653aSJeff Kirsher 
13597ac6653aSJeff Kirsher 	/* Don't allow changing the I/O address */
13607ac6653aSJeff Kirsher 	if (map->base_addr != dev->base_addr) {
13617ac6653aSJeff Kirsher 		pr_warning("%s: can't change I/O address\n", dev->name);
13627ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
13637ac6653aSJeff Kirsher 	}
13647ac6653aSJeff Kirsher 
13657ac6653aSJeff Kirsher 	/* Don't allow changing the IRQ */
13667ac6653aSJeff Kirsher 	if (map->irq != dev->irq) {
13677ac6653aSJeff Kirsher 		pr_warning("%s: can't change IRQ number %d\n",
13687ac6653aSJeff Kirsher 		       dev->name, dev->irq);
13697ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
13707ac6653aSJeff Kirsher 	}
13717ac6653aSJeff Kirsher 
13727ac6653aSJeff Kirsher 	/* ignore other fields */
13737ac6653aSJeff Kirsher 	return 0;
13747ac6653aSJeff Kirsher }
13757ac6653aSJeff Kirsher 
13767ac6653aSJeff Kirsher /**
137701789349SJiri Pirko  *  stmmac_set_rx_mode - entry point for multicast addressing
13787ac6653aSJeff Kirsher  *  @dev : pointer to the device structure
13797ac6653aSJeff Kirsher  *  Description:
13807ac6653aSJeff Kirsher  *  This function is a driver entry point which gets called by the kernel
13817ac6653aSJeff Kirsher  *  whenever multicast addresses must be enabled/disabled.
13827ac6653aSJeff Kirsher  *  Return value:
13837ac6653aSJeff Kirsher  *  void.
13847ac6653aSJeff Kirsher  */
138501789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev)
13867ac6653aSJeff Kirsher {
13877ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
13887ac6653aSJeff Kirsher 
13897ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
13907ac6653aSJeff Kirsher 	priv->hw->mac->set_filter(dev);
13917ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
13927ac6653aSJeff Kirsher }
13937ac6653aSJeff Kirsher 
13947ac6653aSJeff Kirsher /**
13957ac6653aSJeff Kirsher  *  stmmac_change_mtu - entry point to change MTU size for the device.
13967ac6653aSJeff Kirsher  *  @dev : device pointer.
13977ac6653aSJeff Kirsher  *  @new_mtu : the new MTU size for the device.
13987ac6653aSJeff Kirsher  *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
13997ac6653aSJeff Kirsher  *  to drive packet transmission. Ethernet has an MTU of 1500 octets
14007ac6653aSJeff Kirsher  *  (ETH_DATA_LEN). This value can be changed with ifconfig.
14017ac6653aSJeff Kirsher  *  Return value:
14027ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
14037ac6653aSJeff Kirsher  *  file on failure.
14047ac6653aSJeff Kirsher  */
14057ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
14067ac6653aSJeff Kirsher {
14077ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
14087ac6653aSJeff Kirsher 	int max_mtu;
14097ac6653aSJeff Kirsher 
14107ac6653aSJeff Kirsher 	if (netif_running(dev)) {
14117ac6653aSJeff Kirsher 		pr_err("%s: must be stopped to change its MTU\n", dev->name);
14127ac6653aSJeff Kirsher 		return -EBUSY;
14137ac6653aSJeff Kirsher 	}
14147ac6653aSJeff Kirsher 
141548febf7eSGiuseppe CAVALLARO 	if (priv->plat->enh_desc)
14167ac6653aSJeff Kirsher 		max_mtu = JUMBO_LEN;
14177ac6653aSJeff Kirsher 	else
141848febf7eSGiuseppe CAVALLARO 		max_mtu = BUF_SIZE_4KiB;
14197ac6653aSJeff Kirsher 
14207ac6653aSJeff Kirsher 	if ((new_mtu < 46) || (new_mtu > max_mtu)) {
14217ac6653aSJeff Kirsher 		pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
14227ac6653aSJeff Kirsher 		return -EINVAL;
14237ac6653aSJeff Kirsher 	}
14247ac6653aSJeff Kirsher 
14257ac6653aSJeff Kirsher 	dev->mtu = new_mtu;
14267ac6653aSJeff Kirsher 	netdev_update_features(dev);
14277ac6653aSJeff Kirsher 
14287ac6653aSJeff Kirsher 	return 0;
14297ac6653aSJeff Kirsher }
14307ac6653aSJeff Kirsher 
14317ac6653aSJeff Kirsher static u32 stmmac_fix_features(struct net_device *dev, u32 features)
14327ac6653aSJeff Kirsher {
14337ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
14347ac6653aSJeff Kirsher 
14357ac6653aSJeff Kirsher 	if (!priv->rx_coe)
14367ac6653aSJeff Kirsher 		features &= ~NETIF_F_RXCSUM;
14377ac6653aSJeff Kirsher 	if (!priv->plat->tx_coe)
14387ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
14397ac6653aSJeff Kirsher 
14407ac6653aSJeff Kirsher 	/* Some GMAC devices have a bugged Jumbo frame support that
14417ac6653aSJeff Kirsher 	 * needs to have the Tx COE disabled for oversized frames
14427ac6653aSJeff Kirsher 	 * (due to limited buffer sizes). In this case we disable
14437ac6653aSJeff Kirsher 	 * the TX csum insertionin the TDES and not use SF. */
14447ac6653aSJeff Kirsher 	if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
14457ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
14467ac6653aSJeff Kirsher 
14477ac6653aSJeff Kirsher 	return features;
14487ac6653aSJeff Kirsher }
14497ac6653aSJeff Kirsher 
14507ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
14517ac6653aSJeff Kirsher {
14527ac6653aSJeff Kirsher 	struct net_device *dev = (struct net_device *)dev_id;
14537ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
14547ac6653aSJeff Kirsher 
14557ac6653aSJeff Kirsher 	if (unlikely(!dev)) {
14567ac6653aSJeff Kirsher 		pr_err("%s: invalid dev pointer\n", __func__);
14577ac6653aSJeff Kirsher 		return IRQ_NONE;
14587ac6653aSJeff Kirsher 	}
14597ac6653aSJeff Kirsher 
14607ac6653aSJeff Kirsher 	if (priv->plat->has_gmac)
14617ac6653aSJeff Kirsher 		/* To handle GMAC own interrupts */
14627ac6653aSJeff Kirsher 		priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
14637ac6653aSJeff Kirsher 
14647ac6653aSJeff Kirsher 	stmmac_dma_interrupt(priv);
14657ac6653aSJeff Kirsher 
14667ac6653aSJeff Kirsher 	return IRQ_HANDLED;
14677ac6653aSJeff Kirsher }
14687ac6653aSJeff Kirsher 
14697ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
14707ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools
14717ac6653aSJeff Kirsher  * to allow network I/O with interrupts disabled. */
14727ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev)
14737ac6653aSJeff Kirsher {
14747ac6653aSJeff Kirsher 	disable_irq(dev->irq);
14757ac6653aSJeff Kirsher 	stmmac_interrupt(dev->irq, dev);
14767ac6653aSJeff Kirsher 	enable_irq(dev->irq);
14777ac6653aSJeff Kirsher }
14787ac6653aSJeff Kirsher #endif
14797ac6653aSJeff Kirsher 
14807ac6653aSJeff Kirsher /**
14817ac6653aSJeff Kirsher  *  stmmac_ioctl - Entry point for the Ioctl
14827ac6653aSJeff Kirsher  *  @dev: Device pointer.
14837ac6653aSJeff Kirsher  *  @rq: An IOCTL specefic structure, that can contain a pointer to
14847ac6653aSJeff Kirsher  *  a proprietary structure used to pass information to the driver.
14857ac6653aSJeff Kirsher  *  @cmd: IOCTL command
14867ac6653aSJeff Kirsher  *  Description:
14877ac6653aSJeff Kirsher  *  Currently there are no special functionality supported in IOCTL, just the
14887ac6653aSJeff Kirsher  *  phy_mii_ioctl(...) can be invoked.
14897ac6653aSJeff Kirsher  */
14907ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
14917ac6653aSJeff Kirsher {
14927ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
14937ac6653aSJeff Kirsher 	int ret;
14947ac6653aSJeff Kirsher 
14957ac6653aSJeff Kirsher 	if (!netif_running(dev))
14967ac6653aSJeff Kirsher 		return -EINVAL;
14977ac6653aSJeff Kirsher 
14987ac6653aSJeff Kirsher 	if (!priv->phydev)
14997ac6653aSJeff Kirsher 		return -EINVAL;
15007ac6653aSJeff Kirsher 
15017ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
15027ac6653aSJeff Kirsher 	ret = phy_mii_ioctl(priv->phydev, rq, cmd);
15037ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
15047ac6653aSJeff Kirsher 
15057ac6653aSJeff Kirsher 	return ret;
15067ac6653aSJeff Kirsher }
15077ac6653aSJeff Kirsher 
15087ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
15097ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir;
15107ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status;
1511e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap;
15127ac29055SGiuseppe CAVALLARO 
15137ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
15147ac29055SGiuseppe CAVALLARO {
15157ac29055SGiuseppe CAVALLARO 	struct tmp_s {
15167ac29055SGiuseppe CAVALLARO 		u64 a;
15177ac29055SGiuseppe CAVALLARO 		unsigned int b;
15187ac29055SGiuseppe CAVALLARO 		unsigned int c;
15197ac29055SGiuseppe CAVALLARO 	};
15207ac29055SGiuseppe CAVALLARO 	int i;
15217ac29055SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
15227ac29055SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
15237ac29055SGiuseppe CAVALLARO 
15247ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
15257ac29055SGiuseppe CAVALLARO 	seq_printf(seq, " RX descriptor ring\n");
15267ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
15277ac29055SGiuseppe CAVALLARO 
15287ac29055SGiuseppe CAVALLARO 	for (i = 0; i < priv->dma_rx_size; i++) {
15297ac29055SGiuseppe CAVALLARO 		struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i);
15307ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
15317ac29055SGiuseppe CAVALLARO 			   i, (unsigned int)(x->a),
15327ac29055SGiuseppe CAVALLARO 			   (unsigned int)((x->a) >> 32), x->b, x->c);
15337ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
15347ac29055SGiuseppe CAVALLARO 	}
15357ac29055SGiuseppe CAVALLARO 
15367ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "\n");
15377ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
15387ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "  TX descriptor ring\n");
15397ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
15407ac29055SGiuseppe CAVALLARO 
15417ac29055SGiuseppe CAVALLARO 	for (i = 0; i < priv->dma_tx_size; i++) {
15427ac29055SGiuseppe CAVALLARO 		struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i);
15437ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
15447ac29055SGiuseppe CAVALLARO 			   i, (unsigned int)(x->a),
15457ac29055SGiuseppe CAVALLARO 			   (unsigned int)((x->a) >> 32), x->b, x->c);
15467ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
15477ac29055SGiuseppe CAVALLARO 	}
15487ac29055SGiuseppe CAVALLARO 
15497ac29055SGiuseppe CAVALLARO 	return 0;
15507ac29055SGiuseppe CAVALLARO }
15517ac29055SGiuseppe CAVALLARO 
15527ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file)
15537ac29055SGiuseppe CAVALLARO {
15547ac29055SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_ring_read, inode->i_private);
15557ac29055SGiuseppe CAVALLARO }
15567ac29055SGiuseppe CAVALLARO 
15577ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = {
15587ac29055SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
15597ac29055SGiuseppe CAVALLARO 	.open = stmmac_sysfs_ring_open,
15607ac29055SGiuseppe CAVALLARO 	.read = seq_read,
15617ac29055SGiuseppe CAVALLARO 	.llseek = seq_lseek,
15627ac29055SGiuseppe CAVALLARO 	.release = seq_release,
15637ac29055SGiuseppe CAVALLARO };
15647ac29055SGiuseppe CAVALLARO 
1565e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
1566e7434821SGiuseppe CAVALLARO {
1567e7434821SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
1568e7434821SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
1569e7434821SGiuseppe CAVALLARO 
1570e7434821SGiuseppe CAVALLARO 	if (!stmmac_get_hw_features(priv)) {
1571e7434821SGiuseppe CAVALLARO 		seq_printf(seq, "DMA HW features not supported\n");
1572e7434821SGiuseppe CAVALLARO 		return 0;
1573e7434821SGiuseppe CAVALLARO 	}
1574e7434821SGiuseppe CAVALLARO 
1575e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
1576e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tDMA HW features\n");
1577e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
1578e7434821SGiuseppe CAVALLARO 
1579e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t10/100 Mbps %s\n",
1580e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_10_100) ? "Y" : "N");
1581e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t1000 Mbps %s\n",
1582e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_1000) ? "Y" : "N");
1583e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHalf duple %s\n",
1584e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.half_duplex) ? "Y" : "N");
1585e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHash Filter: %s\n",
1586e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.hash_filter) ? "Y" : "N");
1587e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tMultiple MAC address registers: %s\n",
1588e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.multi_addr) ? "Y" : "N");
1589e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n",
1590e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pcs) ? "Y" : "N");
1591e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tSMA (MDIO) Interface: %s\n",
1592e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.sma_mdio) ? "Y" : "N");
1593e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Remote wake up: %s\n",
1594e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N");
1595e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Magic Frame: %s\n",
1596e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_magic_frame) ? "Y" : "N");
1597e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRMON module: %s\n",
1598e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rmon) ? "Y" : "N");
1599e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n",
1600e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.time_stamp) ? "Y" : "N");
1601e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n",
1602e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.atime_stamp) ? "Y" : "N");
1603e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n",
1604e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.eee) ? "Y" : "N");
1605e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N");
1606e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tChecksum Offload in TX: %s\n",
1607e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.tx_coe) ? "Y" : "N");
1608e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n",
1609e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type1) ? "Y" : "N");
1610e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
1611e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type2) ? "Y" : "N");
1612e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n",
1613e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N");
1614e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional RX channel: %d\n",
1615e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_rx_channel);
1616e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional TX channel: %d\n",
1617e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_tx_channel);
1618e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tEnhanced descriptors: %s\n",
1619e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.enh_desc) ? "Y" : "N");
1620e7434821SGiuseppe CAVALLARO 
1621e7434821SGiuseppe CAVALLARO 	return 0;
1622e7434821SGiuseppe CAVALLARO }
1623e7434821SGiuseppe CAVALLARO 
1624e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file)
1625e7434821SGiuseppe CAVALLARO {
1626e7434821SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private);
1627e7434821SGiuseppe CAVALLARO }
1628e7434821SGiuseppe CAVALLARO 
1629e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = {
1630e7434821SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
1631e7434821SGiuseppe CAVALLARO 	.open = stmmac_sysfs_dma_cap_open,
1632e7434821SGiuseppe CAVALLARO 	.read = seq_read,
1633e7434821SGiuseppe CAVALLARO 	.llseek = seq_lseek,
1634e7434821SGiuseppe CAVALLARO 	.release = seq_release,
1635e7434821SGiuseppe CAVALLARO };
1636e7434821SGiuseppe CAVALLARO 
16377ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev)
16387ac29055SGiuseppe CAVALLARO {
16397ac29055SGiuseppe CAVALLARO 	/* Create debugfs entries */
16407ac29055SGiuseppe CAVALLARO 	stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
16417ac29055SGiuseppe CAVALLARO 
16427ac29055SGiuseppe CAVALLARO 	if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
16437ac29055SGiuseppe CAVALLARO 		pr_err("ERROR %s, debugfs create directory failed\n",
16447ac29055SGiuseppe CAVALLARO 		       STMMAC_RESOURCE_NAME);
16457ac29055SGiuseppe CAVALLARO 
16467ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
16477ac29055SGiuseppe CAVALLARO 	}
16487ac29055SGiuseppe CAVALLARO 
16497ac29055SGiuseppe CAVALLARO 	/* Entry to report DMA RX/TX rings */
16507ac29055SGiuseppe CAVALLARO 	stmmac_rings_status = debugfs_create_file("descriptors_status",
16517ac29055SGiuseppe CAVALLARO 					   S_IRUGO, stmmac_fs_dir, dev,
16527ac29055SGiuseppe CAVALLARO 					   &stmmac_rings_status_fops);
16537ac29055SGiuseppe CAVALLARO 
16547ac29055SGiuseppe CAVALLARO 	if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
16557ac29055SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac ring debugfs file\n");
16567ac29055SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
16577ac29055SGiuseppe CAVALLARO 
16587ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
16597ac29055SGiuseppe CAVALLARO 	}
16607ac29055SGiuseppe CAVALLARO 
1661e7434821SGiuseppe CAVALLARO 	/* Entry to report the DMA HW features */
1662e7434821SGiuseppe CAVALLARO 	stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
1663e7434821SGiuseppe CAVALLARO 					     dev, &stmmac_dma_cap_fops);
1664e7434821SGiuseppe CAVALLARO 
1665e7434821SGiuseppe CAVALLARO 	if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
1666e7434821SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac MMC debugfs file\n");
1667e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_rings_status);
1668e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
1669e7434821SGiuseppe CAVALLARO 
1670e7434821SGiuseppe CAVALLARO 		return -ENOMEM;
1671e7434821SGiuseppe CAVALLARO 	}
1672e7434821SGiuseppe CAVALLARO 
16737ac29055SGiuseppe CAVALLARO 	return 0;
16747ac29055SGiuseppe CAVALLARO }
16757ac29055SGiuseppe CAVALLARO 
16767ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void)
16777ac29055SGiuseppe CAVALLARO {
16787ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_rings_status);
1679e7434821SGiuseppe CAVALLARO 	debugfs_remove(stmmac_dma_cap);
16807ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_fs_dir);
16817ac29055SGiuseppe CAVALLARO }
16827ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */
16837ac29055SGiuseppe CAVALLARO 
16847ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = {
16857ac6653aSJeff Kirsher 	.ndo_open = stmmac_open,
16867ac6653aSJeff Kirsher 	.ndo_start_xmit = stmmac_xmit,
16877ac6653aSJeff Kirsher 	.ndo_stop = stmmac_release,
16887ac6653aSJeff Kirsher 	.ndo_change_mtu = stmmac_change_mtu,
16897ac6653aSJeff Kirsher 	.ndo_fix_features = stmmac_fix_features,
169001789349SJiri Pirko 	.ndo_set_rx_mode = stmmac_set_rx_mode,
16917ac6653aSJeff Kirsher 	.ndo_tx_timeout = stmmac_tx_timeout,
16927ac6653aSJeff Kirsher 	.ndo_do_ioctl = stmmac_ioctl,
16937ac6653aSJeff Kirsher 	.ndo_set_config = stmmac_config,
16947ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
16957ac6653aSJeff Kirsher 	.ndo_poll_controller = stmmac_poll_controller,
16967ac6653aSJeff Kirsher #endif
16977ac6653aSJeff Kirsher 	.ndo_set_mac_address = eth_mac_addr,
16987ac6653aSJeff Kirsher };
16997ac6653aSJeff Kirsher 
17007ac6653aSJeff Kirsher /**
17017ac6653aSJeff Kirsher  * stmmac_probe - Initialization of the adapter .
17027ac6653aSJeff Kirsher  * @dev : device pointer
17037ac6653aSJeff Kirsher  * Description: The function initializes the network device structure for
17047ac6653aSJeff Kirsher  * the STMMAC driver. It also calls the low level routines
17057ac6653aSJeff Kirsher  * in order to init the HW (i.e. the DMA engine)
17067ac6653aSJeff Kirsher  */
17077ac6653aSJeff Kirsher static int stmmac_probe(struct net_device *dev)
17087ac6653aSJeff Kirsher {
17097ac6653aSJeff Kirsher 	int ret = 0;
17107ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
17117ac6653aSJeff Kirsher 
17127ac6653aSJeff Kirsher 	ether_setup(dev);
17137ac6653aSJeff Kirsher 
17147ac6653aSJeff Kirsher 	dev->netdev_ops = &stmmac_netdev_ops;
17157ac6653aSJeff Kirsher 	stmmac_set_ethtool_ops(dev);
17167ac6653aSJeff Kirsher 
17177ac6653aSJeff Kirsher 	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
17187ac6653aSJeff Kirsher 	dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
17197ac6653aSJeff Kirsher 	dev->watchdog_timeo = msecs_to_jiffies(watchdog);
17207ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED
17217ac6653aSJeff Kirsher 	/* Both mac100 and gmac support receive VLAN tag detection */
17227ac6653aSJeff Kirsher 	dev->features |= NETIF_F_HW_VLAN_RX;
17237ac6653aSJeff Kirsher #endif
17247ac6653aSJeff Kirsher 	priv->msg_enable = netif_msg_init(debug, default_msg_level);
17257ac6653aSJeff Kirsher 
17267ac6653aSJeff Kirsher 	if (flow_ctrl)
17277ac6653aSJeff Kirsher 		priv->flow_ctrl = FLOW_AUTO;	/* RX/TX pause on */
17287ac6653aSJeff Kirsher 
17297ac6653aSJeff Kirsher 	priv->pause = pause;
17307ac6653aSJeff Kirsher 	netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
17317ac6653aSJeff Kirsher 
17327ac6653aSJeff Kirsher 	/* Get the MAC address */
17337ac6653aSJeff Kirsher 	priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
17347ac6653aSJeff Kirsher 				     dev->dev_addr, 0);
17357ac6653aSJeff Kirsher 
17367ac6653aSJeff Kirsher 	if (!is_valid_ether_addr(dev->dev_addr))
17377ac6653aSJeff Kirsher 		pr_warning("\tno valid MAC address;"
17387ac6653aSJeff Kirsher 			"please, use ifconfig or nwhwconfig!\n");
17397ac6653aSJeff Kirsher 
17407ac6653aSJeff Kirsher 	spin_lock_init(&priv->lock);
1741a9097a96SGiuseppe CAVALLARO 	spin_lock_init(&priv->tx_lock);
17427ac6653aSJeff Kirsher 
17437ac6653aSJeff Kirsher 	ret = register_netdev(dev);
17447ac6653aSJeff Kirsher 	if (ret) {
17457ac6653aSJeff Kirsher 		pr_err("%s: ERROR %i registering the device\n",
17467ac6653aSJeff Kirsher 		       __func__, ret);
17477ac6653aSJeff Kirsher 		return -ENODEV;
17487ac6653aSJeff Kirsher 	}
17497ac6653aSJeff Kirsher 
17507ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
17517ac6653aSJeff Kirsher 	    dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
17527ac6653aSJeff Kirsher 	    (dev->features & NETIF_F_IP_CSUM) ? "on" : "off");
17537ac6653aSJeff Kirsher 
17547ac6653aSJeff Kirsher 	return ret;
17557ac6653aSJeff Kirsher }
17567ac6653aSJeff Kirsher 
17577ac6653aSJeff Kirsher /**
17587ac6653aSJeff Kirsher  * stmmac_mac_device_setup
17597ac6653aSJeff Kirsher  * @dev : device pointer
17607ac6653aSJeff Kirsher  * Description: select and initialise the mac device (mac100 or Gmac).
17617ac6653aSJeff Kirsher  */
17627ac6653aSJeff Kirsher static int stmmac_mac_device_setup(struct net_device *dev)
17637ac6653aSJeff Kirsher {
17647ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
17657ac6653aSJeff Kirsher 
17667ac6653aSJeff Kirsher 	struct mac_device_info *device;
17677ac6653aSJeff Kirsher 
176801789349SJiri Pirko 	if (priv->plat->has_gmac) {
176901789349SJiri Pirko 		dev->priv_flags |= IFF_UNICAST_FLT;
17707ac6653aSJeff Kirsher 		device = dwmac1000_setup(priv->ioaddr);
177101789349SJiri Pirko 	} else {
17727ac6653aSJeff Kirsher 		device = dwmac100_setup(priv->ioaddr);
177301789349SJiri Pirko 	}
17747ac6653aSJeff Kirsher 
17757ac6653aSJeff Kirsher 	if (!device)
17767ac6653aSJeff Kirsher 		return -ENOMEM;
17777ac6653aSJeff Kirsher 
17787ac6653aSJeff Kirsher 	if (priv->plat->enh_desc) {
17797ac6653aSJeff Kirsher 		device->desc = &enh_desc_ops;
17807ac6653aSJeff Kirsher 		pr_info("\tEnhanced descriptor structure\n");
17817ac6653aSJeff Kirsher 	} else
17827ac6653aSJeff Kirsher 		device->desc = &ndesc_ops;
17837ac6653aSJeff Kirsher 
17847ac6653aSJeff Kirsher 	priv->hw = device;
17857ac6653aSJeff Kirsher 
17867ac6653aSJeff Kirsher 	if (device_can_wakeup(priv->device)) {
17877ac6653aSJeff Kirsher 		priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
17883172d3afSDeepak Sikri 		enable_irq_wake(priv->wol_irq);
17897ac6653aSJeff Kirsher 	}
17907ac6653aSJeff Kirsher 
17917ac6653aSJeff Kirsher 	return 0;
17927ac6653aSJeff Kirsher }
17937ac6653aSJeff Kirsher 
17947ac6653aSJeff Kirsher /**
17957ac6653aSJeff Kirsher  * stmmac_dvr_probe
17967ac6653aSJeff Kirsher  * @pdev: platform device pointer
17977ac6653aSJeff Kirsher  * Description: the driver is initialized through platform_device.
17987ac6653aSJeff Kirsher  */
17997ac6653aSJeff Kirsher static int stmmac_dvr_probe(struct platform_device *pdev)
18007ac6653aSJeff Kirsher {
18017ac6653aSJeff Kirsher 	int ret = 0;
18027ac6653aSJeff Kirsher 	struct resource *res;
18037ac6653aSJeff Kirsher 	void __iomem *addr = NULL;
18047ac6653aSJeff Kirsher 	struct net_device *ndev = NULL;
18057ac6653aSJeff Kirsher 	struct stmmac_priv *priv = NULL;
18067ac6653aSJeff Kirsher 	struct plat_stmmacenet_data *plat_dat;
18077ac6653aSJeff Kirsher 
18087ac6653aSJeff Kirsher 	pr_info("STMMAC driver:\n\tplatform registration... ");
18097ac6653aSJeff Kirsher 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
18107ac6653aSJeff Kirsher 	if (!res)
18117ac6653aSJeff Kirsher 		return -ENODEV;
18127ac6653aSJeff Kirsher 	pr_info("\tdone!\n");
18137ac6653aSJeff Kirsher 
18147ac6653aSJeff Kirsher 	if (!request_mem_region(res->start, resource_size(res),
18157ac6653aSJeff Kirsher 				pdev->name)) {
18167ac6653aSJeff Kirsher 		pr_err("%s: ERROR: memory allocation failed"
18177ac6653aSJeff Kirsher 		       "cannot get the I/O addr 0x%x\n",
18187ac6653aSJeff Kirsher 		       __func__, (unsigned int)res->start);
18197ac6653aSJeff Kirsher 		return -EBUSY;
18207ac6653aSJeff Kirsher 	}
18217ac6653aSJeff Kirsher 
18227ac6653aSJeff Kirsher 	addr = ioremap(res->start, resource_size(res));
18237ac6653aSJeff Kirsher 	if (!addr) {
18247ac6653aSJeff Kirsher 		pr_err("%s: ERROR: memory mapping failed\n", __func__);
18257ac6653aSJeff Kirsher 		ret = -ENOMEM;
18267ac6653aSJeff Kirsher 		goto out_release_region;
18277ac6653aSJeff Kirsher 	}
18287ac6653aSJeff Kirsher 
18297ac6653aSJeff Kirsher 	ndev = alloc_etherdev(sizeof(struct stmmac_priv));
18307ac6653aSJeff Kirsher 	if (!ndev) {
18317ac6653aSJeff Kirsher 		pr_err("%s: ERROR: allocating the device\n", __func__);
18327ac6653aSJeff Kirsher 		ret = -ENOMEM;
18337ac6653aSJeff Kirsher 		goto out_unmap;
18347ac6653aSJeff Kirsher 	}
18357ac6653aSJeff Kirsher 
18367ac6653aSJeff Kirsher 	SET_NETDEV_DEV(ndev, &pdev->dev);
18377ac6653aSJeff Kirsher 
18387ac6653aSJeff Kirsher 	/* Get the MAC information */
18397ac6653aSJeff Kirsher 	ndev->irq = platform_get_irq_byname(pdev, "macirq");
18407ac6653aSJeff Kirsher 	if (ndev->irq == -ENXIO) {
18417ac6653aSJeff Kirsher 		pr_err("%s: ERROR: MAC IRQ configuration "
18427ac6653aSJeff Kirsher 		       "information not found\n", __func__);
18437ac6653aSJeff Kirsher 		ret = -ENXIO;
18447ac6653aSJeff Kirsher 		goto out_free_ndev;
18457ac6653aSJeff Kirsher 	}
18467ac6653aSJeff Kirsher 
18477ac6653aSJeff Kirsher 	priv = netdev_priv(ndev);
18487ac6653aSJeff Kirsher 	priv->device = &(pdev->dev);
18497ac6653aSJeff Kirsher 	priv->dev = ndev;
18507ac6653aSJeff Kirsher 	plat_dat = pdev->dev.platform_data;
18517ac6653aSJeff Kirsher 
18527ac6653aSJeff Kirsher 	priv->plat = plat_dat;
18537ac6653aSJeff Kirsher 
18547ac6653aSJeff Kirsher 	priv->ioaddr = addr;
18557ac6653aSJeff Kirsher 
18567ac6653aSJeff Kirsher 	/* PMT module is not integrated in all the MAC devices. */
18577ac6653aSJeff Kirsher 	if (plat_dat->pmt) {
18587ac6653aSJeff Kirsher 		pr_info("\tPMT module supported\n");
18597ac6653aSJeff Kirsher 		device_set_wakeup_capable(&pdev->dev, 1);
18607ac6653aSJeff Kirsher 	}
18613172d3afSDeepak Sikri 	/*
18623172d3afSDeepak Sikri 	 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
18633172d3afSDeepak Sikri 	 * The external wake up irq can be passed through the platform code
18643172d3afSDeepak Sikri 	 * named as "eth_wake_irq"
18653172d3afSDeepak Sikri 	 *
18663172d3afSDeepak Sikri 	 * In case the wake up interrupt is not passed from the platform
18673172d3afSDeepak Sikri 	 * so the driver will continue to use the mac irq (ndev->irq)
18683172d3afSDeepak Sikri 	 */
18693172d3afSDeepak Sikri 	priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
18703172d3afSDeepak Sikri 	if (priv->wol_irq == -ENXIO)
18713172d3afSDeepak Sikri 		priv->wol_irq = ndev->irq;
18723172d3afSDeepak Sikri 
18737ac6653aSJeff Kirsher 
18747ac6653aSJeff Kirsher 	platform_set_drvdata(pdev, ndev);
18757ac6653aSJeff Kirsher 
18767ac6653aSJeff Kirsher 	/* Set the I/O base addr */
18777ac6653aSJeff Kirsher 	ndev->base_addr = (unsigned long)addr;
18787ac6653aSJeff Kirsher 
18797ac6653aSJeff Kirsher 	/* Custom initialisation */
18807ac6653aSJeff Kirsher 	if (priv->plat->init) {
18817ac6653aSJeff Kirsher 		ret = priv->plat->init(pdev);
18827ac6653aSJeff Kirsher 		if (unlikely(ret))
18837ac6653aSJeff Kirsher 			goto out_free_ndev;
18847ac6653aSJeff Kirsher 	}
18857ac6653aSJeff Kirsher 
18867ac6653aSJeff Kirsher 	/* MAC HW revice detection */
18877ac6653aSJeff Kirsher 	ret = stmmac_mac_device_setup(ndev);
18887ac6653aSJeff Kirsher 	if (ret < 0)
18897ac6653aSJeff Kirsher 		goto out_plat_exit;
18907ac6653aSJeff Kirsher 
18917ac6653aSJeff Kirsher 	/* Network Device Registration */
18927ac6653aSJeff Kirsher 	ret = stmmac_probe(ndev);
18937ac6653aSJeff Kirsher 	if (ret < 0)
18947ac6653aSJeff Kirsher 		goto out_plat_exit;
18957ac6653aSJeff Kirsher 
18967ac6653aSJeff Kirsher 	/* Override with kernel parameters if supplied XXX CRS XXX
18977ac6653aSJeff Kirsher 	 * this needs to have multiple instances */
18987ac6653aSJeff Kirsher 	if ((phyaddr >= 0) && (phyaddr <= 31))
18997ac6653aSJeff Kirsher 		priv->plat->phy_addr = phyaddr;
19007ac6653aSJeff Kirsher 
19017ac6653aSJeff Kirsher 	pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
19027ac6653aSJeff Kirsher 	       "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
19037ac6653aSJeff Kirsher 	       pdev->id, ndev->irq, addr);
19047ac6653aSJeff Kirsher 
19057ac6653aSJeff Kirsher 	/* MDIO bus Registration */
19067ac6653aSJeff Kirsher 	pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
19077ac6653aSJeff Kirsher 	ret = stmmac_mdio_register(ndev);
19087ac6653aSJeff Kirsher 	if (ret < 0)
19097ac6653aSJeff Kirsher 		goto out_unregister;
19107ac6653aSJeff Kirsher 	pr_debug("registered!\n");
19117ac29055SGiuseppe CAVALLARO 
19127ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
19137ac29055SGiuseppe CAVALLARO 	ret = stmmac_init_fs(ndev);
19147ac29055SGiuseppe CAVALLARO 	if (ret < 0)
19157ac29055SGiuseppe CAVALLARO 		pr_warning("\tFailed debugFS registration");
19167ac29055SGiuseppe CAVALLARO #endif
19177ac29055SGiuseppe CAVALLARO 
19187ac6653aSJeff Kirsher 	return 0;
19197ac6653aSJeff Kirsher 
19207ac6653aSJeff Kirsher out_unregister:
19217ac6653aSJeff Kirsher 	unregister_netdev(ndev);
19227ac6653aSJeff Kirsher out_plat_exit:
19237ac6653aSJeff Kirsher 	if (priv->plat->exit)
19247ac6653aSJeff Kirsher 		priv->plat->exit(pdev);
19257ac6653aSJeff Kirsher out_free_ndev:
19267ac6653aSJeff Kirsher 	free_netdev(ndev);
19277ac6653aSJeff Kirsher 	platform_set_drvdata(pdev, NULL);
19287ac6653aSJeff Kirsher out_unmap:
19297ac6653aSJeff Kirsher 	iounmap(addr);
19307ac6653aSJeff Kirsher out_release_region:
19317ac6653aSJeff Kirsher 	release_mem_region(res->start, resource_size(res));
19327ac6653aSJeff Kirsher 
19337ac6653aSJeff Kirsher 	return ret;
19347ac6653aSJeff Kirsher }
19357ac6653aSJeff Kirsher 
19367ac6653aSJeff Kirsher /**
19377ac6653aSJeff Kirsher  * stmmac_dvr_remove
19387ac6653aSJeff Kirsher  * @pdev: platform device pointer
19397ac6653aSJeff Kirsher  * Description: this function resets the TX/RX processes, disables the MAC RX/TX
19407ac6653aSJeff Kirsher  * changes the link status, releases the DMA descriptor rings,
19417ac6653aSJeff Kirsher  * unregisters the MDIO bus and unmaps the allocated memory.
19427ac6653aSJeff Kirsher  */
19437ac6653aSJeff Kirsher static int stmmac_dvr_remove(struct platform_device *pdev)
19447ac6653aSJeff Kirsher {
19457ac6653aSJeff Kirsher 	struct net_device *ndev = platform_get_drvdata(pdev);
19467ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
19477ac6653aSJeff Kirsher 	struct resource *res;
19487ac6653aSJeff Kirsher 
19497ac6653aSJeff Kirsher 	pr_info("%s:\n\tremoving driver", __func__);
19507ac6653aSJeff Kirsher 
19517ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
19527ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
19537ac6653aSJeff Kirsher 
19547ac6653aSJeff Kirsher 	stmmac_disable_mac(priv->ioaddr);
19557ac6653aSJeff Kirsher 
19567ac6653aSJeff Kirsher 	netif_carrier_off(ndev);
19577ac6653aSJeff Kirsher 
19587ac6653aSJeff Kirsher 	stmmac_mdio_unregister(ndev);
19597ac6653aSJeff Kirsher 
19607ac6653aSJeff Kirsher 	if (priv->plat->exit)
19617ac6653aSJeff Kirsher 		priv->plat->exit(pdev);
19627ac6653aSJeff Kirsher 
19637ac6653aSJeff Kirsher 	platform_set_drvdata(pdev, NULL);
19647ac6653aSJeff Kirsher 	unregister_netdev(ndev);
19657ac6653aSJeff Kirsher 
19667ac6653aSJeff Kirsher 	iounmap((void *)priv->ioaddr);
19677ac6653aSJeff Kirsher 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
19687ac6653aSJeff Kirsher 	release_mem_region(res->start, resource_size(res));
19697ac6653aSJeff Kirsher 
19707ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
19717ac29055SGiuseppe CAVALLARO 	stmmac_exit_fs();
19727ac29055SGiuseppe CAVALLARO #endif
19737ac29055SGiuseppe CAVALLARO 
19747ac6653aSJeff Kirsher 	free_netdev(ndev);
19757ac6653aSJeff Kirsher 
19767ac6653aSJeff Kirsher 	return 0;
19777ac6653aSJeff Kirsher }
19787ac6653aSJeff Kirsher 
19797ac6653aSJeff Kirsher #ifdef CONFIG_PM
19807ac6653aSJeff Kirsher static int stmmac_suspend(struct device *dev)
19817ac6653aSJeff Kirsher {
19827ac6653aSJeff Kirsher 	struct net_device *ndev = dev_get_drvdata(dev);
19837ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
19847ac6653aSJeff Kirsher 	int dis_ic = 0;
19857ac6653aSJeff Kirsher 
19867ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
19877ac6653aSJeff Kirsher 		return 0;
19887ac6653aSJeff Kirsher 
19897ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
19907ac6653aSJeff Kirsher 
19917ac6653aSJeff Kirsher 	netif_device_detach(ndev);
19927ac6653aSJeff Kirsher 	netif_stop_queue(ndev);
19937ac6653aSJeff Kirsher 	if (priv->phydev)
19947ac6653aSJeff Kirsher 		phy_stop(priv->phydev);
19957ac6653aSJeff Kirsher 
19967ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
19977ac6653aSJeff Kirsher 	priv->tm->timer_stop();
19987ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
19997ac6653aSJeff Kirsher 		dis_ic = 1;
20007ac6653aSJeff Kirsher #endif
20017ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
20027ac6653aSJeff Kirsher 
20037ac6653aSJeff Kirsher 	/* Stop TX/RX DMA */
20047ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
20057ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
20067ac6653aSJeff Kirsher 	/* Clear the Rx/Tx descriptors */
20077ac6653aSJeff Kirsher 	priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
20087ac6653aSJeff Kirsher 				     dis_ic);
20097ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
20107ac6653aSJeff Kirsher 
20117ac6653aSJeff Kirsher 	/* Enable Power down mode by programming the PMT regs */
20127ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
20137ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
20147ac6653aSJeff Kirsher 	else
20157ac6653aSJeff Kirsher 		stmmac_disable_mac(priv->ioaddr);
20167ac6653aSJeff Kirsher 
20177ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
20187ac6653aSJeff Kirsher 	return 0;
20197ac6653aSJeff Kirsher }
20207ac6653aSJeff Kirsher 
20217ac6653aSJeff Kirsher static int stmmac_resume(struct device *dev)
20227ac6653aSJeff Kirsher {
20237ac6653aSJeff Kirsher 	struct net_device *ndev = dev_get_drvdata(dev);
20247ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
20257ac6653aSJeff Kirsher 
20267ac6653aSJeff Kirsher 	if (!netif_running(ndev))
20277ac6653aSJeff Kirsher 		return 0;
20287ac6653aSJeff Kirsher 
20297ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
20307ac6653aSJeff Kirsher 
20317ac6653aSJeff Kirsher 	/* Power Down bit, into the PM register, is cleared
20327ac6653aSJeff Kirsher 	 * automatically as soon as a magic packet or a Wake-up frame
20337ac6653aSJeff Kirsher 	 * is received. Anyway, it's better to manually clear
20347ac6653aSJeff Kirsher 	 * this bit because it can generate problems while resuming
20357ac6653aSJeff Kirsher 	 * from another devices (e.g. serial console). */
20367ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
20377ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, 0);
20387ac6653aSJeff Kirsher 
20397ac6653aSJeff Kirsher 	netif_device_attach(ndev);
20407ac6653aSJeff Kirsher 
20417ac6653aSJeff Kirsher 	/* Enable the MAC and DMA */
20427ac6653aSJeff Kirsher 	stmmac_enable_mac(priv->ioaddr);
20437ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
20447ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
20457ac6653aSJeff Kirsher 
20467ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
20477ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
20487ac6653aSJeff Kirsher 		priv->tm->timer_start(tmrate);
20497ac6653aSJeff Kirsher #endif
20507ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
20517ac6653aSJeff Kirsher 
20527ac6653aSJeff Kirsher 	if (priv->phydev)
20537ac6653aSJeff Kirsher 		phy_start(priv->phydev);
20547ac6653aSJeff Kirsher 
20557ac6653aSJeff Kirsher 	netif_start_queue(ndev);
20567ac6653aSJeff Kirsher 
20577ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
20587ac6653aSJeff Kirsher 	return 0;
20597ac6653aSJeff Kirsher }
20607ac6653aSJeff Kirsher 
20617ac6653aSJeff Kirsher static int stmmac_freeze(struct device *dev)
20627ac6653aSJeff Kirsher {
20637ac6653aSJeff Kirsher 	struct net_device *ndev = dev_get_drvdata(dev);
20647ac6653aSJeff Kirsher 
20657ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
20667ac6653aSJeff Kirsher 		return 0;
20677ac6653aSJeff Kirsher 
20687ac6653aSJeff Kirsher 	return stmmac_release(ndev);
20697ac6653aSJeff Kirsher }
20707ac6653aSJeff Kirsher 
20717ac6653aSJeff Kirsher static int stmmac_restore(struct device *dev)
20727ac6653aSJeff Kirsher {
20737ac6653aSJeff Kirsher 	struct net_device *ndev = dev_get_drvdata(dev);
20747ac6653aSJeff Kirsher 
20757ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
20767ac6653aSJeff Kirsher 		return 0;
20777ac6653aSJeff Kirsher 
20787ac6653aSJeff Kirsher 	return stmmac_open(ndev);
20797ac6653aSJeff Kirsher }
20807ac6653aSJeff Kirsher 
20817ac6653aSJeff Kirsher static const struct dev_pm_ops stmmac_pm_ops = {
20827ac6653aSJeff Kirsher 	.suspend = stmmac_suspend,
20837ac6653aSJeff Kirsher 	.resume = stmmac_resume,
20847ac6653aSJeff Kirsher 	.freeze = stmmac_freeze,
20857ac6653aSJeff Kirsher 	.thaw = stmmac_restore,
20867ac6653aSJeff Kirsher 	.restore = stmmac_restore,
20877ac6653aSJeff Kirsher };
20887ac6653aSJeff Kirsher #else
20897ac6653aSJeff Kirsher static const struct dev_pm_ops stmmac_pm_ops;
20907ac6653aSJeff Kirsher #endif /* CONFIG_PM */
20917ac6653aSJeff Kirsher 
20927ac6653aSJeff Kirsher static struct platform_driver stmmac_driver = {
20937ac6653aSJeff Kirsher 	.probe = stmmac_dvr_probe,
20947ac6653aSJeff Kirsher 	.remove = stmmac_dvr_remove,
20957ac6653aSJeff Kirsher 	.driver = {
20967ac6653aSJeff Kirsher 		.name = STMMAC_RESOURCE_NAME,
20977ac6653aSJeff Kirsher 		.owner = THIS_MODULE,
20987ac6653aSJeff Kirsher 		.pm = &stmmac_pm_ops,
20997ac6653aSJeff Kirsher 	},
21007ac6653aSJeff Kirsher };
21017ac6653aSJeff Kirsher 
21027ac6653aSJeff Kirsher /**
21037ac6653aSJeff Kirsher  * stmmac_init_module - Entry point for the driver
21047ac6653aSJeff Kirsher  * Description: This function is the entry point for the driver.
21057ac6653aSJeff Kirsher  */
21067ac6653aSJeff Kirsher static int __init stmmac_init_module(void)
21077ac6653aSJeff Kirsher {
21087ac6653aSJeff Kirsher 	int ret;
21097ac6653aSJeff Kirsher 
21107ac6653aSJeff Kirsher 	ret = platform_driver_register(&stmmac_driver);
21117ac6653aSJeff Kirsher 	return ret;
21127ac6653aSJeff Kirsher }
21137ac6653aSJeff Kirsher 
21147ac6653aSJeff Kirsher /**
21157ac6653aSJeff Kirsher  * stmmac_cleanup_module - Cleanup routine for the driver
21167ac6653aSJeff Kirsher  * Description: This function is the cleanup routine for the driver.
21177ac6653aSJeff Kirsher  */
21187ac6653aSJeff Kirsher static void __exit stmmac_cleanup_module(void)
21197ac6653aSJeff Kirsher {
21207ac6653aSJeff Kirsher 	platform_driver_unregister(&stmmac_driver);
21217ac6653aSJeff Kirsher }
21227ac6653aSJeff Kirsher 
21237ac6653aSJeff Kirsher #ifndef MODULE
21247ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str)
21257ac6653aSJeff Kirsher {
21267ac6653aSJeff Kirsher 	char *opt;
21277ac6653aSJeff Kirsher 
21287ac6653aSJeff Kirsher 	if (!str || !*str)
21297ac6653aSJeff Kirsher 		return -EINVAL;
21307ac6653aSJeff Kirsher 	while ((opt = strsep(&str, ",")) != NULL) {
21317ac6653aSJeff Kirsher 		if (!strncmp(opt, "debug:", 6)) {
21327ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug))
21337ac6653aSJeff Kirsher 				goto err;
21347ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "phyaddr:", 8)) {
21357ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 8, 0,
21367ac6653aSJeff Kirsher 					   (unsigned long *)&phyaddr))
21377ac6653aSJeff Kirsher 				goto err;
21387ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_txsize:", 11)) {
21397ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 11, 0,
21407ac6653aSJeff Kirsher 					   (unsigned long *)&dma_txsize))
21417ac6653aSJeff Kirsher 				goto err;
21427ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_rxsize:", 11)) {
21437ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 11, 0,
21447ac6653aSJeff Kirsher 					   (unsigned long *)&dma_rxsize))
21457ac6653aSJeff Kirsher 				goto err;
21467ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "buf_sz:", 7)) {
21477ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 7, 0,
21487ac6653aSJeff Kirsher 					   (unsigned long *)&buf_sz))
21497ac6653aSJeff Kirsher 				goto err;
21507ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "tc:", 3)) {
21517ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc))
21527ac6653aSJeff Kirsher 				goto err;
21537ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "watchdog:", 9)) {
21547ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 9, 0,
21557ac6653aSJeff Kirsher 					   (unsigned long *)&watchdog))
21567ac6653aSJeff Kirsher 				goto err;
21577ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "flow_ctrl:", 10)) {
21587ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 10, 0,
21597ac6653aSJeff Kirsher 					   (unsigned long *)&flow_ctrl))
21607ac6653aSJeff Kirsher 				goto err;
21617ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "pause:", 6)) {
21627ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause))
21637ac6653aSJeff Kirsher 				goto err;
21647ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
21657ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "tmrate:", 7)) {
21667ac6653aSJeff Kirsher 			if (strict_strtoul(opt + 7, 0,
21677ac6653aSJeff Kirsher 					   (unsigned long *)&tmrate))
21687ac6653aSJeff Kirsher 				goto err;
21697ac6653aSJeff Kirsher #endif
21707ac6653aSJeff Kirsher 		}
21717ac6653aSJeff Kirsher 	}
21727ac6653aSJeff Kirsher 	return 0;
21737ac6653aSJeff Kirsher 
21747ac6653aSJeff Kirsher err:
21757ac6653aSJeff Kirsher 	pr_err("%s: ERROR broken module parameter conversion", __func__);
21767ac6653aSJeff Kirsher 	return -EINVAL;
21777ac6653aSJeff Kirsher }
21787ac6653aSJeff Kirsher 
21797ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt);
21807ac6653aSJeff Kirsher #endif
21817ac6653aSJeff Kirsher 
21827ac6653aSJeff Kirsher module_init(stmmac_init_module);
21837ac6653aSJeff Kirsher module_exit(stmmac_cleanup_module);
21847ac6653aSJeff Kirsher 
21857ac6653aSJeff Kirsher MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
21867ac6653aSJeff Kirsher MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
21877ac6653aSJeff Kirsher MODULE_LICENSE("GPL");
2188