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 /* Pay attention to tune this parameter; take care of both
1197ac6653aSJeff Kirsher  * hardware capability and network stabitily/performance impact.
1207ac6653aSJeff Kirsher  * Many tests showed that ~4ms latency seems to be good enough. */
1217ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
1227ac6653aSJeff Kirsher #define DEFAULT_PERIODIC_RATE	256
1237ac6653aSJeff Kirsher static int tmrate = DEFAULT_PERIODIC_RATE;
1247ac6653aSJeff Kirsher module_param(tmrate, int, S_IRUGO | S_IWUSR);
1257ac6653aSJeff Kirsher MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
1267ac6653aSJeff Kirsher #endif
1277ac6653aSJeff Kirsher 
1287ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE	BUF_SIZE_2KiB
1297ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE;
1307ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR);
1317ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size");
1327ac6653aSJeff Kirsher 
1337ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
1347ac6653aSJeff Kirsher 				      NETIF_MSG_LINK | NETIF_MSG_IFUP |
1357ac6653aSJeff Kirsher 				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
1367ac6653aSJeff Kirsher 
137d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER	1000
138d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
139d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR);
140d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
141d765955dSGiuseppe CAVALLARO #define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x))
142d765955dSGiuseppe CAVALLARO 
1437ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
1447ac6653aSJeff Kirsher 
145bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
146bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev);
147bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void);
148bfab27a1SGiuseppe CAVALLARO #endif
149bfab27a1SGiuseppe CAVALLARO 
1507ac6653aSJeff Kirsher /**
1517ac6653aSJeff Kirsher  * stmmac_verify_args - verify the driver parameters.
1527ac6653aSJeff Kirsher  * Description: it verifies if some wrong parameter is passed to the driver.
1537ac6653aSJeff Kirsher  * Note that wrong parameters are replaced with the default values.
1547ac6653aSJeff Kirsher  */
1557ac6653aSJeff Kirsher static void stmmac_verify_args(void)
1567ac6653aSJeff Kirsher {
1577ac6653aSJeff Kirsher 	if (unlikely(watchdog < 0))
1587ac6653aSJeff Kirsher 		watchdog = TX_TIMEO;
1597ac6653aSJeff Kirsher 	if (unlikely(dma_rxsize < 0))
1607ac6653aSJeff Kirsher 		dma_rxsize = DMA_RX_SIZE;
1617ac6653aSJeff Kirsher 	if (unlikely(dma_txsize < 0))
1627ac6653aSJeff Kirsher 		dma_txsize = DMA_TX_SIZE;
1637ac6653aSJeff Kirsher 	if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
1647ac6653aSJeff Kirsher 		buf_sz = DMA_BUFFER_SIZE;
1657ac6653aSJeff Kirsher 	if (unlikely(flow_ctrl > 1))
1667ac6653aSJeff Kirsher 		flow_ctrl = FLOW_AUTO;
1677ac6653aSJeff Kirsher 	else if (likely(flow_ctrl < 0))
1687ac6653aSJeff Kirsher 		flow_ctrl = FLOW_OFF;
1697ac6653aSJeff Kirsher 	if (unlikely((pause < 0) || (pause > 0xffff)))
1707ac6653aSJeff Kirsher 		pause = PAUSE_TIME;
171d765955dSGiuseppe CAVALLARO 	if (eee_timer < 0)
172d765955dSGiuseppe CAVALLARO 		eee_timer = STMMAC_DEFAULT_LPI_TIMER;
1737ac6653aSJeff Kirsher }
1747ac6653aSJeff Kirsher 
175cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv)
176cd7201f4SGiuseppe CAVALLARO {
177cd7201f4SGiuseppe CAVALLARO 	u32 clk_rate;
178cd7201f4SGiuseppe CAVALLARO 
179cd7201f4SGiuseppe CAVALLARO 	clk_rate = clk_get_rate(priv->stmmac_clk);
180cd7201f4SGiuseppe CAVALLARO 
181cd7201f4SGiuseppe CAVALLARO 	/* Platform provided default clk_csr would be assumed valid
182cd7201f4SGiuseppe CAVALLARO 	 * for all other cases except for the below mentioned ones. */
183cd7201f4SGiuseppe CAVALLARO 	if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
184cd7201f4SGiuseppe CAVALLARO 		if (clk_rate < CSR_F_35M)
185cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_20_35M;
186cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
187cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_35_60M;
188cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
189cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_60_100M;
190cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
191cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_100_150M;
192cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
193cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_150_250M;
194cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
195cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_250_300M;
196cd7201f4SGiuseppe CAVALLARO 	} /* For values higher than the IEEE 802.3 specified frequency
197cd7201f4SGiuseppe CAVALLARO 	   * we can not estimate the proper divider as it is not known
198cd7201f4SGiuseppe CAVALLARO 	   * the frequency of clk_csr_i. So we do not change the default
199cd7201f4SGiuseppe CAVALLARO 	   * divider. */
200cd7201f4SGiuseppe CAVALLARO }
201cd7201f4SGiuseppe CAVALLARO 
2027ac6653aSJeff Kirsher #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
2037ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len)
2047ac6653aSJeff Kirsher {
2057ac6653aSJeff Kirsher 	int j;
2067ac6653aSJeff Kirsher 	pr_info("len = %d byte, buf addr: 0x%p", len, buf);
2077ac6653aSJeff Kirsher 	for (j = 0; j < len; j++) {
2087ac6653aSJeff Kirsher 		if ((j % 16) == 0)
2097ac6653aSJeff Kirsher 			pr_info("\n %03x:", j);
2107ac6653aSJeff Kirsher 		pr_info(" %02x", buf[j]);
2117ac6653aSJeff Kirsher 	}
2127ac6653aSJeff Kirsher 	pr_info("\n");
2137ac6653aSJeff Kirsher }
2147ac6653aSJeff Kirsher #endif
2157ac6653aSJeff Kirsher 
2167ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */
2177ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x)	(x->dma_tx_size/4)
2187ac6653aSJeff Kirsher 
2197ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
2207ac6653aSJeff Kirsher {
2217ac6653aSJeff Kirsher 	return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
2227ac6653aSJeff Kirsher }
2237ac6653aSJeff Kirsher 
2247ac6653aSJeff Kirsher /* On some ST platforms, some HW system configuraton registers have to be
2257ac6653aSJeff Kirsher  * set according to the link speed negotiated.
2267ac6653aSJeff Kirsher  */
2277ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
2287ac6653aSJeff Kirsher {
2297ac6653aSJeff Kirsher 	struct phy_device *phydev = priv->phydev;
2307ac6653aSJeff Kirsher 
2317ac6653aSJeff Kirsher 	if (likely(priv->plat->fix_mac_speed))
2327ac6653aSJeff Kirsher 		priv->plat->fix_mac_speed(priv->plat->bsp_priv,
2337ac6653aSJeff Kirsher 					  phydev->speed);
2347ac6653aSJeff Kirsher }
2357ac6653aSJeff Kirsher 
236d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
237d765955dSGiuseppe CAVALLARO {
238d765955dSGiuseppe CAVALLARO 	/* Check and enter in LPI mode */
239d765955dSGiuseppe CAVALLARO 	if ((priv->dirty_tx == priv->cur_tx) &&
240d765955dSGiuseppe CAVALLARO 	    (priv->tx_path_in_lpi_mode == false))
241d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_mode(priv->ioaddr);
242d765955dSGiuseppe CAVALLARO }
243d765955dSGiuseppe CAVALLARO 
244d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv)
245d765955dSGiuseppe CAVALLARO {
246d765955dSGiuseppe CAVALLARO 	/* Exit and disable EEE in case of we are are in LPI state. */
247d765955dSGiuseppe CAVALLARO 	priv->hw->mac->reset_eee_mode(priv->ioaddr);
248d765955dSGiuseppe CAVALLARO 	del_timer_sync(&priv->eee_ctrl_timer);
249d765955dSGiuseppe CAVALLARO 	priv->tx_path_in_lpi_mode = false;
250d765955dSGiuseppe CAVALLARO }
251d765955dSGiuseppe CAVALLARO 
252d765955dSGiuseppe CAVALLARO /**
253d765955dSGiuseppe CAVALLARO  * stmmac_eee_ctrl_timer
254d765955dSGiuseppe CAVALLARO  * @arg : data hook
255d765955dSGiuseppe CAVALLARO  * Description:
256d765955dSGiuseppe CAVALLARO  *  If there is no data transfer and if we are not in LPI state,
257d765955dSGiuseppe CAVALLARO  *  then MAC Transmitter can be moved to LPI state.
258d765955dSGiuseppe CAVALLARO  */
259d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg)
260d765955dSGiuseppe CAVALLARO {
261d765955dSGiuseppe CAVALLARO 	struct stmmac_priv *priv = (struct stmmac_priv *)arg;
262d765955dSGiuseppe CAVALLARO 
263d765955dSGiuseppe CAVALLARO 	stmmac_enable_eee_mode(priv);
264d765955dSGiuseppe CAVALLARO 	mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
265d765955dSGiuseppe CAVALLARO }
266d765955dSGiuseppe CAVALLARO 
267d765955dSGiuseppe CAVALLARO /**
268d765955dSGiuseppe CAVALLARO  * stmmac_eee_init
269d765955dSGiuseppe CAVALLARO  * @priv: private device pointer
270d765955dSGiuseppe CAVALLARO  * Description:
271d765955dSGiuseppe CAVALLARO  *  If the EEE support has been enabled while configuring the driver,
272d765955dSGiuseppe CAVALLARO  *  if the GMAC actually supports the EEE (from the HW cap reg) and the
273d765955dSGiuseppe CAVALLARO  *  phy can also manage EEE, so enable the LPI state and start the timer
274d765955dSGiuseppe CAVALLARO  *  to verify if the tx path can enter in LPI state.
275d765955dSGiuseppe CAVALLARO  */
276d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv)
277d765955dSGiuseppe CAVALLARO {
278d765955dSGiuseppe CAVALLARO 	bool ret = false;
279d765955dSGiuseppe CAVALLARO 
280d765955dSGiuseppe CAVALLARO 	/* MAC core supports the EEE feature. */
281d765955dSGiuseppe CAVALLARO 	if (priv->dma_cap.eee) {
282d765955dSGiuseppe CAVALLARO 		/* Check if the PHY supports EEE */
283d765955dSGiuseppe CAVALLARO 		if (phy_init_eee(priv->phydev, 1))
284d765955dSGiuseppe CAVALLARO 			goto out;
285d765955dSGiuseppe CAVALLARO 
286d765955dSGiuseppe CAVALLARO 		priv->eee_active = 1;
287d765955dSGiuseppe CAVALLARO 		init_timer(&priv->eee_ctrl_timer);
288d765955dSGiuseppe CAVALLARO 		priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
289d765955dSGiuseppe CAVALLARO 		priv->eee_ctrl_timer.data = (unsigned long)priv;
290d765955dSGiuseppe CAVALLARO 		priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer);
291d765955dSGiuseppe CAVALLARO 		add_timer(&priv->eee_ctrl_timer);
292d765955dSGiuseppe CAVALLARO 
293d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_timer(priv->ioaddr,
294d765955dSGiuseppe CAVALLARO 					     STMMAC_DEFAULT_LIT_LS_TIMER,
295d765955dSGiuseppe CAVALLARO 					     priv->tx_lpi_timer);
296d765955dSGiuseppe CAVALLARO 
297d765955dSGiuseppe CAVALLARO 		pr_info("stmmac: Energy-Efficient Ethernet initialized\n");
298d765955dSGiuseppe CAVALLARO 
299d765955dSGiuseppe CAVALLARO 		ret = true;
300d765955dSGiuseppe CAVALLARO 	}
301d765955dSGiuseppe CAVALLARO out:
302d765955dSGiuseppe CAVALLARO 	return ret;
303d765955dSGiuseppe CAVALLARO }
304d765955dSGiuseppe CAVALLARO 
305d765955dSGiuseppe CAVALLARO static void stmmac_eee_adjust(struct stmmac_priv *priv)
306d765955dSGiuseppe CAVALLARO {
307d765955dSGiuseppe CAVALLARO 	/* When the EEE has been already initialised we have to
308d765955dSGiuseppe CAVALLARO 	 * modify the PLS bit in the LPI ctrl & status reg according
309d765955dSGiuseppe CAVALLARO 	 * to the PHY link status. For this reason.
310d765955dSGiuseppe CAVALLARO 	 */
311d765955dSGiuseppe CAVALLARO 	if (priv->eee_enabled)
312d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link);
313d765955dSGiuseppe CAVALLARO }
314d765955dSGiuseppe CAVALLARO 
3157ac6653aSJeff Kirsher /**
3167ac6653aSJeff Kirsher  * stmmac_adjust_link
3177ac6653aSJeff Kirsher  * @dev: net device structure
3187ac6653aSJeff Kirsher  * Description: it adjusts the link parameters.
3197ac6653aSJeff Kirsher  */
3207ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev)
3217ac6653aSJeff Kirsher {
3227ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
3237ac6653aSJeff Kirsher 	struct phy_device *phydev = priv->phydev;
3247ac6653aSJeff Kirsher 	unsigned long flags;
3257ac6653aSJeff Kirsher 	int new_state = 0;
3267ac6653aSJeff Kirsher 	unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
3277ac6653aSJeff Kirsher 
3287ac6653aSJeff Kirsher 	if (phydev == NULL)
3297ac6653aSJeff Kirsher 		return;
3307ac6653aSJeff Kirsher 
3317ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "stmmac_adjust_link: called.  address %d link %d\n",
3327ac6653aSJeff Kirsher 	    phydev->addr, phydev->link);
3337ac6653aSJeff Kirsher 
3347ac6653aSJeff Kirsher 	spin_lock_irqsave(&priv->lock, flags);
335d765955dSGiuseppe CAVALLARO 
3367ac6653aSJeff Kirsher 	if (phydev->link) {
3377ac6653aSJeff Kirsher 		u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
3387ac6653aSJeff Kirsher 
3397ac6653aSJeff Kirsher 		/* Now we make sure that we can be in full duplex mode.
3407ac6653aSJeff Kirsher 		 * If not, we operate in half-duplex mode. */
3417ac6653aSJeff Kirsher 		if (phydev->duplex != priv->oldduplex) {
3427ac6653aSJeff Kirsher 			new_state = 1;
3437ac6653aSJeff Kirsher 			if (!(phydev->duplex))
3447ac6653aSJeff Kirsher 				ctrl &= ~priv->hw->link.duplex;
3457ac6653aSJeff Kirsher 			else
3467ac6653aSJeff Kirsher 				ctrl |= priv->hw->link.duplex;
3477ac6653aSJeff Kirsher 			priv->oldduplex = phydev->duplex;
3487ac6653aSJeff Kirsher 		}
3497ac6653aSJeff Kirsher 		/* Flow Control operation */
3507ac6653aSJeff Kirsher 		if (phydev->pause)
3517ac6653aSJeff Kirsher 			priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
3527ac6653aSJeff Kirsher 						 fc, pause_time);
3537ac6653aSJeff Kirsher 
3547ac6653aSJeff Kirsher 		if (phydev->speed != priv->speed) {
3557ac6653aSJeff Kirsher 			new_state = 1;
3567ac6653aSJeff Kirsher 			switch (phydev->speed) {
3577ac6653aSJeff Kirsher 			case 1000:
3587ac6653aSJeff Kirsher 				if (likely(priv->plat->has_gmac))
3597ac6653aSJeff Kirsher 					ctrl &= ~priv->hw->link.port;
3607ac6653aSJeff Kirsher 					stmmac_hw_fix_mac_speed(priv);
3617ac6653aSJeff Kirsher 				break;
3627ac6653aSJeff Kirsher 			case 100:
3637ac6653aSJeff Kirsher 			case 10:
3647ac6653aSJeff Kirsher 				if (priv->plat->has_gmac) {
3657ac6653aSJeff Kirsher 					ctrl |= priv->hw->link.port;
3667ac6653aSJeff Kirsher 					if (phydev->speed == SPEED_100) {
3677ac6653aSJeff Kirsher 						ctrl |= priv->hw->link.speed;
3687ac6653aSJeff Kirsher 					} else {
3697ac6653aSJeff Kirsher 						ctrl &= ~(priv->hw->link.speed);
3707ac6653aSJeff Kirsher 					}
3717ac6653aSJeff Kirsher 				} else {
3727ac6653aSJeff Kirsher 					ctrl &= ~priv->hw->link.port;
3737ac6653aSJeff Kirsher 				}
3747ac6653aSJeff Kirsher 				stmmac_hw_fix_mac_speed(priv);
3757ac6653aSJeff Kirsher 				break;
3767ac6653aSJeff Kirsher 			default:
3777ac6653aSJeff Kirsher 				if (netif_msg_link(priv))
3787ac6653aSJeff Kirsher 					pr_warning("%s: Speed (%d) is not 10"
3797ac6653aSJeff Kirsher 				       " or 100!\n", dev->name, phydev->speed);
3807ac6653aSJeff Kirsher 				break;
3817ac6653aSJeff Kirsher 			}
3827ac6653aSJeff Kirsher 
3837ac6653aSJeff Kirsher 			priv->speed = phydev->speed;
3847ac6653aSJeff Kirsher 		}
3857ac6653aSJeff Kirsher 
3867ac6653aSJeff Kirsher 		writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
3877ac6653aSJeff Kirsher 
3887ac6653aSJeff Kirsher 		if (!priv->oldlink) {
3897ac6653aSJeff Kirsher 			new_state = 1;
3907ac6653aSJeff Kirsher 			priv->oldlink = 1;
3917ac6653aSJeff Kirsher 		}
3927ac6653aSJeff Kirsher 	} else if (priv->oldlink) {
3937ac6653aSJeff Kirsher 		new_state = 1;
3947ac6653aSJeff Kirsher 		priv->oldlink = 0;
3957ac6653aSJeff Kirsher 		priv->speed = 0;
3967ac6653aSJeff Kirsher 		priv->oldduplex = -1;
3977ac6653aSJeff Kirsher 	}
3987ac6653aSJeff Kirsher 
3997ac6653aSJeff Kirsher 	if (new_state && netif_msg_link(priv))
4007ac6653aSJeff Kirsher 		phy_print_status(phydev);
4017ac6653aSJeff Kirsher 
402d765955dSGiuseppe CAVALLARO 	stmmac_eee_adjust(priv);
403d765955dSGiuseppe CAVALLARO 
4047ac6653aSJeff Kirsher 	spin_unlock_irqrestore(&priv->lock, flags);
4057ac6653aSJeff Kirsher 
4067ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
4077ac6653aSJeff Kirsher }
4087ac6653aSJeff Kirsher 
4097ac6653aSJeff Kirsher /**
4107ac6653aSJeff Kirsher  * stmmac_init_phy - PHY initialization
4117ac6653aSJeff Kirsher  * @dev: net device structure
4127ac6653aSJeff Kirsher  * Description: it initializes the driver's PHY state, and attaches the PHY
4137ac6653aSJeff Kirsher  * to the mac driver.
4147ac6653aSJeff Kirsher  *  Return value:
4157ac6653aSJeff Kirsher  *  0 on success
4167ac6653aSJeff Kirsher  */
4177ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev)
4187ac6653aSJeff Kirsher {
4197ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
4207ac6653aSJeff Kirsher 	struct phy_device *phydev;
421d765955dSGiuseppe CAVALLARO 	char phy_id_fmt[MII_BUS_ID_SIZE + 3];
4227ac6653aSJeff Kirsher 	char bus_id[MII_BUS_ID_SIZE];
42379ee1dc3SSrinivas Kandagatla 	int interface = priv->plat->interface;
4247ac6653aSJeff Kirsher 	priv->oldlink = 0;
4257ac6653aSJeff Kirsher 	priv->speed = 0;
4267ac6653aSJeff Kirsher 	priv->oldduplex = -1;
4277ac6653aSJeff Kirsher 
428f142af2eSSrinivas Kandagatla 	if (priv->plat->phy_bus_name)
429f142af2eSSrinivas Kandagatla 		snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
430f142af2eSSrinivas Kandagatla 				priv->plat->phy_bus_name, priv->plat->bus_id);
431f142af2eSSrinivas Kandagatla 	else
432f142af2eSSrinivas Kandagatla 		snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
433f142af2eSSrinivas Kandagatla 				priv->plat->bus_id);
434f142af2eSSrinivas Kandagatla 
435d765955dSGiuseppe CAVALLARO 	snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
4367ac6653aSJeff Kirsher 		 priv->plat->phy_addr);
437d765955dSGiuseppe CAVALLARO 	pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
4387ac6653aSJeff Kirsher 
439d765955dSGiuseppe CAVALLARO 	phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, 0,
440d765955dSGiuseppe CAVALLARO 			     interface);
4417ac6653aSJeff Kirsher 
4427ac6653aSJeff Kirsher 	if (IS_ERR(phydev)) {
4437ac6653aSJeff Kirsher 		pr_err("%s: Could not attach to PHY\n", dev->name);
4447ac6653aSJeff Kirsher 		return PTR_ERR(phydev);
4457ac6653aSJeff Kirsher 	}
4467ac6653aSJeff Kirsher 
44779ee1dc3SSrinivas Kandagatla 	/* Stop Advertising 1000BASE Capability if interface is not GMII */
448c5b9b4e4SSrinivas Kandagatla 	if ((interface == PHY_INTERFACE_MODE_MII) ||
449c5b9b4e4SSrinivas Kandagatla 	    (interface == PHY_INTERFACE_MODE_RMII))
450c5b9b4e4SSrinivas Kandagatla 		phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
451c5b9b4e4SSrinivas Kandagatla 					 SUPPORTED_1000baseT_Full);
45279ee1dc3SSrinivas Kandagatla 
4537ac6653aSJeff Kirsher 	/*
4547ac6653aSJeff Kirsher 	 * Broken HW is sometimes missing the pull-up resistor on the
4557ac6653aSJeff Kirsher 	 * MDIO line, which results in reads to non-existent devices returning
4567ac6653aSJeff Kirsher 	 * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
4577ac6653aSJeff Kirsher 	 * device as well.
4587ac6653aSJeff Kirsher 	 * Note: phydev->phy_id is the result of reading the UID PHY registers.
4597ac6653aSJeff Kirsher 	 */
4607ac6653aSJeff Kirsher 	if (phydev->phy_id == 0) {
4617ac6653aSJeff Kirsher 		phy_disconnect(phydev);
4627ac6653aSJeff Kirsher 		return -ENODEV;
4637ac6653aSJeff Kirsher 	}
4647ac6653aSJeff Kirsher 	pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
4657ac6653aSJeff Kirsher 		 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
4667ac6653aSJeff Kirsher 
4677ac6653aSJeff Kirsher 	priv->phydev = phydev;
4687ac6653aSJeff Kirsher 
4697ac6653aSJeff Kirsher 	return 0;
4707ac6653aSJeff Kirsher }
4717ac6653aSJeff Kirsher 
4727ac6653aSJeff Kirsher /**
4737ac6653aSJeff Kirsher  * display_ring
4747ac6653aSJeff Kirsher  * @p: pointer to the ring.
4757ac6653aSJeff Kirsher  * @size: size of the ring.
4767ac6653aSJeff Kirsher  * Description: display all the descriptors within the ring.
4777ac6653aSJeff Kirsher  */
4787ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size)
4797ac6653aSJeff Kirsher {
4807ac6653aSJeff Kirsher 	struct tmp_s {
4817ac6653aSJeff Kirsher 		u64 a;
4827ac6653aSJeff Kirsher 		unsigned int b;
4837ac6653aSJeff Kirsher 		unsigned int c;
4847ac6653aSJeff Kirsher 	};
4857ac6653aSJeff Kirsher 	int i;
4867ac6653aSJeff Kirsher 	for (i = 0; i < size; i++) {
4877ac6653aSJeff Kirsher 		struct tmp_s *x = (struct tmp_s *)(p + i);
4887ac6653aSJeff Kirsher 		pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
4897ac6653aSJeff Kirsher 		       i, (unsigned int)virt_to_phys(&p[i]),
4907ac6653aSJeff Kirsher 		       (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
4917ac6653aSJeff Kirsher 		       x->b, x->c);
4927ac6653aSJeff Kirsher 		pr_info("\n");
4937ac6653aSJeff Kirsher 	}
4947ac6653aSJeff Kirsher }
4957ac6653aSJeff Kirsher 
496286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize)
497286a8372SGiuseppe CAVALLARO {
498286a8372SGiuseppe CAVALLARO 	int ret = bufsize;
499286a8372SGiuseppe CAVALLARO 
500286a8372SGiuseppe CAVALLARO 	if (mtu >= BUF_SIZE_4KiB)
501286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_8KiB;
502286a8372SGiuseppe CAVALLARO 	else if (mtu >= BUF_SIZE_2KiB)
503286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_4KiB;
504286a8372SGiuseppe CAVALLARO 	else if (mtu >= DMA_BUFFER_SIZE)
505286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_2KiB;
506286a8372SGiuseppe CAVALLARO 	else
507286a8372SGiuseppe CAVALLARO 		ret = DMA_BUFFER_SIZE;
508286a8372SGiuseppe CAVALLARO 
509286a8372SGiuseppe CAVALLARO 	return ret;
510286a8372SGiuseppe CAVALLARO }
511286a8372SGiuseppe CAVALLARO 
5127ac6653aSJeff Kirsher /**
5137ac6653aSJeff Kirsher  * init_dma_desc_rings - init the RX/TX descriptor rings
5147ac6653aSJeff Kirsher  * @dev: net device structure
5157ac6653aSJeff Kirsher  * Description:  this function initializes the DMA RX/TX descriptors
516286a8372SGiuseppe CAVALLARO  * and allocates the socket buffers. It suppors the chained and ring
517286a8372SGiuseppe CAVALLARO  * modes.
5187ac6653aSJeff Kirsher  */
5197ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev)
5207ac6653aSJeff Kirsher {
5217ac6653aSJeff Kirsher 	int i;
5227ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
5237ac6653aSJeff Kirsher 	struct sk_buff *skb;
5247ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
5257ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
526286a8372SGiuseppe CAVALLARO 	unsigned int bfsize;
527286a8372SGiuseppe CAVALLARO 	int dis_ic = 0;
528286a8372SGiuseppe CAVALLARO 	int des3_as_data_buf = 0;
5297ac6653aSJeff Kirsher 
530286a8372SGiuseppe CAVALLARO 	/* Set the max buffer size according to the DESC mode
531286a8372SGiuseppe CAVALLARO 	 * and the MTU. Note that RING mode allows 16KiB bsize. */
532286a8372SGiuseppe CAVALLARO 	bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu);
533286a8372SGiuseppe CAVALLARO 
534286a8372SGiuseppe CAVALLARO 	if (bfsize == BUF_SIZE_16KiB)
535286a8372SGiuseppe CAVALLARO 		des3_as_data_buf = 1;
5367ac6653aSJeff Kirsher 	else
537286a8372SGiuseppe CAVALLARO 		bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
5387ac6653aSJeff Kirsher 
5397ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
5407ac6653aSJeff Kirsher 	/* Disable interrupts on completion for the reception if timer is on */
5417ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
5427ac6653aSJeff Kirsher 		dis_ic = 1;
5437ac6653aSJeff Kirsher #endif
5447ac6653aSJeff Kirsher 
5457ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
5467ac6653aSJeff Kirsher 	    txsize, rxsize, bfsize);
5477ac6653aSJeff Kirsher 
5487ac6653aSJeff Kirsher 	priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
5497ac6653aSJeff Kirsher 	priv->rx_skbuff =
5507ac6653aSJeff Kirsher 	    kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
5517ac6653aSJeff Kirsher 	priv->dma_rx =
5527ac6653aSJeff Kirsher 	    (struct dma_desc *)dma_alloc_coherent(priv->device,
5537ac6653aSJeff Kirsher 						  rxsize *
5547ac6653aSJeff Kirsher 						  sizeof(struct dma_desc),
5557ac6653aSJeff Kirsher 						  &priv->dma_rx_phy,
5567ac6653aSJeff Kirsher 						  GFP_KERNEL);
5577ac6653aSJeff Kirsher 	priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
5587ac6653aSJeff Kirsher 				       GFP_KERNEL);
5597ac6653aSJeff Kirsher 	priv->dma_tx =
5607ac6653aSJeff Kirsher 	    (struct dma_desc *)dma_alloc_coherent(priv->device,
5617ac6653aSJeff Kirsher 						  txsize *
5627ac6653aSJeff Kirsher 						  sizeof(struct dma_desc),
5637ac6653aSJeff Kirsher 						  &priv->dma_tx_phy,
5647ac6653aSJeff Kirsher 						  GFP_KERNEL);
5657ac6653aSJeff Kirsher 
5667ac6653aSJeff Kirsher 	if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
5677ac6653aSJeff Kirsher 		pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
5687ac6653aSJeff Kirsher 		return;
5697ac6653aSJeff Kirsher 	}
5707ac6653aSJeff Kirsher 
571286a8372SGiuseppe CAVALLARO 	DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, "
5727ac6653aSJeff Kirsher 	    "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
5737ac6653aSJeff Kirsher 	    dev->name, priv->dma_rx, priv->dma_tx,
5747ac6653aSJeff Kirsher 	    (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
5757ac6653aSJeff Kirsher 
5767ac6653aSJeff Kirsher 	/* RX INITIALIZATION */
5777ac6653aSJeff Kirsher 	DBG(probe, INFO, "stmmac: SKB addresses:\n"
5787ac6653aSJeff Kirsher 			 "skb\t\tskb data\tdma data\n");
5797ac6653aSJeff Kirsher 
5807ac6653aSJeff Kirsher 	for (i = 0; i < rxsize; i++) {
5817ac6653aSJeff Kirsher 		struct dma_desc *p = priv->dma_rx + i;
5827ac6653aSJeff Kirsher 
58345db81e1SGiuseppe CAVALLARO 		skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN,
58445db81e1SGiuseppe CAVALLARO 					 GFP_KERNEL);
5857ac6653aSJeff Kirsher 		if (unlikely(skb == NULL)) {
5867ac6653aSJeff Kirsher 			pr_err("%s: Rx init fails; skb is NULL\n", __func__);
5877ac6653aSJeff Kirsher 			break;
5887ac6653aSJeff Kirsher 		}
58945db81e1SGiuseppe CAVALLARO 		skb_reserve(skb, NET_IP_ALIGN);
5907ac6653aSJeff Kirsher 		priv->rx_skbuff[i] = skb;
5917ac6653aSJeff Kirsher 		priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
5927ac6653aSJeff Kirsher 						bfsize, DMA_FROM_DEVICE);
5937ac6653aSJeff Kirsher 
5947ac6653aSJeff Kirsher 		p->des2 = priv->rx_skbuff_dma[i];
595286a8372SGiuseppe CAVALLARO 
596286a8372SGiuseppe CAVALLARO 		priv->hw->ring->init_desc3(des3_as_data_buf, p);
597286a8372SGiuseppe CAVALLARO 
5987ac6653aSJeff Kirsher 		DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
5997ac6653aSJeff Kirsher 			priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
6007ac6653aSJeff Kirsher 	}
6017ac6653aSJeff Kirsher 	priv->cur_rx = 0;
6027ac6653aSJeff Kirsher 	priv->dirty_rx = (unsigned int)(i - rxsize);
6037ac6653aSJeff Kirsher 	priv->dma_buf_sz = bfsize;
6047ac6653aSJeff Kirsher 	buf_sz = bfsize;
6057ac6653aSJeff Kirsher 
6067ac6653aSJeff Kirsher 	/* TX INITIALIZATION */
6077ac6653aSJeff Kirsher 	for (i = 0; i < txsize; i++) {
6087ac6653aSJeff Kirsher 		priv->tx_skbuff[i] = NULL;
6097ac6653aSJeff Kirsher 		priv->dma_tx[i].des2 = 0;
6107ac6653aSJeff Kirsher 	}
611286a8372SGiuseppe CAVALLARO 
612286a8372SGiuseppe CAVALLARO 	/* In case of Chained mode this sets the des3 to the next
613286a8372SGiuseppe CAVALLARO 	 * element in the chain */
614286a8372SGiuseppe CAVALLARO 	priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize);
615286a8372SGiuseppe CAVALLARO 	priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize);
616286a8372SGiuseppe CAVALLARO 
6177ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
6187ac6653aSJeff Kirsher 	priv->cur_tx = 0;
6197ac6653aSJeff Kirsher 
6207ac6653aSJeff Kirsher 	/* Clear the Rx/Tx descriptors */
6217ac6653aSJeff Kirsher 	priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
6227ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
6237ac6653aSJeff Kirsher 
6247ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
6257ac6653aSJeff Kirsher 		pr_info("RX descriptor ring:\n");
6267ac6653aSJeff Kirsher 		display_ring(priv->dma_rx, rxsize);
6277ac6653aSJeff Kirsher 		pr_info("TX descriptor ring:\n");
6287ac6653aSJeff Kirsher 		display_ring(priv->dma_tx, txsize);
6297ac6653aSJeff Kirsher 	}
6307ac6653aSJeff Kirsher }
6317ac6653aSJeff Kirsher 
6327ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv)
6337ac6653aSJeff Kirsher {
6347ac6653aSJeff Kirsher 	int i;
6357ac6653aSJeff Kirsher 
6367ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_rx_size; i++) {
6377ac6653aSJeff Kirsher 		if (priv->rx_skbuff[i]) {
6387ac6653aSJeff Kirsher 			dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
6397ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
6407ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->rx_skbuff[i]);
6417ac6653aSJeff Kirsher 		}
6427ac6653aSJeff Kirsher 		priv->rx_skbuff[i] = NULL;
6437ac6653aSJeff Kirsher 	}
6447ac6653aSJeff Kirsher }
6457ac6653aSJeff Kirsher 
6467ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv)
6477ac6653aSJeff Kirsher {
6487ac6653aSJeff Kirsher 	int i;
6497ac6653aSJeff Kirsher 
6507ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_tx_size; i++) {
6517ac6653aSJeff Kirsher 		if (priv->tx_skbuff[i] != NULL) {
6527ac6653aSJeff Kirsher 			struct dma_desc *p = priv->dma_tx + i;
6537ac6653aSJeff Kirsher 			if (p->des2)
6547ac6653aSJeff Kirsher 				dma_unmap_single(priv->device, p->des2,
6557ac6653aSJeff Kirsher 						 priv->hw->desc->get_tx_len(p),
6567ac6653aSJeff Kirsher 						 DMA_TO_DEVICE);
6577ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->tx_skbuff[i]);
6587ac6653aSJeff Kirsher 			priv->tx_skbuff[i] = NULL;
6597ac6653aSJeff Kirsher 		}
6607ac6653aSJeff Kirsher 	}
6617ac6653aSJeff Kirsher }
6627ac6653aSJeff Kirsher 
6637ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv)
6647ac6653aSJeff Kirsher {
6657ac6653aSJeff Kirsher 	/* Release the DMA TX/RX socket buffers */
6667ac6653aSJeff Kirsher 	dma_free_rx_skbufs(priv);
6677ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
6687ac6653aSJeff Kirsher 
6697ac6653aSJeff Kirsher 	/* Free the region of consistent memory previously allocated for
6707ac6653aSJeff Kirsher 	 * the DMA */
6717ac6653aSJeff Kirsher 	dma_free_coherent(priv->device,
6727ac6653aSJeff Kirsher 			  priv->dma_tx_size * sizeof(struct dma_desc),
6737ac6653aSJeff Kirsher 			  priv->dma_tx, priv->dma_tx_phy);
6747ac6653aSJeff Kirsher 	dma_free_coherent(priv->device,
6757ac6653aSJeff Kirsher 			  priv->dma_rx_size * sizeof(struct dma_desc),
6767ac6653aSJeff Kirsher 			  priv->dma_rx, priv->dma_rx_phy);
6777ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff_dma);
6787ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff);
6797ac6653aSJeff Kirsher 	kfree(priv->tx_skbuff);
6807ac6653aSJeff Kirsher }
6817ac6653aSJeff Kirsher 
6827ac6653aSJeff Kirsher /**
6837ac6653aSJeff Kirsher  *  stmmac_dma_operation_mode - HW DMA operation mode
6847ac6653aSJeff Kirsher  *  @priv : pointer to the private device structure.
6857ac6653aSJeff Kirsher  *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
6867ac6653aSJeff Kirsher  *  or Store-And-Forward capability.
6877ac6653aSJeff Kirsher  */
6887ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
6897ac6653aSJeff Kirsher {
6907ac6653aSJeff Kirsher 	if (likely(priv->plat->force_sf_dma_mode ||
6917ac6653aSJeff Kirsher 		((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) {
6927ac6653aSJeff Kirsher 		/*
6937ac6653aSJeff Kirsher 		 * In case of GMAC, SF mode can be enabled
6947ac6653aSJeff Kirsher 		 * to perform the TX COE in HW. This depends on:
6957ac6653aSJeff Kirsher 		 * 1) TX COE if actually supported
6967ac6653aSJeff Kirsher 		 * 2) There is no bugged Jumbo frame support
6977ac6653aSJeff Kirsher 		 *    that needs to not insert csum in the TDES.
6987ac6653aSJeff Kirsher 		 */
6997ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr,
7007ac6653aSJeff Kirsher 					SF_DMA_MODE, SF_DMA_MODE);
7017ac6653aSJeff Kirsher 		tc = SF_DMA_MODE;
7027ac6653aSJeff Kirsher 	} else
7037ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
7047ac6653aSJeff Kirsher }
7057ac6653aSJeff Kirsher 
7067ac6653aSJeff Kirsher /**
7077ac6653aSJeff Kirsher  * stmmac_tx:
7087ac6653aSJeff Kirsher  * @priv: private driver structure
7097ac6653aSJeff Kirsher  * Description: it reclaims resources after transmission completes.
7107ac6653aSJeff Kirsher  */
7117ac6653aSJeff Kirsher static void stmmac_tx(struct stmmac_priv *priv)
7127ac6653aSJeff Kirsher {
7137ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
7147ac6653aSJeff Kirsher 
715a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
716a9097a96SGiuseppe CAVALLARO 
7177ac6653aSJeff Kirsher 	while (priv->dirty_tx != priv->cur_tx) {
7187ac6653aSJeff Kirsher 		int last;
7197ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_tx % txsize;
7207ac6653aSJeff Kirsher 		struct sk_buff *skb = priv->tx_skbuff[entry];
7217ac6653aSJeff Kirsher 		struct dma_desc *p = priv->dma_tx + entry;
7227ac6653aSJeff Kirsher 
7237ac6653aSJeff Kirsher 		/* Check if the descriptor is owned by the DMA. */
7247ac6653aSJeff Kirsher 		if (priv->hw->desc->get_tx_owner(p))
7257ac6653aSJeff Kirsher 			break;
7267ac6653aSJeff Kirsher 
7277ac6653aSJeff Kirsher 		/* Verify tx error by looking at the last segment */
7287ac6653aSJeff Kirsher 		last = priv->hw->desc->get_tx_ls(p);
7297ac6653aSJeff Kirsher 		if (likely(last)) {
7307ac6653aSJeff Kirsher 			int tx_error =
7317ac6653aSJeff Kirsher 				priv->hw->desc->tx_status(&priv->dev->stats,
7327ac6653aSJeff Kirsher 							  &priv->xstats, p,
7337ac6653aSJeff Kirsher 							  priv->ioaddr);
7347ac6653aSJeff Kirsher 			if (likely(tx_error == 0)) {
7357ac6653aSJeff Kirsher 				priv->dev->stats.tx_packets++;
7367ac6653aSJeff Kirsher 				priv->xstats.tx_pkt_n++;
7377ac6653aSJeff Kirsher 			} else
7387ac6653aSJeff Kirsher 				priv->dev->stats.tx_errors++;
7397ac6653aSJeff Kirsher 		}
7407ac6653aSJeff Kirsher 		TX_DBG("%s: curr %d, dirty %d\n", __func__,
7417ac6653aSJeff Kirsher 			priv->cur_tx, priv->dirty_tx);
7427ac6653aSJeff Kirsher 
7437ac6653aSJeff Kirsher 		if (likely(p->des2))
7447ac6653aSJeff Kirsher 			dma_unmap_single(priv->device, p->des2,
7457ac6653aSJeff Kirsher 					 priv->hw->desc->get_tx_len(p),
7467ac6653aSJeff Kirsher 					 DMA_TO_DEVICE);
747286a8372SGiuseppe CAVALLARO 		priv->hw->ring->clean_desc3(p);
7487ac6653aSJeff Kirsher 
7497ac6653aSJeff Kirsher 		if (likely(skb != NULL)) {
7507ac6653aSJeff Kirsher 			/*
7517ac6653aSJeff Kirsher 			 * If there's room in the queue (limit it to size)
7527ac6653aSJeff Kirsher 			 * we add this skb back into the pool,
7537ac6653aSJeff Kirsher 			 * if it's the right size.
7547ac6653aSJeff Kirsher 			 */
7557ac6653aSJeff Kirsher 			if ((skb_queue_len(&priv->rx_recycle) <
7567ac6653aSJeff Kirsher 				priv->dma_rx_size) &&
7577ac6653aSJeff Kirsher 				skb_recycle_check(skb, priv->dma_buf_sz))
7587ac6653aSJeff Kirsher 				__skb_queue_head(&priv->rx_recycle, skb);
7597ac6653aSJeff Kirsher 			else
7607ac6653aSJeff Kirsher 				dev_kfree_skb(skb);
7617ac6653aSJeff Kirsher 
7627ac6653aSJeff Kirsher 			priv->tx_skbuff[entry] = NULL;
7637ac6653aSJeff Kirsher 		}
7647ac6653aSJeff Kirsher 
7657ac6653aSJeff Kirsher 		priv->hw->desc->release_tx_desc(p);
7667ac6653aSJeff Kirsher 
76713497f58SGiuseppe CAVALLARO 		priv->dirty_tx++;
7687ac6653aSJeff Kirsher 	}
7697ac6653aSJeff Kirsher 	if (unlikely(netif_queue_stopped(priv->dev) &&
7707ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
7717ac6653aSJeff Kirsher 		netif_tx_lock(priv->dev);
7727ac6653aSJeff Kirsher 		if (netif_queue_stopped(priv->dev) &&
7737ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
7747ac6653aSJeff Kirsher 			TX_DBG("%s: restart transmit\n", __func__);
7757ac6653aSJeff Kirsher 			netif_wake_queue(priv->dev);
7767ac6653aSJeff Kirsher 		}
7777ac6653aSJeff Kirsher 		netif_tx_unlock(priv->dev);
7787ac6653aSJeff Kirsher 	}
779d765955dSGiuseppe CAVALLARO 
780d765955dSGiuseppe CAVALLARO 	if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
781d765955dSGiuseppe CAVALLARO 		stmmac_enable_eee_mode(priv);
782d765955dSGiuseppe CAVALLARO 		mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer));
783d765955dSGiuseppe CAVALLARO 	}
784a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
7857ac6653aSJeff Kirsher }
7867ac6653aSJeff Kirsher 
7877ac6653aSJeff Kirsher static inline void stmmac_enable_irq(struct stmmac_priv *priv)
7887ac6653aSJeff Kirsher {
7897ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
7907ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
7917ac6653aSJeff Kirsher 		priv->tm->timer_start(tmrate);
7927ac6653aSJeff Kirsher 	else
7937ac6653aSJeff Kirsher #endif
7947ac6653aSJeff Kirsher 		priv->hw->dma->enable_dma_irq(priv->ioaddr);
7957ac6653aSJeff Kirsher }
7967ac6653aSJeff Kirsher 
7977ac6653aSJeff Kirsher static inline void stmmac_disable_irq(struct stmmac_priv *priv)
7987ac6653aSJeff Kirsher {
7997ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
8007ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
8017ac6653aSJeff Kirsher 		priv->tm->timer_stop();
8027ac6653aSJeff Kirsher 	else
8037ac6653aSJeff Kirsher #endif
8047ac6653aSJeff Kirsher 		priv->hw->dma->disable_dma_irq(priv->ioaddr);
8057ac6653aSJeff Kirsher }
8067ac6653aSJeff Kirsher 
8077ac6653aSJeff Kirsher static int stmmac_has_work(struct stmmac_priv *priv)
8087ac6653aSJeff Kirsher {
8097ac6653aSJeff Kirsher 	unsigned int has_work = 0;
8107ac6653aSJeff Kirsher 	int rxret, tx_work = 0;
8117ac6653aSJeff Kirsher 
8127ac6653aSJeff Kirsher 	rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
8137ac6653aSJeff Kirsher 		(priv->cur_rx % priv->dma_rx_size));
8147ac6653aSJeff Kirsher 
8157ac6653aSJeff Kirsher 	if (priv->dirty_tx != priv->cur_tx)
8167ac6653aSJeff Kirsher 		tx_work = 1;
8177ac6653aSJeff Kirsher 
8187ac6653aSJeff Kirsher 	if (likely(!rxret || tx_work))
8197ac6653aSJeff Kirsher 		has_work = 1;
8207ac6653aSJeff Kirsher 
8217ac6653aSJeff Kirsher 	return has_work;
8227ac6653aSJeff Kirsher }
8237ac6653aSJeff Kirsher 
8247ac6653aSJeff Kirsher static inline void _stmmac_schedule(struct stmmac_priv *priv)
8257ac6653aSJeff Kirsher {
8267ac6653aSJeff Kirsher 	if (likely(stmmac_has_work(priv))) {
8277ac6653aSJeff Kirsher 		stmmac_disable_irq(priv);
8287ac6653aSJeff Kirsher 		napi_schedule(&priv->napi);
8297ac6653aSJeff Kirsher 	}
8307ac6653aSJeff Kirsher }
8317ac6653aSJeff Kirsher 
8327ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
8337ac6653aSJeff Kirsher void stmmac_schedule(struct net_device *dev)
8347ac6653aSJeff Kirsher {
8357ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
8367ac6653aSJeff Kirsher 
8377ac6653aSJeff Kirsher 	priv->xstats.sched_timer_n++;
8387ac6653aSJeff Kirsher 
8397ac6653aSJeff Kirsher 	_stmmac_schedule(priv);
8407ac6653aSJeff Kirsher }
8417ac6653aSJeff Kirsher 
8427ac6653aSJeff Kirsher static void stmmac_no_timer_started(unsigned int x)
8437ac6653aSJeff Kirsher {;
8447ac6653aSJeff Kirsher };
8457ac6653aSJeff Kirsher 
8467ac6653aSJeff Kirsher static void stmmac_no_timer_stopped(void)
8477ac6653aSJeff Kirsher {;
8487ac6653aSJeff Kirsher };
8497ac6653aSJeff Kirsher #endif
8507ac6653aSJeff Kirsher 
8517ac6653aSJeff Kirsher /**
8527ac6653aSJeff Kirsher  * stmmac_tx_err:
8537ac6653aSJeff Kirsher  * @priv: pointer to the private device structure
8547ac6653aSJeff Kirsher  * Description: it cleans the descriptors and restarts the transmission
8557ac6653aSJeff Kirsher  * in case of errors.
8567ac6653aSJeff Kirsher  */
8577ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv)
8587ac6653aSJeff Kirsher {
8597ac6653aSJeff Kirsher 	netif_stop_queue(priv->dev);
8607ac6653aSJeff Kirsher 
8617ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
8627ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
8637ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
8647ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
8657ac6653aSJeff Kirsher 	priv->cur_tx = 0;
8667ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
8677ac6653aSJeff Kirsher 
8687ac6653aSJeff Kirsher 	priv->dev->stats.tx_errors++;
8697ac6653aSJeff Kirsher 	netif_wake_queue(priv->dev);
8707ac6653aSJeff Kirsher }
8717ac6653aSJeff Kirsher 
8727ac6653aSJeff Kirsher 
8737ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv)
8747ac6653aSJeff Kirsher {
8757ac6653aSJeff Kirsher 	int status;
8767ac6653aSJeff Kirsher 
8777ac6653aSJeff Kirsher 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
8787ac6653aSJeff Kirsher 	if (likely(status == handle_tx_rx))
8797ac6653aSJeff Kirsher 		_stmmac_schedule(priv);
8807ac6653aSJeff Kirsher 
8817ac6653aSJeff Kirsher 	else if (unlikely(status == tx_hard_error_bump_tc)) {
8827ac6653aSJeff Kirsher 		/* Try to bump up the dma threshold on this failure */
8837ac6653aSJeff Kirsher 		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
8847ac6653aSJeff Kirsher 			tc += 64;
8857ac6653aSJeff Kirsher 			priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
8867ac6653aSJeff Kirsher 			priv->xstats.threshold = tc;
8877ac6653aSJeff Kirsher 		}
8887ac6653aSJeff Kirsher 	} else if (unlikely(status == tx_hard_error))
8897ac6653aSJeff Kirsher 		stmmac_tx_err(priv);
8907ac6653aSJeff Kirsher }
8917ac6653aSJeff Kirsher 
8921c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv)
8931c901a46SGiuseppe CAVALLARO {
8941c901a46SGiuseppe CAVALLARO 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
8951c901a46SGiuseppe CAVALLARO 			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
8961c901a46SGiuseppe CAVALLARO 
8974f795b25SGiuseppe CAVALLARO 	/* Mask MMC irq, counters are managed in SW and registers
8984f795b25SGiuseppe CAVALLARO 	 * are cleared on each READ eventually. */
8991c901a46SGiuseppe CAVALLARO 	dwmac_mmc_intr_all_mask(priv->ioaddr);
9004f795b25SGiuseppe CAVALLARO 
9014f795b25SGiuseppe CAVALLARO 	if (priv->dma_cap.rmon) {
9021c901a46SGiuseppe CAVALLARO 		dwmac_mmc_ctrl(priv->ioaddr, mode);
9031c901a46SGiuseppe CAVALLARO 		memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
9044f795b25SGiuseppe CAVALLARO 	} else
905aae54cffSStefan Roese 		pr_info(" No MAC Management Counters available\n");
9061c901a46SGiuseppe CAVALLARO }
9071c901a46SGiuseppe CAVALLARO 
908f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
909f0b9d786SGiuseppe CAVALLARO {
910f0b9d786SGiuseppe CAVALLARO 	u32 hwid = priv->hw->synopsys_uid;
911f0b9d786SGiuseppe CAVALLARO 
912f0b9d786SGiuseppe CAVALLARO 	/* Only check valid Synopsys Id because old MAC chips
913f0b9d786SGiuseppe CAVALLARO 	 * have no HW registers where get the ID */
914f0b9d786SGiuseppe CAVALLARO 	if (likely(hwid)) {
915f0b9d786SGiuseppe CAVALLARO 		u32 uid = ((hwid & 0x0000ff00) >> 8);
916f0b9d786SGiuseppe CAVALLARO 		u32 synid = (hwid & 0x000000ff);
917f0b9d786SGiuseppe CAVALLARO 
918cf3f047bSGiuseppe CAVALLARO 		pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n",
919f0b9d786SGiuseppe CAVALLARO 			uid, synid);
920f0b9d786SGiuseppe CAVALLARO 
921f0b9d786SGiuseppe CAVALLARO 		return synid;
922f0b9d786SGiuseppe CAVALLARO 	}
923f0b9d786SGiuseppe CAVALLARO 	return 0;
924f0b9d786SGiuseppe CAVALLARO }
925e7434821SGiuseppe CAVALLARO 
92619e30c14SGiuseppe CAVALLARO /**
92719e30c14SGiuseppe CAVALLARO  * stmmac_selec_desc_mode
928ff3dd78cSGiuseppe CAVALLARO  * @priv : private structure
929ff3dd78cSGiuseppe CAVALLARO  * Description: select the Enhanced/Alternate or Normal descriptors
930ff3dd78cSGiuseppe CAVALLARO  */
93119e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
93219e30c14SGiuseppe CAVALLARO {
93319e30c14SGiuseppe CAVALLARO 	if (priv->plat->enh_desc) {
93419e30c14SGiuseppe CAVALLARO 		pr_info(" Enhanced/Alternate descriptors\n");
93519e30c14SGiuseppe CAVALLARO 		priv->hw->desc = &enh_desc_ops;
93619e30c14SGiuseppe CAVALLARO 	} else {
93719e30c14SGiuseppe CAVALLARO 		pr_info(" Normal descriptors\n");
93819e30c14SGiuseppe CAVALLARO 		priv->hw->desc = &ndesc_ops;
93919e30c14SGiuseppe CAVALLARO 	}
94019e30c14SGiuseppe CAVALLARO }
94119e30c14SGiuseppe CAVALLARO 
94219e30c14SGiuseppe CAVALLARO /**
94319e30c14SGiuseppe CAVALLARO  * stmmac_get_hw_features
94419e30c14SGiuseppe CAVALLARO  * @priv : private device pointer
94519e30c14SGiuseppe CAVALLARO  * Description:
94619e30c14SGiuseppe CAVALLARO  *  new GMAC chip generations have a new register to indicate the
947e7434821SGiuseppe CAVALLARO  *  presence of the optional feature/functions.
94819e30c14SGiuseppe CAVALLARO  *  This can be also used to override the value passed through the
94919e30c14SGiuseppe CAVALLARO  *  platform and necessary for old MAC10/100 and GMAC chips.
950e7434821SGiuseppe CAVALLARO  */
951e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv)
952e7434821SGiuseppe CAVALLARO {
9535e6efe88SGiuseppe CAVALLARO 	u32 hw_cap = 0;
9543c20f72fSGiuseppe CAVALLARO 
9555e6efe88SGiuseppe CAVALLARO 	if (priv->hw->dma->get_hw_feature) {
9565e6efe88SGiuseppe CAVALLARO 		hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
957e7434821SGiuseppe CAVALLARO 
9581db123fbSRayagond Kokatanur 		priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
9591db123fbSRayagond Kokatanur 		priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
9601db123fbSRayagond Kokatanur 		priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
9611db123fbSRayagond Kokatanur 		priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
9621db123fbSRayagond Kokatanur 		priv->dma_cap.multi_addr =
9631db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_ADDMACADRSEL) >> 5;
9641db123fbSRayagond Kokatanur 		priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
9651db123fbSRayagond Kokatanur 		priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
9661db123fbSRayagond Kokatanur 		priv->dma_cap.pmt_remote_wake_up =
9671db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
9681db123fbSRayagond Kokatanur 		priv->dma_cap.pmt_magic_frame =
9691db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
9701db123fbSRayagond Kokatanur 		/* MMC */
9711db123fbSRayagond Kokatanur 		priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
972e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2002*/
9731db123fbSRayagond Kokatanur 		priv->dma_cap.time_stamp =
9741db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
975e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2008*/
9761db123fbSRayagond Kokatanur 		priv->dma_cap.atime_stamp =
9771db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
978e7434821SGiuseppe CAVALLARO 		/* 802.3az - Energy-Efficient Ethernet (EEE) */
9791db123fbSRayagond Kokatanur 		priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
9801db123fbSRayagond Kokatanur 		priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
981e7434821SGiuseppe CAVALLARO 		/* TX and RX csum */
9821db123fbSRayagond Kokatanur 		priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
9831db123fbSRayagond Kokatanur 		priv->dma_cap.rx_coe_type1 =
9841db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
9851db123fbSRayagond Kokatanur 		priv->dma_cap.rx_coe_type2 =
9861db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
9871db123fbSRayagond Kokatanur 		priv->dma_cap.rxfifo_over_2048 =
9881db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
989e7434821SGiuseppe CAVALLARO 		/* TX and RX number of channels */
9901db123fbSRayagond Kokatanur 		priv->dma_cap.number_rx_channel =
9911db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
9921db123fbSRayagond Kokatanur 		priv->dma_cap.number_tx_channel =
9931db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
994e7434821SGiuseppe CAVALLARO 		/* Alternate (enhanced) DESC mode*/
9951db123fbSRayagond Kokatanur 		priv->dma_cap.enh_desc =
9961db123fbSRayagond Kokatanur 			(hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
997e7434821SGiuseppe CAVALLARO 
99819e30c14SGiuseppe CAVALLARO 	}
999e7434821SGiuseppe CAVALLARO 
1000e7434821SGiuseppe CAVALLARO 	return hw_cap;
1001e7434821SGiuseppe CAVALLARO }
1002e7434821SGiuseppe CAVALLARO 
1003bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv)
1004bfab27a1SGiuseppe CAVALLARO {
1005bfab27a1SGiuseppe CAVALLARO 	/* verify if the MAC address is valid, in case of failures it
1006bfab27a1SGiuseppe CAVALLARO 	 * generates a random MAC address */
1007bfab27a1SGiuseppe CAVALLARO 	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
1008bfab27a1SGiuseppe CAVALLARO 		priv->hw->mac->get_umac_addr((void __iomem *)
1009bfab27a1SGiuseppe CAVALLARO 					     priv->dev->base_addr,
1010bfab27a1SGiuseppe CAVALLARO 					     priv->dev->dev_addr, 0);
1011bfab27a1SGiuseppe CAVALLARO 		if  (!is_valid_ether_addr(priv->dev->dev_addr))
1012f2cedb63SDanny Kukawka 			eth_hw_addr_random(priv->dev);
1013bfab27a1SGiuseppe CAVALLARO 	}
1014bfab27a1SGiuseppe CAVALLARO 	pr_warning("%s: device MAC address %pM\n", priv->dev->name,
1015bfab27a1SGiuseppe CAVALLARO 						   priv->dev->dev_addr);
1016bfab27a1SGiuseppe CAVALLARO }
1017bfab27a1SGiuseppe CAVALLARO 
10180f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv)
10190f1f88a8SGiuseppe CAVALLARO {
10200f1f88a8SGiuseppe CAVALLARO 	int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
1021b9cde0a8SGiuseppe CAVALLARO 	int mixed_burst = 0;
10220f1f88a8SGiuseppe CAVALLARO 
10230f1f88a8SGiuseppe CAVALLARO 	/* Some DMA parameters can be passed from the platform;
10240f1f88a8SGiuseppe CAVALLARO 	 * in case of these are not passed we keep a default
10250f1f88a8SGiuseppe CAVALLARO 	 * (good for all the chips) and init the DMA! */
10260f1f88a8SGiuseppe CAVALLARO 	if (priv->plat->dma_cfg) {
10270f1f88a8SGiuseppe CAVALLARO 		pbl = priv->plat->dma_cfg->pbl;
10280f1f88a8SGiuseppe CAVALLARO 		fixed_burst = priv->plat->dma_cfg->fixed_burst;
1029b9cde0a8SGiuseppe CAVALLARO 		mixed_burst = priv->plat->dma_cfg->mixed_burst;
10300f1f88a8SGiuseppe CAVALLARO 		burst_len = priv->plat->dma_cfg->burst_len;
10310f1f88a8SGiuseppe CAVALLARO 	}
10320f1f88a8SGiuseppe CAVALLARO 
1033b9cde0a8SGiuseppe CAVALLARO 	return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
10340f1f88a8SGiuseppe CAVALLARO 				   burst_len, priv->dma_tx_phy,
10350f1f88a8SGiuseppe CAVALLARO 				   priv->dma_rx_phy);
10360f1f88a8SGiuseppe CAVALLARO }
10370f1f88a8SGiuseppe CAVALLARO 
1038bfab27a1SGiuseppe CAVALLARO /**
10397ac6653aSJeff Kirsher  *  stmmac_open - open entry point of the driver
10407ac6653aSJeff Kirsher  *  @dev : pointer to the device structure.
10417ac6653aSJeff Kirsher  *  Description:
10427ac6653aSJeff Kirsher  *  This function is the open entry point of the driver.
10437ac6653aSJeff Kirsher  *  Return value:
10447ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
10457ac6653aSJeff Kirsher  *  file on failure.
10467ac6653aSJeff Kirsher  */
10477ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev)
10487ac6653aSJeff Kirsher {
10497ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
10507ac6653aSJeff Kirsher 	int ret;
10517ac6653aSJeff Kirsher 
10527ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
10537ac6653aSJeff Kirsher 	priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
10544bfcbd7aSFrancesco Virlinzi 	if (unlikely(priv->tm == NULL))
10554bfcbd7aSFrancesco Virlinzi 		return -ENOMEM;
1056e404decbSJoe Perches 
10577ac6653aSJeff Kirsher 	priv->tm->freq = tmrate;
10587ac6653aSJeff Kirsher 
10597ac6653aSJeff Kirsher 	/* Test if the external timer can be actually used.
10607ac6653aSJeff Kirsher 	 * In case of failure continue without timer. */
10617ac6653aSJeff Kirsher 	if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
10627ac6653aSJeff Kirsher 		pr_warning("stmmaceth: cannot attach the external timer.\n");
10637ac6653aSJeff Kirsher 		priv->tm->freq = 0;
10647ac6653aSJeff Kirsher 		priv->tm->timer_start = stmmac_no_timer_started;
10657ac6653aSJeff Kirsher 		priv->tm->timer_stop = stmmac_no_timer_stopped;
10667ac6653aSJeff Kirsher 	} else
10677ac6653aSJeff Kirsher 		priv->tm->enable = 1;
10687ac6653aSJeff Kirsher #endif
10696a81c26fSViresh Kumar 	clk_enable(priv->stmmac_clk);
10704bfcbd7aSFrancesco Virlinzi 
10714bfcbd7aSFrancesco Virlinzi 	stmmac_check_ether_addr(priv);
10724bfcbd7aSFrancesco Virlinzi 
10737ac6653aSJeff Kirsher 	ret = stmmac_init_phy(dev);
10747ac6653aSJeff Kirsher 	if (unlikely(ret)) {
10757ac6653aSJeff Kirsher 		pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
10767ac6653aSJeff Kirsher 		goto open_error;
10777ac6653aSJeff Kirsher 	}
10787ac6653aSJeff Kirsher 
10797ac6653aSJeff Kirsher 	/* Create and initialize the TX/RX descriptors chains. */
10807ac6653aSJeff Kirsher 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
10817ac6653aSJeff Kirsher 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
10827ac6653aSJeff Kirsher 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
10837ac6653aSJeff Kirsher 	init_dma_desc_rings(dev);
10847ac6653aSJeff Kirsher 
10857ac6653aSJeff Kirsher 	/* DMA initialization and SW reset */
10860f1f88a8SGiuseppe CAVALLARO 	ret = stmmac_init_dma_engine(priv);
10877ac6653aSJeff Kirsher 	if (ret < 0) {
10887ac6653aSJeff Kirsher 		pr_err("%s: DMA initialization failed\n", __func__);
10897ac6653aSJeff Kirsher 		goto open_error;
10907ac6653aSJeff Kirsher 	}
10917ac6653aSJeff Kirsher 
10927ac6653aSJeff Kirsher 	/* Copy the MAC addr into the HW  */
10937ac6653aSJeff Kirsher 	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
1094cf3f047bSGiuseppe CAVALLARO 
10957ac6653aSJeff Kirsher 	/* If required, perform hw setup of the bus. */
10967ac6653aSJeff Kirsher 	if (priv->plat->bus_setup)
10977ac6653aSJeff Kirsher 		priv->plat->bus_setup(priv->ioaddr);
1098cf3f047bSGiuseppe CAVALLARO 
10997ac6653aSJeff Kirsher 	/* Initialize the MAC Core */
11007ac6653aSJeff Kirsher 	priv->hw->mac->core_init(priv->ioaddr);
11017ac6653aSJeff Kirsher 
11027ac6653aSJeff Kirsher 	/* Request the IRQ lines */
11037ac6653aSJeff Kirsher 	ret = request_irq(dev->irq, stmmac_interrupt,
11047ac6653aSJeff Kirsher 			 IRQF_SHARED, dev->name, dev);
11057ac6653aSJeff Kirsher 	if (unlikely(ret < 0)) {
11067ac6653aSJeff Kirsher 		pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
11077ac6653aSJeff Kirsher 		       __func__, dev->irq, ret);
11087ac6653aSJeff Kirsher 		goto open_error;
11097ac6653aSJeff Kirsher 	}
11107ac6653aSJeff Kirsher 
11117a13f8f5SFrancesco Virlinzi 	/* Request the Wake IRQ in case of another line is used for WoL */
11127a13f8f5SFrancesco Virlinzi 	if (priv->wol_irq != dev->irq) {
11137a13f8f5SFrancesco Virlinzi 		ret = request_irq(priv->wol_irq, stmmac_interrupt,
11147a13f8f5SFrancesco Virlinzi 				  IRQF_SHARED, dev->name, dev);
11157a13f8f5SFrancesco Virlinzi 		if (unlikely(ret < 0)) {
11167a13f8f5SFrancesco Virlinzi 			pr_err("%s: ERROR: allocating the ext WoL IRQ %d "
11177a13f8f5SFrancesco Virlinzi 			       "(error: %d)\n",	__func__, priv->wol_irq, ret);
11187a13f8f5SFrancesco Virlinzi 			goto open_error_wolirq;
11197a13f8f5SFrancesco Virlinzi 		}
11207a13f8f5SFrancesco Virlinzi 	}
11217a13f8f5SFrancesco Virlinzi 
1122d765955dSGiuseppe CAVALLARO 	/* Request the IRQ lines */
1123d765955dSGiuseppe CAVALLARO 	if (priv->lpi_irq != -ENXIO) {
1124d765955dSGiuseppe CAVALLARO 		ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED,
1125d765955dSGiuseppe CAVALLARO 				  dev->name, dev);
1126d765955dSGiuseppe CAVALLARO 		if (unlikely(ret < 0)) {
1127d765955dSGiuseppe CAVALLARO 			pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n",
1128d765955dSGiuseppe CAVALLARO 			       __func__, priv->lpi_irq, ret);
1129d765955dSGiuseppe CAVALLARO 			goto open_error_lpiirq;
1130d765955dSGiuseppe CAVALLARO 		}
1131d765955dSGiuseppe CAVALLARO 	}
1132d765955dSGiuseppe CAVALLARO 
11337ac6653aSJeff Kirsher 	/* Enable the MAC Rx/Tx */
1134bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, true);
11357ac6653aSJeff Kirsher 
11367ac6653aSJeff Kirsher 	/* Set the HW DMA mode and the COE */
11377ac6653aSJeff Kirsher 	stmmac_dma_operation_mode(priv);
11387ac6653aSJeff Kirsher 
11397ac6653aSJeff Kirsher 	/* Extra statistics */
11407ac6653aSJeff Kirsher 	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
11417ac6653aSJeff Kirsher 	priv->xstats.threshold = tc;
11427ac6653aSJeff Kirsher 
11431c901a46SGiuseppe CAVALLARO 	stmmac_mmc_setup(priv);
11441c901a46SGiuseppe CAVALLARO 
1145bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
1146bfab27a1SGiuseppe CAVALLARO 	ret = stmmac_init_fs(dev);
1147bfab27a1SGiuseppe CAVALLARO 	if (ret < 0)
1148cf3f047bSGiuseppe CAVALLARO 		pr_warning("%s: failed debugFS registration\n", __func__);
1149bfab27a1SGiuseppe CAVALLARO #endif
11507ac6653aSJeff Kirsher 	/* Start the ball rolling... */
11517ac6653aSJeff Kirsher 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
11527ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
11537ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
11547ac6653aSJeff Kirsher 
11557ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
11567ac6653aSJeff Kirsher 	priv->tm->timer_start(tmrate);
11577ac6653aSJeff Kirsher #endif
1158cf3f047bSGiuseppe CAVALLARO 
11597ac6653aSJeff Kirsher 	/* Dump DMA/MAC registers */
11607ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
11617ac6653aSJeff Kirsher 		priv->hw->mac->dump_regs(priv->ioaddr);
11627ac6653aSJeff Kirsher 		priv->hw->dma->dump_regs(priv->ioaddr);
11637ac6653aSJeff Kirsher 	}
11647ac6653aSJeff Kirsher 
11657ac6653aSJeff Kirsher 	if (priv->phydev)
11667ac6653aSJeff Kirsher 		phy_start(priv->phydev);
11677ac6653aSJeff Kirsher 
1168d765955dSGiuseppe CAVALLARO 	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER;
1169d765955dSGiuseppe CAVALLARO 	priv->eee_enabled = stmmac_eee_init(priv);
1170d765955dSGiuseppe CAVALLARO 
11717ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
11727ac6653aSJeff Kirsher 	skb_queue_head_init(&priv->rx_recycle);
11737ac6653aSJeff Kirsher 	netif_start_queue(dev);
11747ac6653aSJeff Kirsher 
11757ac6653aSJeff Kirsher 	return 0;
11767ac6653aSJeff Kirsher 
1177d765955dSGiuseppe CAVALLARO open_error_lpiirq:
1178d765955dSGiuseppe CAVALLARO 	if (priv->wol_irq != dev->irq)
1179d765955dSGiuseppe CAVALLARO 		free_irq(priv->wol_irq, dev);
1180d765955dSGiuseppe CAVALLARO 
11817a13f8f5SFrancesco Virlinzi open_error_wolirq:
11827a13f8f5SFrancesco Virlinzi 	free_irq(dev->irq, dev);
11837a13f8f5SFrancesco Virlinzi 
11847ac6653aSJeff Kirsher open_error:
11857ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
11867ac6653aSJeff Kirsher 	kfree(priv->tm);
11877ac6653aSJeff Kirsher #endif
11887ac6653aSJeff Kirsher 	if (priv->phydev)
11897ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
11907ac6653aSJeff Kirsher 
11916a81c26fSViresh Kumar 	clk_disable(priv->stmmac_clk);
11924bfcbd7aSFrancesco Virlinzi 
11937ac6653aSJeff Kirsher 	return ret;
11947ac6653aSJeff Kirsher }
11957ac6653aSJeff Kirsher 
11967ac6653aSJeff Kirsher /**
11977ac6653aSJeff Kirsher  *  stmmac_release - close entry point of the driver
11987ac6653aSJeff Kirsher  *  @dev : device pointer.
11997ac6653aSJeff Kirsher  *  Description:
12007ac6653aSJeff Kirsher  *  This is the stop entry point of the driver.
12017ac6653aSJeff Kirsher  */
12027ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev)
12037ac6653aSJeff Kirsher {
12047ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
12057ac6653aSJeff Kirsher 
1206d765955dSGiuseppe CAVALLARO 	if (priv->eee_enabled)
1207d765955dSGiuseppe CAVALLARO 		del_timer_sync(&priv->eee_ctrl_timer);
1208d765955dSGiuseppe CAVALLARO 
12097ac6653aSJeff Kirsher 	/* Stop and disconnect the PHY */
12107ac6653aSJeff Kirsher 	if (priv->phydev) {
12117ac6653aSJeff Kirsher 		phy_stop(priv->phydev);
12127ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
12137ac6653aSJeff Kirsher 		priv->phydev = NULL;
12147ac6653aSJeff Kirsher 	}
12157ac6653aSJeff Kirsher 
12167ac6653aSJeff Kirsher 	netif_stop_queue(dev);
12177ac6653aSJeff Kirsher 
12187ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
12197ac6653aSJeff Kirsher 	/* Stop and release the timer */
12207ac6653aSJeff Kirsher 	stmmac_close_ext_timer();
12217ac6653aSJeff Kirsher 	if (priv->tm != NULL)
12227ac6653aSJeff Kirsher 		kfree(priv->tm);
12237ac6653aSJeff Kirsher #endif
12247ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
12257ac6653aSJeff Kirsher 	skb_queue_purge(&priv->rx_recycle);
12267ac6653aSJeff Kirsher 
12277ac6653aSJeff Kirsher 	/* Free the IRQ lines */
12287ac6653aSJeff Kirsher 	free_irq(dev->irq, dev);
12297a13f8f5SFrancesco Virlinzi 	if (priv->wol_irq != dev->irq)
12307a13f8f5SFrancesco Virlinzi 		free_irq(priv->wol_irq, dev);
1231d765955dSGiuseppe CAVALLARO 	if (priv->lpi_irq != -ENXIO)
1232d765955dSGiuseppe CAVALLARO 		free_irq(priv->lpi_irq, dev);
12337ac6653aSJeff Kirsher 
12347ac6653aSJeff Kirsher 	/* Stop TX/RX DMA and clear the descriptors */
12357ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
12367ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
12377ac6653aSJeff Kirsher 
12387ac6653aSJeff Kirsher 	/* Release and free the Rx/Tx resources */
12397ac6653aSJeff Kirsher 	free_dma_desc_resources(priv);
12407ac6653aSJeff Kirsher 
12417ac6653aSJeff Kirsher 	/* Disable the MAC Rx/Tx */
1242bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, false);
12437ac6653aSJeff Kirsher 
12447ac6653aSJeff Kirsher 	netif_carrier_off(dev);
12457ac6653aSJeff Kirsher 
1246bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
1247bfab27a1SGiuseppe CAVALLARO 	stmmac_exit_fs();
1248bfab27a1SGiuseppe CAVALLARO #endif
12496a81c26fSViresh Kumar 	clk_disable(priv->stmmac_clk);
1250bfab27a1SGiuseppe CAVALLARO 
12517ac6653aSJeff Kirsher 	return 0;
12527ac6653aSJeff Kirsher }
12537ac6653aSJeff Kirsher 
12547ac6653aSJeff Kirsher /**
12557ac6653aSJeff Kirsher  *  stmmac_xmit:
12567ac6653aSJeff Kirsher  *  @skb : the socket buffer
12577ac6653aSJeff Kirsher  *  @dev : device pointer
12587ac6653aSJeff Kirsher  *  Description : Tx entry point of the driver.
12597ac6653aSJeff Kirsher  */
12607ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
12617ac6653aSJeff Kirsher {
12627ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
12637ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
12647ac6653aSJeff Kirsher 	unsigned int entry;
12657ac6653aSJeff Kirsher 	int i, csum_insertion = 0;
12667ac6653aSJeff Kirsher 	int nfrags = skb_shinfo(skb)->nr_frags;
12677ac6653aSJeff Kirsher 	struct dma_desc *desc, *first;
1268286a8372SGiuseppe CAVALLARO 	unsigned int nopaged_len = skb_headlen(skb);
12697ac6653aSJeff Kirsher 
12707ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
12717ac6653aSJeff Kirsher 		if (!netif_queue_stopped(dev)) {
12727ac6653aSJeff Kirsher 			netif_stop_queue(dev);
12737ac6653aSJeff Kirsher 			/* This is a hard error, log it. */
12747ac6653aSJeff Kirsher 			pr_err("%s: BUG! Tx Ring full when queue awake\n",
12757ac6653aSJeff Kirsher 				__func__);
12767ac6653aSJeff Kirsher 		}
12777ac6653aSJeff Kirsher 		return NETDEV_TX_BUSY;
12787ac6653aSJeff Kirsher 	}
12797ac6653aSJeff Kirsher 
1280a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
1281a9097a96SGiuseppe CAVALLARO 
1282d765955dSGiuseppe CAVALLARO 	if (priv->tx_path_in_lpi_mode)
1283d765955dSGiuseppe CAVALLARO 		stmmac_disable_eee_mode(priv);
1284d765955dSGiuseppe CAVALLARO 
12857ac6653aSJeff Kirsher 	entry = priv->cur_tx % txsize;
12867ac6653aSJeff Kirsher 
12877ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
12887ac6653aSJeff Kirsher 	if ((skb->len > ETH_FRAME_LEN) || nfrags)
12897ac6653aSJeff Kirsher 		pr_info("stmmac xmit:\n"
12907ac6653aSJeff Kirsher 		       "\tskb addr %p - len: %d - nopaged_len: %d\n"
12917ac6653aSJeff Kirsher 		       "\tn_frags: %d - ip_summed: %d - %s gso\n",
1292286a8372SGiuseppe CAVALLARO 		       skb, skb->len, nopaged_len, nfrags, skb->ip_summed,
12937ac6653aSJeff Kirsher 		       !skb_is_gso(skb) ? "isn't" : "is");
12947ac6653aSJeff Kirsher #endif
12957ac6653aSJeff Kirsher 
12967ac6653aSJeff Kirsher 	csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
12977ac6653aSJeff Kirsher 
12987ac6653aSJeff Kirsher 	desc = priv->dma_tx + entry;
12997ac6653aSJeff Kirsher 	first = desc;
13007ac6653aSJeff Kirsher 
13017ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
13027ac6653aSJeff Kirsher 	if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
13037ac6653aSJeff Kirsher 		pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
13047ac6653aSJeff Kirsher 		       "\t\tn_frags: %d, ip_summed: %d\n",
1305286a8372SGiuseppe CAVALLARO 		       skb->len, nopaged_len, nfrags, skb->ip_summed);
13067ac6653aSJeff Kirsher #endif
13077ac6653aSJeff Kirsher 	priv->tx_skbuff[entry] = skb;
1308286a8372SGiuseppe CAVALLARO 
1309286a8372SGiuseppe CAVALLARO 	if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) {
1310286a8372SGiuseppe CAVALLARO 		entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion);
13117ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
13127ac6653aSJeff Kirsher 	} else {
13137ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device, skb->data,
13147ac6653aSJeff Kirsher 					nopaged_len, DMA_TO_DEVICE);
13157ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
13167ac6653aSJeff Kirsher 						csum_insertion);
13177ac6653aSJeff Kirsher 	}
13187ac6653aSJeff Kirsher 
13197ac6653aSJeff Kirsher 	for (i = 0; i < nfrags; i++) {
13209e903e08SEric Dumazet 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
13219e903e08SEric Dumazet 		int len = skb_frag_size(frag);
13227ac6653aSJeff Kirsher 
13237ac6653aSJeff Kirsher 		entry = (++priv->cur_tx) % txsize;
13247ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
13257ac6653aSJeff Kirsher 
13267ac6653aSJeff Kirsher 		TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
1327f722380dSIan Campbell 		desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
1328f722380dSIan Campbell 					      DMA_TO_DEVICE);
13297ac6653aSJeff Kirsher 		priv->tx_skbuff[entry] = NULL;
13307ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
13317ac6653aSJeff Kirsher 		wmb();
13327ac6653aSJeff Kirsher 		priv->hw->desc->set_tx_owner(desc);
13338e839891SDeepak Sikri 		wmb();
13347ac6653aSJeff Kirsher 	}
13357ac6653aSJeff Kirsher 
13367ac6653aSJeff Kirsher 	/* Interrupt on completition only for the latest segment */
13377ac6653aSJeff Kirsher 	priv->hw->desc->close_tx_desc(desc);
13387ac6653aSJeff Kirsher 
13397ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
13407ac6653aSJeff Kirsher 	/* Clean IC while using timer */
13417ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
13427ac6653aSJeff Kirsher 		priv->hw->desc->clear_tx_ic(desc);
13437ac6653aSJeff Kirsher #endif
13447ac6653aSJeff Kirsher 
13457ac6653aSJeff Kirsher 	wmb();
13467ac6653aSJeff Kirsher 
13477ac6653aSJeff Kirsher 	/* To avoid raise condition */
13487ac6653aSJeff Kirsher 	priv->hw->desc->set_tx_owner(first);
13498e839891SDeepak Sikri 	wmb();
13507ac6653aSJeff Kirsher 
13517ac6653aSJeff Kirsher 	priv->cur_tx++;
13527ac6653aSJeff Kirsher 
13537ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG
13547ac6653aSJeff Kirsher 	if (netif_msg_pktdata(priv)) {
13557ac6653aSJeff Kirsher 		pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
13567ac6653aSJeff Kirsher 		       "first=%p, nfrags=%d\n",
13577ac6653aSJeff Kirsher 		       (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
13587ac6653aSJeff Kirsher 		       entry, first, nfrags);
13597ac6653aSJeff Kirsher 		display_ring(priv->dma_tx, txsize);
13607ac6653aSJeff Kirsher 		pr_info(">>> frame to be transmitted: ");
13617ac6653aSJeff Kirsher 		print_pkt(skb->data, skb->len);
13627ac6653aSJeff Kirsher 	}
13637ac6653aSJeff Kirsher #endif
13647ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
13657ac6653aSJeff Kirsher 		TX_DBG("%s: stop transmitted packets\n", __func__);
13667ac6653aSJeff Kirsher 		netif_stop_queue(dev);
13677ac6653aSJeff Kirsher 	}
13687ac6653aSJeff Kirsher 
13697ac6653aSJeff Kirsher 	dev->stats.tx_bytes += skb->len;
13707ac6653aSJeff Kirsher 
13717ac6653aSJeff Kirsher 	skb_tx_timestamp(skb);
13727ac6653aSJeff Kirsher 
13737ac6653aSJeff Kirsher 	priv->hw->dma->enable_dma_transmission(priv->ioaddr);
13747ac6653aSJeff Kirsher 
1375a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
1376a9097a96SGiuseppe CAVALLARO 
13777ac6653aSJeff Kirsher 	return NETDEV_TX_OK;
13787ac6653aSJeff Kirsher }
13797ac6653aSJeff Kirsher 
13807ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv)
13817ac6653aSJeff Kirsher {
13827ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
13837ac6653aSJeff Kirsher 	int bfsize = priv->dma_buf_sz;
13847ac6653aSJeff Kirsher 	struct dma_desc *p = priv->dma_rx;
13857ac6653aSJeff Kirsher 
13867ac6653aSJeff Kirsher 	for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
13877ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_rx % rxsize;
13887ac6653aSJeff Kirsher 		if (likely(priv->rx_skbuff[entry] == NULL)) {
13897ac6653aSJeff Kirsher 			struct sk_buff *skb;
13907ac6653aSJeff Kirsher 
13917ac6653aSJeff Kirsher 			skb = __skb_dequeue(&priv->rx_recycle);
13927ac6653aSJeff Kirsher 			if (skb == NULL)
13937ac6653aSJeff Kirsher 				skb = netdev_alloc_skb_ip_align(priv->dev,
13947ac6653aSJeff Kirsher 								bfsize);
13957ac6653aSJeff Kirsher 
13967ac6653aSJeff Kirsher 			if (unlikely(skb == NULL))
13977ac6653aSJeff Kirsher 				break;
13987ac6653aSJeff Kirsher 
13997ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = skb;
14007ac6653aSJeff Kirsher 			priv->rx_skbuff_dma[entry] =
14017ac6653aSJeff Kirsher 			    dma_map_single(priv->device, skb->data, bfsize,
14027ac6653aSJeff Kirsher 					   DMA_FROM_DEVICE);
14037ac6653aSJeff Kirsher 
14047ac6653aSJeff Kirsher 			(p + entry)->des2 = priv->rx_skbuff_dma[entry];
1405286a8372SGiuseppe CAVALLARO 
1406286a8372SGiuseppe CAVALLARO 			if (unlikely(priv->plat->has_gmac))
1407286a8372SGiuseppe CAVALLARO 				priv->hw->ring->refill_desc3(bfsize, p + entry);
1408286a8372SGiuseppe CAVALLARO 
14097ac6653aSJeff Kirsher 			RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
14107ac6653aSJeff Kirsher 		}
14117ac6653aSJeff Kirsher 		wmb();
14127ac6653aSJeff Kirsher 		priv->hw->desc->set_rx_owner(p + entry);
14138e839891SDeepak Sikri 		wmb();
14147ac6653aSJeff Kirsher 	}
14157ac6653aSJeff Kirsher }
14167ac6653aSJeff Kirsher 
14177ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit)
14187ac6653aSJeff Kirsher {
14197ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
14207ac6653aSJeff Kirsher 	unsigned int entry = priv->cur_rx % rxsize;
14217ac6653aSJeff Kirsher 	unsigned int next_entry;
14227ac6653aSJeff Kirsher 	unsigned int count = 0;
14237ac6653aSJeff Kirsher 	struct dma_desc *p = priv->dma_rx + entry;
14247ac6653aSJeff Kirsher 	struct dma_desc *p_next;
14257ac6653aSJeff Kirsher 
14267ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
14277ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
14287ac6653aSJeff Kirsher 		pr_debug(">>> stmmac_rx: descriptor ring:\n");
14297ac6653aSJeff Kirsher 		display_ring(priv->dma_rx, rxsize);
14307ac6653aSJeff Kirsher 	}
14317ac6653aSJeff Kirsher #endif
14327ac6653aSJeff Kirsher 	while (!priv->hw->desc->get_rx_owner(p)) {
14337ac6653aSJeff Kirsher 		int status;
14347ac6653aSJeff Kirsher 
14357ac6653aSJeff Kirsher 		if (count >= limit)
14367ac6653aSJeff Kirsher 			break;
14377ac6653aSJeff Kirsher 
14387ac6653aSJeff Kirsher 		count++;
14397ac6653aSJeff Kirsher 
14407ac6653aSJeff Kirsher 		next_entry = (++priv->cur_rx) % rxsize;
14417ac6653aSJeff Kirsher 		p_next = priv->dma_rx + next_entry;
14427ac6653aSJeff Kirsher 		prefetch(p_next);
14437ac6653aSJeff Kirsher 
14447ac6653aSJeff Kirsher 		/* read the status of the incoming frame */
14457ac6653aSJeff Kirsher 		status = (priv->hw->desc->rx_status(&priv->dev->stats,
14467ac6653aSJeff Kirsher 						    &priv->xstats, p));
14477ac6653aSJeff Kirsher 		if (unlikely(status == discard_frame))
14487ac6653aSJeff Kirsher 			priv->dev->stats.rx_errors++;
14497ac6653aSJeff Kirsher 		else {
14507ac6653aSJeff Kirsher 			struct sk_buff *skb;
14517ac6653aSJeff Kirsher 			int frame_len;
14527ac6653aSJeff Kirsher 
145338912bdbSDeepak SIKRI 			frame_len = priv->hw->desc->get_rx_frame_len(p,
145438912bdbSDeepak SIKRI 					priv->plat->rx_coe);
14557ac6653aSJeff Kirsher 			/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
14567ac6653aSJeff Kirsher 			 * Type frames (LLC/LLC-SNAP) */
14577ac6653aSJeff Kirsher 			if (unlikely(status != llc_snap))
14587ac6653aSJeff Kirsher 				frame_len -= ETH_FCS_LEN;
14597ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
14607ac6653aSJeff Kirsher 			if (frame_len > ETH_FRAME_LEN)
14617ac6653aSJeff Kirsher 				pr_debug("\tRX frame size %d, COE status: %d\n",
14627ac6653aSJeff Kirsher 					frame_len, status);
14637ac6653aSJeff Kirsher 
14647ac6653aSJeff Kirsher 			if (netif_msg_hw(priv))
14657ac6653aSJeff Kirsher 				pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
14667ac6653aSJeff Kirsher 					p, entry, p->des2);
14677ac6653aSJeff Kirsher #endif
14687ac6653aSJeff Kirsher 			skb = priv->rx_skbuff[entry];
14697ac6653aSJeff Kirsher 			if (unlikely(!skb)) {
14707ac6653aSJeff Kirsher 				pr_err("%s: Inconsistent Rx descriptor chain\n",
14717ac6653aSJeff Kirsher 					priv->dev->name);
14727ac6653aSJeff Kirsher 				priv->dev->stats.rx_dropped++;
14737ac6653aSJeff Kirsher 				break;
14747ac6653aSJeff Kirsher 			}
14757ac6653aSJeff Kirsher 			prefetch(skb->data - NET_IP_ALIGN);
14767ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = NULL;
14777ac6653aSJeff Kirsher 
14787ac6653aSJeff Kirsher 			skb_put(skb, frame_len);
14797ac6653aSJeff Kirsher 			dma_unmap_single(priv->device,
14807ac6653aSJeff Kirsher 					 priv->rx_skbuff_dma[entry],
14817ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
14827ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG
14837ac6653aSJeff Kirsher 			if (netif_msg_pktdata(priv)) {
14847ac6653aSJeff Kirsher 				pr_info(" frame received (%dbytes)", frame_len);
14857ac6653aSJeff Kirsher 				print_pkt(skb->data, frame_len);
14867ac6653aSJeff Kirsher 			}
14877ac6653aSJeff Kirsher #endif
14887ac6653aSJeff Kirsher 			skb->protocol = eth_type_trans(skb, priv->dev);
14897ac6653aSJeff Kirsher 
149038912bdbSDeepak SIKRI 			if (unlikely(!priv->plat->rx_coe)) {
14913c20f72fSGiuseppe CAVALLARO 				/* No RX COE for old mac10/100 devices */
14927ac6653aSJeff Kirsher 				skb_checksum_none_assert(skb);
14937ac6653aSJeff Kirsher 				netif_receive_skb(skb);
14947ac6653aSJeff Kirsher 			} else {
14957ac6653aSJeff Kirsher 				skb->ip_summed = CHECKSUM_UNNECESSARY;
14967ac6653aSJeff Kirsher 				napi_gro_receive(&priv->napi, skb);
14977ac6653aSJeff Kirsher 			}
14987ac6653aSJeff Kirsher 
14997ac6653aSJeff Kirsher 			priv->dev->stats.rx_packets++;
15007ac6653aSJeff Kirsher 			priv->dev->stats.rx_bytes += frame_len;
15017ac6653aSJeff Kirsher 		}
15027ac6653aSJeff Kirsher 		entry = next_entry;
15037ac6653aSJeff Kirsher 		p = p_next;	/* use prefetched values */
15047ac6653aSJeff Kirsher 	}
15057ac6653aSJeff Kirsher 
15067ac6653aSJeff Kirsher 	stmmac_rx_refill(priv);
15077ac6653aSJeff Kirsher 
15087ac6653aSJeff Kirsher 	priv->xstats.rx_pkt_n += count;
15097ac6653aSJeff Kirsher 
15107ac6653aSJeff Kirsher 	return count;
15117ac6653aSJeff Kirsher }
15127ac6653aSJeff Kirsher 
15137ac6653aSJeff Kirsher /**
15147ac6653aSJeff Kirsher  *  stmmac_poll - stmmac poll method (NAPI)
15157ac6653aSJeff Kirsher  *  @napi : pointer to the napi structure.
15167ac6653aSJeff Kirsher  *  @budget : maximum number of packets that the current CPU can receive from
15177ac6653aSJeff Kirsher  *	      all interfaces.
15187ac6653aSJeff Kirsher  *  Description :
15197ac6653aSJeff Kirsher  *   This function implements the the reception process.
15207ac6653aSJeff Kirsher  *   Also it runs the TX completion thread
15217ac6653aSJeff Kirsher  */
15227ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget)
15237ac6653aSJeff Kirsher {
15247ac6653aSJeff Kirsher 	struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
15257ac6653aSJeff Kirsher 	int work_done = 0;
15267ac6653aSJeff Kirsher 
15277ac6653aSJeff Kirsher 	priv->xstats.poll_n++;
15287ac6653aSJeff Kirsher 	stmmac_tx(priv);
15297ac6653aSJeff Kirsher 	work_done = stmmac_rx(priv, budget);
15307ac6653aSJeff Kirsher 
15317ac6653aSJeff Kirsher 	if (work_done < budget) {
15327ac6653aSJeff Kirsher 		napi_complete(napi);
15337ac6653aSJeff Kirsher 		stmmac_enable_irq(priv);
15347ac6653aSJeff Kirsher 	}
15357ac6653aSJeff Kirsher 	return work_done;
15367ac6653aSJeff Kirsher }
15377ac6653aSJeff Kirsher 
15387ac6653aSJeff Kirsher /**
15397ac6653aSJeff Kirsher  *  stmmac_tx_timeout
15407ac6653aSJeff Kirsher  *  @dev : Pointer to net device structure
15417ac6653aSJeff Kirsher  *  Description: this function is called when a packet transmission fails to
15427ac6653aSJeff Kirsher  *   complete within a reasonable tmrate. The driver will mark the error in the
15437ac6653aSJeff Kirsher  *   netdev structure and arrange for the device to be reset to a sane state
15447ac6653aSJeff Kirsher  *   in order to transmit a new packet.
15457ac6653aSJeff Kirsher  */
15467ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev)
15477ac6653aSJeff Kirsher {
15487ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
15497ac6653aSJeff Kirsher 
15507ac6653aSJeff Kirsher 	/* Clear Tx resources and restart transmitting again */
15517ac6653aSJeff Kirsher 	stmmac_tx_err(priv);
15527ac6653aSJeff Kirsher }
15537ac6653aSJeff Kirsher 
15547ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */
15557ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map)
15567ac6653aSJeff Kirsher {
15577ac6653aSJeff Kirsher 	if (dev->flags & IFF_UP)	/* can't act on a running interface */
15587ac6653aSJeff Kirsher 		return -EBUSY;
15597ac6653aSJeff Kirsher 
15607ac6653aSJeff Kirsher 	/* Don't allow changing the I/O address */
15617ac6653aSJeff Kirsher 	if (map->base_addr != dev->base_addr) {
15627ac6653aSJeff Kirsher 		pr_warning("%s: can't change I/O address\n", dev->name);
15637ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
15647ac6653aSJeff Kirsher 	}
15657ac6653aSJeff Kirsher 
15667ac6653aSJeff Kirsher 	/* Don't allow changing the IRQ */
15677ac6653aSJeff Kirsher 	if (map->irq != dev->irq) {
15687ac6653aSJeff Kirsher 		pr_warning("%s: can't change IRQ number %d\n",
15697ac6653aSJeff Kirsher 		       dev->name, dev->irq);
15707ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
15717ac6653aSJeff Kirsher 	}
15727ac6653aSJeff Kirsher 
15737ac6653aSJeff Kirsher 	/* ignore other fields */
15747ac6653aSJeff Kirsher 	return 0;
15757ac6653aSJeff Kirsher }
15767ac6653aSJeff Kirsher 
15777ac6653aSJeff Kirsher /**
157801789349SJiri Pirko  *  stmmac_set_rx_mode - entry point for multicast addressing
15797ac6653aSJeff Kirsher  *  @dev : pointer to the device structure
15807ac6653aSJeff Kirsher  *  Description:
15817ac6653aSJeff Kirsher  *  This function is a driver entry point which gets called by the kernel
15827ac6653aSJeff Kirsher  *  whenever multicast addresses must be enabled/disabled.
15837ac6653aSJeff Kirsher  *  Return value:
15847ac6653aSJeff Kirsher  *  void.
15857ac6653aSJeff Kirsher  */
158601789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev)
15877ac6653aSJeff Kirsher {
15887ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
15897ac6653aSJeff Kirsher 
15907ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
1591cffb13f4SGiuseppe CAVALLARO 	priv->hw->mac->set_filter(dev, priv->synopsys_id);
15927ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
15937ac6653aSJeff Kirsher }
15947ac6653aSJeff Kirsher 
15957ac6653aSJeff Kirsher /**
15967ac6653aSJeff Kirsher  *  stmmac_change_mtu - entry point to change MTU size for the device.
15977ac6653aSJeff Kirsher  *  @dev : device pointer.
15987ac6653aSJeff Kirsher  *  @new_mtu : the new MTU size for the device.
15997ac6653aSJeff Kirsher  *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
16007ac6653aSJeff Kirsher  *  to drive packet transmission. Ethernet has an MTU of 1500 octets
16017ac6653aSJeff Kirsher  *  (ETH_DATA_LEN). This value can be changed with ifconfig.
16027ac6653aSJeff Kirsher  *  Return value:
16037ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
16047ac6653aSJeff Kirsher  *  file on failure.
16057ac6653aSJeff Kirsher  */
16067ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
16077ac6653aSJeff Kirsher {
16087ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
16097ac6653aSJeff Kirsher 	int max_mtu;
16107ac6653aSJeff Kirsher 
16117ac6653aSJeff Kirsher 	if (netif_running(dev)) {
16127ac6653aSJeff Kirsher 		pr_err("%s: must be stopped to change its MTU\n", dev->name);
16137ac6653aSJeff Kirsher 		return -EBUSY;
16147ac6653aSJeff Kirsher 	}
16157ac6653aSJeff Kirsher 
161648febf7eSGiuseppe CAVALLARO 	if (priv->plat->enh_desc)
16177ac6653aSJeff Kirsher 		max_mtu = JUMBO_LEN;
16187ac6653aSJeff Kirsher 	else
161945db81e1SGiuseppe CAVALLARO 		max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
16207ac6653aSJeff Kirsher 
16217ac6653aSJeff Kirsher 	if ((new_mtu < 46) || (new_mtu > max_mtu)) {
16227ac6653aSJeff Kirsher 		pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
16237ac6653aSJeff Kirsher 		return -EINVAL;
16247ac6653aSJeff Kirsher 	}
16257ac6653aSJeff Kirsher 
16267ac6653aSJeff Kirsher 	dev->mtu = new_mtu;
16277ac6653aSJeff Kirsher 	netdev_update_features(dev);
16287ac6653aSJeff Kirsher 
16297ac6653aSJeff Kirsher 	return 0;
16307ac6653aSJeff Kirsher }
16317ac6653aSJeff Kirsher 
1632c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev,
1633c8f44affSMichał Mirosław 	netdev_features_t features)
16347ac6653aSJeff Kirsher {
16357ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
16367ac6653aSJeff Kirsher 
163738912bdbSDeepak SIKRI 	if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
16387ac6653aSJeff Kirsher 		features &= ~NETIF_F_RXCSUM;
163938912bdbSDeepak SIKRI 	else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
164038912bdbSDeepak SIKRI 		features &= ~NETIF_F_IPV6_CSUM;
16417ac6653aSJeff Kirsher 	if (!priv->plat->tx_coe)
16427ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
16437ac6653aSJeff Kirsher 
16447ac6653aSJeff Kirsher 	/* Some GMAC devices have a bugged Jumbo frame support that
16457ac6653aSJeff Kirsher 	 * needs to have the Tx COE disabled for oversized frames
16467ac6653aSJeff Kirsher 	 * (due to limited buffer sizes). In this case we disable
16477ac6653aSJeff Kirsher 	 * the TX csum insertionin the TDES and not use SF. */
16487ac6653aSJeff Kirsher 	if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
16497ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
16507ac6653aSJeff Kirsher 
16517ac6653aSJeff Kirsher 	return features;
16527ac6653aSJeff Kirsher }
16537ac6653aSJeff Kirsher 
16547ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
16557ac6653aSJeff Kirsher {
16567ac6653aSJeff Kirsher 	struct net_device *dev = (struct net_device *)dev_id;
16577ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
16587ac6653aSJeff Kirsher 
16597ac6653aSJeff Kirsher 	if (unlikely(!dev)) {
16607ac6653aSJeff Kirsher 		pr_err("%s: invalid dev pointer\n", __func__);
16617ac6653aSJeff Kirsher 		return IRQ_NONE;
16627ac6653aSJeff Kirsher 	}
16637ac6653aSJeff Kirsher 
16647ac6653aSJeff Kirsher 	/* To handle GMAC own interrupts */
1665d765955dSGiuseppe CAVALLARO 	if (priv->plat->has_gmac) {
1666d765955dSGiuseppe CAVALLARO 		int status = priv->hw->mac->host_irq_status((void __iomem *)
1667d765955dSGiuseppe CAVALLARO 							    dev->base_addr);
1668d765955dSGiuseppe CAVALLARO 		if (unlikely(status)) {
1669d765955dSGiuseppe CAVALLARO 			if (status & core_mmc_tx_irq)
1670d765955dSGiuseppe CAVALLARO 				priv->xstats.mmc_tx_irq_n++;
1671d765955dSGiuseppe CAVALLARO 			if (status & core_mmc_rx_irq)
1672d765955dSGiuseppe CAVALLARO 				priv->xstats.mmc_rx_irq_n++;
1673d765955dSGiuseppe CAVALLARO 			if (status & core_mmc_rx_csum_offload_irq)
1674d765955dSGiuseppe CAVALLARO 				priv->xstats.mmc_rx_csum_offload_irq_n++;
1675d765955dSGiuseppe CAVALLARO 			if (status & core_irq_receive_pmt_irq)
1676d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_receive_pmt_irq_n++;
16777ac6653aSJeff Kirsher 
1678d765955dSGiuseppe CAVALLARO 			/* For LPI we need to save the tx status */
1679d765955dSGiuseppe CAVALLARO 			if (status & core_irq_tx_path_in_lpi_mode) {
1680d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_tx_path_in_lpi_mode_n++;
1681d765955dSGiuseppe CAVALLARO 				priv->tx_path_in_lpi_mode = true;
1682d765955dSGiuseppe CAVALLARO 			}
1683d765955dSGiuseppe CAVALLARO 			if (status & core_irq_tx_path_exit_lpi_mode) {
1684d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_tx_path_exit_lpi_mode_n++;
1685d765955dSGiuseppe CAVALLARO 				priv->tx_path_in_lpi_mode = false;
1686d765955dSGiuseppe CAVALLARO 			}
1687d765955dSGiuseppe CAVALLARO 			if (status & core_irq_rx_path_in_lpi_mode)
1688d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_rx_path_in_lpi_mode_n++;
1689d765955dSGiuseppe CAVALLARO 			if (status & core_irq_rx_path_exit_lpi_mode)
1690d765955dSGiuseppe CAVALLARO 				priv->xstats.irq_rx_path_exit_lpi_mode_n++;
1691d765955dSGiuseppe CAVALLARO 		}
1692d765955dSGiuseppe CAVALLARO 	}
1693d765955dSGiuseppe CAVALLARO 
1694d765955dSGiuseppe CAVALLARO 	/* To handle DMA interrupts */
16957ac6653aSJeff Kirsher 	stmmac_dma_interrupt(priv);
16967ac6653aSJeff Kirsher 
16977ac6653aSJeff Kirsher 	return IRQ_HANDLED;
16987ac6653aSJeff Kirsher }
16997ac6653aSJeff Kirsher 
17007ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
17017ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools
17027ac6653aSJeff Kirsher  * to allow network I/O with interrupts disabled. */
17037ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev)
17047ac6653aSJeff Kirsher {
17057ac6653aSJeff Kirsher 	disable_irq(dev->irq);
17067ac6653aSJeff Kirsher 	stmmac_interrupt(dev->irq, dev);
17077ac6653aSJeff Kirsher 	enable_irq(dev->irq);
17087ac6653aSJeff Kirsher }
17097ac6653aSJeff Kirsher #endif
17107ac6653aSJeff Kirsher 
17117ac6653aSJeff Kirsher /**
17127ac6653aSJeff Kirsher  *  stmmac_ioctl - Entry point for the Ioctl
17137ac6653aSJeff Kirsher  *  @dev: Device pointer.
17147ac6653aSJeff Kirsher  *  @rq: An IOCTL specefic structure, that can contain a pointer to
17157ac6653aSJeff Kirsher  *  a proprietary structure used to pass information to the driver.
17167ac6653aSJeff Kirsher  *  @cmd: IOCTL command
17177ac6653aSJeff Kirsher  *  Description:
17187ac6653aSJeff Kirsher  *  Currently there are no special functionality supported in IOCTL, just the
17197ac6653aSJeff Kirsher  *  phy_mii_ioctl(...) can be invoked.
17207ac6653aSJeff Kirsher  */
17217ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
17227ac6653aSJeff Kirsher {
17237ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
17247ac6653aSJeff Kirsher 	int ret;
17257ac6653aSJeff Kirsher 
17267ac6653aSJeff Kirsher 	if (!netif_running(dev))
17277ac6653aSJeff Kirsher 		return -EINVAL;
17287ac6653aSJeff Kirsher 
17297ac6653aSJeff Kirsher 	if (!priv->phydev)
17307ac6653aSJeff Kirsher 		return -EINVAL;
17317ac6653aSJeff Kirsher 
17327ac6653aSJeff Kirsher 	ret = phy_mii_ioctl(priv->phydev, rq, cmd);
17337ac6653aSJeff Kirsher 
17347ac6653aSJeff Kirsher 	return ret;
17357ac6653aSJeff Kirsher }
17367ac6653aSJeff Kirsher 
17377ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
17387ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir;
17397ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status;
1740e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap;
17417ac29055SGiuseppe CAVALLARO 
17427ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
17437ac29055SGiuseppe CAVALLARO {
17447ac29055SGiuseppe CAVALLARO 	struct tmp_s {
17457ac29055SGiuseppe CAVALLARO 		u64 a;
17467ac29055SGiuseppe CAVALLARO 		unsigned int b;
17477ac29055SGiuseppe CAVALLARO 		unsigned int c;
17487ac29055SGiuseppe CAVALLARO 	};
17497ac29055SGiuseppe CAVALLARO 	int i;
17507ac29055SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
17517ac29055SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
17527ac29055SGiuseppe CAVALLARO 
17537ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
17547ac29055SGiuseppe CAVALLARO 	seq_printf(seq, " RX descriptor ring\n");
17557ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
17567ac29055SGiuseppe CAVALLARO 
17577ac29055SGiuseppe CAVALLARO 	for (i = 0; i < priv->dma_rx_size; i++) {
17587ac29055SGiuseppe CAVALLARO 		struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i);
17597ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
17607ac29055SGiuseppe CAVALLARO 			   i, (unsigned int)(x->a),
17617ac29055SGiuseppe CAVALLARO 			   (unsigned int)((x->a) >> 32), x->b, x->c);
17627ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
17637ac29055SGiuseppe CAVALLARO 	}
17647ac29055SGiuseppe CAVALLARO 
17657ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "\n");
17667ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
17677ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "  TX descriptor ring\n");
17687ac29055SGiuseppe CAVALLARO 	seq_printf(seq, "=======================\n");
17697ac29055SGiuseppe CAVALLARO 
17707ac29055SGiuseppe CAVALLARO 	for (i = 0; i < priv->dma_tx_size; i++) {
17717ac29055SGiuseppe CAVALLARO 		struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i);
17727ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
17737ac29055SGiuseppe CAVALLARO 			   i, (unsigned int)(x->a),
17747ac29055SGiuseppe CAVALLARO 			   (unsigned int)((x->a) >> 32), x->b, x->c);
17757ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
17767ac29055SGiuseppe CAVALLARO 	}
17777ac29055SGiuseppe CAVALLARO 
17787ac29055SGiuseppe CAVALLARO 	return 0;
17797ac29055SGiuseppe CAVALLARO }
17807ac29055SGiuseppe CAVALLARO 
17817ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file)
17827ac29055SGiuseppe CAVALLARO {
17837ac29055SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_ring_read, inode->i_private);
17847ac29055SGiuseppe CAVALLARO }
17857ac29055SGiuseppe CAVALLARO 
17867ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = {
17877ac29055SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
17887ac29055SGiuseppe CAVALLARO 	.open = stmmac_sysfs_ring_open,
17897ac29055SGiuseppe CAVALLARO 	.read = seq_read,
17907ac29055SGiuseppe CAVALLARO 	.llseek = seq_lseek,
179174863948SDjalal Harouni 	.release = single_release,
17927ac29055SGiuseppe CAVALLARO };
17937ac29055SGiuseppe CAVALLARO 
1794e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
1795e7434821SGiuseppe CAVALLARO {
1796e7434821SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
1797e7434821SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
1798e7434821SGiuseppe CAVALLARO 
179919e30c14SGiuseppe CAVALLARO 	if (!priv->hw_cap_support) {
1800e7434821SGiuseppe CAVALLARO 		seq_printf(seq, "DMA HW features not supported\n");
1801e7434821SGiuseppe CAVALLARO 		return 0;
1802e7434821SGiuseppe CAVALLARO 	}
1803e7434821SGiuseppe CAVALLARO 
1804e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
1805e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tDMA HW features\n");
1806e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
1807e7434821SGiuseppe CAVALLARO 
1808e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t10/100 Mbps %s\n",
1809e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_10_100) ? "Y" : "N");
1810e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t1000 Mbps %s\n",
1811e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_1000) ? "Y" : "N");
1812e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHalf duple %s\n",
1813e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.half_duplex) ? "Y" : "N");
1814e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHash Filter: %s\n",
1815e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.hash_filter) ? "Y" : "N");
1816e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tMultiple MAC address registers: %s\n",
1817e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.multi_addr) ? "Y" : "N");
1818e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n",
1819e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pcs) ? "Y" : "N");
1820e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tSMA (MDIO) Interface: %s\n",
1821e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.sma_mdio) ? "Y" : "N");
1822e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Remote wake up: %s\n",
1823e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N");
1824e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Magic Frame: %s\n",
1825e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_magic_frame) ? "Y" : "N");
1826e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRMON module: %s\n",
1827e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rmon) ? "Y" : "N");
1828e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n",
1829e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.time_stamp) ? "Y" : "N");
1830e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n",
1831e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.atime_stamp) ? "Y" : "N");
1832e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n",
1833e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.eee) ? "Y" : "N");
1834e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N");
1835e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tChecksum Offload in TX: %s\n",
1836e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.tx_coe) ? "Y" : "N");
1837e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n",
1838e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type1) ? "Y" : "N");
1839e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
1840e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type2) ? "Y" : "N");
1841e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n",
1842e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N");
1843e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional RX channel: %d\n",
1844e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_rx_channel);
1845e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional TX channel: %d\n",
1846e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_tx_channel);
1847e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tEnhanced descriptors: %s\n",
1848e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.enh_desc) ? "Y" : "N");
1849e7434821SGiuseppe CAVALLARO 
1850e7434821SGiuseppe CAVALLARO 	return 0;
1851e7434821SGiuseppe CAVALLARO }
1852e7434821SGiuseppe CAVALLARO 
1853e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file)
1854e7434821SGiuseppe CAVALLARO {
1855e7434821SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private);
1856e7434821SGiuseppe CAVALLARO }
1857e7434821SGiuseppe CAVALLARO 
1858e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = {
1859e7434821SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
1860e7434821SGiuseppe CAVALLARO 	.open = stmmac_sysfs_dma_cap_open,
1861e7434821SGiuseppe CAVALLARO 	.read = seq_read,
1862e7434821SGiuseppe CAVALLARO 	.llseek = seq_lseek,
186374863948SDjalal Harouni 	.release = single_release,
1864e7434821SGiuseppe CAVALLARO };
1865e7434821SGiuseppe CAVALLARO 
18667ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev)
18677ac29055SGiuseppe CAVALLARO {
18687ac29055SGiuseppe CAVALLARO 	/* Create debugfs entries */
18697ac29055SGiuseppe CAVALLARO 	stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
18707ac29055SGiuseppe CAVALLARO 
18717ac29055SGiuseppe CAVALLARO 	if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
18727ac29055SGiuseppe CAVALLARO 		pr_err("ERROR %s, debugfs create directory failed\n",
18737ac29055SGiuseppe CAVALLARO 		       STMMAC_RESOURCE_NAME);
18747ac29055SGiuseppe CAVALLARO 
18757ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
18767ac29055SGiuseppe CAVALLARO 	}
18777ac29055SGiuseppe CAVALLARO 
18787ac29055SGiuseppe CAVALLARO 	/* Entry to report DMA RX/TX rings */
18797ac29055SGiuseppe CAVALLARO 	stmmac_rings_status = debugfs_create_file("descriptors_status",
18807ac29055SGiuseppe CAVALLARO 					   S_IRUGO, stmmac_fs_dir, dev,
18817ac29055SGiuseppe CAVALLARO 					   &stmmac_rings_status_fops);
18827ac29055SGiuseppe CAVALLARO 
18837ac29055SGiuseppe CAVALLARO 	if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
18847ac29055SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac ring debugfs file\n");
18857ac29055SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
18867ac29055SGiuseppe CAVALLARO 
18877ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
18887ac29055SGiuseppe CAVALLARO 	}
18897ac29055SGiuseppe CAVALLARO 
1890e7434821SGiuseppe CAVALLARO 	/* Entry to report the DMA HW features */
1891e7434821SGiuseppe CAVALLARO 	stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
1892e7434821SGiuseppe CAVALLARO 					     dev, &stmmac_dma_cap_fops);
1893e7434821SGiuseppe CAVALLARO 
1894e7434821SGiuseppe CAVALLARO 	if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
1895e7434821SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac MMC debugfs file\n");
1896e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_rings_status);
1897e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
1898e7434821SGiuseppe CAVALLARO 
1899e7434821SGiuseppe CAVALLARO 		return -ENOMEM;
1900e7434821SGiuseppe CAVALLARO 	}
1901e7434821SGiuseppe CAVALLARO 
19027ac29055SGiuseppe CAVALLARO 	return 0;
19037ac29055SGiuseppe CAVALLARO }
19047ac29055SGiuseppe CAVALLARO 
19057ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void)
19067ac29055SGiuseppe CAVALLARO {
19077ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_rings_status);
1908e7434821SGiuseppe CAVALLARO 	debugfs_remove(stmmac_dma_cap);
19097ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_fs_dir);
19107ac29055SGiuseppe CAVALLARO }
19117ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */
19127ac29055SGiuseppe CAVALLARO 
19137ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = {
19147ac6653aSJeff Kirsher 	.ndo_open = stmmac_open,
19157ac6653aSJeff Kirsher 	.ndo_start_xmit = stmmac_xmit,
19167ac6653aSJeff Kirsher 	.ndo_stop = stmmac_release,
19177ac6653aSJeff Kirsher 	.ndo_change_mtu = stmmac_change_mtu,
19187ac6653aSJeff Kirsher 	.ndo_fix_features = stmmac_fix_features,
191901789349SJiri Pirko 	.ndo_set_rx_mode = stmmac_set_rx_mode,
19207ac6653aSJeff Kirsher 	.ndo_tx_timeout = stmmac_tx_timeout,
19217ac6653aSJeff Kirsher 	.ndo_do_ioctl = stmmac_ioctl,
19227ac6653aSJeff Kirsher 	.ndo_set_config = stmmac_config,
19237ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
19247ac6653aSJeff Kirsher 	.ndo_poll_controller = stmmac_poll_controller,
19257ac6653aSJeff Kirsher #endif
19267ac6653aSJeff Kirsher 	.ndo_set_mac_address = eth_mac_addr,
19277ac6653aSJeff Kirsher };
19287ac6653aSJeff Kirsher 
19297ac6653aSJeff Kirsher /**
1930cf3f047bSGiuseppe CAVALLARO  *  stmmac_hw_init - Init the MAC device
1931cf3f047bSGiuseppe CAVALLARO  *  @priv : pointer to the private device structure.
1932cf3f047bSGiuseppe CAVALLARO  *  Description: this function detects which MAC device
1933cf3f047bSGiuseppe CAVALLARO  *  (GMAC/MAC10-100) has to attached, checks the HW capability
1934cf3f047bSGiuseppe CAVALLARO  *  (if supported) and sets the driver's features (for example
1935cf3f047bSGiuseppe CAVALLARO  *  to use the ring or chaine mode or support the normal/enh
1936cf3f047bSGiuseppe CAVALLARO  *  descriptor structure).
1937cf3f047bSGiuseppe CAVALLARO  */
1938cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv)
1939cf3f047bSGiuseppe CAVALLARO {
1940cf3f047bSGiuseppe CAVALLARO 	int ret = 0;
1941cf3f047bSGiuseppe CAVALLARO 	struct mac_device_info *mac;
1942cf3f047bSGiuseppe CAVALLARO 
1943cf3f047bSGiuseppe CAVALLARO 	/* Identify the MAC HW device */
194403f2eecdSMarc Kleine-Budde 	if (priv->plat->has_gmac) {
194503f2eecdSMarc Kleine-Budde 		priv->dev->priv_flags |= IFF_UNICAST_FLT;
1946cf3f047bSGiuseppe CAVALLARO 		mac = dwmac1000_setup(priv->ioaddr);
194703f2eecdSMarc Kleine-Budde 	} else {
1948cf3f047bSGiuseppe CAVALLARO 		mac = dwmac100_setup(priv->ioaddr);
194903f2eecdSMarc Kleine-Budde 	}
1950cf3f047bSGiuseppe CAVALLARO 	if (!mac)
1951cf3f047bSGiuseppe CAVALLARO 		return -ENOMEM;
1952cf3f047bSGiuseppe CAVALLARO 
1953cf3f047bSGiuseppe CAVALLARO 	priv->hw = mac;
1954cf3f047bSGiuseppe CAVALLARO 
1955cf3f047bSGiuseppe CAVALLARO 	/* To use the chained or ring mode */
1956cf3f047bSGiuseppe CAVALLARO 	priv->hw->ring = &ring_mode_ops;
1957cf3f047bSGiuseppe CAVALLARO 
1958cf3f047bSGiuseppe CAVALLARO 	/* Get and dump the chip ID */
1959cffb13f4SGiuseppe CAVALLARO 	priv->synopsys_id = stmmac_get_synopsys_id(priv);
1960cf3f047bSGiuseppe CAVALLARO 
1961cf3f047bSGiuseppe CAVALLARO 	/* Get the HW capability (new GMAC newer than 3.50a) */
1962cf3f047bSGiuseppe CAVALLARO 	priv->hw_cap_support = stmmac_get_hw_features(priv);
1963cf3f047bSGiuseppe CAVALLARO 	if (priv->hw_cap_support) {
1964cf3f047bSGiuseppe CAVALLARO 		pr_info(" DMA HW capability register supported");
1965cf3f047bSGiuseppe CAVALLARO 
1966cf3f047bSGiuseppe CAVALLARO 		/* We can override some gmac/dma configuration fields: e.g.
1967cf3f047bSGiuseppe CAVALLARO 		 * enh_desc, tx_coe (e.g. that are passed through the
1968cf3f047bSGiuseppe CAVALLARO 		 * platform) with the values from the HW capability
1969cf3f047bSGiuseppe CAVALLARO 		 * register (if supported).
1970cf3f047bSGiuseppe CAVALLARO 		 */
1971cf3f047bSGiuseppe CAVALLARO 		priv->plat->enh_desc = priv->dma_cap.enh_desc;
1972cf3f047bSGiuseppe CAVALLARO 		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
197338912bdbSDeepak SIKRI 
197438912bdbSDeepak SIKRI 		priv->plat->tx_coe = priv->dma_cap.tx_coe;
197538912bdbSDeepak SIKRI 
197638912bdbSDeepak SIKRI 		if (priv->dma_cap.rx_coe_type2)
197738912bdbSDeepak SIKRI 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
197838912bdbSDeepak SIKRI 		else if (priv->dma_cap.rx_coe_type1)
197938912bdbSDeepak SIKRI 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE1;
198038912bdbSDeepak SIKRI 
1981cf3f047bSGiuseppe CAVALLARO 	} else
1982cf3f047bSGiuseppe CAVALLARO 		pr_info(" No HW DMA feature register supported");
1983cf3f047bSGiuseppe CAVALLARO 
1984cf3f047bSGiuseppe CAVALLARO 	/* Select the enhnaced/normal descriptor structures */
1985cf3f047bSGiuseppe CAVALLARO 	stmmac_selec_desc_mode(priv);
1986cf3f047bSGiuseppe CAVALLARO 
198738912bdbSDeepak SIKRI 	/* Enable the IPC (Checksum Offload) and check if the feature has been
198838912bdbSDeepak SIKRI 	 * enabled during the core configuration. */
198938912bdbSDeepak SIKRI 	ret = priv->hw->mac->rx_ipc(priv->ioaddr);
199038912bdbSDeepak SIKRI 	if (!ret) {
199138912bdbSDeepak SIKRI 		pr_warning(" RX IPC Checksum Offload not configured.\n");
199238912bdbSDeepak SIKRI 		priv->plat->rx_coe = STMMAC_RX_COE_NONE;
199338912bdbSDeepak SIKRI 	}
199438912bdbSDeepak SIKRI 
199538912bdbSDeepak SIKRI 	if (priv->plat->rx_coe)
199638912bdbSDeepak SIKRI 		pr_info(" RX Checksum Offload Engine supported (type %d)\n",
199738912bdbSDeepak SIKRI 			priv->plat->rx_coe);
1998cf3f047bSGiuseppe CAVALLARO 	if (priv->plat->tx_coe)
1999cf3f047bSGiuseppe CAVALLARO 		pr_info(" TX Checksum insertion supported\n");
2000cf3f047bSGiuseppe CAVALLARO 
2001cf3f047bSGiuseppe CAVALLARO 	if (priv->plat->pmt) {
2002cf3f047bSGiuseppe CAVALLARO 		pr_info(" Wake-Up On Lan supported\n");
2003cf3f047bSGiuseppe CAVALLARO 		device_set_wakeup_capable(priv->device, 1);
2004cf3f047bSGiuseppe CAVALLARO 	}
2005cf3f047bSGiuseppe CAVALLARO 
2006cf3f047bSGiuseppe CAVALLARO 	return ret;
2007cf3f047bSGiuseppe CAVALLARO }
2008cf3f047bSGiuseppe CAVALLARO 
2009cf3f047bSGiuseppe CAVALLARO /**
2010bfab27a1SGiuseppe CAVALLARO  * stmmac_dvr_probe
2011bfab27a1SGiuseppe CAVALLARO  * @device: device pointer
2012ff3dd78cSGiuseppe CAVALLARO  * @plat_dat: platform data pointer
2013ff3dd78cSGiuseppe CAVALLARO  * @addr: iobase memory address
2014bfab27a1SGiuseppe CAVALLARO  * Description: this is the main probe function used to
2015bfab27a1SGiuseppe CAVALLARO  * call the alloc_etherdev, allocate the priv structure.
20167ac6653aSJeff Kirsher  */
2017bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device,
2018cf3f047bSGiuseppe CAVALLARO 				     struct plat_stmmacenet_data *plat_dat,
2019cf3f047bSGiuseppe CAVALLARO 				     void __iomem *addr)
20207ac6653aSJeff Kirsher {
20217ac6653aSJeff Kirsher 	int ret = 0;
2022bfab27a1SGiuseppe CAVALLARO 	struct net_device *ndev = NULL;
2023bfab27a1SGiuseppe CAVALLARO 	struct stmmac_priv *priv;
20247ac6653aSJeff Kirsher 
2025bfab27a1SGiuseppe CAVALLARO 	ndev = alloc_etherdev(sizeof(struct stmmac_priv));
202641de8d4cSJoe Perches 	if (!ndev)
2027bfab27a1SGiuseppe CAVALLARO 		return NULL;
20287ac6653aSJeff Kirsher 
2029bfab27a1SGiuseppe CAVALLARO 	SET_NETDEV_DEV(ndev, device);
20307ac6653aSJeff Kirsher 
2031bfab27a1SGiuseppe CAVALLARO 	priv = netdev_priv(ndev);
2032bfab27a1SGiuseppe CAVALLARO 	priv->device = device;
2033bfab27a1SGiuseppe CAVALLARO 	priv->dev = ndev;
2034bfab27a1SGiuseppe CAVALLARO 
2035bfab27a1SGiuseppe CAVALLARO 	ether_setup(ndev);
2036bfab27a1SGiuseppe CAVALLARO 
2037bfab27a1SGiuseppe CAVALLARO 	stmmac_set_ethtool_ops(ndev);
2038cf3f047bSGiuseppe CAVALLARO 	priv->pause = pause;
2039cf3f047bSGiuseppe CAVALLARO 	priv->plat = plat_dat;
2040cf3f047bSGiuseppe CAVALLARO 	priv->ioaddr = addr;
2041cf3f047bSGiuseppe CAVALLARO 	priv->dev->base_addr = (unsigned long)addr;
2042bfab27a1SGiuseppe CAVALLARO 
2043cf3f047bSGiuseppe CAVALLARO 	/* Verify driver arguments */
2044cf3f047bSGiuseppe CAVALLARO 	stmmac_verify_args();
2045cf3f047bSGiuseppe CAVALLARO 
2046cf3f047bSGiuseppe CAVALLARO 	/* Override with kernel parameters if supplied XXX CRS XXX
2047cf3f047bSGiuseppe CAVALLARO 	 * this needs to have multiple instances */
2048cf3f047bSGiuseppe CAVALLARO 	if ((phyaddr >= 0) && (phyaddr <= 31))
2049cf3f047bSGiuseppe CAVALLARO 		priv->plat->phy_addr = phyaddr;
2050cf3f047bSGiuseppe CAVALLARO 
2051cf3f047bSGiuseppe CAVALLARO 	/* Init MAC and get the capabilities */
2052cf3f047bSGiuseppe CAVALLARO 	stmmac_hw_init(priv);
2053cf3f047bSGiuseppe CAVALLARO 
2054cf3f047bSGiuseppe CAVALLARO 	ndev->netdev_ops = &stmmac_netdev_ops;
2055cf3f047bSGiuseppe CAVALLARO 
2056cf3f047bSGiuseppe CAVALLARO 	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2057cf3f047bSGiuseppe CAVALLARO 			    NETIF_F_RXCSUM;
2058bfab27a1SGiuseppe CAVALLARO 	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
2059bfab27a1SGiuseppe CAVALLARO 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
20607ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED
20617ac6653aSJeff Kirsher 	/* Both mac100 and gmac support receive VLAN tag detection */
2062bfab27a1SGiuseppe CAVALLARO 	ndev->features |= NETIF_F_HW_VLAN_RX;
20637ac6653aSJeff Kirsher #endif
20647ac6653aSJeff Kirsher 	priv->msg_enable = netif_msg_init(debug, default_msg_level);
20657ac6653aSJeff Kirsher 
20667ac6653aSJeff Kirsher 	if (flow_ctrl)
20677ac6653aSJeff Kirsher 		priv->flow_ctrl = FLOW_AUTO;	/* RX/TX pause on */
20687ac6653aSJeff Kirsher 
2069bfab27a1SGiuseppe CAVALLARO 	netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
20707ac6653aSJeff Kirsher 
20717ac6653aSJeff Kirsher 	spin_lock_init(&priv->lock);
2072a9097a96SGiuseppe CAVALLARO 	spin_lock_init(&priv->tx_lock);
20737ac6653aSJeff Kirsher 
2074bfab27a1SGiuseppe CAVALLARO 	ret = register_netdev(ndev);
20757ac6653aSJeff Kirsher 	if (ret) {
2076cf3f047bSGiuseppe CAVALLARO 		pr_err("%s: ERROR %i registering the device\n", __func__, ret);
20776a81c26fSViresh Kumar 		goto error_netdev_register;
20787ac6653aSJeff Kirsher 	}
20797ac6653aSJeff Kirsher 
2080ae4d8cf2SKelvin Cheung 	priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
20816a81c26fSViresh Kumar 	if (IS_ERR(priv->stmmac_clk)) {
208231ea38eeSGiuseppe CAVALLARO 		pr_warning("%s: warning: cannot get CSR clock\n", __func__);
20836a81c26fSViresh Kumar 		goto error_clk_get;
20846a81c26fSViresh Kumar 	}
2085ba1377ffSGiuseppe CAVALLARO 
2086cd7201f4SGiuseppe CAVALLARO 	/* If a specific clk_csr value is passed from the platform
2087cd7201f4SGiuseppe CAVALLARO 	 * this means that the CSR Clock Range selection cannot be
2088cd7201f4SGiuseppe CAVALLARO 	 * changed at run-time and it is fixed. Viceversa the driver'll try to
2089cd7201f4SGiuseppe CAVALLARO 	 * set the MDC clock dynamically according to the csr actual
2090cd7201f4SGiuseppe CAVALLARO 	 * clock input.
2091cd7201f4SGiuseppe CAVALLARO 	 */
2092cd7201f4SGiuseppe CAVALLARO 	if (!priv->plat->clk_csr)
2093cd7201f4SGiuseppe CAVALLARO 		stmmac_clk_csr_set(priv);
2094cd7201f4SGiuseppe CAVALLARO 	else
2095cd7201f4SGiuseppe CAVALLARO 		priv->clk_csr = priv->plat->clk_csr;
2096cd7201f4SGiuseppe CAVALLARO 
20974bfcbd7aSFrancesco Virlinzi 	/* MDIO bus Registration */
20984bfcbd7aSFrancesco Virlinzi 	ret = stmmac_mdio_register(ndev);
20994bfcbd7aSFrancesco Virlinzi 	if (ret < 0) {
21004bfcbd7aSFrancesco Virlinzi 		pr_debug("%s: MDIO bus (id: %d) registration failed",
21014bfcbd7aSFrancesco Virlinzi 			 __func__, priv->plat->bus_id);
21026a81c26fSViresh Kumar 		goto error_mdio_register;
21034bfcbd7aSFrancesco Virlinzi 	}
21044bfcbd7aSFrancesco Virlinzi 
2105bfab27a1SGiuseppe CAVALLARO 	return priv;
21067ac6653aSJeff Kirsher 
21076a81c26fSViresh Kumar error_mdio_register:
21086a81c26fSViresh Kumar 	clk_put(priv->stmmac_clk);
21096a81c26fSViresh Kumar error_clk_get:
21107ac6653aSJeff Kirsher 	unregister_netdev(ndev);
21116a81c26fSViresh Kumar error_netdev_register:
21126a81c26fSViresh Kumar 	netif_napi_del(&priv->napi);
21137ac6653aSJeff Kirsher 	free_netdev(ndev);
21147ac6653aSJeff Kirsher 
2115bfab27a1SGiuseppe CAVALLARO 	return NULL;
21167ac6653aSJeff Kirsher }
21177ac6653aSJeff Kirsher 
21187ac6653aSJeff Kirsher /**
21197ac6653aSJeff Kirsher  * stmmac_dvr_remove
2120bfab27a1SGiuseppe CAVALLARO  * @ndev: net device pointer
21217ac6653aSJeff Kirsher  * Description: this function resets the TX/RX processes, disables the MAC RX/TX
2122bfab27a1SGiuseppe CAVALLARO  * changes the link status, releases the DMA descriptor rings.
21237ac6653aSJeff Kirsher  */
2124bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev)
21257ac6653aSJeff Kirsher {
21267ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
21277ac6653aSJeff Kirsher 
21287ac6653aSJeff Kirsher 	pr_info("%s:\n\tremoving driver", __func__);
21297ac6653aSJeff Kirsher 
21307ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
21317ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
21327ac6653aSJeff Kirsher 
2133bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, false);
21344bfcbd7aSFrancesco Virlinzi 	stmmac_mdio_unregister(ndev);
21357ac6653aSJeff Kirsher 	netif_carrier_off(ndev);
21367ac6653aSJeff Kirsher 	unregister_netdev(ndev);
21377ac6653aSJeff Kirsher 	free_netdev(ndev);
21387ac6653aSJeff Kirsher 
21397ac6653aSJeff Kirsher 	return 0;
21407ac6653aSJeff Kirsher }
21417ac6653aSJeff Kirsher 
21427ac6653aSJeff Kirsher #ifdef CONFIG_PM
2143bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev)
21447ac6653aSJeff Kirsher {
21457ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
21467ac6653aSJeff Kirsher 	int dis_ic = 0;
2147f8c5a875SGiuseppe CAVALLARO 	unsigned long flags;
21487ac6653aSJeff Kirsher 
21497ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
21507ac6653aSJeff Kirsher 		return 0;
21517ac6653aSJeff Kirsher 
2152102463b1SFrancesco Virlinzi 	if (priv->phydev)
2153102463b1SFrancesco Virlinzi 		phy_stop(priv->phydev);
2154102463b1SFrancesco Virlinzi 
2155f8c5a875SGiuseppe CAVALLARO 	spin_lock_irqsave(&priv->lock, flags);
21567ac6653aSJeff Kirsher 
21577ac6653aSJeff Kirsher 	netif_device_detach(ndev);
21587ac6653aSJeff Kirsher 	netif_stop_queue(ndev);
21597ac6653aSJeff Kirsher 
21607ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
21617ac6653aSJeff Kirsher 	priv->tm->timer_stop();
21627ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
21637ac6653aSJeff Kirsher 		dis_ic = 1;
21647ac6653aSJeff Kirsher #endif
21657ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
21667ac6653aSJeff Kirsher 
21677ac6653aSJeff Kirsher 	/* Stop TX/RX DMA */
21687ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
21697ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
21707ac6653aSJeff Kirsher 	/* Clear the Rx/Tx descriptors */
21717ac6653aSJeff Kirsher 	priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
21727ac6653aSJeff Kirsher 				     dis_ic);
21737ac6653aSJeff Kirsher 	priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
21747ac6653aSJeff Kirsher 
21757ac6653aSJeff Kirsher 	/* Enable Power down mode by programming the PMT regs */
21767ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
21777ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
2178ba1377ffSGiuseppe CAVALLARO 	else {
2179bfab27a1SGiuseppe CAVALLARO 		stmmac_set_mac(priv->ioaddr, false);
2180ba1377ffSGiuseppe CAVALLARO 		/* Disable clock in case of PWM is off */
21816a81c26fSViresh Kumar 		clk_disable(priv->stmmac_clk);
2182ba1377ffSGiuseppe CAVALLARO 	}
2183f8c5a875SGiuseppe CAVALLARO 	spin_unlock_irqrestore(&priv->lock, flags);
21847ac6653aSJeff Kirsher 	return 0;
21857ac6653aSJeff Kirsher }
21867ac6653aSJeff Kirsher 
2187bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev)
21887ac6653aSJeff Kirsher {
21897ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
2190f8c5a875SGiuseppe CAVALLARO 	unsigned long flags;
21917ac6653aSJeff Kirsher 
21927ac6653aSJeff Kirsher 	if (!netif_running(ndev))
21937ac6653aSJeff Kirsher 		return 0;
21947ac6653aSJeff Kirsher 
2195f8c5a875SGiuseppe CAVALLARO 	spin_lock_irqsave(&priv->lock, flags);
21967ac6653aSJeff Kirsher 
21977ac6653aSJeff Kirsher 	/* Power Down bit, into the PM register, is cleared
21987ac6653aSJeff Kirsher 	 * automatically as soon as a magic packet or a Wake-up frame
21997ac6653aSJeff Kirsher 	 * is received. Anyway, it's better to manually clear
22007ac6653aSJeff Kirsher 	 * this bit because it can generate problems while resuming
22017ac6653aSJeff Kirsher 	 * from another devices (e.g. serial console). */
22027ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
22037ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, 0);
2204ba1377ffSGiuseppe CAVALLARO 	else
2205ba1377ffSGiuseppe CAVALLARO 		/* enable the clk prevously disabled */
22066a81c26fSViresh Kumar 		clk_enable(priv->stmmac_clk);
22077ac6653aSJeff Kirsher 
22087ac6653aSJeff Kirsher 	netif_device_attach(ndev);
22097ac6653aSJeff Kirsher 
22107ac6653aSJeff Kirsher 	/* Enable the MAC and DMA */
2211bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, true);
22127ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
22137ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
22147ac6653aSJeff Kirsher 
22157ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
22167ac6653aSJeff Kirsher 	if (likely(priv->tm->enable))
22177ac6653aSJeff Kirsher 		priv->tm->timer_start(tmrate);
22187ac6653aSJeff Kirsher #endif
22197ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
22207ac6653aSJeff Kirsher 
22217ac6653aSJeff Kirsher 	netif_start_queue(ndev);
22227ac6653aSJeff Kirsher 
2223f8c5a875SGiuseppe CAVALLARO 	spin_unlock_irqrestore(&priv->lock, flags);
2224102463b1SFrancesco Virlinzi 
2225102463b1SFrancesco Virlinzi 	if (priv->phydev)
2226102463b1SFrancesco Virlinzi 		phy_start(priv->phydev);
2227102463b1SFrancesco Virlinzi 
22287ac6653aSJeff Kirsher 	return 0;
22297ac6653aSJeff Kirsher }
22307ac6653aSJeff Kirsher 
2231bfab27a1SGiuseppe CAVALLARO int stmmac_freeze(struct net_device *ndev)
22327ac6653aSJeff Kirsher {
22337ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
22347ac6653aSJeff Kirsher 		return 0;
22357ac6653aSJeff Kirsher 
22367ac6653aSJeff Kirsher 	return stmmac_release(ndev);
22377ac6653aSJeff Kirsher }
22387ac6653aSJeff Kirsher 
2239bfab27a1SGiuseppe CAVALLARO int stmmac_restore(struct net_device *ndev)
22407ac6653aSJeff Kirsher {
22417ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
22427ac6653aSJeff Kirsher 		return 0;
22437ac6653aSJeff Kirsher 
22447ac6653aSJeff Kirsher 	return stmmac_open(ndev);
22457ac6653aSJeff Kirsher }
22467ac6653aSJeff Kirsher #endif /* CONFIG_PM */
22477ac6653aSJeff Kirsher 
224833d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers
224933d5e332SGiuseppe CAVALLARO  * depending on the configuration selected.
225033d5e332SGiuseppe CAVALLARO  */
2251ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void)
2252ba27ec66SGiuseppe CAVALLARO {
225333d5e332SGiuseppe CAVALLARO 	int err_plt = 0;
225433d5e332SGiuseppe CAVALLARO 	int err_pci = 0;
2255ba27ec66SGiuseppe CAVALLARO 
225633d5e332SGiuseppe CAVALLARO 	err_plt = stmmac_register_platform();
225733d5e332SGiuseppe CAVALLARO 	err_pci = stmmac_register_pci();
2258ba27ec66SGiuseppe CAVALLARO 
225933d5e332SGiuseppe CAVALLARO 	if ((err_pci) && (err_plt)) {
226033d5e332SGiuseppe CAVALLARO 		pr_err("stmmac: driver registration failed\n");
226133d5e332SGiuseppe CAVALLARO 		return -EINVAL;
2262ba27ec66SGiuseppe CAVALLARO 	}
2263ba27ec66SGiuseppe CAVALLARO 
226433d5e332SGiuseppe CAVALLARO 	return 0;
2265ba27ec66SGiuseppe CAVALLARO }
2266ba27ec66SGiuseppe CAVALLARO 
2267ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void)
2268ba27ec66SGiuseppe CAVALLARO {
226933d5e332SGiuseppe CAVALLARO 	stmmac_unregister_platform();
227033d5e332SGiuseppe CAVALLARO 	stmmac_unregister_pci();
2271ba27ec66SGiuseppe CAVALLARO }
2272ba27ec66SGiuseppe CAVALLARO 
2273ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init);
2274ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit);
2275ba27ec66SGiuseppe CAVALLARO 
22767ac6653aSJeff Kirsher #ifndef MODULE
22777ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str)
22787ac6653aSJeff Kirsher {
22797ac6653aSJeff Kirsher 	char *opt;
22807ac6653aSJeff Kirsher 
22817ac6653aSJeff Kirsher 	if (!str || !*str)
22827ac6653aSJeff Kirsher 		return -EINVAL;
22837ac6653aSJeff Kirsher 	while ((opt = strsep(&str, ",")) != NULL) {
22847ac6653aSJeff Kirsher 		if (!strncmp(opt, "debug:", 6)) {
2285ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 6, 0, &debug))
22867ac6653aSJeff Kirsher 				goto err;
22877ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "phyaddr:", 8)) {
2288ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 8, 0, &phyaddr))
22897ac6653aSJeff Kirsher 				goto err;
22907ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_txsize:", 11)) {
2291ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &dma_txsize))
22927ac6653aSJeff Kirsher 				goto err;
22937ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_rxsize:", 11)) {
2294ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &dma_rxsize))
22957ac6653aSJeff Kirsher 				goto err;
22967ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "buf_sz:", 7)) {
2297ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 7, 0, &buf_sz))
22987ac6653aSJeff Kirsher 				goto err;
22997ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "tc:", 3)) {
2300ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 3, 0, &tc))
23017ac6653aSJeff Kirsher 				goto err;
23027ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "watchdog:", 9)) {
2303ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 9, 0, &watchdog))
23047ac6653aSJeff Kirsher 				goto err;
23057ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "flow_ctrl:", 10)) {
2306ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 10, 0, &flow_ctrl))
23077ac6653aSJeff Kirsher 				goto err;
23087ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "pause:", 6)) {
2309ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 6, 0, &pause))
23107ac6653aSJeff Kirsher 				goto err;
2311d765955dSGiuseppe CAVALLARO 		} else if (!strncmp(opt, "eee_timer:", 6)) {
2312d765955dSGiuseppe CAVALLARO 			if (kstrtoint(opt + 10, 0, &eee_timer))
2313d765955dSGiuseppe CAVALLARO 				goto err;
23147ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER
23157ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "tmrate:", 7)) {
2316ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 7, 0, &tmrate))
23177ac6653aSJeff Kirsher 				goto err;
23187ac6653aSJeff Kirsher #endif
23197ac6653aSJeff Kirsher 		}
23207ac6653aSJeff Kirsher 	}
23217ac6653aSJeff Kirsher 	return 0;
23227ac6653aSJeff Kirsher 
23237ac6653aSJeff Kirsher err:
23247ac6653aSJeff Kirsher 	pr_err("%s: ERROR broken module parameter conversion", __func__);
23257ac6653aSJeff Kirsher 	return -EINVAL;
23267ac6653aSJeff Kirsher }
23277ac6653aSJeff Kirsher 
23287ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt);
23297ac6653aSJeff Kirsher #endif
23306fc0d0f2SGiuseppe Cavallaro 
23316fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
23326fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
23336fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL");
2334