17ac6653aSJeff Kirsher /*******************************************************************************
27ac6653aSJeff Kirsher   This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
37ac6653aSJeff Kirsher   ST Ethernet IPs are built around a Synopsys IP Core.
47ac6653aSJeff Kirsher 
5286a8372SGiuseppe CAVALLARO 	Copyright(C) 2007-2011 STMicroelectronics Ltd
67ac6653aSJeff Kirsher 
77ac6653aSJeff Kirsher   This program is free software; you can redistribute it and/or modify it
87ac6653aSJeff Kirsher   under the terms and conditions of the GNU General Public License,
97ac6653aSJeff Kirsher   version 2, as published by the Free Software Foundation.
107ac6653aSJeff Kirsher 
117ac6653aSJeff Kirsher   This program is distributed in the hope it will be useful, but WITHOUT
127ac6653aSJeff Kirsher   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
137ac6653aSJeff Kirsher   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
147ac6653aSJeff Kirsher   more details.
157ac6653aSJeff Kirsher 
167ac6653aSJeff Kirsher   You should have received a copy of the GNU General Public License along with
177ac6653aSJeff Kirsher   this program; if not, write to the Free Software Foundation, Inc.,
187ac6653aSJeff Kirsher   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
197ac6653aSJeff Kirsher 
207ac6653aSJeff Kirsher   The full GNU General Public License is included in this distribution in
217ac6653aSJeff Kirsher   the file called "COPYING".
227ac6653aSJeff Kirsher 
237ac6653aSJeff Kirsher   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
247ac6653aSJeff Kirsher 
257ac6653aSJeff Kirsher   Documentation available at:
267ac6653aSJeff Kirsher 	http://www.stlinux.com
277ac6653aSJeff Kirsher   Support available at:
287ac6653aSJeff Kirsher 	https://bugzilla.stlinux.com/
297ac6653aSJeff Kirsher *******************************************************************************/
307ac6653aSJeff Kirsher 
316a81c26fSViresh Kumar #include <linux/clk.h>
327ac6653aSJeff Kirsher #include <linux/kernel.h>
337ac6653aSJeff Kirsher #include <linux/interrupt.h>
347ac6653aSJeff Kirsher #include <linux/ip.h>
357ac6653aSJeff Kirsher #include <linux/tcp.h>
367ac6653aSJeff Kirsher #include <linux/skbuff.h>
377ac6653aSJeff Kirsher #include <linux/ethtool.h>
387ac6653aSJeff Kirsher #include <linux/if_ether.h>
397ac6653aSJeff Kirsher #include <linux/crc32.h>
407ac6653aSJeff Kirsher #include <linux/mii.h>
4101789349SJiri Pirko #include <linux/if.h>
427ac6653aSJeff Kirsher #include <linux/if_vlan.h>
437ac6653aSJeff Kirsher #include <linux/dma-mapping.h>
447ac6653aSJeff Kirsher #include <linux/slab.h>
457ac6653aSJeff Kirsher #include <linux/prefetch.h>
467ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
477ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h>
487ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h>
497ac29055SGiuseppe CAVALLARO #endif
50286a8372SGiuseppe CAVALLARO #include "stmmac.h"
517ac6653aSJeff Kirsher 
527ac6653aSJeff Kirsher #undef STMMAC_DEBUG
537ac6653aSJeff Kirsher /*#define STMMAC_DEBUG*/
547ac6653aSJeff Kirsher #ifdef STMMAC_DEBUG
557ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) \
567ac6653aSJeff Kirsher 		((void)(netif_msg_##nlevel(priv) && \
577ac6653aSJeff Kirsher 		printk(KERN_##klevel fmt, ## args)))
587ac6653aSJeff Kirsher #else
597ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) do { } while (0)
607ac6653aSJeff Kirsher #endif
617ac6653aSJeff Kirsher 
627ac6653aSJeff Kirsher #undef STMMAC_RX_DEBUG
637ac6653aSJeff Kirsher /*#define STMMAC_RX_DEBUG*/
647ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
657ac6653aSJeff Kirsher #define RX_DBG(fmt, args...)  printk(fmt, ## args)
667ac6653aSJeff Kirsher #else
677ac6653aSJeff Kirsher #define RX_DBG(fmt, args...)  do { } while (0)
687ac6653aSJeff Kirsher #endif
697ac6653aSJeff Kirsher 
707ac6653aSJeff Kirsher #undef STMMAC_XMIT_DEBUG
717ac6653aSJeff Kirsher /*#define STMMAC_XMIT_DEBUG*/
727ac6653aSJeff Kirsher #ifdef STMMAC_TX_DEBUG
737ac6653aSJeff Kirsher #define TX_DBG(fmt, args...)  printk(fmt, ## args)
747ac6653aSJeff Kirsher #else
757ac6653aSJeff Kirsher #define TX_DBG(fmt, args...)  do { } while (0)
767ac6653aSJeff Kirsher #endif
777ac6653aSJeff Kirsher 
787ac6653aSJeff Kirsher #define STMMAC_ALIGN(x)	L1_CACHE_ALIGN(x)
797ac6653aSJeff Kirsher #define JUMBO_LEN	9000
807ac6653aSJeff Kirsher 
817ac6653aSJeff Kirsher /* Module parameters */
827ac6653aSJeff Kirsher #define TX_TIMEO 5000 /* default 5 seconds */
837ac6653aSJeff Kirsher static int watchdog = TX_TIMEO;
847ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR);
857ac6653aSJeff Kirsher MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
867ac6653aSJeff Kirsher 
877ac6653aSJeff Kirsher static int debug = -1;		/* -1: default, 0: no output, 16:  all */
887ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR);
897ac6653aSJeff Kirsher MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
907ac6653aSJeff Kirsher 
91bfab27a1SGiuseppe CAVALLARO int phyaddr = -1;
927ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO);
937ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address");
947ac6653aSJeff Kirsher 
957ac6653aSJeff Kirsher #define DMA_TX_SIZE 256
967ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE;
977ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
987ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
997ac6653aSJeff Kirsher 
1007ac6653aSJeff Kirsher #define DMA_RX_SIZE 256
1017ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE;
1027ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
1037ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
1047ac6653aSJeff Kirsher 
1057ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF;
1067ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
1077ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
1087ac6653aSJeff Kirsher 
1097ac6653aSJeff Kirsher static int pause = PAUSE_TIME;
1107ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR);
1117ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time");
1127ac6653aSJeff Kirsher 
1137ac6653aSJeff Kirsher #define TC_DEFAULT 64
1147ac6653aSJeff Kirsher static int tc = TC_DEFAULT;
1157ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR);
1167ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value");
1177ac6653aSJeff Kirsher 
1187ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE	BUF_SIZE_2KiB
1197ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE;
1207ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR);
1217ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size");
1227ac6653aSJeff Kirsher 
1237ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
1247ac6653aSJeff Kirsher 				      NETIF_MSG_LINK | NETIF_MSG_IFUP |
1257ac6653aSJeff Kirsher 				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
1267ac6653aSJeff Kirsher 
127d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER	1000
128d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
129d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR);
130d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
131d765955dSGiuseppe CAVALLARO #define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
132d765955dSGiuseppe CAVALLARO 
1337ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
1347ac6653aSJeff Kirsher 
135bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
136bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev);
137bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void);
138bfab27a1SGiuseppe CAVALLARO #endif
139bfab27a1SGiuseppe CAVALLARO 
1409125cdd1SGiuseppe CAVALLARO #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
1419125cdd1SGiuseppe CAVALLARO 
1427ac6653aSJeff Kirsher /**
1437ac6653aSJeff Kirsher  * stmmac_verify_args - verify the driver parameters.
1447ac6653aSJeff Kirsher  * Description: it verifies if some wrong parameter is passed to the driver.
1457ac6653aSJeff Kirsher  * Note that wrong parameters are replaced with the default values.
1467ac6653aSJeff Kirsher  */
1477ac6653aSJeff Kirsher static void stmmac_verify_args(void)
1487ac6653aSJeff Kirsher {
1497ac6653aSJeff Kirsher 	if (unlikely(watchdog < 0))
1507ac6653aSJeff Kirsher 		watchdog = TX_TIMEO;
1517ac6653aSJeff Kirsher 	if (unlikely(dma_rxsize < 0))
1527ac6653aSJeff Kirsher 		dma_rxsize = DMA_RX_SIZE;
1537ac6653aSJeff Kirsher 	if (unlikely(dma_txsize < 0))
1547ac6653aSJeff Kirsher 		dma_txsize = DMA_TX_SIZE;
1557ac6653aSJeff Kirsher 	if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
1567ac6653aSJeff Kirsher 		buf_sz = DMA_BUFFER_SIZE;
1577ac6653aSJeff Kirsher 	if (unlikely(flow_ctrl > 1))
1587ac6653aSJeff Kirsher 		flow_ctrl = FLOW_AUTO;
1597ac6653aSJeff Kirsher 	else if (likely(flow_ctrl < 0))
1607ac6653aSJeff Kirsher 		flow_ctrl = FLOW_OFF;
1617ac6653aSJeff Kirsher 	if (unlikely((pause < 0) || (pause > 0xffff)))
1627ac6653aSJeff Kirsher 		pause = PAUSE_TIME;
163d765955dSGiuseppe CAVALLARO 	if (eee_timer < 0)
164d765955dSGiuseppe CAVALLARO 		eee_timer = STMMAC_DEFAULT_LPI_TIMER;
1657ac6653aSJeff Kirsher }
1667ac6653aSJeff Kirsher 
167cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv)
168cd7201f4SGiuseppe CAVALLARO {
169cd7201f4SGiuseppe CAVALLARO 	u32 clk_rate;
170cd7201f4SGiuseppe CAVALLARO 
171cd7201f4SGiuseppe CAVALLARO 	clk_rate = clk_get_rate(priv->stmmac_clk);
172cd7201f4SGiuseppe CAVALLARO 
173cd7201f4SGiuseppe CAVALLARO 	/* Platform provided default clk_csr would be assumed valid
174cd7201f4SGiuseppe CAVALLARO 	 * for all other cases except for the below mentioned ones. */
175cd7201f4SGiuseppe CAVALLARO 	if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
176cd7201f4SGiuseppe CAVALLARO 		if (clk_rate < CSR_F_35M)
177cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_20_35M;
178cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
179cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_35_60M;
180cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
181cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_60_100M;
182cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
183cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_100_150M;
184cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
185cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_150_250M;
186cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
187cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_250_300M;
188cd7201f4SGiuseppe CAVALLARO 	} /* For values higher than the IEEE 802.3 specified frequency
189cd7201f4SGiuseppe CAVALLARO 	   * we can not estimate the proper divider as it is not known
190cd7201f4SGiuseppe CAVALLARO 	   * the frequency of clk_csr_i. So we do not change the default
191cd7201f4SGiuseppe CAVALLARO 	   * divider. */
192cd7201f4SGiuseppe CAVALLARO }
193cd7201f4SGiuseppe CAVALLARO 
1947ac6653aSJeff Kirsher #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
1957ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len)
1967ac6653aSJeff Kirsher {
1977ac6653aSJeff Kirsher 	int j;
1987ac6653aSJeff Kirsher 	pr_info("len = %d byte, buf addr: 0x%p", len, buf);
1997ac6653aSJeff Kirsher 	for (j = 0; j < len; j++) {
2007ac6653aSJeff Kirsher 		if ((j % 16) == 0)
2017ac6653aSJeff Kirsher 			pr_info("\n %03x:", j);
2027ac6653aSJeff Kirsher 		pr_info(" %02x", buf[j]);
2037ac6653aSJeff Kirsher 	}
2047ac6653aSJeff Kirsher 	pr_info("\n");
2057ac6653aSJeff Kirsher }
2067ac6653aSJeff Kirsher #endif
2077ac6653aSJeff Kirsher 
2087ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */
2097ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x)	(x->dma_tx_size/4)
2107ac6653aSJeff Kirsher 
2117ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
2127ac6653aSJeff Kirsher {
2137ac6653aSJeff Kirsher 	return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
2147ac6653aSJeff Kirsher }
2157ac6653aSJeff Kirsher 
2167ac6653aSJeff Kirsher /* On some ST platforms, some HW system configuraton registers have to be
2177ac6653aSJeff Kirsher  * set according to the link speed negotiated.
2187ac6653aSJeff Kirsher  */
2197ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
2207ac6653aSJeff Kirsher {
2217ac6653aSJeff Kirsher 	struct phy_device *phydev = priv->phydev;
2227ac6653aSJeff Kirsher 
2237ac6653aSJeff Kirsher 	if (likely(priv->plat->fix_mac_speed))
2247ac6653aSJeff Kirsher 		priv->plat->fix_mac_speed(priv->plat->bsp_priv,
2257ac6653aSJeff Kirsher 					  phydev->speed);
2267ac6653aSJeff Kirsher }
2277ac6653aSJeff Kirsher 
228d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
229d765955dSGiuseppe CAVALLARO {
230d765955dSGiuseppe CAVALLARO 	/* Check and enter in LPI mode */
231d765955dSGiuseppe CAVALLARO 	if ((priv->dirty_tx == priv->cur_tx) &&
232d765955dSGiuseppe CAVALLARO 	    (priv->tx_path_in_lpi_mode == false))
233d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_mode(priv->ioaddr);
234d765955dSGiuseppe CAVALLARO }
235d765955dSGiuseppe CAVALLARO 
236d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv)
237d765955dSGiuseppe CAVALLARO {
238d765955dSGiuseppe CAVALLARO 	/* Exit and disable EEE in case of we are are in LPI state. */
239d765955dSGiuseppe CAVALLARO 	priv->hw->mac->reset_eee_mode(priv->ioaddr);
240d765955dSGiuseppe CAVALLARO 	del_timer_sync(&priv->eee_ctrl_timer);
241d765955dSGiuseppe CAVALLARO 	priv->tx_path_in_lpi_mode = false;
242d765955dSGiuseppe CAVALLARO }
243d765955dSGiuseppe CAVALLARO 
244d765955dSGiuseppe CAVALLARO /**
245d765955dSGiuseppe CAVALLARO  * stmmac_eee_ctrl_timer
246d765955dSGiuseppe CAVALLARO  * @arg : data hook
247d765955dSGiuseppe CAVALLARO  * Description:
248d765955dSGiuseppe CAVALLARO  *  If there is no data transfer and if we are not in LPI state,
249d765955dSGiuseppe CAVALLARO  *  then MAC Transmitter can be moved to LPI state.
250d765955dSGiuseppe CAVALLARO  */
251d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg)
252d765955dSGiuseppe CAVALLARO {
253d765955dSGiuseppe CAVALLARO 	struct stmmac_priv *priv = (struct stmmac_priv *)arg;
254d765955dSGiuseppe CAVALLARO 
255d765955dSGiuseppe CAVALLARO 	stmmac_enable_eee_mode(priv);
256d765955dSGiuseppe CAVALLARO 	mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
257d765955dSGiuseppe CAVALLARO }
258d765955dSGiuseppe CAVALLARO 
259d765955dSGiuseppe CAVALLARO /**
260d765955dSGiuseppe CAVALLARO  * stmmac_eee_init
261d765955dSGiuseppe CAVALLARO  * @priv: private device pointer
262d765955dSGiuseppe CAVALLARO  * Description:
263d765955dSGiuseppe CAVALLARO  *  If the EEE support has been enabled while configuring the driver,
264d765955dSGiuseppe CAVALLARO  *  if the GMAC actually supports the EEE (from the HW cap reg) and the
265d765955dSGiuseppe CAVALLARO  *  phy can also manage EEE, so enable the LPI state and start the timer
266d765955dSGiuseppe CAVALLARO  *  to verify if the tx path can enter in LPI state.
267d765955dSGiuseppe CAVALLARO  */
268d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv)
269d765955dSGiuseppe CAVALLARO {
270d765955dSGiuseppe CAVALLARO 	bool ret = false;
271d765955dSGiuseppe CAVALLARO 
272d765955dSGiuseppe CAVALLARO 	/* MAC core supports the EEE feature. */
273d765955dSGiuseppe CAVALLARO 	if (priv->dma_cap.eee) {
274d765955dSGiuseppe CAVALLARO 		/* Check if the PHY supports EEE */
275d765955dSGiuseppe CAVALLARO 		if (phy_init_eee(priv->phydev, 1))
276d765955dSGiuseppe CAVALLARO 			goto out;
277d765955dSGiuseppe CAVALLARO 
278d765955dSGiuseppe CAVALLARO 		priv->eee_active = 1;
279d765955dSGiuseppe CAVALLARO 		init_timer(&priv->eee_ctrl_timer);
280d765955dSGiuseppe CAVALLARO 		priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
281d765955dSGiuseppe CAVALLARO 		priv->eee_ctrl_timer.data = (unsigned long)priv;
282d765955dSGiuseppe CAVALLARO 		priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer);
283d765955dSGiuseppe CAVALLARO 		add_timer(&priv->eee_ctrl_timer);
284d765955dSGiuseppe CAVALLARO 
285d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_timer(priv->ioaddr,
286d765955dSGiuseppe CAVALLARO 					     STMMAC_DEFAULT_LIT_LS_TIMER,
287d765955dSGiuseppe CAVALLARO 					     priv->tx_lpi_timer);
288d765955dSGiuseppe CAVALLARO 
289d765955dSGiuseppe CAVALLARO 		pr_info("stmmac: Energy-Efficient Ethernet initialized\n");
290d765955dSGiuseppe CAVALLARO 
291d765955dSGiuseppe CAVALLARO 		ret = true;
292d765955dSGiuseppe CAVALLARO 	}
293d765955dSGiuseppe CAVALLARO out:
294d765955dSGiuseppe CAVALLARO 	return ret;
295d765955dSGiuseppe CAVALLARO }
296d765955dSGiuseppe CAVALLARO 
297d765955dSGiuseppe CAVALLARO static void stmmac_eee_adjust(struct stmmac_priv *priv)
298d765955dSGiuseppe CAVALLARO {
299d765955dSGiuseppe CAVALLARO 	/* When the EEE has been already initialised we have to
300d765955dSGiuseppe CAVALLARO 	 * modify the PLS bit in the LPI ctrl & status reg according
301d765955dSGiuseppe CAVALLARO 	 * to the PHY link status. For this reason.
302d765955dSGiuseppe CAVALLARO 	 */
303d765955dSGiuseppe CAVALLARO 	if (priv->eee_enabled)
304d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link);
305d765955dSGiuseppe CAVALLARO }
306d765955dSGiuseppe CAVALLARO 
3077ac6653aSJeff Kirsher /**
3087ac6653aSJeff Kirsher  * stmmac_adjust_link
3097ac6653aSJeff Kirsher  * @dev: net device structure
3107ac6653aSJeff Kirsher  * Description: it adjusts the link parameters.
3117ac6653aSJeff Kirsher  */
3127ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev)
3137ac6653aSJeff Kirsher {
3147ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
3157ac6653aSJeff Kirsher 	struct phy_device *phydev = priv->phydev;
3167ac6653aSJeff Kirsher 	unsigned long flags;
3177ac6653aSJeff Kirsher 	int new_state = 0;
3187ac6653aSJeff Kirsher 	unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
3197ac6653aSJeff Kirsher 
3207ac6653aSJeff Kirsher 	if (phydev == NULL)
3217ac6653aSJeff Kirsher 		return;
3227ac6653aSJeff Kirsher 
3237ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "stmmac_adjust_link: called.  address %d link %d\n",
3247ac6653aSJeff Kirsher 	    phydev->addr, phydev->link);
3257ac6653aSJeff Kirsher 
3267ac6653aSJeff Kirsher 	spin_lock_irqsave(&priv->lock, flags);
327d765955dSGiuseppe CAVALLARO 
3287ac6653aSJeff Kirsher 	if (phydev->link) {
3297ac6653aSJeff Kirsher 		u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
3307ac6653aSJeff Kirsher 
3317ac6653aSJeff Kirsher 		/* Now we make sure that we can be in full duplex mode.
3327ac6653aSJeff Kirsher 		 * If not, we operate in half-duplex mode. */
3337ac6653aSJeff Kirsher 		if (phydev->duplex != priv->oldduplex) {
3347ac6653aSJeff Kirsher 			new_state = 1;
3357ac6653aSJeff Kirsher 			if (!(phydev->duplex))
3367ac6653aSJeff Kirsher 				ctrl &= ~priv->hw->link.duplex;
3377ac6653aSJeff Kirsher 			else
3387ac6653aSJeff Kirsher 				ctrl |= priv->hw->link.duplex;
3397ac6653aSJeff Kirsher 			priv->oldduplex = phydev->duplex;
3407ac6653aSJeff Kirsher 		}
3417ac6653aSJeff Kirsher 		/* Flow Control operation */
3427ac6653aSJeff Kirsher 		if (phydev->pause)
3437ac6653aSJeff Kirsher 			priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
3447ac6653aSJeff Kirsher 						 fc, pause_time);
3457ac6653aSJeff Kirsher 
3467ac6653aSJeff Kirsher 		if (phydev->speed != priv->speed) {
3477ac6653aSJeff Kirsher 			new_state = 1;
3487ac6653aSJeff Kirsher 			switch (phydev->speed) {
3497ac6653aSJeff Kirsher 			case 1000:
3507ac6653aSJeff Kirsher 				if (likely(priv->plat->has_gmac))
3517ac6653aSJeff Kirsher 					ctrl &= ~priv->hw->link.port;
3527ac6653aSJeff Kirsher 					stmmac_hw_fix_mac_speed(priv);
3537ac6653aSJeff Kirsher 				break;
3547ac6653aSJeff Kirsher 			case 100:
3557ac6653aSJeff Kirsher 			case 10:
3567ac6653aSJeff Kirsher 				if (priv->plat->has_gmac) {
3577ac6653aSJeff Kirsher 					ctrl |= priv->hw->link.port;
3587ac6653aSJeff Kirsher 					if (phydev->speed == SPEED_100) {
3597ac6653aSJeff Kirsher 						ctrl |= priv->hw->link.speed;
3607ac6653aSJeff Kirsher 					} else {
3617ac6653aSJeff Kirsher 						ctrl &= ~(priv->hw->link.speed);
3627ac6653aSJeff Kirsher 					}
3637ac6653aSJeff Kirsher 				} else {
3647ac6653aSJeff Kirsher 					ctrl &= ~priv->hw->link.port;
3657ac6653aSJeff Kirsher 				}
3667ac6653aSJeff Kirsher 				stmmac_hw_fix_mac_speed(priv);
3677ac6653aSJeff Kirsher 				break;
3687ac6653aSJeff Kirsher 			default:
3697ac6653aSJeff Kirsher 				if (netif_msg_link(priv))
3707ac6653aSJeff Kirsher 					pr_warning("%s: Speed (%d) is not 10"
3717ac6653aSJeff Kirsher 				       " or 100!\n", dev->name, phydev->speed);
3727ac6653aSJeff Kirsher 				break;
3737ac6653aSJeff Kirsher 			}
3747ac6653aSJeff Kirsher 
3757ac6653aSJeff Kirsher 			priv->speed = phydev->speed;
3767ac6653aSJeff Kirsher 		}
3777ac6653aSJeff Kirsher 
3787ac6653aSJeff Kirsher 		writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
3797ac6653aSJeff Kirsher 
3807ac6653aSJeff Kirsher 		if (!priv->oldlink) {
3817ac6653aSJeff Kirsher 			new_state = 1;
3827ac6653aSJeff Kirsher 			priv->oldlink = 1;
3837ac6653aSJeff Kirsher 		}
3847ac6653aSJeff Kirsher 	} else if (priv->oldlink) {
3857ac6653aSJeff Kirsher 		new_state = 1;
3867ac6653aSJeff Kirsher 		priv->oldlink = 0;
3877ac6653aSJeff Kirsher 		priv->speed = 0;
3887ac6653aSJeff Kirsher 		priv->oldduplex = -1;
3897ac6653aSJeff Kirsher 	}
3907ac6653aSJeff Kirsher 
3917ac6653aSJeff Kirsher 	if (new_state && netif_msg_link(priv))
3927ac6653aSJeff Kirsher 		phy_print_status(phydev);
3937ac6653aSJeff Kirsher 
394d765955dSGiuseppe CAVALLARO 	stmmac_eee_adjust(priv);
395d765955dSGiuseppe CAVALLARO 
3967ac6653aSJeff Kirsher 	spin_unlock_irqrestore(&priv->lock, flags);
3977ac6653aSJeff Kirsher 
3987ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
3997ac6653aSJeff Kirsher }
4007ac6653aSJeff Kirsher 
4017ac6653aSJeff Kirsher /**
4027ac6653aSJeff Kirsher  * stmmac_init_phy - PHY initialization
4037ac6653aSJeff Kirsher  * @dev: net device structure
4047ac6653aSJeff Kirsher  * Description: it initializes the driver's PHY state, and attaches the PHY
4057ac6653aSJeff Kirsher  * to the mac driver.
4067ac6653aSJeff Kirsher  *  Return value:
4077ac6653aSJeff Kirsher  *  0 on success
4087ac6653aSJeff Kirsher  */
4097ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev)
4107ac6653aSJeff Kirsher {
4117ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
4127ac6653aSJeff Kirsher 	struct phy_device *phydev;
413d765955dSGiuseppe CAVALLARO 	char phy_id_fmt[MII_BUS_ID_SIZE + 3];
4147ac6653aSJeff Kirsher 	char bus_id[MII_BUS_ID_SIZE];
41579ee1dc3SSrinivas Kandagatla 	int interface = priv->plat->interface;
4167ac6653aSJeff Kirsher 	priv->oldlink = 0;
4177ac6653aSJeff Kirsher 	priv->speed = 0;
4187ac6653aSJeff Kirsher 	priv->oldduplex = -1;
4197ac6653aSJeff Kirsher 
420f142af2eSSrinivas Kandagatla 	if (priv->plat->phy_bus_name)
421f142af2eSSrinivas Kandagatla 		snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
422f142af2eSSrinivas Kandagatla 				priv->plat->phy_bus_name, priv->plat->bus_id);
423f142af2eSSrinivas Kandagatla 	else
424f142af2eSSrinivas Kandagatla 		snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
425f142af2eSSrinivas Kandagatla 				priv->plat->bus_id);
426f142af2eSSrinivas Kandagatla 
427d765955dSGiuseppe CAVALLARO 	snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
4287ac6653aSJeff Kirsher 		 priv->plat->phy_addr);
429d765955dSGiuseppe CAVALLARO 	pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
4307ac6653aSJeff Kirsher 
431d765955dSGiuseppe CAVALLARO 	phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, 0,
432d765955dSGiuseppe CAVALLARO 			     interface);
4337ac6653aSJeff Kirsher 
4347ac6653aSJeff Kirsher 	if (IS_ERR(phydev)) {
4357ac6653aSJeff Kirsher 		pr_err("%s: Could not attach to PHY\n", dev->name);
4367ac6653aSJeff Kirsher 		return PTR_ERR(phydev);
4377ac6653aSJeff Kirsher 	}
4387ac6653aSJeff Kirsher 
43979ee1dc3SSrinivas Kandagatla 	/* Stop Advertising 1000BASE Capability if interface is not GMII */
440c5b9b4e4SSrinivas Kandagatla 	if ((interface == PHY_INTERFACE_MODE_MII) ||
441c5b9b4e4SSrinivas Kandagatla 	    (interface == PHY_INTERFACE_MODE_RMII))
442c5b9b4e4SSrinivas Kandagatla 		phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
443c5b9b4e4SSrinivas Kandagatla 					 SUPPORTED_1000baseT_Full);
44479ee1dc3SSrinivas Kandagatla 
4457ac6653aSJeff Kirsher 	/*
4467ac6653aSJeff Kirsher 	 * Broken HW is sometimes missing the pull-up resistor on the
4477ac6653aSJeff Kirsher 	 * MDIO line, which results in reads to non-existent devices returning
4487ac6653aSJeff Kirsher 	 * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
4497ac6653aSJeff Kirsher 	 * device as well.
4507ac6653aSJeff Kirsher 	 * Note: phydev->phy_id is the result of reading the UID PHY registers.
4517ac6653aSJeff Kirsher 	 */
4527ac6653aSJeff Kirsher 	if (phydev->phy_id == 0) {
4537ac6653aSJeff Kirsher 		phy_disconnect(phydev);
4547ac6653aSJeff Kirsher 		return -ENODEV;
4557ac6653aSJeff Kirsher 	}
4567ac6653aSJeff Kirsher 	pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
4577ac6653aSJeff Kirsher 		 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
4587ac6653aSJeff Kirsher 
4597ac6653aSJeff Kirsher 	priv->phydev = phydev;
4607ac6653aSJeff Kirsher 
4617ac6653aSJeff Kirsher 	return 0;
4627ac6653aSJeff Kirsher }
4637ac6653aSJeff Kirsher 
4647ac6653aSJeff Kirsher /**
4657ac6653aSJeff Kirsher  * display_ring
4667ac6653aSJeff Kirsher  * @p: pointer to the ring.
4677ac6653aSJeff Kirsher  * @size: size of the ring.
4687ac6653aSJeff Kirsher  * Description: display all the descriptors within the ring.
4697ac6653aSJeff Kirsher  */
4707ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size)
4717ac6653aSJeff Kirsher {
4727ac6653aSJeff Kirsher 	struct tmp_s {
4737ac6653aSJeff Kirsher 		u64 a;
4747ac6653aSJeff Kirsher 		unsigned int b;
4757ac6653aSJeff Kirsher 		unsigned int c;
4767ac6653aSJeff Kirsher 	};
4777ac6653aSJeff Kirsher 	int i;
4787ac6653aSJeff Kirsher 	for (i = 0; i < size; i++) {
4797ac6653aSJeff Kirsher 		struct tmp_s *x = (struct tmp_s *)(p + i);
4807ac6653aSJeff Kirsher 		pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
4817ac6653aSJeff Kirsher 		       i, (unsigned int)virt_to_phys(&p[i]),
4827ac6653aSJeff Kirsher 		       (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
4837ac6653aSJeff Kirsher 		       x->b, x->c);
4847ac6653aSJeff Kirsher 		pr_info("\n");
4857ac6653aSJeff Kirsher 	}
4867ac6653aSJeff Kirsher }
4877ac6653aSJeff Kirsher 
488286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize)
489286a8372SGiuseppe CAVALLARO {
490286a8372SGiuseppe CAVALLARO 	int ret = bufsize;
491286a8372SGiuseppe CAVALLARO 
492286a8372SGiuseppe CAVALLARO 	if (mtu >= BUF_SIZE_4KiB)
493286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_8KiB;
494286a8372SGiuseppe CAVALLARO 	else if (mtu >= BUF_SIZE_2KiB)
495286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_4KiB;
496286a8372SGiuseppe CAVALLARO 	else if (mtu >= DMA_BUFFER_SIZE)
497286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_2KiB;
498286a8372SGiuseppe CAVALLARO 	else
499286a8372SGiuseppe CAVALLARO 		ret = DMA_BUFFER_SIZE;
500286a8372SGiuseppe CAVALLARO 
501286a8372SGiuseppe CAVALLARO 	return ret;
502286a8372SGiuseppe CAVALLARO }
503286a8372SGiuseppe CAVALLARO 
5047ac6653aSJeff Kirsher /**
5057ac6653aSJeff Kirsher  * init_dma_desc_rings - init the RX/TX descriptor rings
5067ac6653aSJeff Kirsher  * @dev: net device structure
5077ac6653aSJeff Kirsher  * Description:  this function initializes the DMA RX/TX descriptors
508286a8372SGiuseppe CAVALLARO  * and allocates the socket buffers. It suppors the chained and ring
509286a8372SGiuseppe CAVALLARO  * modes.
5107ac6653aSJeff Kirsher  */
5117ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev)
5127ac6653aSJeff Kirsher {
5137ac6653aSJeff Kirsher 	int i;
5147ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
5157ac6653aSJeff Kirsher 	struct sk_buff *skb;
5167ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
5177ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
518286a8372SGiuseppe CAVALLARO 	unsigned int bfsize;
519286a8372SGiuseppe CAVALLARO 	int dis_ic = 0;
520286a8372SGiuseppe CAVALLARO 	int des3_as_data_buf = 0;
5217ac6653aSJeff Kirsher 
522286a8372SGiuseppe CAVALLARO 	/* Set the max buffer size according to the DESC mode
523286a8372SGiuseppe CAVALLARO 	 * and the MTU. Note that RING mode allows 16KiB bsize. */
524286a8372SGiuseppe CAVALLARO 	bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu);
525286a8372SGiuseppe CAVALLARO 
526286a8372SGiuseppe CAVALLARO 	if (bfsize == BUF_SIZE_16KiB)
527286a8372SGiuseppe CAVALLARO 		des3_as_data_buf = 1;
5287ac6653aSJeff Kirsher 	else
529286a8372SGiuseppe CAVALLARO 		bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
5307ac6653aSJeff Kirsher 
5317ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
5327ac6653aSJeff Kirsher 	    txsize, rxsize, bfsize);
5337ac6653aSJeff Kirsher 
5347ac6653aSJeff Kirsher 	priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
5357ac6653aSJeff Kirsher 	priv->rx_skbuff =
5367ac6653aSJeff Kirsher 	    kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
5377ac6653aSJeff Kirsher 	priv->dma_rx =
5387ac6653aSJeff Kirsher 	    (struct dma_desc *)dma_alloc_coherent(priv->device,
5397ac6653aSJeff Kirsher 						  rxsize *
5407ac6653aSJeff Kirsher 						  sizeof(struct dma_desc),
5417ac6653aSJeff Kirsher 						  &priv->dma_rx_phy,
5427ac6653aSJeff Kirsher 						  GFP_KERNEL);
5437ac6653aSJeff Kirsher 	priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
5447ac6653aSJeff Kirsher 				       GFP_KERNEL);
5457ac6653aSJeff Kirsher 	priv->dma_tx =
5467ac6653aSJeff Kirsher 	    (struct dma_desc *)dma_alloc_coherent(priv->device,
5477ac6653aSJeff Kirsher 						  txsize *
5487ac6653aSJeff Kirsher 						  sizeof(struct dma_desc),
5497ac6653aSJeff Kirsher 						  &priv->dma_tx_phy,
5507ac6653aSJeff Kirsher 						  GFP_KERNEL);
5517ac6653aSJeff Kirsher 
5527ac6653aSJeff Kirsher 	if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
5537ac6653aSJeff Kirsher 		pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
5547ac6653aSJeff Kirsher 		return;
5557ac6653aSJeff Kirsher 	}
5567ac6653aSJeff Kirsher 
557286a8372SGiuseppe CAVALLARO 	DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, "
5587ac6653aSJeff Kirsher 	    "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
5597ac6653aSJeff Kirsher 	    dev->name, priv->dma_rx, priv->dma_tx,
5607ac6653aSJeff Kirsher 	    (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
5617ac6653aSJeff Kirsher 
5627ac6653aSJeff Kirsher 	/* RX INITIALIZATION */
5637ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac: SKB addresses:\n"
5647ac6653aSJeff Kirsher 			 "skb\t\tskb data\tdma data\n");
5657ac6653aSJeff Kirsher 
5667ac6653aSJeff Kirsher 	for (i = 0; i < rxsize; i++) {
5677ac6653aSJeff Kirsher 		struct dma_desc *p = priv->dma_rx + i;
5687ac6653aSJeff Kirsher 
56945db81e1SGiuseppe CAVALLARO 		skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN,
57045db81e1SGiuseppe CAVALLARO 					 GFP_KERNEL);
5717ac6653aSJeff Kirsher 		if (unlikely(skb == NULL)) {
5727ac6653aSJeff Kirsher 			pr_err("%s: Rx init fails; skb is NULL\n", __func__);
5737ac6653aSJeff Kirsher 			break;
5747ac6653aSJeff Kirsher 		}
57545db81e1SGiuseppe CAVALLARO 		skb_reserve(skb, NET_IP_ALIGN);
5767ac6653aSJeff Kirsher 		priv->rx_skbuff[i] = skb;
5777ac6653aSJeff Kirsher 		priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
5787ac6653aSJeff Kirsher 						bfsize, DMA_FROM_DEVICE);
5797ac6653aSJeff Kirsher 
5807ac6653aSJeff Kirsher 		p->des2 = priv->rx_skbuff_dma[i];
581286a8372SGiuseppe CAVALLARO 
582286a8372SGiuseppe CAVALLARO 		priv->hw->ring->init_desc3(des3_as_data_buf, p);
583286a8372SGiuseppe CAVALLARO 
5847ac6653aSJeff Kirsher 		DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
5857ac6653aSJeff Kirsher 			priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
5867ac6653aSJeff Kirsher 	}
5877ac6653aSJeff Kirsher 	priv->cur_rx = 0;
5887ac6653aSJeff Kirsher 	priv->dirty_rx = (unsigned int)(i - rxsize);
5897ac6653aSJeff Kirsher 	priv->dma_buf_sz = bfsize;
5907ac6653aSJeff Kirsher 	buf_sz = bfsize;
5917ac6653aSJeff Kirsher 
5927ac6653aSJeff Kirsher 	/* TX INITIALIZATION */
5937ac6653aSJeff Kirsher 	for (i = 0; i < txsize; i++) {
5947ac6653aSJeff Kirsher 		priv->tx_skbuff[i] = NULL;
5957ac6653aSJeff Kirsher 		priv->dma_tx[i].des2 = 0;
5967ac6653aSJeff Kirsher 	}
597286a8372SGiuseppe CAVALLARO 
598286a8372SGiuseppe CAVALLARO 	/* In case of Chained mode this sets the des3 to the next
599286a8372SGiuseppe CAVALLARO 	 * element in the chain */
600286a8372SGiuseppe CAVALLARO 	priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize);
601286a8372SGiuseppe CAVALLARO 	priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize);
602286a8372SGiuseppe CAVALLARO 
6037ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
6047ac6653aSJeff Kirsher 	priv->cur_tx = 0;
6057ac6653aSJeff Kirsher 
60662a2ab93SGiuseppe CAVALLARO 	if (priv->use_riwt)
60762a2ab93SGiuseppe CAVALLARO 		dis_ic = 1;
6087ac6653aSJeff Kirsher 	/* Clear the Rx/Tx descriptors */
6097ac6653aSJeff Kirsher 	priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
6107ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
6117ac6653aSJeff Kirsher 
6127ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
6137ac6653aSJeff Kirsher 		pr_info("RX descriptor ring:\n");
6147ac6653aSJeff Kirsher 		display_ring(priv->dma_rx, rxsize);
6157ac6653aSJeff Kirsher 		pr_info("TX descriptor ring:\n");
6167ac6653aSJeff Kirsher 		display_ring(priv->dma_tx, txsize);
6177ac6653aSJeff Kirsher 	}
6187ac6653aSJeff Kirsher }
6197ac6653aSJeff Kirsher 
6207ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv)
6217ac6653aSJeff Kirsher {
6227ac6653aSJeff Kirsher 	int i;
6237ac6653aSJeff Kirsher 
6247ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_rx_size; i++) {
6257ac6653aSJeff Kirsher 		if (priv->rx_skbuff[i]) {
6267ac6653aSJeff Kirsher 			dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
6277ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
6287ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->rx_skbuff[i]);
6297ac6653aSJeff Kirsher 		}
6307ac6653aSJeff Kirsher 		priv->rx_skbuff[i] = NULL;
6317ac6653aSJeff Kirsher 	}
6327ac6653aSJeff Kirsher }
6337ac6653aSJeff Kirsher 
6347ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv)
6357ac6653aSJeff Kirsher {
6367ac6653aSJeff Kirsher 	int i;
6377ac6653aSJeff Kirsher 
6387ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_tx_size; i++) {
6397ac6653aSJeff Kirsher 		if (priv->tx_skbuff[i] != NULL) {
6407ac6653aSJeff Kirsher 			struct dma_desc *p = priv->dma_tx + i;
6417ac6653aSJeff Kirsher 			if (p->des2)
6427ac6653aSJeff Kirsher 				dma_unmap_single(priv->device, p->des2,
6437ac6653aSJeff Kirsher 						 priv->hw->desc->get_tx_len(p),
6447ac6653aSJeff Kirsher 						 DMA_TO_DEVICE);
6457ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->tx_skbuff[i]);
6467ac6653aSJeff Kirsher 			priv->tx_skbuff[i] = NULL;
6477ac6653aSJeff Kirsher 		}
6487ac6653aSJeff Kirsher 	}
6497ac6653aSJeff Kirsher }
6507ac6653aSJeff Kirsher 
6517ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv)
6527ac6653aSJeff Kirsher {
6537ac6653aSJeff Kirsher 	/* Release the DMA TX/RX socket buffers */
6547ac6653aSJeff Kirsher 	dma_free_rx_skbufs(priv);
6557ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
6567ac6653aSJeff Kirsher 
6577ac6653aSJeff Kirsher 	/* Free the region of consistent memory previously allocated for
6587ac6653aSJeff Kirsher 	 * the DMA */
6597ac6653aSJeff Kirsher 	dma_free_coherent(priv->device,
6607ac6653aSJeff Kirsher 			  priv->dma_tx_size * sizeof(struct dma_desc),
6617ac6653aSJeff Kirsher 			  priv->dma_tx, priv->dma_tx_phy);
6627ac6653aSJeff Kirsher 	dma_free_coherent(priv->device,
6637ac6653aSJeff Kirsher 			  priv->dma_rx_size * sizeof(struct dma_desc),
6647ac6653aSJeff Kirsher 			  priv->dma_rx, priv->dma_rx_phy);
6657ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff_dma);
6667ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff);
6677ac6653aSJeff Kirsher 	kfree(priv->tx_skbuff);
6687ac6653aSJeff Kirsher }
6697ac6653aSJeff Kirsher 
6707ac6653aSJeff Kirsher /**
6717ac6653aSJeff Kirsher  *  stmmac_dma_operation_mode - HW DMA operation mode
6727ac6653aSJeff Kirsher  *  @priv : pointer to the private device structure.
6737ac6653aSJeff Kirsher  *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
6747ac6653aSJeff Kirsher  *  or Store-And-Forward capability.
6757ac6653aSJeff Kirsher  */
6767ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
6777ac6653aSJeff Kirsher {
6787ac6653aSJeff Kirsher 	if (likely(priv->plat->force_sf_dma_mode ||
6797ac6653aSJeff Kirsher 		((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) {
6807ac6653aSJeff Kirsher 		/*
6817ac6653aSJeff Kirsher 		 * In case of GMAC, SF mode can be enabled
6827ac6653aSJeff Kirsher 		 * to perform the TX COE in HW. This depends on:
6837ac6653aSJeff Kirsher 		 * 1) TX COE if actually supported
6847ac6653aSJeff Kirsher 		 * 2) There is no bugged Jumbo frame support
6857ac6653aSJeff Kirsher 		 *    that needs to not insert csum in the TDES.
6867ac6653aSJeff Kirsher 		 */
6877ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr,
6887ac6653aSJeff Kirsher 					SF_DMA_MODE, SF_DMA_MODE);
6897ac6653aSJeff Kirsher 		tc = SF_DMA_MODE;
6907ac6653aSJeff Kirsher 	} else
6917ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
6927ac6653aSJeff Kirsher }
6937ac6653aSJeff Kirsher 
6947ac6653aSJeff Kirsher /**
6959125cdd1SGiuseppe CAVALLARO  * stmmac_tx_clean:
6969125cdd1SGiuseppe CAVALLARO  * @priv: private data pointer
6977ac6653aSJeff Kirsher  * Description: it reclaims resources after transmission completes.
6987ac6653aSJeff Kirsher  */
6999125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv)
7007ac6653aSJeff Kirsher {
7017ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
7027ac6653aSJeff Kirsher 
703a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
704a9097a96SGiuseppe CAVALLARO 
7059125cdd1SGiuseppe CAVALLARO 	priv->xstats.tx_clean++;
7069125cdd1SGiuseppe CAVALLARO 
7077ac6653aSJeff Kirsher 	while (priv->dirty_tx != priv->cur_tx) {
7087ac6653aSJeff Kirsher 		int last;
7097ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_tx % txsize;
7107ac6653aSJeff Kirsher 		struct sk_buff *skb = priv->tx_skbuff[entry];
7117ac6653aSJeff Kirsher 		struct dma_desc *p = priv->dma_tx + entry;
7127ac6653aSJeff Kirsher 
7137ac6653aSJeff Kirsher 		/* Check if the descriptor is owned by the DMA. */
7147ac6653aSJeff Kirsher 		if (priv->hw->desc->get_tx_owner(p))
7157ac6653aSJeff Kirsher 			break;
7167ac6653aSJeff Kirsher 
7177ac6653aSJeff Kirsher 		/* Verify tx error by looking at the last segment */
7187ac6653aSJeff Kirsher 		last = priv->hw->desc->get_tx_ls(p);
7197ac6653aSJeff Kirsher 		if (likely(last)) {
7207ac6653aSJeff Kirsher 			int tx_error =
7217ac6653aSJeff Kirsher 				priv->hw->desc->tx_status(&priv->dev->stats,
7227ac6653aSJeff Kirsher 							  &priv->xstats, p,
7237ac6653aSJeff Kirsher 							  priv->ioaddr);
7247ac6653aSJeff Kirsher 			if (likely(tx_error == 0)) {
7257ac6653aSJeff Kirsher 				priv->dev->stats.tx_packets++;
7267ac6653aSJeff Kirsher 				priv->xstats.tx_pkt_n++;
7277ac6653aSJeff Kirsher 			} else
7287ac6653aSJeff Kirsher 				priv->dev->stats.tx_errors++;
7297ac6653aSJeff Kirsher 		}
7307ac6653aSJeff Kirsher 		TX_DBG("%s: curr %d, dirty %d\n", __func__,
7317ac6653aSJeff Kirsher 			priv->cur_tx, priv->dirty_tx);
7327ac6653aSJeff Kirsher 
7337ac6653aSJeff Kirsher 		if (likely(p->des2))
7347ac6653aSJeff Kirsher 			dma_unmap_single(priv->device, p->des2,
7357ac6653aSJeff Kirsher 					 priv->hw->desc->get_tx_len(p),
7367ac6653aSJeff Kirsher 					 DMA_TO_DEVICE);
737286a8372SGiuseppe CAVALLARO 		priv->hw->ring->clean_desc3(p);
7387ac6653aSJeff Kirsher 
7397ac6653aSJeff Kirsher 		if (likely(skb != NULL)) {
7407ac6653aSJeff Kirsher 			dev_kfree_skb(skb);
7417ac6653aSJeff Kirsher 			priv->tx_skbuff[entry] = NULL;
7427ac6653aSJeff Kirsher 		}
7437ac6653aSJeff Kirsher 
7447ac6653aSJeff Kirsher 		priv->hw->desc->release_tx_desc(p);
7457ac6653aSJeff Kirsher 
74613497f58SGiuseppe CAVALLARO 		priv->dirty_tx++;
7477ac6653aSJeff Kirsher 	}
7487ac6653aSJeff Kirsher 	if (unlikely(netif_queue_stopped(priv->dev) &&
7497ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
7507ac6653aSJeff Kirsher 		netif_tx_lock(priv->dev);
7517ac6653aSJeff Kirsher 		if (netif_queue_stopped(priv->dev) &&
7527ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
7537ac6653aSJeff Kirsher 			TX_DBG("%s: restart transmit\n", __func__);
7547ac6653aSJeff Kirsher 			netif_wake_queue(priv->dev);
7557ac6653aSJeff Kirsher 		}
7567ac6653aSJeff Kirsher 		netif_tx_unlock(priv->dev);
7577ac6653aSJeff Kirsher 	}
758d765955dSGiuseppe CAVALLARO 
759d765955dSGiuseppe CAVALLARO 	if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
760d765955dSGiuseppe CAVALLARO 		stmmac_enable_eee_mode(priv);
761d765955dSGiuseppe CAVALLARO 		mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
762d765955dSGiuseppe CAVALLARO 	}
763a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
7647ac6653aSJeff Kirsher }
7657ac6653aSJeff Kirsher 
7669125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv)
7677ac6653aSJeff Kirsher {
7687ac6653aSJeff Kirsher 	priv->hw->dma->enable_dma_irq(priv->ioaddr);
7697ac6653aSJeff Kirsher }
7707ac6653aSJeff Kirsher 
7719125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv)
7727ac6653aSJeff Kirsher {
7737ac6653aSJeff Kirsher 	priv->hw->dma->disable_dma_irq(priv->ioaddr);
7747ac6653aSJeff Kirsher }
7757ac6653aSJeff Kirsher 
7767ac6653aSJeff Kirsher 
7777ac6653aSJeff Kirsher /**
7787ac6653aSJeff Kirsher  * stmmac_tx_err:
7797ac6653aSJeff Kirsher  * @priv: pointer to the private device structure
7807ac6653aSJeff Kirsher  * Description: it cleans the descriptors and restarts the transmission
7817ac6653aSJeff Kirsher  * in case of errors.
7827ac6653aSJeff Kirsher  */
7837ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv)
7847ac6653aSJeff Kirsher {
7857ac6653aSJeff Kirsher 	netif_stop_queue(priv->dev);
7867ac6653aSJeff Kirsher 
7877ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
7887ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
7897ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
7907ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
7917ac6653aSJeff Kirsher 	priv->cur_tx = 0;
7927ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
7937ac6653aSJeff Kirsher 
7947ac6653aSJeff Kirsher 	priv->dev->stats.tx_errors++;
7957ac6653aSJeff Kirsher 	netif_wake_queue(priv->dev);
7967ac6653aSJeff Kirsher }
7977ac6653aSJeff Kirsher 
7987ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv)
7997ac6653aSJeff Kirsher {
8007ac6653aSJeff Kirsher 	int status;
8017ac6653aSJeff Kirsher 
8027ac6653aSJeff Kirsher 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
8039125cdd1SGiuseppe CAVALLARO 	if (likely((status & handle_rx)) || (status & handle_tx)) {
8049125cdd1SGiuseppe CAVALLARO 		if (likely(napi_schedule_prep(&priv->napi))) {
8059125cdd1SGiuseppe CAVALLARO 			stmmac_disable_dma_irq(priv);
8069125cdd1SGiuseppe CAVALLARO 			__napi_schedule(&priv->napi);
8079125cdd1SGiuseppe CAVALLARO 		}
8089125cdd1SGiuseppe CAVALLARO 	}
8099125cdd1SGiuseppe CAVALLARO 	if (unlikely(status & tx_hard_error_bump_tc)) {
8107ac6653aSJeff Kirsher 		/* Try to bump up the dma threshold on this failure */
8117ac6653aSJeff Kirsher 		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
8127ac6653aSJeff Kirsher 			tc += 64;
8137ac6653aSJeff Kirsher 			priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
8147ac6653aSJeff Kirsher 			priv->xstats.threshold = tc;
8157ac6653aSJeff Kirsher 		}
8167ac6653aSJeff Kirsher 	} else if (unlikely(status == tx_hard_error))
8177ac6653aSJeff Kirsher 		stmmac_tx_err(priv);
8187ac6653aSJeff Kirsher }
8197ac6653aSJeff Kirsher 
8201c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv)
8211c901a46SGiuseppe CAVALLARO {
8221c901a46SGiuseppe CAVALLARO 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
8231c901a46SGiuseppe CAVALLARO 			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
8241c901a46SGiuseppe CAVALLARO 
8254f795b25SGiuseppe CAVALLARO 	/* Mask MMC irq, counters are managed in SW and registers
8264f795b25SGiuseppe CAVALLARO 	 * are cleared on each READ eventually. */
8271c901a46SGiuseppe CAVALLARO 	dwmac_mmc_intr_all_mask(priv->ioaddr);
8284f795b25SGiuseppe CAVALLARO 
8294f795b25SGiuseppe CAVALLARO 	if (priv->dma_cap.rmon) {
8301c901a46SGiuseppe CAVALLARO 		dwmac_mmc_ctrl(priv->ioaddr, mode);
8311c901a46SGiuseppe CAVALLARO 		memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
8324f795b25SGiuseppe CAVALLARO 	} else
833aae54cffSStefan Roese 		pr_info(" No MAC Management Counters available\n");
8341c901a46SGiuseppe CAVALLARO }
8351c901a46SGiuseppe CAVALLARO 
836f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
837f0b9d786SGiuseppe CAVALLARO {
838f0b9d786SGiuseppe CAVALLARO 	u32 hwid = priv->hw->synopsys_uid;
839f0b9d786SGiuseppe CAVALLARO 
840f0b9d786SGiuseppe CAVALLARO 	/* Only check valid Synopsys Id because old MAC chips
841f0b9d786SGiuseppe CAVALLARO 	 * have no HW registers where get the ID */
842f0b9d786SGiuseppe CAVALLARO 	if (likely(hwid)) {
843f0b9d786SGiuseppe CAVALLARO 		u32 uid = ((hwid & 0x0000ff00) >> 8);
844f0b9d786SGiuseppe CAVALLARO 		u32 synid = (hwid & 0x000000ff);
845f0b9d786SGiuseppe CAVALLARO 
846cf3f047bSGiuseppe CAVALLARO 		pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n",
847f0b9d786SGiuseppe CAVALLARO 			uid, synid);
848f0b9d786SGiuseppe CAVALLARO 
849f0b9d786SGiuseppe CAVALLARO 		return synid;
850f0b9d786SGiuseppe CAVALLARO 	}
851f0b9d786SGiuseppe CAVALLARO 	return 0;
852f0b9d786SGiuseppe CAVALLARO }
853e7434821SGiuseppe CAVALLARO 
85419e30c14SGiuseppe CAVALLARO /**
85519e30c14SGiuseppe CAVALLARO  * stmmac_selec_desc_mode
856ff3dd78cSGiuseppe CAVALLARO  * @priv : private structure
857ff3dd78cSGiuseppe CAVALLARO  * Description: select the Enhanced/Alternate or Normal descriptors
858ff3dd78cSGiuseppe CAVALLARO  */
85919e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
86019e30c14SGiuseppe CAVALLARO {
86119e30c14SGiuseppe CAVALLARO 	if (priv->plat->enh_desc) {
86219e30c14SGiuseppe CAVALLARO 		pr_info(" Enhanced/Alternate descriptors\n");
86319e30c14SGiuseppe CAVALLARO 		priv->hw->desc = &enh_desc_ops;
86419e30c14SGiuseppe CAVALLARO 	} else {
86519e30c14SGiuseppe CAVALLARO 		pr_info(" Normal descriptors\n");
86619e30c14SGiuseppe CAVALLARO 		priv->hw->desc = &ndesc_ops;
86719e30c14SGiuseppe CAVALLARO 	}
86819e30c14SGiuseppe CAVALLARO }
86919e30c14SGiuseppe CAVALLARO 
87019e30c14SGiuseppe CAVALLARO /**
87119e30c14SGiuseppe CAVALLARO  * stmmac_get_hw_features
87219e30c14SGiuseppe CAVALLARO  * @priv : private device pointer
87319e30c14SGiuseppe CAVALLARO  * Description:
87419e30c14SGiuseppe CAVALLARO  *  new GMAC chip generations have a new register to indicate the
875e7434821SGiuseppe CAVALLARO  *  presence of the optional feature/functions.
87619e30c14SGiuseppe CAVALLARO  *  This can be also used to override the value passed through the
87719e30c14SGiuseppe CAVALLARO  *  platform and necessary for old MAC10/100 and GMAC chips.
878e7434821SGiuseppe CAVALLARO  */
879e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv)
880e7434821SGiuseppe CAVALLARO {
8815e6efe88SGiuseppe CAVALLARO 	u32 hw_cap = 0;
8823c20f72fSGiuseppe CAVALLARO 
8835e6efe88SGiuseppe CAVALLARO 	if (priv->hw->dma->get_hw_feature) {
8845e6efe88SGiuseppe CAVALLARO 		hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
885e7434821SGiuseppe CAVALLARO 
8861db123fbSRayagond Kokatanur 		priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
8871db123fbSRayagond Kokatanur 		priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
8881db123fbSRayagond Kokatanur 		priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
8891db123fbSRayagond Kokatanur 		priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
8901db123fbSRayagond Kokatanur 		priv->dma_cap.multi_addr =
8911db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_ADDMACADRSEL) >> 5;
8921db123fbSRayagond Kokatanur 		priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
8931db123fbSRayagond Kokatanur 		priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
8941db123fbSRayagond Kokatanur 		priv->dma_cap.pmt_remote_wake_up =
8951db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
8961db123fbSRayagond Kokatanur 		priv->dma_cap.pmt_magic_frame =
8971db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
8981db123fbSRayagond Kokatanur 		/* MMC */
8991db123fbSRayagond Kokatanur 		priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
900e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2002*/
9011db123fbSRayagond Kokatanur 		priv->dma_cap.time_stamp =
9021db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
903e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2008*/
9041db123fbSRayagond Kokatanur 		priv->dma_cap.atime_stamp =
9051db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
906e7434821SGiuseppe CAVALLARO 		/* 802.3az - Energy-Efficient Ethernet (EEE) */
9071db123fbSRayagond Kokatanur 		priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
9081db123fbSRayagond Kokatanur 		priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
909e7434821SGiuseppe CAVALLARO 		/* TX and RX csum */
9101db123fbSRayagond Kokatanur 		priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
9111db123fbSRayagond Kokatanur 		priv->dma_cap.rx_coe_type1 =
9121db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
9131db123fbSRayagond Kokatanur 		priv->dma_cap.rx_coe_type2 =
9141db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
9151db123fbSRayagond Kokatanur 		priv->dma_cap.rxfifo_over_2048 =
9161db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
917e7434821SGiuseppe CAVALLARO 		/* TX and RX number of channels */
9181db123fbSRayagond Kokatanur 		priv->dma_cap.number_rx_channel =
9191db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
9201db123fbSRayagond Kokatanur 		priv->dma_cap.number_tx_channel =
9211db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
922e7434821SGiuseppe CAVALLARO 		/* Alternate (enhanced) DESC mode*/
9231db123fbSRayagond Kokatanur 		priv->dma_cap.enh_desc =
9241db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
92519e30c14SGiuseppe CAVALLARO 	}
926e7434821SGiuseppe CAVALLARO 
927e7434821SGiuseppe CAVALLARO 	return hw_cap;
928e7434821SGiuseppe CAVALLARO }
929e7434821SGiuseppe CAVALLARO 
930bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv)
931bfab27a1SGiuseppe CAVALLARO {
932bfab27a1SGiuseppe CAVALLARO 	/* verify if the MAC address is valid, in case of failures it
933bfab27a1SGiuseppe CAVALLARO 	 * generates a random MAC address */
934bfab27a1SGiuseppe CAVALLARO 	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
935bfab27a1SGiuseppe CAVALLARO 		priv->hw->mac->get_umac_addr((void __iomem *)
936bfab27a1SGiuseppe CAVALLARO 					     priv->dev->base_addr,
937bfab27a1SGiuseppe CAVALLARO 					     priv->dev->dev_addr, 0);
938bfab27a1SGiuseppe CAVALLARO 		if  (!is_valid_ether_addr(priv->dev->dev_addr))
939f2cedb63SDanny Kukawka 			eth_hw_addr_random(priv->dev);
940bfab27a1SGiuseppe CAVALLARO 	}
941bfab27a1SGiuseppe CAVALLARO 	pr_warning("%s: device MAC address %pM\n", priv->dev->name,
942bfab27a1SGiuseppe CAVALLARO 						   priv->dev->dev_addr);
943bfab27a1SGiuseppe CAVALLARO }
944bfab27a1SGiuseppe CAVALLARO 
9450f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv)
9460f1f88a8SGiuseppe CAVALLARO {
9470f1f88a8SGiuseppe CAVALLARO 	int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
948b9cde0a8SGiuseppe CAVALLARO 	int mixed_burst = 0;
9490f1f88a8SGiuseppe CAVALLARO 
9500f1f88a8SGiuseppe CAVALLARO 	/* Some DMA parameters can be passed from the platform;
9510f1f88a8SGiuseppe CAVALLARO 	 * in case of these are not passed we keep a default
9520f1f88a8SGiuseppe CAVALLARO 	 * (good for all the chips) and init the DMA! */
9530f1f88a8SGiuseppe CAVALLARO 	if (priv->plat->dma_cfg) {
9540f1f88a8SGiuseppe CAVALLARO 		pbl = priv->plat->dma_cfg->pbl;
9550f1f88a8SGiuseppe CAVALLARO 		fixed_burst = priv->plat->dma_cfg->fixed_burst;
956b9cde0a8SGiuseppe CAVALLARO 		mixed_burst = priv->plat->dma_cfg->mixed_burst;
9570f1f88a8SGiuseppe CAVALLARO 		burst_len = priv->plat->dma_cfg->burst_len;
9580f1f88a8SGiuseppe CAVALLARO 	}
9590f1f88a8SGiuseppe CAVALLARO 
960b9cde0a8SGiuseppe CAVALLARO 	return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
9610f1f88a8SGiuseppe CAVALLARO 				   burst_len, priv->dma_tx_phy,
9620f1f88a8SGiuseppe CAVALLARO 				   priv->dma_rx_phy);
9630f1f88a8SGiuseppe CAVALLARO }
9640f1f88a8SGiuseppe CAVALLARO 
965bfab27a1SGiuseppe CAVALLARO /**
9669125cdd1SGiuseppe CAVALLARO  * stmmac_tx_timer:
9679125cdd1SGiuseppe CAVALLARO  * @data: data pointer
9689125cdd1SGiuseppe CAVALLARO  * Description:
9699125cdd1SGiuseppe CAVALLARO  * This is the timer handler to directly invoke the stmmac_tx_clean.
9709125cdd1SGiuseppe CAVALLARO  */
9719125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data)
9729125cdd1SGiuseppe CAVALLARO {
9739125cdd1SGiuseppe CAVALLARO 	struct stmmac_priv *priv = (struct stmmac_priv *)data;
9749125cdd1SGiuseppe CAVALLARO 
9759125cdd1SGiuseppe CAVALLARO 	stmmac_tx_clean(priv);
9769125cdd1SGiuseppe CAVALLARO }
9779125cdd1SGiuseppe CAVALLARO 
9789125cdd1SGiuseppe CAVALLARO /**
9799125cdd1SGiuseppe CAVALLARO  * stmmac_tx_timer:
9809125cdd1SGiuseppe CAVALLARO  * @priv: private data structure
9819125cdd1SGiuseppe CAVALLARO  * Description:
9829125cdd1SGiuseppe CAVALLARO  * This inits the transmit coalesce parameters: i.e. timer rate,
9839125cdd1SGiuseppe CAVALLARO  * timer handler and default threshold used for enabling the
9849125cdd1SGiuseppe CAVALLARO  * interrupt on completion bit.
9859125cdd1SGiuseppe CAVALLARO  */
9869125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
9879125cdd1SGiuseppe CAVALLARO {
9889125cdd1SGiuseppe CAVALLARO 	priv->tx_coal_frames = STMMAC_TX_FRAMES;
9899125cdd1SGiuseppe CAVALLARO 	priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
9909125cdd1SGiuseppe CAVALLARO 	init_timer(&priv->txtimer);
9919125cdd1SGiuseppe CAVALLARO 	priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer);
9929125cdd1SGiuseppe CAVALLARO 	priv->txtimer.data = (unsigned long)priv;
9939125cdd1SGiuseppe CAVALLARO 	priv->txtimer.function = stmmac_tx_timer;
9949125cdd1SGiuseppe CAVALLARO 	add_timer(&priv->txtimer);
9959125cdd1SGiuseppe CAVALLARO }
9969125cdd1SGiuseppe CAVALLARO 
9979125cdd1SGiuseppe CAVALLARO /**
9987ac6653aSJeff Kirsher  *  stmmac_open - open entry point of the driver
9997ac6653aSJeff Kirsher  *  @dev : pointer to the device structure.
10007ac6653aSJeff Kirsher  *  Description:
10017ac6653aSJeff Kirsher  *  This function is the open entry point of the driver.
10027ac6653aSJeff Kirsher  *  Return value:
10037ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
10047ac6653aSJeff Kirsher  *  file on failure.
10057ac6653aSJeff Kirsher  */
10067ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev)
10077ac6653aSJeff Kirsher {
10087ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
10097ac6653aSJeff Kirsher 	int ret;
10107ac6653aSJeff Kirsher 
1011a630844dSStefan Roese 	clk_prepare_enable(priv->stmmac_clk);
10124bfcbd7aSFrancesco Virlinzi 
10134bfcbd7aSFrancesco Virlinzi 	stmmac_check_ether_addr(priv);
10144bfcbd7aSFrancesco Virlinzi 
10157ac6653aSJeff Kirsher 	ret = stmmac_init_phy(dev);
10167ac6653aSJeff Kirsher 	if (unlikely(ret)) {
10177ac6653aSJeff Kirsher 		pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
10187ac6653aSJeff Kirsher 		goto open_error;
10197ac6653aSJeff Kirsher 	}
10207ac6653aSJeff Kirsher 
10217ac6653aSJeff Kirsher 	/* Create and initialize the TX/RX descriptors chains. */
10227ac6653aSJeff Kirsher 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
10237ac6653aSJeff Kirsher 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
10247ac6653aSJeff Kirsher 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
10257ac6653aSJeff Kirsher 	init_dma_desc_rings(dev);
10267ac6653aSJeff Kirsher 
10277ac6653aSJeff Kirsher 	/* DMA initialization and SW reset */
10280f1f88a8SGiuseppe CAVALLARO 	ret = stmmac_init_dma_engine(priv);
10297ac6653aSJeff Kirsher 	if (ret < 0) {
10307ac6653aSJeff Kirsher 		pr_err("%s: DMA initialization failed\n", __func__);
10317ac6653aSJeff Kirsher 		goto open_error;
10327ac6653aSJeff Kirsher 	}
10337ac6653aSJeff Kirsher 
10347ac6653aSJeff Kirsher 	/* Copy the MAC addr into the HW  */
10357ac6653aSJeff Kirsher 	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
1036cf3f047bSGiuseppe CAVALLARO 
10377ac6653aSJeff Kirsher 	/* If required, perform hw setup of the bus. */
10387ac6653aSJeff Kirsher 	if (priv->plat->bus_setup)
10397ac6653aSJeff Kirsher 		priv->plat->bus_setup(priv->ioaddr);
1040cf3f047bSGiuseppe CAVALLARO 
10417ac6653aSJeff Kirsher 	/* Initialize the MAC Core */
10427ac6653aSJeff Kirsher 	priv->hw->mac->core_init(priv->ioaddr);
10437ac6653aSJeff Kirsher 
10447ac6653aSJeff Kirsher 	/* Request the IRQ lines */
10457ac6653aSJeff Kirsher 	ret = request_irq(dev->irq, stmmac_interrupt,
10467ac6653aSJeff Kirsher 			 IRQF_SHARED, dev->name, dev);
10477ac6653aSJeff Kirsher 	if (unlikely(ret < 0)) {
10487ac6653aSJeff Kirsher 		pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
10497ac6653aSJeff Kirsher 		       __func__, dev->irq, ret);
10507ac6653aSJeff Kirsher 		goto open_error;
10517ac6653aSJeff Kirsher 	}
10527ac6653aSJeff Kirsher 
10537a13f8f5SFrancesco Virlinzi 	/* Request the Wake IRQ in case of another line is used for WoL */
10547a13f8f5SFrancesco Virlinzi 	if (priv->wol_irq != dev->irq) {
10557a13f8f5SFrancesco Virlinzi 		ret = request_irq(priv->wol_irq, stmmac_interrupt,
10567a13f8f5SFrancesco Virlinzi 				  IRQF_SHARED, dev->name, dev);
10577a13f8f5SFrancesco Virlinzi 		if (unlikely(ret < 0)) {
10587a13f8f5SFrancesco Virlinzi 			pr_err("%s: ERROR: allocating the ext WoL IRQ %d "
10597a13f8f5SFrancesco Virlinzi 			       "(error: %d)\n",	__func__, priv->wol_irq, ret);
10607a13f8f5SFrancesco Virlinzi 			goto open_error_wolirq;
10617a13f8f5SFrancesco Virlinzi 		}
10627a13f8f5SFrancesco Virlinzi 	}
10637a13f8f5SFrancesco Virlinzi 
1064d765955dSGiuseppe CAVALLARO 	/* Request the IRQ lines */
1065d765955dSGiuseppe CAVALLARO 	if (priv->lpi_irq != -ENXIO) {
1066d765955dSGiuseppe CAVALLARO 		ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED,
1067d765955dSGiuseppe CAVALLARO 				  dev->name, dev);
1068d765955dSGiuseppe CAVALLARO 		if (unlikely(ret < 0)) {
1069d765955dSGiuseppe CAVALLARO 			pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n",
1070d765955dSGiuseppe CAVALLARO 			       __func__, priv->lpi_irq, ret);
1071d765955dSGiuseppe CAVALLARO 			goto open_error_lpiirq;
1072d765955dSGiuseppe CAVALLARO 		}
1073d765955dSGiuseppe CAVALLARO 	}
1074d765955dSGiuseppe CAVALLARO 
10757ac6653aSJeff Kirsher 	/* Enable the MAC Rx/Tx */
1076bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, true);
10777ac6653aSJeff Kirsher 
10787ac6653aSJeff Kirsher 	/* Set the HW DMA mode and the COE */
10797ac6653aSJeff Kirsher 	stmmac_dma_operation_mode(priv);
10807ac6653aSJeff Kirsher 
10817ac6653aSJeff Kirsher 	/* Extra statistics */
10827ac6653aSJeff Kirsher 	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
10837ac6653aSJeff Kirsher 	priv->xstats.threshold = tc;
10847ac6653aSJeff Kirsher 
10851c901a46SGiuseppe CAVALLARO 	stmmac_mmc_setup(priv);
10861c901a46SGiuseppe CAVALLARO 
1087bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
1088bfab27a1SGiuseppe CAVALLARO 	ret = stmmac_init_fs(dev);
1089bfab27a1SGiuseppe CAVALLARO 	if (ret < 0)
1090cf3f047bSGiuseppe CAVALLARO 		pr_warning("%s: failed debugFS registration\n", __func__);
1091bfab27a1SGiuseppe CAVALLARO #endif
10927ac6653aSJeff Kirsher 	/* Start the ball rolling... */
10937ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
10947ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
10957ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
10967ac6653aSJeff Kirsher 
10977ac6653aSJeff Kirsher 	/* Dump DMA/MAC registers */
10987ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
10997ac6653aSJeff Kirsher 		priv->hw->mac->dump_regs(priv->ioaddr);
11007ac6653aSJeff Kirsher 		priv->hw->dma->dump_regs(priv->ioaddr);
11017ac6653aSJeff Kirsher 	}
11027ac6653aSJeff Kirsher 
11037ac6653aSJeff Kirsher 	if (priv->phydev)
11047ac6653aSJeff Kirsher 		phy_start(priv->phydev);
11057ac6653aSJeff Kirsher 
1106d765955dSGiuseppe CAVALLARO 	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER;
1107d765955dSGiuseppe CAVALLARO 	priv->eee_enabled = stmmac_eee_init(priv);
1108d765955dSGiuseppe CAVALLARO 
11099125cdd1SGiuseppe CAVALLARO 	stmmac_init_tx_coalesce(priv);
11109125cdd1SGiuseppe CAVALLARO 
111162a2ab93SGiuseppe CAVALLARO 	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
111262a2ab93SGiuseppe CAVALLARO 		priv->rx_riwt = MAX_DMA_RIWT;
111362a2ab93SGiuseppe CAVALLARO 		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
111462a2ab93SGiuseppe CAVALLARO 	}
111562a2ab93SGiuseppe CAVALLARO 
11167ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
11177ac6653aSJeff Kirsher 	netif_start_queue(dev);
11187ac6653aSJeff Kirsher 
11197ac6653aSJeff Kirsher 	return 0;
11207ac6653aSJeff Kirsher 
1121d765955dSGiuseppe CAVALLARO open_error_lpiirq:
1122d765955dSGiuseppe CAVALLARO 	if (priv->wol_irq != dev->irq)
1123d765955dSGiuseppe CAVALLARO 		free_irq(priv->wol_irq, dev);
1124d765955dSGiuseppe CAVALLARO 
11257a13f8f5SFrancesco Virlinzi open_error_wolirq:
11267a13f8f5SFrancesco Virlinzi 	free_irq(dev->irq, dev);
11277a13f8f5SFrancesco Virlinzi 
11287ac6653aSJeff Kirsher open_error:
11297ac6653aSJeff Kirsher 	if (priv->phydev)
11307ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
11317ac6653aSJeff Kirsher 
1132a630844dSStefan Roese 	clk_disable_unprepare(priv->stmmac_clk);
11334bfcbd7aSFrancesco Virlinzi 
11347ac6653aSJeff Kirsher 	return ret;
11357ac6653aSJeff Kirsher }
11367ac6653aSJeff Kirsher 
11377ac6653aSJeff Kirsher /**
11387ac6653aSJeff Kirsher  *  stmmac_release - close entry point of the driver
11397ac6653aSJeff Kirsher  *  @dev : device pointer.
11407ac6653aSJeff Kirsher  *  Description:
11417ac6653aSJeff Kirsher  *  This is the stop entry point of the driver.
11427ac6653aSJeff Kirsher  */
11437ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev)
11447ac6653aSJeff Kirsher {
11457ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
11467ac6653aSJeff Kirsher 
1147d765955dSGiuseppe CAVALLARO 	if (priv->eee_enabled)
1148d765955dSGiuseppe CAVALLARO 		del_timer_sync(&priv->eee_ctrl_timer);
1149d765955dSGiuseppe CAVALLARO 
11507ac6653aSJeff Kirsher 	/* Stop and disconnect the PHY */
11517ac6653aSJeff Kirsher 	if (priv->phydev) {
11527ac6653aSJeff Kirsher 		phy_stop(priv->phydev);
11537ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
11547ac6653aSJeff Kirsher 		priv->phydev = NULL;
11557ac6653aSJeff Kirsher 	}
11567ac6653aSJeff Kirsher 
11577ac6653aSJeff Kirsher 	netif_stop_queue(dev);
11587ac6653aSJeff Kirsher 
11597ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
11607ac6653aSJeff Kirsher 
11619125cdd1SGiuseppe CAVALLARO 	del_timer_sync(&priv->txtimer);
11629125cdd1SGiuseppe CAVALLARO 
11637ac6653aSJeff Kirsher 	/* Free the IRQ lines */
11647ac6653aSJeff Kirsher 	free_irq(dev->irq, dev);
11657a13f8f5SFrancesco Virlinzi 	if (priv->wol_irq != dev->irq)
11667a13f8f5SFrancesco Virlinzi 		free_irq(priv->wol_irq, dev);
1167d765955dSGiuseppe CAVALLARO 	if (priv->lpi_irq != -ENXIO)
1168d765955dSGiuseppe CAVALLARO 		free_irq(priv->lpi_irq, dev);
11697ac6653aSJeff Kirsher 
11707ac6653aSJeff Kirsher 	/* Stop TX/RX DMA and clear the descriptors */
11717ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
11727ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
11737ac6653aSJeff Kirsher 
11747ac6653aSJeff Kirsher 	/* Release and free the Rx/Tx resources */
11757ac6653aSJeff Kirsher 	free_dma_desc_resources(priv);
11767ac6653aSJeff Kirsher 
11777ac6653aSJeff Kirsher 	/* Disable the MAC Rx/Tx */
1178bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, false);
11797ac6653aSJeff Kirsher 
11807ac6653aSJeff Kirsher 	netif_carrier_off(dev);
11817ac6653aSJeff Kirsher 
1182bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
1183bfab27a1SGiuseppe CAVALLARO 	stmmac_exit_fs();
1184bfab27a1SGiuseppe CAVALLARO #endif
1185a630844dSStefan Roese 	clk_disable_unprepare(priv->stmmac_clk);
1186bfab27a1SGiuseppe CAVALLARO 
11877ac6653aSJeff Kirsher 	return 0;
11887ac6653aSJeff Kirsher }
11897ac6653aSJeff Kirsher 
11907ac6653aSJeff Kirsher /**
11917ac6653aSJeff Kirsher  *  stmmac_xmit:
11927ac6653aSJeff Kirsher  *  @skb : the socket buffer
11937ac6653aSJeff Kirsher  *  @dev : device pointer
11947ac6653aSJeff Kirsher  *  Description : Tx entry point of the driver.
11957ac6653aSJeff Kirsher  */
11967ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
11977ac6653aSJeff Kirsher {
11987ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
11997ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
12007ac6653aSJeff Kirsher 	unsigned int entry;
12017ac6653aSJeff Kirsher 	int i, csum_insertion = 0;
12027ac6653aSJeff Kirsher 	int nfrags = skb_shinfo(skb)->nr_frags;
12037ac6653aSJeff Kirsher 	struct dma_desc *desc, *first;
1204286a8372SGiuseppe CAVALLARO 	unsigned int nopaged_len = skb_headlen(skb);
12057ac6653aSJeff Kirsher 
12067ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
12077ac6653aSJeff Kirsher 		if (!netif_queue_stopped(dev)) {
12087ac6653aSJeff Kirsher 			netif_stop_queue(dev);
12097ac6653aSJeff Kirsher 			/* This is a hard error, log it. */
12107ac6653aSJeff Kirsher 			pr_err("%s: BUG! Tx Ring full when queue awake\n",
12117ac6653aSJeff Kirsher 				__func__);
12127ac6653aSJeff Kirsher 		}
12137ac6653aSJeff Kirsher 		return NETDEV_TX_BUSY;
12147ac6653aSJeff Kirsher 	}
12157ac6653aSJeff Kirsher 
1216a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
1217a9097a96SGiuseppe CAVALLARO 
1218d765955dSGiuseppe CAVALLARO 	if (priv->tx_path_in_lpi_mode)
1219d765955dSGiuseppe CAVALLARO 		stmmac_disable_eee_mode(priv);
1220d765955dSGiuseppe CAVALLARO 
12217ac6653aSJeff Kirsher 	entry = priv->cur_tx % txsize;
12227ac6653aSJeff Kirsher 
12237ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
12247ac6653aSJeff Kirsher 	if ((skb->len > ETH_FRAME_LEN) || nfrags)
12259125cdd1SGiuseppe CAVALLARO 		pr_debug("stmmac xmit: [entry %d]\n"
12267ac6653aSJeff Kirsher 			 "\tskb addr %p - len: %d - nopaged_len: %d\n"
12279125cdd1SGiuseppe CAVALLARO 			 "\tn_frags: %d - ip_summed: %d - %s gso\n"
12289125cdd1SGiuseppe CAVALLARO 			 "\ttx_count_frames %d\n", entry,
1229286a8372SGiuseppe CAVALLARO 			 skb, skb->len, nopaged_len, nfrags, skb->ip_summed,
12309125cdd1SGiuseppe CAVALLARO 			 !skb_is_gso(skb) ? "isn't" : "is",
12319125cdd1SGiuseppe CAVALLARO 			 priv->tx_count_frames);
12327ac6653aSJeff Kirsher #endif
12337ac6653aSJeff Kirsher 
12347ac6653aSJeff Kirsher 	csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
12357ac6653aSJeff Kirsher 
12367ac6653aSJeff Kirsher 	desc = priv->dma_tx + entry;
12377ac6653aSJeff Kirsher 	first = desc;
12387ac6653aSJeff Kirsher 
12397ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
12407ac6653aSJeff Kirsher 	if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
12419125cdd1SGiuseppe CAVALLARO 		pr_debug("\tskb len: %d, nopaged_len: %d,\n"
12427ac6653aSJeff Kirsher 			 "\t\tn_frags: %d, ip_summed: %d\n",
1243286a8372SGiuseppe CAVALLARO 			 skb->len, nopaged_len, nfrags, skb->ip_summed);
12447ac6653aSJeff Kirsher #endif
12457ac6653aSJeff Kirsher 	priv->tx_skbuff[entry] = skb;
1246286a8372SGiuseppe CAVALLARO 
1247286a8372SGiuseppe CAVALLARO 	if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) {
1248286a8372SGiuseppe CAVALLARO 		entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion);
12497ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
12507ac6653aSJeff Kirsher 	} else {
12517ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device, skb->data,
12527ac6653aSJeff Kirsher 					nopaged_len, DMA_TO_DEVICE);
12537ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
12547ac6653aSJeff Kirsher 						csum_insertion);
12557ac6653aSJeff Kirsher 	}
12567ac6653aSJeff Kirsher 
12577ac6653aSJeff Kirsher 	for (i = 0; i < nfrags; i++) {
12589e903e08SEric Dumazet 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
12599e903e08SEric Dumazet 		int len = skb_frag_size(frag);
12607ac6653aSJeff Kirsher 
12617ac6653aSJeff Kirsher 		entry = (++priv->cur_tx) % txsize;
12627ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
12637ac6653aSJeff Kirsher 
12647ac6653aSJeff Kirsher 		TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
1265f722380dSIan Campbell 		desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
1266f722380dSIan Campbell 					      DMA_TO_DEVICE);
12677ac6653aSJeff Kirsher 		priv->tx_skbuff[entry] = NULL;
12687ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
12697ac6653aSJeff Kirsher 		wmb();
12707ac6653aSJeff Kirsher 		priv->hw->desc->set_tx_owner(desc);
12718e839891SDeepak Sikri 		wmb();
12727ac6653aSJeff Kirsher 	}
12737ac6653aSJeff Kirsher 
12749125cdd1SGiuseppe CAVALLARO 	/* Finalize the latest segment. */
12757ac6653aSJeff Kirsher 	priv->hw->desc->close_tx_desc(desc);
12767ac6653aSJeff Kirsher 
12777ac6653aSJeff Kirsher 	wmb();
12789125cdd1SGiuseppe CAVALLARO 	/* According to the coalesce parameter the IC bit for the latest
12799125cdd1SGiuseppe CAVALLARO 	 * segment could be reset and the timer re-started to invoke the
12809125cdd1SGiuseppe CAVALLARO 	 * stmmac_tx function. This approach takes care about the fragments.
12819125cdd1SGiuseppe CAVALLARO 	 */
12829125cdd1SGiuseppe CAVALLARO 	priv->tx_count_frames += nfrags + 1;
12839125cdd1SGiuseppe CAVALLARO 	if (priv->tx_coal_frames > priv->tx_count_frames) {
12849125cdd1SGiuseppe CAVALLARO 		priv->hw->desc->clear_tx_ic(desc);
12859125cdd1SGiuseppe CAVALLARO 		priv->xstats.tx_reset_ic_bit++;
12869125cdd1SGiuseppe CAVALLARO 		TX_DBG("\t[entry %d]: tx_count_frames %d\n", entry,
12879125cdd1SGiuseppe CAVALLARO 		       priv->tx_count_frames);
12889125cdd1SGiuseppe CAVALLARO 		mod_timer(&priv->txtimer,
12899125cdd1SGiuseppe CAVALLARO 			  STMMAC_COAL_TIMER(priv->tx_coal_timer));
12909125cdd1SGiuseppe CAVALLARO 	} else
12919125cdd1SGiuseppe CAVALLARO 		priv->tx_count_frames = 0;
12927ac6653aSJeff Kirsher 
12937ac6653aSJeff Kirsher 	/* To avoid raise condition */
12947ac6653aSJeff Kirsher 	priv->hw->desc->set_tx_owner(first);
12958e839891SDeepak Sikri 	wmb();
12967ac6653aSJeff Kirsher 
12977ac6653aSJeff Kirsher 	priv->cur_tx++;
12987ac6653aSJeff Kirsher 
12997ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
13007ac6653aSJeff Kirsher 	if (netif_msg_pktdata(priv)) {
13017ac6653aSJeff Kirsher 		pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
13027ac6653aSJeff Kirsher 		       "first=%p, nfrags=%d\n",
13037ac6653aSJeff Kirsher 		       (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
13047ac6653aSJeff Kirsher 		       entry, first, nfrags);
13057ac6653aSJeff Kirsher 		display_ring(priv->dma_tx, txsize);
13067ac6653aSJeff Kirsher 		pr_info(">>> frame to be transmitted: ");
13077ac6653aSJeff Kirsher 		print_pkt(skb->data, skb->len);
13087ac6653aSJeff Kirsher 	}
13097ac6653aSJeff Kirsher #endif
13107ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
13117ac6653aSJeff Kirsher 		TX_DBG("%s: stop transmitted packets\n", __func__);
13127ac6653aSJeff Kirsher 		netif_stop_queue(dev);
13137ac6653aSJeff Kirsher 	}
13147ac6653aSJeff Kirsher 
13157ac6653aSJeff Kirsher 	dev->stats.tx_bytes += skb->len;
13167ac6653aSJeff Kirsher 
13177ac6653aSJeff Kirsher 	skb_tx_timestamp(skb);
13187ac6653aSJeff Kirsher 
13197ac6653aSJeff Kirsher 	priv->hw->dma->enable_dma_transmission(priv->ioaddr);
13207ac6653aSJeff Kirsher 
1321a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
1322a9097a96SGiuseppe CAVALLARO 
13237ac6653aSJeff Kirsher 	return NETDEV_TX_OK;
13247ac6653aSJeff Kirsher }
13257ac6653aSJeff Kirsher 
13267ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv)
13277ac6653aSJeff Kirsher {
13287ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
13297ac6653aSJeff Kirsher 	int bfsize = priv->dma_buf_sz;
13307ac6653aSJeff Kirsher 	struct dma_desc *p = priv->dma_rx;
13317ac6653aSJeff Kirsher 
13327ac6653aSJeff Kirsher 	for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
13337ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_rx % rxsize;
13347ac6653aSJeff Kirsher 		if (likely(priv->rx_skbuff[entry] == NULL)) {
13357ac6653aSJeff Kirsher 			struct sk_buff *skb;
13367ac6653aSJeff Kirsher 
1337acb600deSEric Dumazet 			skb = netdev_alloc_skb_ip_align(priv->dev, bfsize);
13387ac6653aSJeff Kirsher 
13397ac6653aSJeff Kirsher 			if (unlikely(skb == NULL))
13407ac6653aSJeff Kirsher 				break;
13417ac6653aSJeff Kirsher 
13427ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = skb;
13437ac6653aSJeff Kirsher 			priv->rx_skbuff_dma[entry] =
13447ac6653aSJeff Kirsher 			    dma_map_single(priv->device, skb->data, bfsize,
13457ac6653aSJeff Kirsher 					   DMA_FROM_DEVICE);
13467ac6653aSJeff Kirsher 
13477ac6653aSJeff Kirsher 			(p + entry)->des2 = priv->rx_skbuff_dma[entry];
1348286a8372SGiuseppe CAVALLARO 
1349286a8372SGiuseppe CAVALLARO 			if (unlikely(priv->plat->has_gmac))
1350286a8372SGiuseppe CAVALLARO 				priv->hw->ring->refill_desc3(bfsize, p + entry);
1351286a8372SGiuseppe CAVALLARO 
13527ac6653aSJeff Kirsher 			RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
13537ac6653aSJeff Kirsher 		}
13547ac6653aSJeff Kirsher 		wmb();
13557ac6653aSJeff Kirsher 		priv->hw->desc->set_rx_owner(p + entry);
13568e839891SDeepak Sikri 		wmb();
13577ac6653aSJeff Kirsher 	}
13587ac6653aSJeff Kirsher }
13597ac6653aSJeff Kirsher 
13607ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit)
13617ac6653aSJeff Kirsher {
13627ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
13637ac6653aSJeff Kirsher 	unsigned int entry = priv->cur_rx % rxsize;
13647ac6653aSJeff Kirsher 	unsigned int next_entry;
13657ac6653aSJeff Kirsher 	unsigned int count = 0;
13667ac6653aSJeff Kirsher 	struct dma_desc *p = priv->dma_rx + entry;
13677ac6653aSJeff Kirsher 	struct dma_desc *p_next;
13687ac6653aSJeff Kirsher 
13697ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
13707ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
13717ac6653aSJeff Kirsher 		pr_debug(">>> stmmac_rx: descriptor ring:\n");
13727ac6653aSJeff Kirsher 		display_ring(priv->dma_rx, rxsize);
13737ac6653aSJeff Kirsher 	}
13747ac6653aSJeff Kirsher #endif
13757ac6653aSJeff Kirsher 	while (!priv->hw->desc->get_rx_owner(p)) {
13767ac6653aSJeff Kirsher 		int status;
13777ac6653aSJeff Kirsher 
13787ac6653aSJeff Kirsher 		if (count >= limit)
13797ac6653aSJeff Kirsher 			break;
13807ac6653aSJeff Kirsher 
13817ac6653aSJeff Kirsher 		count++;
13827ac6653aSJeff Kirsher 
13837ac6653aSJeff Kirsher 		next_entry = (++priv->cur_rx) % rxsize;
13847ac6653aSJeff Kirsher 		p_next = priv->dma_rx + next_entry;
13857ac6653aSJeff Kirsher 		prefetch(p_next);
13867ac6653aSJeff Kirsher 
13877ac6653aSJeff Kirsher 		/* read the status of the incoming frame */
13887ac6653aSJeff Kirsher 		status = (priv->hw->desc->rx_status(&priv->dev->stats,
13897ac6653aSJeff Kirsher 						    &priv->xstats, p));
13907ac6653aSJeff Kirsher 		if (unlikely(status == discard_frame))
13917ac6653aSJeff Kirsher 			priv->dev->stats.rx_errors++;
13927ac6653aSJeff Kirsher 		else {
13937ac6653aSJeff Kirsher 			struct sk_buff *skb;
13947ac6653aSJeff Kirsher 			int frame_len;
13957ac6653aSJeff Kirsher 
139638912bdbSDeepak SIKRI 			frame_len = priv->hw->desc->get_rx_frame_len(p,
139738912bdbSDeepak SIKRI 					priv->plat->rx_coe);
13987ac6653aSJeff Kirsher 			/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
13997ac6653aSJeff Kirsher 			 * Type frames (LLC/LLC-SNAP) */
14007ac6653aSJeff Kirsher 			if (unlikely(status != llc_snap))
14017ac6653aSJeff Kirsher 				frame_len -= ETH_FCS_LEN;
14027ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
14037ac6653aSJeff Kirsher 			if (frame_len > ETH_FRAME_LEN)
14047ac6653aSJeff Kirsher 				pr_debug("\tRX frame size %d, COE status: %d\n",
14057ac6653aSJeff Kirsher 					frame_len, status);
14067ac6653aSJeff Kirsher 
14077ac6653aSJeff Kirsher 			if (netif_msg_hw(priv))
14087ac6653aSJeff Kirsher 				pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
14097ac6653aSJeff Kirsher 					p, entry, p->des2);
14107ac6653aSJeff Kirsher #endif
14117ac6653aSJeff Kirsher 			skb = priv->rx_skbuff[entry];
14127ac6653aSJeff Kirsher 			if (unlikely(!skb)) {
14137ac6653aSJeff Kirsher 				pr_err("%s: Inconsistent Rx descriptor chain\n",
14147ac6653aSJeff Kirsher 					priv->dev->name);
14157ac6653aSJeff Kirsher 				priv->dev->stats.rx_dropped++;
14167ac6653aSJeff Kirsher 				break;
14177ac6653aSJeff Kirsher 			}
14187ac6653aSJeff Kirsher 			prefetch(skb->data - NET_IP_ALIGN);
14197ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = NULL;
14207ac6653aSJeff Kirsher 
14217ac6653aSJeff Kirsher 			skb_put(skb, frame_len);
14227ac6653aSJeff Kirsher 			dma_unmap_single(priv->device,
14237ac6653aSJeff Kirsher 					 priv->rx_skbuff_dma[entry],
14247ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
14257ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
14267ac6653aSJeff Kirsher 			if (netif_msg_pktdata(priv)) {
14277ac6653aSJeff Kirsher 				pr_info(" frame received (%dbytes)", frame_len);
14287ac6653aSJeff Kirsher 				print_pkt(skb->data, frame_len);
14297ac6653aSJeff Kirsher 			}
14307ac6653aSJeff Kirsher #endif
14317ac6653aSJeff Kirsher 			skb->protocol = eth_type_trans(skb, priv->dev);
14327ac6653aSJeff Kirsher 
143362a2ab93SGiuseppe CAVALLARO 			if (unlikely(!priv->plat->rx_coe))
14347ac6653aSJeff Kirsher 				skb_checksum_none_assert(skb);
143562a2ab93SGiuseppe CAVALLARO 			else
14367ac6653aSJeff Kirsher 				skb->ip_summed = CHECKSUM_UNNECESSARY;
143762a2ab93SGiuseppe CAVALLARO 
14387ac6653aSJeff Kirsher 			napi_gro_receive(&priv->napi, skb);
14397ac6653aSJeff Kirsher 
14407ac6653aSJeff Kirsher 			priv->dev->stats.rx_packets++;
14417ac6653aSJeff Kirsher 			priv->dev->stats.rx_bytes += frame_len;
14427ac6653aSJeff Kirsher 		}
14437ac6653aSJeff Kirsher 		entry = next_entry;
14447ac6653aSJeff Kirsher 		p = p_next;	/* use prefetched values */
14457ac6653aSJeff Kirsher 	}
14467ac6653aSJeff Kirsher 
14477ac6653aSJeff Kirsher 	stmmac_rx_refill(priv);
14487ac6653aSJeff Kirsher 
14497ac6653aSJeff Kirsher 	priv->xstats.rx_pkt_n += count;
14507ac6653aSJeff Kirsher 
14517ac6653aSJeff Kirsher 	return count;
14527ac6653aSJeff Kirsher }
14537ac6653aSJeff Kirsher 
14547ac6653aSJeff Kirsher /**
14557ac6653aSJeff Kirsher  *  stmmac_poll - stmmac poll method (NAPI)
14567ac6653aSJeff Kirsher  *  @napi : pointer to the napi structure.
14577ac6653aSJeff Kirsher  *  @budget : maximum number of packets that the current CPU can receive from
14587ac6653aSJeff Kirsher  *	      all interfaces.
14597ac6653aSJeff Kirsher  *  Description :
14609125cdd1SGiuseppe CAVALLARO  *  To look at the incoming frames and clear the tx resources.
14617ac6653aSJeff Kirsher  */
14627ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget)
14637ac6653aSJeff Kirsher {
14647ac6653aSJeff Kirsher 	struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
14657ac6653aSJeff Kirsher 	int work_done = 0;
14667ac6653aSJeff Kirsher 
14679125cdd1SGiuseppe CAVALLARO 	priv->xstats.napi_poll++;
14689125cdd1SGiuseppe CAVALLARO 	stmmac_tx_clean(priv);
14697ac6653aSJeff Kirsher 
14709125cdd1SGiuseppe CAVALLARO 	work_done = stmmac_rx(priv, budget);
14717ac6653aSJeff Kirsher 	if (work_done < budget) {
14727ac6653aSJeff Kirsher 		napi_complete(napi);
14739125cdd1SGiuseppe CAVALLARO 		stmmac_enable_dma_irq(priv);
14747ac6653aSJeff Kirsher 	}
14757ac6653aSJeff Kirsher 	return work_done;
14767ac6653aSJeff Kirsher }
14777ac6653aSJeff Kirsher 
14787ac6653aSJeff Kirsher /**
14797ac6653aSJeff Kirsher  *  stmmac_tx_timeout
14807ac6653aSJeff Kirsher  *  @dev : Pointer to net device structure
14817ac6653aSJeff Kirsher  *  Description: this function is called when a packet transmission fails to
14827284a3f1SGiuseppe CAVALLARO  *   complete within a reasonable time. The driver will mark the error in the
14837ac6653aSJeff Kirsher  *   netdev structure and arrange for the device to be reset to a sane state
14847ac6653aSJeff Kirsher  *   in order to transmit a new packet.
14857ac6653aSJeff Kirsher  */
14867ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev)
14877ac6653aSJeff Kirsher {
14887ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
14897ac6653aSJeff Kirsher 
14907ac6653aSJeff Kirsher 	/* Clear Tx resources and restart transmitting again */
14917ac6653aSJeff Kirsher 	stmmac_tx_err(priv);
14927ac6653aSJeff Kirsher }
14937ac6653aSJeff Kirsher 
14947ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */
14957ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map)
14967ac6653aSJeff Kirsher {
14977ac6653aSJeff Kirsher 	if (dev->flags & IFF_UP)	/* can't act on a running interface */
14987ac6653aSJeff Kirsher 		return -EBUSY;
14997ac6653aSJeff Kirsher 
15007ac6653aSJeff Kirsher 	/* Don't allow changing the I/O address */
15017ac6653aSJeff Kirsher 	if (map->base_addr != dev->base_addr) {
15027ac6653aSJeff Kirsher 		pr_warning("%s: can't change I/O address\n", dev->name);
15037ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
15047ac6653aSJeff Kirsher 	}
15057ac6653aSJeff Kirsher 
15067ac6653aSJeff Kirsher 	/* Don't allow changing the IRQ */
15077ac6653aSJeff Kirsher 	if (map->irq != dev->irq) {
15087ac6653aSJeff Kirsher 		pr_warning("%s: can't change IRQ number %d\n",
15097ac6653aSJeff Kirsher 		       dev->name, dev->irq);
15107ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
15117ac6653aSJeff Kirsher 	}
15127ac6653aSJeff Kirsher 
15137ac6653aSJeff Kirsher 	/* ignore other fields */
15147ac6653aSJeff Kirsher 	return 0;
15157ac6653aSJeff Kirsher }
15167ac6653aSJeff Kirsher 
15177ac6653aSJeff Kirsher /**
151801789349SJiri Pirko  *  stmmac_set_rx_mode - entry point for multicast addressing
15197ac6653aSJeff Kirsher  *  @dev : pointer to the device structure
15207ac6653aSJeff Kirsher  *  Description:
15217ac6653aSJeff Kirsher  *  This function is a driver entry point which gets called by the kernel
15227ac6653aSJeff Kirsher  *  whenever multicast addresses must be enabled/disabled.
15237ac6653aSJeff Kirsher  *  Return value:
15247ac6653aSJeff Kirsher  *  void.
15257ac6653aSJeff Kirsher  */
152601789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev)
15277ac6653aSJeff Kirsher {
15287ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
15297ac6653aSJeff Kirsher 
15307ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
1531cffb13f4SGiuseppe CAVALLARO 	priv->hw->mac->set_filter(dev, priv->synopsys_id);
15327ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
15337ac6653aSJeff Kirsher }
15347ac6653aSJeff Kirsher 
15357ac6653aSJeff Kirsher /**
15367ac6653aSJeff Kirsher  *  stmmac_change_mtu - entry point to change MTU size for the device.
15377ac6653aSJeff Kirsher  *  @dev : device pointer.
15387ac6653aSJeff Kirsher  *  @new_mtu : the new MTU size for the device.
15397ac6653aSJeff Kirsher  *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
15407ac6653aSJeff Kirsher  *  to drive packet transmission. Ethernet has an MTU of 1500 octets
15417ac6653aSJeff Kirsher  *  (ETH_DATA_LEN). This value can be changed with ifconfig.
15427ac6653aSJeff Kirsher  *  Return value:
15437ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
15447ac6653aSJeff Kirsher  *  file on failure.
15457ac6653aSJeff Kirsher  */
15467ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
15477ac6653aSJeff Kirsher {
15487ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
15497ac6653aSJeff Kirsher 	int max_mtu;
15507ac6653aSJeff Kirsher 
15517ac6653aSJeff Kirsher 	if (netif_running(dev)) {
15527ac6653aSJeff Kirsher 		pr_err("%s: must be stopped to change its MTU\n", dev->name);
15537ac6653aSJeff Kirsher 		return -EBUSY;
15547ac6653aSJeff Kirsher 	}
15557ac6653aSJeff Kirsher 
155648febf7eSGiuseppe CAVALLARO 	if (priv->plat->enh_desc)
15577ac6653aSJeff Kirsher 		max_mtu = JUMBO_LEN;
15587ac6653aSJeff Kirsher 	else
155945db81e1SGiuseppe CAVALLARO 		max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
15607ac6653aSJeff Kirsher 
15617ac6653aSJeff Kirsher 	if ((new_mtu < 46) || (new_mtu > max_mtu)) {
15627ac6653aSJeff Kirsher 		pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
15637ac6653aSJeff Kirsher 		return -EINVAL;
15647ac6653aSJeff Kirsher 	}
15657ac6653aSJeff Kirsher 
15667ac6653aSJeff Kirsher 	dev->mtu = new_mtu;
15677ac6653aSJeff Kirsher 	netdev_update_features(dev);
15687ac6653aSJeff Kirsher 
15697ac6653aSJeff Kirsher 	return 0;
15707ac6653aSJeff Kirsher }
15717ac6653aSJeff Kirsher 
1572c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev,
1573c8f44affSMichał Mirosław 	netdev_features_t features)
15747ac6653aSJeff Kirsher {
15757ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
15767ac6653aSJeff Kirsher 
157738912bdbSDeepak SIKRI 	if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
15787ac6653aSJeff Kirsher 		features &= ~NETIF_F_RXCSUM;
157938912bdbSDeepak SIKRI 	else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
158038912bdbSDeepak SIKRI 		features &= ~NETIF_F_IPV6_CSUM;
15817ac6653aSJeff Kirsher 	if (!priv->plat->tx_coe)
15827ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
15837ac6653aSJeff Kirsher 
15847ac6653aSJeff Kirsher 	/* Some GMAC devices have a bugged Jumbo frame support that
15857ac6653aSJeff Kirsher 	 * needs to have the Tx COE disabled for oversized frames
15867ac6653aSJeff Kirsher 	 * (due to limited buffer sizes). In this case we disable
15877ac6653aSJeff Kirsher 	 * the TX csum insertionin the TDES and not use SF. */
15887ac6653aSJeff Kirsher 	if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
15897ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
15907ac6653aSJeff Kirsher 
15917ac6653aSJeff Kirsher 	return features;
15927ac6653aSJeff Kirsher }
15937ac6653aSJeff Kirsher 
15947ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
15957ac6653aSJeff Kirsher {
15967ac6653aSJeff Kirsher 	struct net_device *dev = (struct net_device *)dev_id;
15977ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
15987ac6653aSJeff Kirsher 
15997ac6653aSJeff Kirsher 	if (unlikely(!dev)) {
16007ac6653aSJeff Kirsher 		pr_err("%s: invalid dev pointer\n", __func__);
16017ac6653aSJeff Kirsher 		return IRQ_NONE;
16027ac6653aSJeff Kirsher 	}
16037ac6653aSJeff Kirsher 
16047ac6653aSJeff Kirsher 	/* To handle GMAC own interrupts */
1605d765955dSGiuseppe CAVALLARO 	if (priv->plat->has_gmac) {
1606d765955dSGiuseppe CAVALLARO 		int status = priv->hw->mac->host_irq_status((void __iomem *)
1607d765955dSGiuseppe CAVALLARO 							    dev->base_addr);
1608d765955dSGiuseppe CAVALLARO 		if (unlikely(status)) {
1609d765955dSGiuseppe CAVALLARO 			if (status & core_mmc_tx_irq)
1610d765955dSGiuseppe CAVALLARO 				priv->xstats.mmc_tx_irq_n++;
1611d765955dSGiuseppe CAVALLARO 			if (status & core_mmc_rx_irq)
1612d765955dSGiuseppe CAVALLARO 				priv->xstats.mmc_rx_irq_n++;
1613d765955dSGiuseppe CAVALLARO 			if (status & core_mmc_rx_csum_offload_irq)
1614d765955dSGiuseppe CAVALLARO 				priv->xstats.mmc_rx_csum_offload_irq_n++;
1615d765955dSGiuseppe CAVALLARO 			if (status & core_irq_receive_pmt_irq)
1616d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_receive_pmt_irq_n++;
16177ac6653aSJeff Kirsher 
1618d765955dSGiuseppe CAVALLARO 			/* For LPI we need to save the tx status */
1619d765955dSGiuseppe CAVALLARO 			if (status & core_irq_tx_path_in_lpi_mode) {
1620d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_tx_path_in_lpi_mode_n++;
1621d765955dSGiuseppe CAVALLARO 				priv->tx_path_in_lpi_mode = true;
1622d765955dSGiuseppe CAVALLARO 			}
1623d765955dSGiuseppe CAVALLARO 			if (status & core_irq_tx_path_exit_lpi_mode) {
1624d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_tx_path_exit_lpi_mode_n++;
1625d765955dSGiuseppe CAVALLARO 				priv->tx_path_in_lpi_mode = false;
1626d765955dSGiuseppe CAVALLARO 			}
1627d765955dSGiuseppe CAVALLARO 			if (status & core_irq_rx_path_in_lpi_mode)
1628d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_rx_path_in_lpi_mode_n++;
1629d765955dSGiuseppe CAVALLARO 			if (status & core_irq_rx_path_exit_lpi_mode)
1630d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_rx_path_exit_lpi_mode_n++;
1631d765955dSGiuseppe CAVALLARO 		}
1632d765955dSGiuseppe CAVALLARO 	}
1633d765955dSGiuseppe CAVALLARO 
1634d765955dSGiuseppe CAVALLARO 	/* To handle DMA interrupts */
16357ac6653aSJeff Kirsher 	stmmac_dma_interrupt(priv);
16367ac6653aSJeff Kirsher 
16377ac6653aSJeff Kirsher 	return IRQ_HANDLED;
16387ac6653aSJeff Kirsher }
16397ac6653aSJeff Kirsher 
16407ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
16417ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools
16427ac6653aSJeff Kirsher  * to allow network I/O with interrupts disabled. */
16437ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev)
16447ac6653aSJeff Kirsher {
16457ac6653aSJeff Kirsher 	disable_irq(dev->irq);
16467ac6653aSJeff Kirsher 	stmmac_interrupt(dev->irq, dev);
16477ac6653aSJeff Kirsher 	enable_irq(dev->irq);
16487ac6653aSJeff Kirsher }
16497ac6653aSJeff Kirsher #endif
16507ac6653aSJeff Kirsher 
16517ac6653aSJeff Kirsher /**
16527ac6653aSJeff Kirsher  *  stmmac_ioctl - Entry point for the Ioctl
16537ac6653aSJeff Kirsher  *  @dev: Device pointer.
16547ac6653aSJeff Kirsher  *  @rq: An IOCTL specefic structure, that can contain a pointer to
16557ac6653aSJeff Kirsher  *  a proprietary structure used to pass information to the driver.
16567ac6653aSJeff Kirsher  *  @cmd: IOCTL command
16577ac6653aSJeff Kirsher  *  Description:
16587ac6653aSJeff Kirsher  *  Currently there are no special functionality supported in IOCTL, just the
16597ac6653aSJeff Kirsher  *  phy_mii_ioctl(...) can be invoked.
16607ac6653aSJeff Kirsher  */
16617ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
16627ac6653aSJeff Kirsher {
16637ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
16647ac6653aSJeff Kirsher 	int ret;
16657ac6653aSJeff Kirsher 
16667ac6653aSJeff Kirsher 	if (!netif_running(dev))
16677ac6653aSJeff Kirsher 		return -EINVAL;
16687ac6653aSJeff Kirsher 
16697ac6653aSJeff Kirsher 	if (!priv->phydev)
16707ac6653aSJeff Kirsher 		return -EINVAL;
16717ac6653aSJeff Kirsher 
16727ac6653aSJeff Kirsher 	ret = phy_mii_ioctl(priv->phydev, rq, cmd);
16737ac6653aSJeff Kirsher 
16747ac6653aSJeff Kirsher 	return ret;
16757ac6653aSJeff Kirsher }
16767ac6653aSJeff Kirsher 
16777ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
16787ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir;
16797ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status;
1680e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap;
16817ac29055SGiuseppe CAVALLARO 
16827ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
16837ac29055SGiuseppe CAVALLARO {
16847ac29055SGiuseppe CAVALLARO 	struct tmp_s {
16857ac29055SGiuseppe CAVALLARO 		u64 a;
16867ac29055SGiuseppe CAVALLARO 		unsigned int b;
16877ac29055SGiuseppe CAVALLARO 		unsigned int c;
16887ac29055SGiuseppe CAVALLARO 	};
16897ac29055SGiuseppe CAVALLARO 	int i;
16907ac29055SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
16917ac29055SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
16927ac29055SGiuseppe CAVALLARO 
16937ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
16947ac29055SGiuseppe CAVALLARO 	seq_printf(seq, " RX descriptor ring\n");
16957ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
16967ac29055SGiuseppe CAVALLARO 
16977ac29055SGiuseppe CAVALLARO 	for (i = 0; i < priv->dma_rx_size; i++) {
16987ac29055SGiuseppe CAVALLARO 		struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i);
16997ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
17007ac29055SGiuseppe CAVALLARO 			   i, (unsigned int)(x->a),
17017ac29055SGiuseppe CAVALLARO 			   (unsigned int)((x->a) >> 32), x->b, x->c);
17027ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
17037ac29055SGiuseppe CAVALLARO 	}
17047ac29055SGiuseppe CAVALLARO 
17057ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "\n");
17067ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
17077ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "  TX descriptor ring\n");
17087ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
17097ac29055SGiuseppe CAVALLARO 
17107ac29055SGiuseppe CAVALLARO 	for (i = 0; i < priv->dma_tx_size; i++) {
17117ac29055SGiuseppe CAVALLARO 		struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i);
17127ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
17137ac29055SGiuseppe CAVALLARO 			   i, (unsigned int)(x->a),
17147ac29055SGiuseppe CAVALLARO 			   (unsigned int)((x->a) >> 32), x->b, x->c);
17157ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
17167ac29055SGiuseppe CAVALLARO 	}
17177ac29055SGiuseppe CAVALLARO 
17187ac29055SGiuseppe CAVALLARO 	return 0;
17197ac29055SGiuseppe CAVALLARO }
17207ac29055SGiuseppe CAVALLARO 
17217ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file)
17227ac29055SGiuseppe CAVALLARO {
17237ac29055SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_ring_read, inode->i_private);
17247ac29055SGiuseppe CAVALLARO }
17257ac29055SGiuseppe CAVALLARO 
17267ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = {
17277ac29055SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
17287ac29055SGiuseppe CAVALLARO 	.open = stmmac_sysfs_ring_open,
17297ac29055SGiuseppe CAVALLARO 	.read = seq_read,
17307ac29055SGiuseppe CAVALLARO 	.llseek = seq_lseek,
173174863948SDjalal Harouni 	.release = single_release,
17327ac29055SGiuseppe CAVALLARO };
17337ac29055SGiuseppe CAVALLARO 
1734e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
1735e7434821SGiuseppe CAVALLARO {
1736e7434821SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
1737e7434821SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
1738e7434821SGiuseppe CAVALLARO 
173919e30c14SGiuseppe CAVALLARO 	if (!priv->hw_cap_support) {
1740e7434821SGiuseppe CAVALLARO 		seq_printf(seq, "DMA HW features not supported\n");
1741e7434821SGiuseppe CAVALLARO 		return 0;
1742e7434821SGiuseppe CAVALLARO 	}
1743e7434821SGiuseppe CAVALLARO 
1744e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
1745e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tDMA HW features\n");
1746e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
1747e7434821SGiuseppe CAVALLARO 
1748e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t10/100 Mbps %s\n",
1749e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_10_100) ? "Y" : "N");
1750e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t1000 Mbps %s\n",
1751e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_1000) ? "Y" : "N");
1752e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHalf duple %s\n",
1753e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.half_duplex) ? "Y" : "N");
1754e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHash Filter: %s\n",
1755e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.hash_filter) ? "Y" : "N");
1756e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tMultiple MAC address registers: %s\n",
1757e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.multi_addr) ? "Y" : "N");
1758e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n",
1759e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pcs) ? "Y" : "N");
1760e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tSMA (MDIO) Interface: %s\n",
1761e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.sma_mdio) ? "Y" : "N");
1762e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Remote wake up: %s\n",
1763e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N");
1764e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Magic Frame: %s\n",
1765e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_magic_frame) ? "Y" : "N");
1766e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRMON module: %s\n",
1767e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rmon) ? "Y" : "N");
1768e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n",
1769e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.time_stamp) ? "Y" : "N");
1770e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n",
1771e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.atime_stamp) ? "Y" : "N");
1772e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n",
1773e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.eee) ? "Y" : "N");
1774e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N");
1775e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tChecksum Offload in TX: %s\n",
1776e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.tx_coe) ? "Y" : "N");
1777e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n",
1778e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type1) ? "Y" : "N");
1779e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
1780e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type2) ? "Y" : "N");
1781e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n",
1782e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N");
1783e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional RX channel: %d\n",
1784e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_rx_channel);
1785e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional TX channel: %d\n",
1786e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_tx_channel);
1787e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tEnhanced descriptors: %s\n",
1788e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.enh_desc) ? "Y" : "N");
1789e7434821SGiuseppe CAVALLARO 
1790e7434821SGiuseppe CAVALLARO 	return 0;
1791e7434821SGiuseppe CAVALLARO }
1792e7434821SGiuseppe CAVALLARO 
1793e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file)
1794e7434821SGiuseppe CAVALLARO {
1795e7434821SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private);
1796e7434821SGiuseppe CAVALLARO }
1797e7434821SGiuseppe CAVALLARO 
1798e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = {
1799e7434821SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
1800e7434821SGiuseppe CAVALLARO 	.open = stmmac_sysfs_dma_cap_open,
1801e7434821SGiuseppe CAVALLARO 	.read = seq_read,
1802e7434821SGiuseppe CAVALLARO 	.llseek = seq_lseek,
180374863948SDjalal Harouni 	.release = single_release,
1804e7434821SGiuseppe CAVALLARO };
1805e7434821SGiuseppe CAVALLARO 
18067ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev)
18077ac29055SGiuseppe CAVALLARO {
18087ac29055SGiuseppe CAVALLARO 	/* Create debugfs entries */
18097ac29055SGiuseppe CAVALLARO 	stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
18107ac29055SGiuseppe CAVALLARO 
18117ac29055SGiuseppe CAVALLARO 	if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
18127ac29055SGiuseppe CAVALLARO 		pr_err("ERROR %s, debugfs create directory failed\n",
18137ac29055SGiuseppe CAVALLARO 		       STMMAC_RESOURCE_NAME);
18147ac29055SGiuseppe CAVALLARO 
18157ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
18167ac29055SGiuseppe CAVALLARO 	}
18177ac29055SGiuseppe CAVALLARO 
18187ac29055SGiuseppe CAVALLARO 	/* Entry to report DMA RX/TX rings */
18197ac29055SGiuseppe CAVALLARO 	stmmac_rings_status = debugfs_create_file("descriptors_status",
18207ac29055SGiuseppe CAVALLARO 					   S_IRUGO, stmmac_fs_dir, dev,
18217ac29055SGiuseppe CAVALLARO 					   &stmmac_rings_status_fops);
18227ac29055SGiuseppe CAVALLARO 
18237ac29055SGiuseppe CAVALLARO 	if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
18247ac29055SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac ring debugfs file\n");
18257ac29055SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
18267ac29055SGiuseppe CAVALLARO 
18277ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
18287ac29055SGiuseppe CAVALLARO 	}
18297ac29055SGiuseppe CAVALLARO 
1830e7434821SGiuseppe CAVALLARO 	/* Entry to report the DMA HW features */
1831e7434821SGiuseppe CAVALLARO 	stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
1832e7434821SGiuseppe CAVALLARO 					     dev, &stmmac_dma_cap_fops);
1833e7434821SGiuseppe CAVALLARO 
1834e7434821SGiuseppe CAVALLARO 	if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
1835e7434821SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac MMC debugfs file\n");
1836e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_rings_status);
1837e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
1838e7434821SGiuseppe CAVALLARO 
1839e7434821SGiuseppe CAVALLARO 		return -ENOMEM;
1840e7434821SGiuseppe CAVALLARO 	}
1841e7434821SGiuseppe CAVALLARO 
18427ac29055SGiuseppe CAVALLARO 	return 0;
18437ac29055SGiuseppe CAVALLARO }
18447ac29055SGiuseppe CAVALLARO 
18457ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void)
18467ac29055SGiuseppe CAVALLARO {
18477ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_rings_status);
1848e7434821SGiuseppe CAVALLARO 	debugfs_remove(stmmac_dma_cap);
18497ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_fs_dir);
18507ac29055SGiuseppe CAVALLARO }
18517ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */
18527ac29055SGiuseppe CAVALLARO 
18537ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = {
18547ac6653aSJeff Kirsher 	.ndo_open = stmmac_open,
18557ac6653aSJeff Kirsher 	.ndo_start_xmit = stmmac_xmit,
18567ac6653aSJeff Kirsher 	.ndo_stop = stmmac_release,
18577ac6653aSJeff Kirsher 	.ndo_change_mtu = stmmac_change_mtu,
18587ac6653aSJeff Kirsher 	.ndo_fix_features = stmmac_fix_features,
185901789349SJiri Pirko 	.ndo_set_rx_mode = stmmac_set_rx_mode,
18607ac6653aSJeff Kirsher 	.ndo_tx_timeout = stmmac_tx_timeout,
18617ac6653aSJeff Kirsher 	.ndo_do_ioctl = stmmac_ioctl,
18627ac6653aSJeff Kirsher 	.ndo_set_config = stmmac_config,
18637ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
18647ac6653aSJeff Kirsher 	.ndo_poll_controller = stmmac_poll_controller,
18657ac6653aSJeff Kirsher #endif
18667ac6653aSJeff Kirsher 	.ndo_set_mac_address = eth_mac_addr,
18677ac6653aSJeff Kirsher };
18687ac6653aSJeff Kirsher 
18697ac6653aSJeff Kirsher /**
1870cf3f047bSGiuseppe CAVALLARO  *  stmmac_hw_init - Init the MAC device
1871cf3f047bSGiuseppe CAVALLARO  *  @priv : pointer to the private device structure.
1872cf3f047bSGiuseppe CAVALLARO  *  Description: this function detects which MAC device
1873cf3f047bSGiuseppe CAVALLARO  *  (GMAC/MAC10-100) has to attached, checks the HW capability
1874cf3f047bSGiuseppe CAVALLARO  *  (if supported) and sets the driver's features (for example
1875cf3f047bSGiuseppe CAVALLARO  *  to use the ring or chaine mode or support the normal/enh
1876cf3f047bSGiuseppe CAVALLARO  *  descriptor structure).
1877cf3f047bSGiuseppe CAVALLARO  */
1878cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv)
1879cf3f047bSGiuseppe CAVALLARO {
1880cf3f047bSGiuseppe CAVALLARO 	int ret = 0;
1881cf3f047bSGiuseppe CAVALLARO 	struct mac_device_info *mac;
1882cf3f047bSGiuseppe CAVALLARO 
1883cf3f047bSGiuseppe CAVALLARO 	/* Identify the MAC HW device */
188403f2eecdSMarc Kleine-Budde 	if (priv->plat->has_gmac) {
188503f2eecdSMarc Kleine-Budde 		priv->dev->priv_flags |= IFF_UNICAST_FLT;
1886cf3f047bSGiuseppe CAVALLARO 		mac = dwmac1000_setup(priv->ioaddr);
188703f2eecdSMarc Kleine-Budde 	} else {
1888cf3f047bSGiuseppe CAVALLARO 		mac = dwmac100_setup(priv->ioaddr);
188903f2eecdSMarc Kleine-Budde 	}
1890cf3f047bSGiuseppe CAVALLARO 	if (!mac)
1891cf3f047bSGiuseppe CAVALLARO 		return -ENOMEM;
1892cf3f047bSGiuseppe CAVALLARO 
1893cf3f047bSGiuseppe CAVALLARO 	priv->hw = mac;
1894cf3f047bSGiuseppe CAVALLARO 
1895cf3f047bSGiuseppe CAVALLARO 	/* To use the chained or ring mode */
1896cf3f047bSGiuseppe CAVALLARO 	priv->hw->ring = &ring_mode_ops;
1897cf3f047bSGiuseppe CAVALLARO 
1898cf3f047bSGiuseppe CAVALLARO 	/* Get and dump the chip ID */
1899cffb13f4SGiuseppe CAVALLARO 	priv->synopsys_id = stmmac_get_synopsys_id(priv);
1900cf3f047bSGiuseppe CAVALLARO 
1901cf3f047bSGiuseppe CAVALLARO 	/* Get the HW capability (new GMAC newer than 3.50a) */
1902cf3f047bSGiuseppe CAVALLARO 	priv->hw_cap_support = stmmac_get_hw_features(priv);
1903cf3f047bSGiuseppe CAVALLARO 	if (priv->hw_cap_support) {
1904cf3f047bSGiuseppe CAVALLARO 		pr_info(" DMA HW capability register supported");
1905cf3f047bSGiuseppe CAVALLARO 
1906cf3f047bSGiuseppe CAVALLARO 		/* We can override some gmac/dma configuration fields: e.g.
1907cf3f047bSGiuseppe CAVALLARO 		 * enh_desc, tx_coe (e.g. that are passed through the
1908cf3f047bSGiuseppe CAVALLARO 		 * platform) with the values from the HW capability
1909cf3f047bSGiuseppe CAVALLARO 		 * register (if supported).
1910cf3f047bSGiuseppe CAVALLARO 		 */
1911cf3f047bSGiuseppe CAVALLARO 		priv->plat->enh_desc = priv->dma_cap.enh_desc;
1912cf3f047bSGiuseppe CAVALLARO 		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
191338912bdbSDeepak SIKRI 
191438912bdbSDeepak SIKRI 		priv->plat->tx_coe = priv->dma_cap.tx_coe;
191538912bdbSDeepak SIKRI 
191638912bdbSDeepak SIKRI 		if (priv->dma_cap.rx_coe_type2)
191738912bdbSDeepak SIKRI 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
191838912bdbSDeepak SIKRI 		else if (priv->dma_cap.rx_coe_type1)
191938912bdbSDeepak SIKRI 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE1;
192038912bdbSDeepak SIKRI 
1921cf3f047bSGiuseppe CAVALLARO 	} else
1922cf3f047bSGiuseppe CAVALLARO 		pr_info(" No HW DMA feature register supported");
1923cf3f047bSGiuseppe CAVALLARO 
1924cf3f047bSGiuseppe CAVALLARO 	/* Select the enhnaced/normal descriptor structures */
1925cf3f047bSGiuseppe CAVALLARO 	stmmac_selec_desc_mode(priv);
1926cf3f047bSGiuseppe CAVALLARO 
192738912bdbSDeepak SIKRI 	/* Enable the IPC (Checksum Offload) and check if the feature has been
192838912bdbSDeepak SIKRI 	 * enabled during the core configuration. */
192938912bdbSDeepak SIKRI 	ret = priv->hw->mac->rx_ipc(priv->ioaddr);
193038912bdbSDeepak SIKRI 	if (!ret) {
193138912bdbSDeepak SIKRI 		pr_warning(" RX IPC Checksum Offload not configured.\n");
193238912bdbSDeepak SIKRI 		priv->plat->rx_coe = STMMAC_RX_COE_NONE;
193338912bdbSDeepak SIKRI 	}
193438912bdbSDeepak SIKRI 
193538912bdbSDeepak SIKRI 	if (priv->plat->rx_coe)
193638912bdbSDeepak SIKRI 		pr_info(" RX Checksum Offload Engine supported (type %d)\n",
193738912bdbSDeepak SIKRI 			priv->plat->rx_coe);
1938cf3f047bSGiuseppe CAVALLARO 	if (priv->plat->tx_coe)
1939cf3f047bSGiuseppe CAVALLARO 		pr_info(" TX Checksum insertion supported\n");
1940cf3f047bSGiuseppe CAVALLARO 
1941cf3f047bSGiuseppe CAVALLARO 	if (priv->plat->pmt) {
1942cf3f047bSGiuseppe CAVALLARO 		pr_info(" Wake-Up On Lan supported\n");
1943cf3f047bSGiuseppe CAVALLARO 		device_set_wakeup_capable(priv->device, 1);
1944cf3f047bSGiuseppe CAVALLARO 	}
1945cf3f047bSGiuseppe CAVALLARO 
1946cf3f047bSGiuseppe CAVALLARO 	return ret;
1947cf3f047bSGiuseppe CAVALLARO }
1948cf3f047bSGiuseppe CAVALLARO 
1949cf3f047bSGiuseppe CAVALLARO /**
1950bfab27a1SGiuseppe CAVALLARO  * stmmac_dvr_probe
1951bfab27a1SGiuseppe CAVALLARO  * @device: device pointer
1952ff3dd78cSGiuseppe CAVALLARO  * @plat_dat: platform data pointer
1953ff3dd78cSGiuseppe CAVALLARO  * @addr: iobase memory address
1954bfab27a1SGiuseppe CAVALLARO  * Description: this is the main probe function used to
1955bfab27a1SGiuseppe CAVALLARO  * call the alloc_etherdev, allocate the priv structure.
19567ac6653aSJeff Kirsher  */
1957bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device,
1958cf3f047bSGiuseppe CAVALLARO 				     struct plat_stmmacenet_data *plat_dat,
1959cf3f047bSGiuseppe CAVALLARO 				     void __iomem *addr)
19607ac6653aSJeff Kirsher {
19617ac6653aSJeff Kirsher 	int ret = 0;
1962bfab27a1SGiuseppe CAVALLARO 	struct net_device *ndev = NULL;
1963bfab27a1SGiuseppe CAVALLARO 	struct stmmac_priv *priv;
19647ac6653aSJeff Kirsher 
1965bfab27a1SGiuseppe CAVALLARO 	ndev = alloc_etherdev(sizeof(struct stmmac_priv));
196641de8d4cSJoe Perches 	if (!ndev)
1967bfab27a1SGiuseppe CAVALLARO 		return NULL;
19687ac6653aSJeff Kirsher 
1969bfab27a1SGiuseppe CAVALLARO 	SET_NETDEV_DEV(ndev, device);
19707ac6653aSJeff Kirsher 
1971bfab27a1SGiuseppe CAVALLARO 	priv = netdev_priv(ndev);
1972bfab27a1SGiuseppe CAVALLARO 	priv->device = device;
1973bfab27a1SGiuseppe CAVALLARO 	priv->dev = ndev;
1974bfab27a1SGiuseppe CAVALLARO 
1975bfab27a1SGiuseppe CAVALLARO 	ether_setup(ndev);
1976bfab27a1SGiuseppe CAVALLARO 
1977bfab27a1SGiuseppe CAVALLARO 	stmmac_set_ethtool_ops(ndev);
1978cf3f047bSGiuseppe CAVALLARO 	priv->pause = pause;
1979cf3f047bSGiuseppe CAVALLARO 	priv->plat = plat_dat;
1980cf3f047bSGiuseppe CAVALLARO 	priv->ioaddr = addr;
1981cf3f047bSGiuseppe CAVALLARO 	priv->dev->base_addr = (unsigned long)addr;
1982bfab27a1SGiuseppe CAVALLARO 
1983cf3f047bSGiuseppe CAVALLARO 	/* Verify driver arguments */
1984cf3f047bSGiuseppe CAVALLARO 	stmmac_verify_args();
1985cf3f047bSGiuseppe CAVALLARO 
1986cf3f047bSGiuseppe CAVALLARO 	/* Override with kernel parameters if supplied XXX CRS XXX
1987cf3f047bSGiuseppe CAVALLARO 	 * this needs to have multiple instances */
1988cf3f047bSGiuseppe CAVALLARO 	if ((phyaddr >= 0) && (phyaddr <= 31))
1989cf3f047bSGiuseppe CAVALLARO 		priv->plat->phy_addr = phyaddr;
1990cf3f047bSGiuseppe CAVALLARO 
1991cf3f047bSGiuseppe CAVALLARO 	/* Init MAC and get the capabilities */
1992cf3f047bSGiuseppe CAVALLARO 	stmmac_hw_init(priv);
1993cf3f047bSGiuseppe CAVALLARO 
1994cf3f047bSGiuseppe CAVALLARO 	ndev->netdev_ops = &stmmac_netdev_ops;
1995cf3f047bSGiuseppe CAVALLARO 
1996cf3f047bSGiuseppe CAVALLARO 	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
1997cf3f047bSGiuseppe CAVALLARO 			    NETIF_F_RXCSUM;
1998bfab27a1SGiuseppe CAVALLARO 	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
1999bfab27a1SGiuseppe CAVALLARO 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
20007ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED
20017ac6653aSJeff Kirsher 	/* Both mac100 and gmac support receive VLAN tag detection */
2002bfab27a1SGiuseppe CAVALLARO 	ndev->features |= NETIF_F_HW_VLAN_RX;
20037ac6653aSJeff Kirsher #endif
20047ac6653aSJeff Kirsher 	priv->msg_enable = netif_msg_init(debug, default_msg_level);
20057ac6653aSJeff Kirsher 
20067ac6653aSJeff Kirsher 	if (flow_ctrl)
20077ac6653aSJeff Kirsher 		priv->flow_ctrl = FLOW_AUTO;	/* RX/TX pause on */
20087ac6653aSJeff Kirsher 
200962a2ab93SGiuseppe CAVALLARO 	/* Rx Watchdog is available in the COREs newer than the 3.40.
201062a2ab93SGiuseppe CAVALLARO 	 * In some case, for example on bugged HW this feature
201162a2ab93SGiuseppe CAVALLARO 	 * has to be disable and this can be done by passing the
201262a2ab93SGiuseppe CAVALLARO 	 * riwt_off field from the platform.
201362a2ab93SGiuseppe CAVALLARO 	 */
201462a2ab93SGiuseppe CAVALLARO 	if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) {
201562a2ab93SGiuseppe CAVALLARO 		priv->use_riwt = 1;
201662a2ab93SGiuseppe CAVALLARO 		pr_info(" Enable RX Mitigation via HW Watchdog Timer\n");
201762a2ab93SGiuseppe CAVALLARO 	}
201862a2ab93SGiuseppe CAVALLARO 
2019bfab27a1SGiuseppe CAVALLARO 	netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
20207ac6653aSJeff Kirsher 
20217ac6653aSJeff Kirsher 	spin_lock_init(&priv->lock);
2022a9097a96SGiuseppe CAVALLARO 	spin_lock_init(&priv->tx_lock);
20237ac6653aSJeff Kirsher 
2024bfab27a1SGiuseppe CAVALLARO 	ret = register_netdev(ndev);
20257ac6653aSJeff Kirsher 	if (ret) {
2026cf3f047bSGiuseppe CAVALLARO 		pr_err("%s: ERROR %i registering the device\n", __func__, ret);
20276a81c26fSViresh Kumar 		goto error_netdev_register;
20287ac6653aSJeff Kirsher 	}
20297ac6653aSJeff Kirsher 
2030ae4d8cf2SKelvin Cheung 	priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
20316a81c26fSViresh Kumar 	if (IS_ERR(priv->stmmac_clk)) {
203231ea38eeSGiuseppe CAVALLARO 		pr_warning("%s: warning: cannot get CSR clock\n", __func__);
20336a81c26fSViresh Kumar 		goto error_clk_get;
20346a81c26fSViresh Kumar 	}
2035ba1377ffSGiuseppe CAVALLARO 
2036cd7201f4SGiuseppe CAVALLARO 	/* If a specific clk_csr value is passed from the platform
2037cd7201f4SGiuseppe CAVALLARO 	 * this means that the CSR Clock Range selection cannot be
2038cd7201f4SGiuseppe CAVALLARO 	 * changed at run-time and it is fixed. Viceversa the driver'll try to
2039cd7201f4SGiuseppe CAVALLARO 	 * set the MDC clock dynamically according to the csr actual
2040cd7201f4SGiuseppe CAVALLARO 	 * clock input.
2041cd7201f4SGiuseppe CAVALLARO 	 */
2042cd7201f4SGiuseppe CAVALLARO 	if (!priv->plat->clk_csr)
2043cd7201f4SGiuseppe CAVALLARO 		stmmac_clk_csr_set(priv);
2044cd7201f4SGiuseppe CAVALLARO 	else
2045cd7201f4SGiuseppe CAVALLARO 		priv->clk_csr = priv->plat->clk_csr;
2046cd7201f4SGiuseppe CAVALLARO 
20474bfcbd7aSFrancesco Virlinzi 	/* MDIO bus Registration */
20484bfcbd7aSFrancesco Virlinzi 	ret = stmmac_mdio_register(ndev);
20494bfcbd7aSFrancesco Virlinzi 	if (ret < 0) {
20504bfcbd7aSFrancesco Virlinzi 		pr_debug("%s: MDIO bus (id: %d) registration failed",
20514bfcbd7aSFrancesco Virlinzi 			 __func__, priv->plat->bus_id);
20526a81c26fSViresh Kumar 		goto error_mdio_register;
20534bfcbd7aSFrancesco Virlinzi 	}
20544bfcbd7aSFrancesco Virlinzi 
2055bfab27a1SGiuseppe CAVALLARO 	return priv;
20567ac6653aSJeff Kirsher 
20576a81c26fSViresh Kumar error_mdio_register:
20586a81c26fSViresh Kumar 	clk_put(priv->stmmac_clk);
20596a81c26fSViresh Kumar error_clk_get:
20607ac6653aSJeff Kirsher 	unregister_netdev(ndev);
20616a81c26fSViresh Kumar error_netdev_register:
20626a81c26fSViresh Kumar 	netif_napi_del(&priv->napi);
20637ac6653aSJeff Kirsher 	free_netdev(ndev);
20647ac6653aSJeff Kirsher 
2065bfab27a1SGiuseppe CAVALLARO 	return NULL;
20667ac6653aSJeff Kirsher }
20677ac6653aSJeff Kirsher 
20687ac6653aSJeff Kirsher /**
20697ac6653aSJeff Kirsher  * stmmac_dvr_remove
2070bfab27a1SGiuseppe CAVALLARO  * @ndev: net device pointer
20717ac6653aSJeff Kirsher  * Description: this function resets the TX/RX processes, disables the MAC RX/TX
2072bfab27a1SGiuseppe CAVALLARO  * changes the link status, releases the DMA descriptor rings.
20737ac6653aSJeff Kirsher  */
2074bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev)
20757ac6653aSJeff Kirsher {
20767ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
20777ac6653aSJeff Kirsher 
20787ac6653aSJeff Kirsher 	pr_info("%s:\n\tremoving driver", __func__);
20797ac6653aSJeff Kirsher 
20807ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
20817ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
20827ac6653aSJeff Kirsher 
2083bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, false);
20844bfcbd7aSFrancesco Virlinzi 	stmmac_mdio_unregister(ndev);
20857ac6653aSJeff Kirsher 	netif_carrier_off(ndev);
20867ac6653aSJeff Kirsher 	unregister_netdev(ndev);
20877ac6653aSJeff Kirsher 	free_netdev(ndev);
20887ac6653aSJeff Kirsher 
20897ac6653aSJeff Kirsher 	return 0;
20907ac6653aSJeff Kirsher }
20917ac6653aSJeff Kirsher 
20927ac6653aSJeff Kirsher #ifdef CONFIG_PM
2093bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev)
20947ac6653aSJeff Kirsher {
20957ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
20967ac6653aSJeff Kirsher 	int dis_ic = 0;
2097f8c5a875SGiuseppe CAVALLARO 	unsigned long flags;
20987ac6653aSJeff Kirsher 
20997ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
21007ac6653aSJeff Kirsher 		return 0;
21017ac6653aSJeff Kirsher 
2102102463b1SFrancesco Virlinzi 	if (priv->phydev)
2103102463b1SFrancesco Virlinzi 		phy_stop(priv->phydev);
2104102463b1SFrancesco Virlinzi 
2105f8c5a875SGiuseppe CAVALLARO 	spin_lock_irqsave(&priv->lock, flags);
21067ac6653aSJeff Kirsher 
21077ac6653aSJeff Kirsher 	netif_device_detach(ndev);
21087ac6653aSJeff Kirsher 	netif_stop_queue(ndev);
21097ac6653aSJeff Kirsher 
211062a2ab93SGiuseppe CAVALLARO 	if (priv->use_riwt)
211162a2ab93SGiuseppe CAVALLARO 		dis_ic = 1;
211262a2ab93SGiuseppe CAVALLARO 
21137ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
21147ac6653aSJeff Kirsher 
21157ac6653aSJeff Kirsher 	/* Stop TX/RX DMA */
21167ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
21177ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
21187ac6653aSJeff Kirsher 	/* Clear the Rx/Tx descriptors */
21197ac6653aSJeff Kirsher 	priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
21207ac6653aSJeff Kirsher 				     dis_ic);
21217ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
21227ac6653aSJeff Kirsher 
21237ac6653aSJeff Kirsher 	/* Enable Power down mode by programming the PMT regs */
21247ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
21257ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
2126ba1377ffSGiuseppe CAVALLARO 	else {
2127bfab27a1SGiuseppe CAVALLARO 		stmmac_set_mac(priv->ioaddr, false);
2128ba1377ffSGiuseppe CAVALLARO 		/* Disable clock in case of PWM is off */
2129a630844dSStefan Roese 		clk_disable_unprepare(priv->stmmac_clk);
2130ba1377ffSGiuseppe CAVALLARO 	}
2131f8c5a875SGiuseppe CAVALLARO 	spin_unlock_irqrestore(&priv->lock, flags);
21327ac6653aSJeff Kirsher 	return 0;
21337ac6653aSJeff Kirsher }
21347ac6653aSJeff Kirsher 
2135bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev)
21367ac6653aSJeff Kirsher {
21377ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
2138f8c5a875SGiuseppe CAVALLARO 	unsigned long flags;
21397ac6653aSJeff Kirsher 
21407ac6653aSJeff Kirsher 	if (!netif_running(ndev))
21417ac6653aSJeff Kirsher 		return 0;
21427ac6653aSJeff Kirsher 
2143f8c5a875SGiuseppe CAVALLARO 	spin_lock_irqsave(&priv->lock, flags);
21447ac6653aSJeff Kirsher 
21457ac6653aSJeff Kirsher 	/* Power Down bit, into the PM register, is cleared
21467ac6653aSJeff Kirsher 	 * automatically as soon as a magic packet or a Wake-up frame
21477ac6653aSJeff Kirsher 	 * is received. Anyway, it's better to manually clear
21487ac6653aSJeff Kirsher 	 * this bit because it can generate problems while resuming
21497ac6653aSJeff Kirsher 	 * from another devices (e.g. serial console). */
21507ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
21517ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, 0);
2152ba1377ffSGiuseppe CAVALLARO 	else
2153ba1377ffSGiuseppe CAVALLARO 		/* enable the clk prevously disabled */
2154a630844dSStefan Roese 		clk_prepare_enable(priv->stmmac_clk);
21557ac6653aSJeff Kirsher 
21567ac6653aSJeff Kirsher 	netif_device_attach(ndev);
21577ac6653aSJeff Kirsher 
21587ac6653aSJeff Kirsher 	/* Enable the MAC and DMA */
2159bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, true);
21607ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
21617ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
21627ac6653aSJeff Kirsher 
21637ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
21647ac6653aSJeff Kirsher 
21657ac6653aSJeff Kirsher 	netif_start_queue(ndev);
21667ac6653aSJeff Kirsher 
2167f8c5a875SGiuseppe CAVALLARO 	spin_unlock_irqrestore(&priv->lock, flags);
2168102463b1SFrancesco Virlinzi 
2169102463b1SFrancesco Virlinzi 	if (priv->phydev)
2170102463b1SFrancesco Virlinzi 		phy_start(priv->phydev);
2171102463b1SFrancesco Virlinzi 
21727ac6653aSJeff Kirsher 	return 0;
21737ac6653aSJeff Kirsher }
21747ac6653aSJeff Kirsher 
2175bfab27a1SGiuseppe CAVALLARO int stmmac_freeze(struct net_device *ndev)
21767ac6653aSJeff Kirsher {
21777ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
21787ac6653aSJeff Kirsher 		return 0;
21797ac6653aSJeff Kirsher 
21807ac6653aSJeff Kirsher 	return stmmac_release(ndev);
21817ac6653aSJeff Kirsher }
21827ac6653aSJeff Kirsher 
2183bfab27a1SGiuseppe CAVALLARO int stmmac_restore(struct net_device *ndev)
21847ac6653aSJeff Kirsher {
21857ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
21867ac6653aSJeff Kirsher 		return 0;
21877ac6653aSJeff Kirsher 
21887ac6653aSJeff Kirsher 	return stmmac_open(ndev);
21897ac6653aSJeff Kirsher }
21907ac6653aSJeff Kirsher #endif /* CONFIG_PM */
21917ac6653aSJeff Kirsher 
219233d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers
219333d5e332SGiuseppe CAVALLARO  * depending on the configuration selected.
219433d5e332SGiuseppe CAVALLARO  */
2195ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void)
2196ba27ec66SGiuseppe CAVALLARO {
219733d5e332SGiuseppe CAVALLARO 	int err_plt = 0;
219833d5e332SGiuseppe CAVALLARO 	int err_pci = 0;
2199ba27ec66SGiuseppe CAVALLARO 
220033d5e332SGiuseppe CAVALLARO 	err_plt = stmmac_register_platform();
220133d5e332SGiuseppe CAVALLARO 	err_pci = stmmac_register_pci();
2202ba27ec66SGiuseppe CAVALLARO 
220333d5e332SGiuseppe CAVALLARO 	if ((err_pci) && (err_plt)) {
220433d5e332SGiuseppe CAVALLARO 		pr_err("stmmac: driver registration failed\n");
220533d5e332SGiuseppe CAVALLARO 		return -EINVAL;
2206ba27ec66SGiuseppe CAVALLARO 	}
2207ba27ec66SGiuseppe CAVALLARO 
220833d5e332SGiuseppe CAVALLARO 	return 0;
2209ba27ec66SGiuseppe CAVALLARO }
2210ba27ec66SGiuseppe CAVALLARO 
2211ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void)
2212ba27ec66SGiuseppe CAVALLARO {
221333d5e332SGiuseppe CAVALLARO 	stmmac_unregister_platform();
221433d5e332SGiuseppe CAVALLARO 	stmmac_unregister_pci();
2215ba27ec66SGiuseppe CAVALLARO }
2216ba27ec66SGiuseppe CAVALLARO 
2217ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init);
2218ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit);
2219ba27ec66SGiuseppe CAVALLARO 
22207ac6653aSJeff Kirsher #ifndef MODULE
22217ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str)
22227ac6653aSJeff Kirsher {
22237ac6653aSJeff Kirsher 	char *opt;
22247ac6653aSJeff Kirsher 
22257ac6653aSJeff Kirsher 	if (!str || !*str)
22267ac6653aSJeff Kirsher 		return -EINVAL;
22277ac6653aSJeff Kirsher 	while ((opt = strsep(&str, ",")) != NULL) {
22287ac6653aSJeff Kirsher 		if (!strncmp(opt, "debug:", 6)) {
2229ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 6, 0, &debug))
22307ac6653aSJeff Kirsher 				goto err;
22317ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "phyaddr:", 8)) {
2232ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 8, 0, &phyaddr))
22337ac6653aSJeff Kirsher 				goto err;
22347ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_txsize:", 11)) {
2235ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &dma_txsize))
22367ac6653aSJeff Kirsher 				goto err;
22377ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_rxsize:", 11)) {
2238ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &dma_rxsize))
22397ac6653aSJeff Kirsher 				goto err;
22407ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "buf_sz:", 7)) {
2241ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 7, 0, &buf_sz))
22427ac6653aSJeff Kirsher 				goto err;
22437ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "tc:", 3)) {
2244ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 3, 0, &tc))
22457ac6653aSJeff Kirsher 				goto err;
22467ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "watchdog:", 9)) {
2247ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 9, 0, &watchdog))
22487ac6653aSJeff Kirsher 				goto err;
22497ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "flow_ctrl:", 10)) {
2250ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 10, 0, &flow_ctrl))
22517ac6653aSJeff Kirsher 				goto err;
22527ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "pause:", 6)) {
2253ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 6, 0, &pause))
22547ac6653aSJeff Kirsher 				goto err;
2255d765955dSGiuseppe CAVALLARO 		} else if (!strncmp(opt, "eee_timer:", 6)) {
2256d765955dSGiuseppe CAVALLARO 			if (kstrtoint(opt + 10, 0, &eee_timer))
2257d765955dSGiuseppe CAVALLARO 				goto err;
22587ac6653aSJeff Kirsher 		}
22597ac6653aSJeff Kirsher 	}
22607ac6653aSJeff Kirsher 	return 0;
22617ac6653aSJeff Kirsher 
22627ac6653aSJeff Kirsher err:
22637ac6653aSJeff Kirsher 	pr_err("%s: ERROR broken module parameter conversion", __func__);
22647ac6653aSJeff Kirsher 	return -EINVAL;
22657ac6653aSJeff Kirsher }
22667ac6653aSJeff Kirsher 
22677ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt);
22687ac6653aSJeff Kirsher #endif
22696fc0d0f2SGiuseppe Cavallaro 
22706fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
22716fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
22726fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL");
2273