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>
49ceb69499SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */
50891434b1SRayagond Kokatanur #include <linux/net_tstamp.h>
51891434b1SRayagond Kokatanur #include "stmmac_ptp.h"
52286a8372SGiuseppe CAVALLARO #include "stmmac.h"
537ac6653aSJeff Kirsher 
547ac6653aSJeff Kirsher #define STMMAC_ALIGN(x)	L1_CACHE_ALIGN(x)
557ac6653aSJeff Kirsher #define JUMBO_LEN	9000
567ac6653aSJeff Kirsher 
577ac6653aSJeff Kirsher /* Module parameters */
5832ceabcaSGiuseppe CAVALLARO #define TX_TIMEO	5000
597ac6653aSJeff Kirsher static int watchdog = TX_TIMEO;
607ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR);
6132ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds (default 5s)");
627ac6653aSJeff Kirsher 
6332ceabcaSGiuseppe CAVALLARO static int debug = -1;
647ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR);
6532ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)");
667ac6653aSJeff Kirsher 
67bfab27a1SGiuseppe CAVALLARO int phyaddr = -1;
687ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO);
697ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address");
707ac6653aSJeff Kirsher 
717ac6653aSJeff Kirsher #define DMA_TX_SIZE 256
727ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE;
737ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
747ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
757ac6653aSJeff Kirsher 
767ac6653aSJeff Kirsher #define DMA_RX_SIZE 256
777ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE;
787ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
797ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
807ac6653aSJeff Kirsher 
817ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF;
827ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
837ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
847ac6653aSJeff Kirsher 
857ac6653aSJeff Kirsher static int pause = PAUSE_TIME;
867ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR);
877ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time");
887ac6653aSJeff Kirsher 
897ac6653aSJeff Kirsher #define TC_DEFAULT 64
907ac6653aSJeff Kirsher static int tc = TC_DEFAULT;
917ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR);
927ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value");
937ac6653aSJeff Kirsher 
947ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE	BUF_SIZE_2KiB
957ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE;
967ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR);
977ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size");
987ac6653aSJeff Kirsher 
997ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
1007ac6653aSJeff Kirsher 				      NETIF_MSG_LINK | NETIF_MSG_IFUP |
1017ac6653aSJeff Kirsher 				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
1027ac6653aSJeff Kirsher 
103d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER	1000
104d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER;
105d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR);
106d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec");
107f5351ef7SGiuseppe CAVALLARO #define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x))
108d765955dSGiuseppe CAVALLARO 
1094a7d666aSGiuseppe CAVALLARO /* By default the driver will use the ring mode to manage tx and rx descriptors
1104a7d666aSGiuseppe CAVALLARO  * but passing this value so user can force to use the chain instead of the ring
1114a7d666aSGiuseppe CAVALLARO  */
1124a7d666aSGiuseppe CAVALLARO static unsigned int chain_mode;
1134a7d666aSGiuseppe CAVALLARO module_param(chain_mode, int, S_IRUGO);
1144a7d666aSGiuseppe CAVALLARO MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode");
1154a7d666aSGiuseppe CAVALLARO 
1167ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
1177ac6653aSJeff Kirsher 
118bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
119bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev);
120bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void);
121bfab27a1SGiuseppe CAVALLARO #endif
122bfab27a1SGiuseppe CAVALLARO 
1239125cdd1SGiuseppe CAVALLARO #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
1249125cdd1SGiuseppe CAVALLARO 
1257ac6653aSJeff Kirsher /**
1267ac6653aSJeff Kirsher  * stmmac_verify_args - verify the driver parameters.
1277ac6653aSJeff Kirsher  * Description: it verifies if some wrong parameter is passed to the driver.
1287ac6653aSJeff Kirsher  * Note that wrong parameters are replaced with the default values.
1297ac6653aSJeff Kirsher  */
1307ac6653aSJeff Kirsher static void stmmac_verify_args(void)
1317ac6653aSJeff Kirsher {
1327ac6653aSJeff Kirsher 	if (unlikely(watchdog < 0))
1337ac6653aSJeff Kirsher 		watchdog = TX_TIMEO;
1347ac6653aSJeff Kirsher 	if (unlikely(dma_rxsize < 0))
1357ac6653aSJeff Kirsher 		dma_rxsize = DMA_RX_SIZE;
1367ac6653aSJeff Kirsher 	if (unlikely(dma_txsize < 0))
1377ac6653aSJeff Kirsher 		dma_txsize = DMA_TX_SIZE;
1387ac6653aSJeff Kirsher 	if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
1397ac6653aSJeff Kirsher 		buf_sz = DMA_BUFFER_SIZE;
1407ac6653aSJeff Kirsher 	if (unlikely(flow_ctrl > 1))
1417ac6653aSJeff Kirsher 		flow_ctrl = FLOW_AUTO;
1427ac6653aSJeff Kirsher 	else if (likely(flow_ctrl < 0))
1437ac6653aSJeff Kirsher 		flow_ctrl = FLOW_OFF;
1447ac6653aSJeff Kirsher 	if (unlikely((pause < 0) || (pause > 0xffff)))
1457ac6653aSJeff Kirsher 		pause = PAUSE_TIME;
146d765955dSGiuseppe CAVALLARO 	if (eee_timer < 0)
147d765955dSGiuseppe CAVALLARO 		eee_timer = STMMAC_DEFAULT_LPI_TIMER;
1487ac6653aSJeff Kirsher }
1497ac6653aSJeff Kirsher 
15032ceabcaSGiuseppe CAVALLARO /**
15132ceabcaSGiuseppe CAVALLARO  * stmmac_clk_csr_set - dynamically set the MDC clock
15232ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
15332ceabcaSGiuseppe CAVALLARO  * Description: this is to dynamically set the MDC clock according to the csr
15432ceabcaSGiuseppe CAVALLARO  * clock input.
15532ceabcaSGiuseppe CAVALLARO  * Note:
15632ceabcaSGiuseppe CAVALLARO  *	If a specific clk_csr value is passed from the platform
15732ceabcaSGiuseppe CAVALLARO  *	this means that the CSR Clock Range selection cannot be
15832ceabcaSGiuseppe CAVALLARO  *	changed at run-time and it is fixed (as reported in the driver
15932ceabcaSGiuseppe CAVALLARO  *	documentation). Viceversa the driver will try to set the MDC
16032ceabcaSGiuseppe CAVALLARO  *	clock dynamically according to the actual clock input.
16132ceabcaSGiuseppe CAVALLARO  */
162cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv)
163cd7201f4SGiuseppe CAVALLARO {
164cd7201f4SGiuseppe CAVALLARO 	u32 clk_rate;
165cd7201f4SGiuseppe CAVALLARO 
166cd7201f4SGiuseppe CAVALLARO 	clk_rate = clk_get_rate(priv->stmmac_clk);
167cd7201f4SGiuseppe CAVALLARO 
168cd7201f4SGiuseppe CAVALLARO 	/* Platform provided default clk_csr would be assumed valid
169ceb69499SGiuseppe CAVALLARO 	 * for all other cases except for the below mentioned ones.
170ceb69499SGiuseppe CAVALLARO 	 * For values higher than the IEEE 802.3 specified frequency
171ceb69499SGiuseppe CAVALLARO 	 * we can not estimate the proper divider as it is not known
172ceb69499SGiuseppe CAVALLARO 	 * the frequency of clk_csr_i. So we do not change the default
173ceb69499SGiuseppe CAVALLARO 	 * divider.
174ceb69499SGiuseppe CAVALLARO 	 */
175cd7201f4SGiuseppe CAVALLARO 	if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
176cd7201f4SGiuseppe CAVALLARO 		if (clk_rate < CSR_F_35M)
177cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_20_35M;
178cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
179cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_35_60M;
180cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
181cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_60_100M;
182cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
183cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_100_150M;
184cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
185cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_150_250M;
186cd7201f4SGiuseppe CAVALLARO 		else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
187cd7201f4SGiuseppe CAVALLARO 			priv->clk_csr = STMMAC_CSR_250_300M;
188ceb69499SGiuseppe CAVALLARO 	}
189cd7201f4SGiuseppe CAVALLARO }
190cd7201f4SGiuseppe CAVALLARO 
1917ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len)
1927ac6653aSJeff Kirsher {
1937ac6653aSJeff Kirsher 	int j;
19483d7af64SGiuseppe CAVALLARO 	pr_debug("len = %d byte, buf addr: 0x%p", len, buf);
1957ac6653aSJeff Kirsher 	for (j = 0; j < len; j++) {
1967ac6653aSJeff Kirsher 		if ((j % 16) == 0)
19783d7af64SGiuseppe CAVALLARO 			pr_debug("\n %03x:", j);
19883d7af64SGiuseppe CAVALLARO 		pr_debug(" %02x", buf[j]);
1997ac6653aSJeff Kirsher 	}
20083d7af64SGiuseppe CAVALLARO 	pr_debug("\n");
2017ac6653aSJeff Kirsher }
2027ac6653aSJeff Kirsher 
2037ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */
2047ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x)	(x->dma_tx_size/4)
2057ac6653aSJeff Kirsher 
2067ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
2077ac6653aSJeff Kirsher {
2087ac6653aSJeff Kirsher 	return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
2097ac6653aSJeff Kirsher }
2107ac6653aSJeff Kirsher 
21132ceabcaSGiuseppe CAVALLARO /**
21232ceabcaSGiuseppe CAVALLARO  * stmmac_hw_fix_mac_speed: callback for speed selection
21332ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
21432ceabcaSGiuseppe CAVALLARO  * Description: on some platforms (e.g. ST), some HW system configuraton
21532ceabcaSGiuseppe CAVALLARO  * registers have to be set according to the link speed negotiated.
2167ac6653aSJeff Kirsher  */
2177ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
2187ac6653aSJeff Kirsher {
2197ac6653aSJeff Kirsher 	struct phy_device *phydev = priv->phydev;
2207ac6653aSJeff Kirsher 
2217ac6653aSJeff Kirsher 	if (likely(priv->plat->fix_mac_speed))
222ceb69499SGiuseppe CAVALLARO 		priv->plat->fix_mac_speed(priv->plat->bsp_priv, phydev->speed);
2237ac6653aSJeff Kirsher }
2247ac6653aSJeff Kirsher 
22532ceabcaSGiuseppe CAVALLARO /**
22632ceabcaSGiuseppe CAVALLARO  * stmmac_enable_eee_mode: Check and enter in LPI mode
22732ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
22832ceabcaSGiuseppe CAVALLARO  * Description: this function is to verify and enter in LPI mode for EEE.
22932ceabcaSGiuseppe CAVALLARO  */
230d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
231d765955dSGiuseppe CAVALLARO {
232d765955dSGiuseppe CAVALLARO 	/* Check and enter in LPI mode */
233d765955dSGiuseppe CAVALLARO 	if ((priv->dirty_tx == priv->cur_tx) &&
234d765955dSGiuseppe CAVALLARO 	    (priv->tx_path_in_lpi_mode == false))
235d765955dSGiuseppe CAVALLARO 		priv->hw->mac->set_eee_mode(priv->ioaddr);
236d765955dSGiuseppe CAVALLARO }
237d765955dSGiuseppe CAVALLARO 
23832ceabcaSGiuseppe CAVALLARO /**
23932ceabcaSGiuseppe CAVALLARO  * stmmac_disable_eee_mode: disable/exit from EEE
24032ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
24132ceabcaSGiuseppe CAVALLARO  * Description: this function is to exit and disable EEE in case of
24232ceabcaSGiuseppe CAVALLARO  * LPI state is true. This is called by the xmit.
24332ceabcaSGiuseppe CAVALLARO  */
244d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv)
245d765955dSGiuseppe CAVALLARO {
246d765955dSGiuseppe CAVALLARO 	priv->hw->mac->reset_eee_mode(priv->ioaddr);
247d765955dSGiuseppe CAVALLARO 	del_timer_sync(&priv->eee_ctrl_timer);
248d765955dSGiuseppe CAVALLARO 	priv->tx_path_in_lpi_mode = false;
249d765955dSGiuseppe CAVALLARO }
250d765955dSGiuseppe CAVALLARO 
251d765955dSGiuseppe CAVALLARO /**
25232ceabcaSGiuseppe CAVALLARO  * stmmac_eee_ctrl_timer: EEE TX SW timer.
253d765955dSGiuseppe CAVALLARO  * @arg : data hook
254d765955dSGiuseppe CAVALLARO  * Description:
25532ceabcaSGiuseppe CAVALLARO  *  if there is no data transfer and if we are not in LPI state,
256d765955dSGiuseppe CAVALLARO  *  then MAC Transmitter can be moved to LPI state.
257d765955dSGiuseppe CAVALLARO  */
258d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg)
259d765955dSGiuseppe CAVALLARO {
260d765955dSGiuseppe CAVALLARO 	struct stmmac_priv *priv = (struct stmmac_priv *)arg;
261d765955dSGiuseppe CAVALLARO 
262d765955dSGiuseppe CAVALLARO 	stmmac_enable_eee_mode(priv);
263f5351ef7SGiuseppe CAVALLARO 	mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
264d765955dSGiuseppe CAVALLARO }
265d765955dSGiuseppe CAVALLARO 
266d765955dSGiuseppe CAVALLARO /**
26732ceabcaSGiuseppe CAVALLARO  * stmmac_eee_init: init EEE
26832ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
269d765955dSGiuseppe CAVALLARO  * Description:
270d765955dSGiuseppe CAVALLARO  *  If the EEE support has been enabled while configuring the driver,
271d765955dSGiuseppe CAVALLARO  *  if the GMAC actually supports the EEE (from the HW cap reg) and the
272d765955dSGiuseppe CAVALLARO  *  phy can also manage EEE, so enable the LPI state and start the timer
273d765955dSGiuseppe CAVALLARO  *  to verify if the tx path can enter in LPI state.
274d765955dSGiuseppe CAVALLARO  */
275d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv)
276d765955dSGiuseppe CAVALLARO {
277d765955dSGiuseppe CAVALLARO 	bool ret = false;
278d765955dSGiuseppe CAVALLARO 
279f5351ef7SGiuseppe CAVALLARO 	/* Using PCS we cannot dial with the phy registers at this stage
280f5351ef7SGiuseppe CAVALLARO 	 * so we do not support extra feature like EEE.
281f5351ef7SGiuseppe CAVALLARO 	 */
282f5351ef7SGiuseppe CAVALLARO 	if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) ||
283f5351ef7SGiuseppe CAVALLARO 	    (priv->pcs == STMMAC_PCS_RTBI))
284f5351ef7SGiuseppe CAVALLARO 		goto out;
285f5351ef7SGiuseppe CAVALLARO 
286d765955dSGiuseppe CAVALLARO 	/* MAC core supports the EEE feature. */
287d765955dSGiuseppe CAVALLARO 	if (priv->dma_cap.eee) {
288d765955dSGiuseppe CAVALLARO 		/* Check if the PHY supports EEE */
289d765955dSGiuseppe CAVALLARO 		if (phy_init_eee(priv->phydev, 1))
290d765955dSGiuseppe CAVALLARO 			goto out;
291d765955dSGiuseppe CAVALLARO 
292f5351ef7SGiuseppe CAVALLARO 		if (!priv->eee_active) {
293d765955dSGiuseppe CAVALLARO 			priv->eee_active = 1;
294d765955dSGiuseppe CAVALLARO 			init_timer(&priv->eee_ctrl_timer);
295d765955dSGiuseppe CAVALLARO 			priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer;
296d765955dSGiuseppe CAVALLARO 			priv->eee_ctrl_timer.data = (unsigned long)priv;
297f5351ef7SGiuseppe CAVALLARO 			priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer);
298d765955dSGiuseppe CAVALLARO 			add_timer(&priv->eee_ctrl_timer);
299d765955dSGiuseppe CAVALLARO 
300d765955dSGiuseppe CAVALLARO 			priv->hw->mac->set_eee_timer(priv->ioaddr,
301f5351ef7SGiuseppe CAVALLARO 						     STMMAC_DEFAULT_LIT_LS,
302d765955dSGiuseppe CAVALLARO 						     priv->tx_lpi_timer);
303f5351ef7SGiuseppe CAVALLARO 		} else
304f5351ef7SGiuseppe CAVALLARO 			/* Set HW EEE according to the speed */
305f5351ef7SGiuseppe CAVALLARO 			priv->hw->mac->set_eee_pls(priv->ioaddr,
306f5351ef7SGiuseppe CAVALLARO 						   priv->phydev->link);
307d765955dSGiuseppe CAVALLARO 
308d765955dSGiuseppe CAVALLARO 		pr_info("stmmac: Energy-Efficient Ethernet initialized\n");
309d765955dSGiuseppe CAVALLARO 
310d765955dSGiuseppe CAVALLARO 		ret = true;
311d765955dSGiuseppe CAVALLARO 	}
312d765955dSGiuseppe CAVALLARO out:
313d765955dSGiuseppe CAVALLARO 	return ret;
314d765955dSGiuseppe CAVALLARO }
315d765955dSGiuseppe CAVALLARO 
31632ceabcaSGiuseppe CAVALLARO /* stmmac_get_tx_hwtstamp: get HW TX timestamps
31732ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
318891434b1SRayagond Kokatanur  * @entry : descriptor index to be used.
319891434b1SRayagond Kokatanur  * @skb : the socket buffer
320891434b1SRayagond Kokatanur  * Description :
321891434b1SRayagond Kokatanur  * This function will read timestamp from the descriptor & pass it to stack.
322891434b1SRayagond Kokatanur  * and also perform some sanity checks.
323891434b1SRayagond Kokatanur  */
324891434b1SRayagond Kokatanur static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
325ceb69499SGiuseppe CAVALLARO 				   unsigned int entry, struct sk_buff *skb)
326891434b1SRayagond Kokatanur {
327891434b1SRayagond Kokatanur 	struct skb_shared_hwtstamps shhwtstamp;
328891434b1SRayagond Kokatanur 	u64 ns;
329891434b1SRayagond Kokatanur 	void *desc = NULL;
330891434b1SRayagond Kokatanur 
331891434b1SRayagond Kokatanur 	if (!priv->hwts_tx_en)
332891434b1SRayagond Kokatanur 		return;
333891434b1SRayagond Kokatanur 
334ceb69499SGiuseppe CAVALLARO 	/* exit if skb doesn't support hw tstamp */
335891434b1SRayagond Kokatanur 	if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)))
336891434b1SRayagond Kokatanur 		return;
337891434b1SRayagond Kokatanur 
338891434b1SRayagond Kokatanur 	if (priv->adv_ts)
339891434b1SRayagond Kokatanur 		desc = (priv->dma_etx + entry);
340891434b1SRayagond Kokatanur 	else
341891434b1SRayagond Kokatanur 		desc = (priv->dma_tx + entry);
342891434b1SRayagond Kokatanur 
343891434b1SRayagond Kokatanur 	/* check tx tstamp status */
344891434b1SRayagond Kokatanur 	if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc))
345891434b1SRayagond Kokatanur 		return;
346891434b1SRayagond Kokatanur 
347891434b1SRayagond Kokatanur 	/* get the valid tstamp */
348891434b1SRayagond Kokatanur 	ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
349891434b1SRayagond Kokatanur 
350891434b1SRayagond Kokatanur 	memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
351891434b1SRayagond Kokatanur 	shhwtstamp.hwtstamp = ns_to_ktime(ns);
352891434b1SRayagond Kokatanur 	/* pass tstamp to stack */
353891434b1SRayagond Kokatanur 	skb_tstamp_tx(skb, &shhwtstamp);
354891434b1SRayagond Kokatanur 
355891434b1SRayagond Kokatanur 	return;
356891434b1SRayagond Kokatanur }
357891434b1SRayagond Kokatanur 
35832ceabcaSGiuseppe CAVALLARO /* stmmac_get_rx_hwtstamp: get HW RX timestamps
35932ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
360891434b1SRayagond Kokatanur  * @entry : descriptor index to be used.
361891434b1SRayagond Kokatanur  * @skb : the socket buffer
362891434b1SRayagond Kokatanur  * Description :
363891434b1SRayagond Kokatanur  * This function will read received packet's timestamp from the descriptor
364891434b1SRayagond Kokatanur  * and pass it to stack. It also perform some sanity checks.
365891434b1SRayagond Kokatanur  */
366891434b1SRayagond Kokatanur static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv,
367ceb69499SGiuseppe CAVALLARO 				   unsigned int entry, struct sk_buff *skb)
368891434b1SRayagond Kokatanur {
369891434b1SRayagond Kokatanur 	struct skb_shared_hwtstamps *shhwtstamp = NULL;
370891434b1SRayagond Kokatanur 	u64 ns;
371891434b1SRayagond Kokatanur 	void *desc = NULL;
372891434b1SRayagond Kokatanur 
373891434b1SRayagond Kokatanur 	if (!priv->hwts_rx_en)
374891434b1SRayagond Kokatanur 		return;
375891434b1SRayagond Kokatanur 
376891434b1SRayagond Kokatanur 	if (priv->adv_ts)
377891434b1SRayagond Kokatanur 		desc = (priv->dma_erx + entry);
378891434b1SRayagond Kokatanur 	else
379891434b1SRayagond Kokatanur 		desc = (priv->dma_rx + entry);
380891434b1SRayagond Kokatanur 
381ceb69499SGiuseppe CAVALLARO 	/* exit if rx tstamp is not valid */
382891434b1SRayagond Kokatanur 	if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts))
383891434b1SRayagond Kokatanur 		return;
384891434b1SRayagond Kokatanur 
385891434b1SRayagond Kokatanur 	/* get valid tstamp */
386891434b1SRayagond Kokatanur 	ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
387891434b1SRayagond Kokatanur 	shhwtstamp = skb_hwtstamps(skb);
388891434b1SRayagond Kokatanur 	memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
389891434b1SRayagond Kokatanur 	shhwtstamp->hwtstamp = ns_to_ktime(ns);
390891434b1SRayagond Kokatanur }
391891434b1SRayagond Kokatanur 
392891434b1SRayagond Kokatanur /**
393891434b1SRayagond Kokatanur  *  stmmac_hwtstamp_ioctl - control hardware timestamping.
394891434b1SRayagond Kokatanur  *  @dev: device pointer.
395891434b1SRayagond Kokatanur  *  @ifr: An IOCTL specefic structure, that can contain a pointer to
396891434b1SRayagond Kokatanur  *  a proprietary structure used to pass information to the driver.
397891434b1SRayagond Kokatanur  *  Description:
398891434b1SRayagond Kokatanur  *  This function configures the MAC to enable/disable both outgoing(TX)
399891434b1SRayagond Kokatanur  *  and incoming(RX) packets time stamping based on user input.
400891434b1SRayagond Kokatanur  *  Return Value:
401891434b1SRayagond Kokatanur  *  0 on success and an appropriate -ve integer on failure.
402891434b1SRayagond Kokatanur  */
403891434b1SRayagond Kokatanur static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
404891434b1SRayagond Kokatanur {
405891434b1SRayagond Kokatanur 	struct stmmac_priv *priv = netdev_priv(dev);
406891434b1SRayagond Kokatanur 	struct hwtstamp_config config;
407891434b1SRayagond Kokatanur 	struct timespec now;
408891434b1SRayagond Kokatanur 	u64 temp = 0;
409891434b1SRayagond Kokatanur 	u32 ptp_v2 = 0;
410891434b1SRayagond Kokatanur 	u32 tstamp_all = 0;
411891434b1SRayagond Kokatanur 	u32 ptp_over_ipv4_udp = 0;
412891434b1SRayagond Kokatanur 	u32 ptp_over_ipv6_udp = 0;
413891434b1SRayagond Kokatanur 	u32 ptp_over_ethernet = 0;
414891434b1SRayagond Kokatanur 	u32 snap_type_sel = 0;
415891434b1SRayagond Kokatanur 	u32 ts_master_en = 0;
416891434b1SRayagond Kokatanur 	u32 ts_event_en = 0;
417891434b1SRayagond Kokatanur 	u32 value = 0;
418891434b1SRayagond Kokatanur 
419891434b1SRayagond Kokatanur 	if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
420891434b1SRayagond Kokatanur 		netdev_alert(priv->dev, "No support for HW time stamping\n");
421891434b1SRayagond Kokatanur 		priv->hwts_tx_en = 0;
422891434b1SRayagond Kokatanur 		priv->hwts_rx_en = 0;
423891434b1SRayagond Kokatanur 
424891434b1SRayagond Kokatanur 		return -EOPNOTSUPP;
425891434b1SRayagond Kokatanur 	}
426891434b1SRayagond Kokatanur 
427891434b1SRayagond Kokatanur 	if (copy_from_user(&config, ifr->ifr_data,
428891434b1SRayagond Kokatanur 			   sizeof(struct hwtstamp_config)))
429891434b1SRayagond Kokatanur 		return -EFAULT;
430891434b1SRayagond Kokatanur 
431891434b1SRayagond Kokatanur 	pr_debug("%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
432891434b1SRayagond Kokatanur 		 __func__, config.flags, config.tx_type, config.rx_filter);
433891434b1SRayagond Kokatanur 
434891434b1SRayagond Kokatanur 	/* reserved for future extensions */
435891434b1SRayagond Kokatanur 	if (config.flags)
436891434b1SRayagond Kokatanur 		return -EINVAL;
437891434b1SRayagond Kokatanur 
4385f3da328SBen Hutchings 	if (config.tx_type != HWTSTAMP_TX_OFF &&
4395f3da328SBen Hutchings 	    config.tx_type != HWTSTAMP_TX_ON)
440891434b1SRayagond Kokatanur 		return -ERANGE;
441891434b1SRayagond Kokatanur 
442891434b1SRayagond Kokatanur 	if (priv->adv_ts) {
443891434b1SRayagond Kokatanur 		switch (config.rx_filter) {
444891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_NONE:
445ceb69499SGiuseppe CAVALLARO 			/* time stamp no incoming packet at all */
446891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_NONE;
447891434b1SRayagond Kokatanur 			break;
448891434b1SRayagond Kokatanur 
449891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
450ceb69499SGiuseppe CAVALLARO 			/* PTP v1, UDP, any kind of event packet */
451891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
452891434b1SRayagond Kokatanur 			/* take time stamp for all event messages */
453891434b1SRayagond Kokatanur 			snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
454891434b1SRayagond Kokatanur 
455891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
456891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
457891434b1SRayagond Kokatanur 			break;
458891434b1SRayagond Kokatanur 
459891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
460ceb69499SGiuseppe CAVALLARO 			/* PTP v1, UDP, Sync packet */
461891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
462891434b1SRayagond Kokatanur 			/* take time stamp for SYNC messages only */
463891434b1SRayagond Kokatanur 			ts_event_en = PTP_TCR_TSEVNTENA;
464891434b1SRayagond Kokatanur 
465891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
466891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
467891434b1SRayagond Kokatanur 			break;
468891434b1SRayagond Kokatanur 
469891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
470ceb69499SGiuseppe CAVALLARO 			/* PTP v1, UDP, Delay_req packet */
471891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ;
472891434b1SRayagond Kokatanur 			/* take time stamp for Delay_Req messages only */
473891434b1SRayagond Kokatanur 			ts_master_en = PTP_TCR_TSMSTRENA;
474891434b1SRayagond Kokatanur 			ts_event_en = PTP_TCR_TSEVNTENA;
475891434b1SRayagond Kokatanur 
476891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
477891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
478891434b1SRayagond Kokatanur 			break;
479891434b1SRayagond Kokatanur 
480891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
481ceb69499SGiuseppe CAVALLARO 			/* PTP v2, UDP, any kind of event packet */
482891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
483891434b1SRayagond Kokatanur 			ptp_v2 = PTP_TCR_TSVER2ENA;
484891434b1SRayagond Kokatanur 			/* take time stamp for all event messages */
485891434b1SRayagond Kokatanur 			snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
486891434b1SRayagond Kokatanur 
487891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
488891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
489891434b1SRayagond Kokatanur 			break;
490891434b1SRayagond Kokatanur 
491891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
492ceb69499SGiuseppe CAVALLARO 			/* PTP v2, UDP, Sync packet */
493891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC;
494891434b1SRayagond Kokatanur 			ptp_v2 = PTP_TCR_TSVER2ENA;
495891434b1SRayagond Kokatanur 			/* take time stamp for SYNC messages only */
496891434b1SRayagond Kokatanur 			ts_event_en = PTP_TCR_TSEVNTENA;
497891434b1SRayagond Kokatanur 
498891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
499891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
500891434b1SRayagond Kokatanur 			break;
501891434b1SRayagond Kokatanur 
502891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
503ceb69499SGiuseppe CAVALLARO 			/* PTP v2, UDP, Delay_req packet */
504891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ;
505891434b1SRayagond Kokatanur 			ptp_v2 = PTP_TCR_TSVER2ENA;
506891434b1SRayagond Kokatanur 			/* take time stamp for Delay_Req messages only */
507891434b1SRayagond Kokatanur 			ts_master_en = PTP_TCR_TSMSTRENA;
508891434b1SRayagond Kokatanur 			ts_event_en = PTP_TCR_TSEVNTENA;
509891434b1SRayagond Kokatanur 
510891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
511891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
512891434b1SRayagond Kokatanur 			break;
513891434b1SRayagond Kokatanur 
514891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V2_EVENT:
515ceb69499SGiuseppe CAVALLARO 			/* PTP v2/802.AS1 any layer, any kind of event packet */
516891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
517891434b1SRayagond Kokatanur 			ptp_v2 = PTP_TCR_TSVER2ENA;
518891434b1SRayagond Kokatanur 			/* take time stamp for all event messages */
519891434b1SRayagond Kokatanur 			snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
520891434b1SRayagond Kokatanur 
521891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
522891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
523891434b1SRayagond Kokatanur 			ptp_over_ethernet = PTP_TCR_TSIPENA;
524891434b1SRayagond Kokatanur 			break;
525891434b1SRayagond Kokatanur 
526891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V2_SYNC:
527ceb69499SGiuseppe CAVALLARO 			/* PTP v2/802.AS1, any layer, Sync packet */
528891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC;
529891434b1SRayagond Kokatanur 			ptp_v2 = PTP_TCR_TSVER2ENA;
530891434b1SRayagond Kokatanur 			/* take time stamp for SYNC messages only */
531891434b1SRayagond Kokatanur 			ts_event_en = PTP_TCR_TSEVNTENA;
532891434b1SRayagond Kokatanur 
533891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
534891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
535891434b1SRayagond Kokatanur 			ptp_over_ethernet = PTP_TCR_TSIPENA;
536891434b1SRayagond Kokatanur 			break;
537891434b1SRayagond Kokatanur 
538891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
539ceb69499SGiuseppe CAVALLARO 			/* PTP v2/802.AS1, any layer, Delay_req packet */
540891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ;
541891434b1SRayagond Kokatanur 			ptp_v2 = PTP_TCR_TSVER2ENA;
542891434b1SRayagond Kokatanur 			/* take time stamp for Delay_Req messages only */
543891434b1SRayagond Kokatanur 			ts_master_en = PTP_TCR_TSMSTRENA;
544891434b1SRayagond Kokatanur 			ts_event_en = PTP_TCR_TSEVNTENA;
545891434b1SRayagond Kokatanur 
546891434b1SRayagond Kokatanur 			ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA;
547891434b1SRayagond Kokatanur 			ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA;
548891434b1SRayagond Kokatanur 			ptp_over_ethernet = PTP_TCR_TSIPENA;
549891434b1SRayagond Kokatanur 			break;
550891434b1SRayagond Kokatanur 
551891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_ALL:
552ceb69499SGiuseppe CAVALLARO 			/* time stamp any incoming packet */
553891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_ALL;
554891434b1SRayagond Kokatanur 			tstamp_all = PTP_TCR_TSENALL;
555891434b1SRayagond Kokatanur 			break;
556891434b1SRayagond Kokatanur 
557891434b1SRayagond Kokatanur 		default:
558891434b1SRayagond Kokatanur 			return -ERANGE;
559891434b1SRayagond Kokatanur 		}
560891434b1SRayagond Kokatanur 	} else {
561891434b1SRayagond Kokatanur 		switch (config.rx_filter) {
562891434b1SRayagond Kokatanur 		case HWTSTAMP_FILTER_NONE:
563891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_NONE;
564891434b1SRayagond Kokatanur 			break;
565891434b1SRayagond Kokatanur 		default:
566891434b1SRayagond Kokatanur 			/* PTP v1, UDP, any kind of event packet */
567891434b1SRayagond Kokatanur 			config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
568891434b1SRayagond Kokatanur 			break;
569891434b1SRayagond Kokatanur 		}
570891434b1SRayagond Kokatanur 	}
571891434b1SRayagond Kokatanur 	priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1);
5725f3da328SBen Hutchings 	priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
573891434b1SRayagond Kokatanur 
574891434b1SRayagond Kokatanur 	if (!priv->hwts_tx_en && !priv->hwts_rx_en)
575891434b1SRayagond Kokatanur 		priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
576891434b1SRayagond Kokatanur 	else {
577891434b1SRayagond Kokatanur 		value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR |
578891434b1SRayagond Kokatanur 			 tstamp_all | ptp_v2 | ptp_over_ethernet |
579891434b1SRayagond Kokatanur 			 ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
580891434b1SRayagond Kokatanur 			 ts_master_en | snap_type_sel);
581891434b1SRayagond Kokatanur 
582891434b1SRayagond Kokatanur 		priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value);
583891434b1SRayagond Kokatanur 
584891434b1SRayagond Kokatanur 		/* program Sub Second Increment reg */
585891434b1SRayagond Kokatanur 		priv->hw->ptp->config_sub_second_increment(priv->ioaddr);
586891434b1SRayagond Kokatanur 
587891434b1SRayagond Kokatanur 		/* calculate default added value:
588891434b1SRayagond Kokatanur 		 * formula is :
589891434b1SRayagond Kokatanur 		 * addend = (2^32)/freq_div_ratio;
590891434b1SRayagond Kokatanur 		 * where, freq_div_ratio = STMMAC_SYSCLOCK/50MHz
591891434b1SRayagond Kokatanur 		 * hence, addend = ((2^32) * 50MHz)/STMMAC_SYSCLOCK;
592891434b1SRayagond Kokatanur 		 * NOTE: STMMAC_SYSCLOCK should be >= 50MHz to
593891434b1SRayagond Kokatanur 		 *       achive 20ns accuracy.
594891434b1SRayagond Kokatanur 		 *
595891434b1SRayagond Kokatanur 		 * 2^x * y == (y << x), hence
596891434b1SRayagond Kokatanur 		 * 2^32 * 50000000 ==> (50000000 << 32)
597891434b1SRayagond Kokatanur 		 */
598891434b1SRayagond Kokatanur 		temp = (u64) (50000000ULL << 32);
599891434b1SRayagond Kokatanur 		priv->default_addend = div_u64(temp, STMMAC_SYSCLOCK);
600891434b1SRayagond Kokatanur 		priv->hw->ptp->config_addend(priv->ioaddr,
601891434b1SRayagond Kokatanur 					     priv->default_addend);
602891434b1SRayagond Kokatanur 
603891434b1SRayagond Kokatanur 		/* initialize system time */
604891434b1SRayagond Kokatanur 		getnstimeofday(&now);
605891434b1SRayagond Kokatanur 		priv->hw->ptp->init_systime(priv->ioaddr, now.tv_sec,
606891434b1SRayagond Kokatanur 					    now.tv_nsec);
607891434b1SRayagond Kokatanur 	}
608891434b1SRayagond Kokatanur 
609891434b1SRayagond Kokatanur 	return copy_to_user(ifr->ifr_data, &config,
610891434b1SRayagond Kokatanur 			    sizeof(struct hwtstamp_config)) ? -EFAULT : 0;
611891434b1SRayagond Kokatanur }
612891434b1SRayagond Kokatanur 
61332ceabcaSGiuseppe CAVALLARO /**
61432ceabcaSGiuseppe CAVALLARO  * stmmac_init_ptp: init PTP
61532ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
61632ceabcaSGiuseppe CAVALLARO  * Description: this is to verify if the HW supports the PTPv1 or v2.
61732ceabcaSGiuseppe CAVALLARO  * This is done by looking at the HW cap. register.
61832ceabcaSGiuseppe CAVALLARO  * Also it registers the ptp driver.
61932ceabcaSGiuseppe CAVALLARO  */
62092ba6888SRayagond Kokatanur static int stmmac_init_ptp(struct stmmac_priv *priv)
621891434b1SRayagond Kokatanur {
62292ba6888SRayagond Kokatanur 	if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
62392ba6888SRayagond Kokatanur 		return -EOPNOTSUPP;
62492ba6888SRayagond Kokatanur 
62592ba6888SRayagond Kokatanur 	if (netif_msg_hw(priv)) {
626891434b1SRayagond Kokatanur 		if (priv->dma_cap.time_stamp) {
627891434b1SRayagond Kokatanur 			pr_debug("IEEE 1588-2002 Time Stamp supported\n");
628891434b1SRayagond Kokatanur 			priv->adv_ts = 0;
629891434b1SRayagond Kokatanur 		}
630891434b1SRayagond Kokatanur 		if (priv->dma_cap.atime_stamp && priv->extend_desc) {
631ceb69499SGiuseppe CAVALLARO 			pr_debug
632ceb69499SGiuseppe CAVALLARO 			    ("IEEE 1588-2008 Advanced Time Stamp supported\n");
633891434b1SRayagond Kokatanur 			priv->adv_ts = 1;
634891434b1SRayagond Kokatanur 		}
63592ba6888SRayagond Kokatanur 	}
636891434b1SRayagond Kokatanur 
637891434b1SRayagond Kokatanur 	priv->hw->ptp = &stmmac_ptp;
638891434b1SRayagond Kokatanur 	priv->hwts_tx_en = 0;
639891434b1SRayagond Kokatanur 	priv->hwts_rx_en = 0;
64092ba6888SRayagond Kokatanur 
64192ba6888SRayagond Kokatanur 	return stmmac_ptp_register(priv);
64292ba6888SRayagond Kokatanur }
64392ba6888SRayagond Kokatanur 
64492ba6888SRayagond Kokatanur static void stmmac_release_ptp(struct stmmac_priv *priv)
64592ba6888SRayagond Kokatanur {
64692ba6888SRayagond Kokatanur 	stmmac_ptp_unregister(priv);
647891434b1SRayagond Kokatanur }
648891434b1SRayagond Kokatanur 
6497ac6653aSJeff Kirsher /**
6507ac6653aSJeff Kirsher  * stmmac_adjust_link
6517ac6653aSJeff Kirsher  * @dev: net device structure
6527ac6653aSJeff Kirsher  * Description: it adjusts the link parameters.
6537ac6653aSJeff Kirsher  */
6547ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev)
6557ac6653aSJeff Kirsher {
6567ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
6577ac6653aSJeff Kirsher 	struct phy_device *phydev = priv->phydev;
6587ac6653aSJeff Kirsher 	unsigned long flags;
6597ac6653aSJeff Kirsher 	int new_state = 0;
6607ac6653aSJeff Kirsher 	unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
6617ac6653aSJeff Kirsher 
6627ac6653aSJeff Kirsher 	if (phydev == NULL)
6637ac6653aSJeff Kirsher 		return;
6647ac6653aSJeff Kirsher 
6657ac6653aSJeff Kirsher 	spin_lock_irqsave(&priv->lock, flags);
666d765955dSGiuseppe CAVALLARO 
6677ac6653aSJeff Kirsher 	if (phydev->link) {
6687ac6653aSJeff Kirsher 		u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
6697ac6653aSJeff Kirsher 
6707ac6653aSJeff Kirsher 		/* Now we make sure that we can be in full duplex mode.
6717ac6653aSJeff Kirsher 		 * If not, we operate in half-duplex mode. */
6727ac6653aSJeff Kirsher 		if (phydev->duplex != priv->oldduplex) {
6737ac6653aSJeff Kirsher 			new_state = 1;
6747ac6653aSJeff Kirsher 			if (!(phydev->duplex))
6757ac6653aSJeff Kirsher 				ctrl &= ~priv->hw->link.duplex;
6767ac6653aSJeff Kirsher 			else
6777ac6653aSJeff Kirsher 				ctrl |= priv->hw->link.duplex;
6787ac6653aSJeff Kirsher 			priv->oldduplex = phydev->duplex;
6797ac6653aSJeff Kirsher 		}
6807ac6653aSJeff Kirsher 		/* Flow Control operation */
6817ac6653aSJeff Kirsher 		if (phydev->pause)
6827ac6653aSJeff Kirsher 			priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
6837ac6653aSJeff Kirsher 						 fc, pause_time);
6847ac6653aSJeff Kirsher 
6857ac6653aSJeff Kirsher 		if (phydev->speed != priv->speed) {
6867ac6653aSJeff Kirsher 			new_state = 1;
6877ac6653aSJeff Kirsher 			switch (phydev->speed) {
6887ac6653aSJeff Kirsher 			case 1000:
6897ac6653aSJeff Kirsher 				if (likely(priv->plat->has_gmac))
6907ac6653aSJeff Kirsher 					ctrl &= ~priv->hw->link.port;
6917ac6653aSJeff Kirsher 				stmmac_hw_fix_mac_speed(priv);
6927ac6653aSJeff Kirsher 				break;
6937ac6653aSJeff Kirsher 			case 100:
6947ac6653aSJeff Kirsher 			case 10:
6957ac6653aSJeff Kirsher 				if (priv->plat->has_gmac) {
6967ac6653aSJeff Kirsher 					ctrl |= priv->hw->link.port;
6977ac6653aSJeff Kirsher 					if (phydev->speed == SPEED_100) {
6987ac6653aSJeff Kirsher 						ctrl |= priv->hw->link.speed;
6997ac6653aSJeff Kirsher 					} else {
7007ac6653aSJeff Kirsher 						ctrl &= ~(priv->hw->link.speed);
7017ac6653aSJeff Kirsher 					}
7027ac6653aSJeff Kirsher 				} else {
7037ac6653aSJeff Kirsher 					ctrl &= ~priv->hw->link.port;
7047ac6653aSJeff Kirsher 				}
7057ac6653aSJeff Kirsher 				stmmac_hw_fix_mac_speed(priv);
7067ac6653aSJeff Kirsher 				break;
7077ac6653aSJeff Kirsher 			default:
7087ac6653aSJeff Kirsher 				if (netif_msg_link(priv))
709ceb69499SGiuseppe CAVALLARO 					pr_warn("%s: Speed (%d) not 10/100\n",
710ceb69499SGiuseppe CAVALLARO 						dev->name, phydev->speed);
7117ac6653aSJeff Kirsher 				break;
7127ac6653aSJeff Kirsher 			}
7137ac6653aSJeff Kirsher 
7147ac6653aSJeff Kirsher 			priv->speed = phydev->speed;
7157ac6653aSJeff Kirsher 		}
7167ac6653aSJeff Kirsher 
7177ac6653aSJeff Kirsher 		writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
7187ac6653aSJeff Kirsher 
7197ac6653aSJeff Kirsher 		if (!priv->oldlink) {
7207ac6653aSJeff Kirsher 			new_state = 1;
7217ac6653aSJeff Kirsher 			priv->oldlink = 1;
7227ac6653aSJeff Kirsher 		}
7237ac6653aSJeff Kirsher 	} else if (priv->oldlink) {
7247ac6653aSJeff Kirsher 		new_state = 1;
7257ac6653aSJeff Kirsher 		priv->oldlink = 0;
7267ac6653aSJeff Kirsher 		priv->speed = 0;
7277ac6653aSJeff Kirsher 		priv->oldduplex = -1;
7287ac6653aSJeff Kirsher 	}
7297ac6653aSJeff Kirsher 
7307ac6653aSJeff Kirsher 	if (new_state && netif_msg_link(priv))
7317ac6653aSJeff Kirsher 		phy_print_status(phydev);
7327ac6653aSJeff Kirsher 
733f5351ef7SGiuseppe CAVALLARO 	/* At this stage, it could be needed to setup the EEE or adjust some
734f5351ef7SGiuseppe CAVALLARO 	 * MAC related HW registers.
735f5351ef7SGiuseppe CAVALLARO 	 */
736f5351ef7SGiuseppe CAVALLARO 	priv->eee_enabled = stmmac_eee_init(priv);
737d765955dSGiuseppe CAVALLARO 
7387ac6653aSJeff Kirsher 	spin_unlock_irqrestore(&priv->lock, flags);
7397ac6653aSJeff Kirsher }
7407ac6653aSJeff Kirsher 
74132ceabcaSGiuseppe CAVALLARO /**
74232ceabcaSGiuseppe CAVALLARO  * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported
74332ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
74432ceabcaSGiuseppe CAVALLARO  * Description: this is to verify if the HW supports the PCS.
74532ceabcaSGiuseppe CAVALLARO  * Physical Coding Sublayer (PCS) interface that can be used when the MAC is
74632ceabcaSGiuseppe CAVALLARO  * configured for the TBI, RTBI, or SGMII PHY interface.
74732ceabcaSGiuseppe CAVALLARO  */
748e58bb43fSGiuseppe CAVALLARO static void stmmac_check_pcs_mode(struct stmmac_priv *priv)
749e58bb43fSGiuseppe CAVALLARO {
750e58bb43fSGiuseppe CAVALLARO 	int interface = priv->plat->interface;
751e58bb43fSGiuseppe CAVALLARO 
752e58bb43fSGiuseppe CAVALLARO 	if (priv->dma_cap.pcs) {
7530d909dcdSByungho An 		if ((interface == PHY_INTERFACE_MODE_RGMII) ||
7540d909dcdSByungho An 		    (interface == PHY_INTERFACE_MODE_RGMII_ID) ||
7550d909dcdSByungho An 		    (interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
7560d909dcdSByungho An 		    (interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
757e58bb43fSGiuseppe CAVALLARO 			pr_debug("STMMAC: PCS RGMII support enable\n");
758e58bb43fSGiuseppe CAVALLARO 			priv->pcs = STMMAC_PCS_RGMII;
7590d909dcdSByungho An 		} else if (interface == PHY_INTERFACE_MODE_SGMII) {
760e58bb43fSGiuseppe CAVALLARO 			pr_debug("STMMAC: PCS SGMII support enable\n");
761e58bb43fSGiuseppe CAVALLARO 			priv->pcs = STMMAC_PCS_SGMII;
762e58bb43fSGiuseppe CAVALLARO 		}
763e58bb43fSGiuseppe CAVALLARO 	}
764e58bb43fSGiuseppe CAVALLARO }
765e58bb43fSGiuseppe CAVALLARO 
7667ac6653aSJeff Kirsher /**
7677ac6653aSJeff Kirsher  * stmmac_init_phy - PHY initialization
7687ac6653aSJeff Kirsher  * @dev: net device structure
7697ac6653aSJeff Kirsher  * Description: it initializes the driver's PHY state, and attaches the PHY
7707ac6653aSJeff Kirsher  * to the mac driver.
7717ac6653aSJeff Kirsher  *  Return value:
7727ac6653aSJeff Kirsher  *  0 on success
7737ac6653aSJeff Kirsher  */
7747ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev)
7757ac6653aSJeff Kirsher {
7767ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
7777ac6653aSJeff Kirsher 	struct phy_device *phydev;
778d765955dSGiuseppe CAVALLARO 	char phy_id_fmt[MII_BUS_ID_SIZE + 3];
7797ac6653aSJeff Kirsher 	char bus_id[MII_BUS_ID_SIZE];
78079ee1dc3SSrinivas Kandagatla 	int interface = priv->plat->interface;
7817ac6653aSJeff Kirsher 	priv->oldlink = 0;
7827ac6653aSJeff Kirsher 	priv->speed = 0;
7837ac6653aSJeff Kirsher 	priv->oldduplex = -1;
7847ac6653aSJeff Kirsher 
785f142af2eSSrinivas Kandagatla 	if (priv->plat->phy_bus_name)
786f142af2eSSrinivas Kandagatla 		snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
787f142af2eSSrinivas Kandagatla 			 priv->plat->phy_bus_name, priv->plat->bus_id);
788f142af2eSSrinivas Kandagatla 	else
789f142af2eSSrinivas Kandagatla 		snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
790f142af2eSSrinivas Kandagatla 			 priv->plat->bus_id);
791f142af2eSSrinivas Kandagatla 
792d765955dSGiuseppe CAVALLARO 	snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
7937ac6653aSJeff Kirsher 		 priv->plat->phy_addr);
794d765955dSGiuseppe CAVALLARO 	pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id_fmt);
7957ac6653aSJeff Kirsher 
796f9a8f83bSFlorian Fainelli 	phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
7977ac6653aSJeff Kirsher 
7987ac6653aSJeff Kirsher 	if (IS_ERR(phydev)) {
7997ac6653aSJeff Kirsher 		pr_err("%s: Could not attach to PHY\n", dev->name);
8007ac6653aSJeff Kirsher 		return PTR_ERR(phydev);
8017ac6653aSJeff Kirsher 	}
8027ac6653aSJeff Kirsher 
80379ee1dc3SSrinivas Kandagatla 	/* Stop Advertising 1000BASE Capability if interface is not GMII */
804c5b9b4e4SSrinivas Kandagatla 	if ((interface == PHY_INTERFACE_MODE_MII) ||
805c5b9b4e4SSrinivas Kandagatla 	    (interface == PHY_INTERFACE_MODE_RMII))
806c5b9b4e4SSrinivas Kandagatla 		phydev->advertising &= ~(SUPPORTED_1000baseT_Half |
807c5b9b4e4SSrinivas Kandagatla 					 SUPPORTED_1000baseT_Full);
80879ee1dc3SSrinivas Kandagatla 
8097ac6653aSJeff Kirsher 	/*
8107ac6653aSJeff Kirsher 	 * Broken HW is sometimes missing the pull-up resistor on the
8117ac6653aSJeff Kirsher 	 * MDIO line, which results in reads to non-existent devices returning
8127ac6653aSJeff Kirsher 	 * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
8137ac6653aSJeff Kirsher 	 * device as well.
8147ac6653aSJeff Kirsher 	 * Note: phydev->phy_id is the result of reading the UID PHY registers.
8157ac6653aSJeff Kirsher 	 */
8167ac6653aSJeff Kirsher 	if (phydev->phy_id == 0) {
8177ac6653aSJeff Kirsher 		phy_disconnect(phydev);
8187ac6653aSJeff Kirsher 		return -ENODEV;
8197ac6653aSJeff Kirsher 	}
8207ac6653aSJeff Kirsher 	pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
8217ac6653aSJeff Kirsher 		 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
8227ac6653aSJeff Kirsher 
8237ac6653aSJeff Kirsher 	priv->phydev = phydev;
8247ac6653aSJeff Kirsher 
8257ac6653aSJeff Kirsher 	return 0;
8267ac6653aSJeff Kirsher }
8277ac6653aSJeff Kirsher 
8287ac6653aSJeff Kirsher /**
82932ceabcaSGiuseppe CAVALLARO  * stmmac_display_ring: display ring
83032ceabcaSGiuseppe CAVALLARO  * @head: pointer to the head of the ring passed.
8317ac6653aSJeff Kirsher  * @size: size of the ring.
83232ceabcaSGiuseppe CAVALLARO  * @extend_desc: to verify if extended descriptors are used.
833c24602efSGiuseppe CAVALLARO  * Description: display the control/status and buffer descriptors.
8347ac6653aSJeff Kirsher  */
835c24602efSGiuseppe CAVALLARO static void stmmac_display_ring(void *head, int size, int extend_desc)
8367ac6653aSJeff Kirsher {
8377ac6653aSJeff Kirsher 	int i;
838c24602efSGiuseppe CAVALLARO 	struct dma_extended_desc *ep = (struct dma_extended_desc *)head;
839c24602efSGiuseppe CAVALLARO 	struct dma_desc *p = (struct dma_desc *)head;
840c24602efSGiuseppe CAVALLARO 
8417ac6653aSJeff Kirsher 	for (i = 0; i < size; i++) {
842c24602efSGiuseppe CAVALLARO 		u64 x;
843c24602efSGiuseppe CAVALLARO 		if (extend_desc) {
844c24602efSGiuseppe CAVALLARO 			x = *(u64 *) ep;
845c24602efSGiuseppe CAVALLARO 			pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
846c24602efSGiuseppe CAVALLARO 				i, (unsigned int)virt_to_phys(ep),
847c24602efSGiuseppe CAVALLARO 				(unsigned int)x, (unsigned int)(x >> 32),
848c24602efSGiuseppe CAVALLARO 				ep->basic.des2, ep->basic.des3);
849c24602efSGiuseppe CAVALLARO 			ep++;
850c24602efSGiuseppe CAVALLARO 		} else {
851c24602efSGiuseppe CAVALLARO 			x = *(u64 *) p;
852c24602efSGiuseppe CAVALLARO 			pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x",
853c24602efSGiuseppe CAVALLARO 				i, (unsigned int)virt_to_phys(p),
854c24602efSGiuseppe CAVALLARO 				(unsigned int)x, (unsigned int)(x >> 32),
855c24602efSGiuseppe CAVALLARO 				p->des2, p->des3);
856c24602efSGiuseppe CAVALLARO 			p++;
857c24602efSGiuseppe CAVALLARO 		}
8587ac6653aSJeff Kirsher 		pr_info("\n");
8597ac6653aSJeff Kirsher 	}
8607ac6653aSJeff Kirsher }
8617ac6653aSJeff Kirsher 
862c24602efSGiuseppe CAVALLARO static void stmmac_display_rings(struct stmmac_priv *priv)
863c24602efSGiuseppe CAVALLARO {
864c24602efSGiuseppe CAVALLARO 	unsigned int txsize = priv->dma_tx_size;
865c24602efSGiuseppe CAVALLARO 	unsigned int rxsize = priv->dma_rx_size;
866c24602efSGiuseppe CAVALLARO 
867c24602efSGiuseppe CAVALLARO 	if (priv->extend_desc) {
868c24602efSGiuseppe CAVALLARO 		pr_info("Extended RX descriptor ring:\n");
869c24602efSGiuseppe CAVALLARO 		stmmac_display_ring((void *)priv->dma_erx, rxsize, 1);
870c24602efSGiuseppe CAVALLARO 		pr_info("Extended TX descriptor ring:\n");
871c24602efSGiuseppe CAVALLARO 		stmmac_display_ring((void *)priv->dma_etx, txsize, 1);
872c24602efSGiuseppe CAVALLARO 	} else {
873c24602efSGiuseppe CAVALLARO 		pr_info("RX descriptor ring:\n");
874c24602efSGiuseppe CAVALLARO 		stmmac_display_ring((void *)priv->dma_rx, rxsize, 0);
875c24602efSGiuseppe CAVALLARO 		pr_info("TX descriptor ring:\n");
876c24602efSGiuseppe CAVALLARO 		stmmac_display_ring((void *)priv->dma_tx, txsize, 0);
877c24602efSGiuseppe CAVALLARO 	}
878c24602efSGiuseppe CAVALLARO }
879c24602efSGiuseppe CAVALLARO 
880286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize)
881286a8372SGiuseppe CAVALLARO {
882286a8372SGiuseppe CAVALLARO 	int ret = bufsize;
883286a8372SGiuseppe CAVALLARO 
884286a8372SGiuseppe CAVALLARO 	if (mtu >= BUF_SIZE_4KiB)
885286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_8KiB;
886286a8372SGiuseppe CAVALLARO 	else if (mtu >= BUF_SIZE_2KiB)
887286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_4KiB;
888286a8372SGiuseppe CAVALLARO 	else if (mtu >= DMA_BUFFER_SIZE)
889286a8372SGiuseppe CAVALLARO 		ret = BUF_SIZE_2KiB;
890286a8372SGiuseppe CAVALLARO 	else
891286a8372SGiuseppe CAVALLARO 		ret = DMA_BUFFER_SIZE;
892286a8372SGiuseppe CAVALLARO 
893286a8372SGiuseppe CAVALLARO 	return ret;
894286a8372SGiuseppe CAVALLARO }
895286a8372SGiuseppe CAVALLARO 
89632ceabcaSGiuseppe CAVALLARO /**
89732ceabcaSGiuseppe CAVALLARO  * stmmac_clear_descriptors: clear descriptors
89832ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
89932ceabcaSGiuseppe CAVALLARO  * Description: this function is called to clear the tx and rx descriptors
90032ceabcaSGiuseppe CAVALLARO  * in case of both basic and extended descriptors are used.
90132ceabcaSGiuseppe CAVALLARO  */
902c24602efSGiuseppe CAVALLARO static void stmmac_clear_descriptors(struct stmmac_priv *priv)
903c24602efSGiuseppe CAVALLARO {
904c24602efSGiuseppe CAVALLARO 	int i;
905c24602efSGiuseppe CAVALLARO 	unsigned int txsize = priv->dma_tx_size;
906c24602efSGiuseppe CAVALLARO 	unsigned int rxsize = priv->dma_rx_size;
907c24602efSGiuseppe CAVALLARO 
908c24602efSGiuseppe CAVALLARO 	/* Clear the Rx/Tx descriptors */
909c24602efSGiuseppe CAVALLARO 	for (i = 0; i < rxsize; i++)
910c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
911c24602efSGiuseppe CAVALLARO 			priv->hw->desc->init_rx_desc(&priv->dma_erx[i].basic,
912c24602efSGiuseppe CAVALLARO 						     priv->use_riwt, priv->mode,
913c24602efSGiuseppe CAVALLARO 						     (i == rxsize - 1));
914c24602efSGiuseppe CAVALLARO 		else
915c24602efSGiuseppe CAVALLARO 			priv->hw->desc->init_rx_desc(&priv->dma_rx[i],
916c24602efSGiuseppe CAVALLARO 						     priv->use_riwt, priv->mode,
917c24602efSGiuseppe CAVALLARO 						     (i == rxsize - 1));
918c24602efSGiuseppe CAVALLARO 	for (i = 0; i < txsize; i++)
919c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
920c24602efSGiuseppe CAVALLARO 			priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic,
921c24602efSGiuseppe CAVALLARO 						     priv->mode,
922c24602efSGiuseppe CAVALLARO 						     (i == txsize - 1));
923c24602efSGiuseppe CAVALLARO 		else
924c24602efSGiuseppe CAVALLARO 			priv->hw->desc->init_tx_desc(&priv->dma_tx[i],
925c24602efSGiuseppe CAVALLARO 						     priv->mode,
926c24602efSGiuseppe CAVALLARO 						     (i == txsize - 1));
927c24602efSGiuseppe CAVALLARO }
928c24602efSGiuseppe CAVALLARO 
929c24602efSGiuseppe CAVALLARO static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,
930c24602efSGiuseppe CAVALLARO 				  int i)
931c24602efSGiuseppe CAVALLARO {
932c24602efSGiuseppe CAVALLARO 	struct sk_buff *skb;
933c24602efSGiuseppe CAVALLARO 
934c24602efSGiuseppe CAVALLARO 	skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
935c24602efSGiuseppe CAVALLARO 				 GFP_KERNEL);
93656329137SBartlomiej Zolnierkiewicz 	if (!skb) {
937c24602efSGiuseppe CAVALLARO 		pr_err("%s: Rx init fails; skb is NULL\n", __func__);
93856329137SBartlomiej Zolnierkiewicz 		return -ENOMEM;
939c24602efSGiuseppe CAVALLARO 	}
940c24602efSGiuseppe CAVALLARO 	skb_reserve(skb, NET_IP_ALIGN);
941c24602efSGiuseppe CAVALLARO 	priv->rx_skbuff[i] = skb;
942c24602efSGiuseppe CAVALLARO 	priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
943c24602efSGiuseppe CAVALLARO 						priv->dma_buf_sz,
944c24602efSGiuseppe CAVALLARO 						DMA_FROM_DEVICE);
94556329137SBartlomiej Zolnierkiewicz 	if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) {
94656329137SBartlomiej Zolnierkiewicz 		pr_err("%s: DMA mapping error\n", __func__);
94756329137SBartlomiej Zolnierkiewicz 		dev_kfree_skb_any(skb);
94856329137SBartlomiej Zolnierkiewicz 		return -EINVAL;
94956329137SBartlomiej Zolnierkiewicz 	}
950c24602efSGiuseppe CAVALLARO 
951c24602efSGiuseppe CAVALLARO 	p->des2 = priv->rx_skbuff_dma[i];
952c24602efSGiuseppe CAVALLARO 
953c24602efSGiuseppe CAVALLARO 	if ((priv->mode == STMMAC_RING_MODE) &&
954c24602efSGiuseppe CAVALLARO 	    (priv->dma_buf_sz == BUF_SIZE_16KiB))
955c24602efSGiuseppe CAVALLARO 		priv->hw->ring->init_desc3(p);
956c24602efSGiuseppe CAVALLARO 
957c24602efSGiuseppe CAVALLARO 	return 0;
958c24602efSGiuseppe CAVALLARO }
959c24602efSGiuseppe CAVALLARO 
96056329137SBartlomiej Zolnierkiewicz static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i)
96156329137SBartlomiej Zolnierkiewicz {
96256329137SBartlomiej Zolnierkiewicz 	if (priv->rx_skbuff[i]) {
96356329137SBartlomiej Zolnierkiewicz 		dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
96456329137SBartlomiej Zolnierkiewicz 				 priv->dma_buf_sz, DMA_FROM_DEVICE);
96556329137SBartlomiej Zolnierkiewicz 		dev_kfree_skb_any(priv->rx_skbuff[i]);
96656329137SBartlomiej Zolnierkiewicz 	}
96756329137SBartlomiej Zolnierkiewicz 	priv->rx_skbuff[i] = NULL;
96856329137SBartlomiej Zolnierkiewicz }
96956329137SBartlomiej Zolnierkiewicz 
9707ac6653aSJeff Kirsher /**
9717ac6653aSJeff Kirsher  * init_dma_desc_rings - init the RX/TX descriptor rings
9727ac6653aSJeff Kirsher  * @dev: net device structure
9737ac6653aSJeff Kirsher  * Description:  this function initializes the DMA RX/TX descriptors
974286a8372SGiuseppe CAVALLARO  * and allocates the socket buffers. It suppors the chained and ring
975286a8372SGiuseppe CAVALLARO  * modes.
9767ac6653aSJeff Kirsher  */
97756329137SBartlomiej Zolnierkiewicz static int init_dma_desc_rings(struct net_device *dev)
9787ac6653aSJeff Kirsher {
9797ac6653aSJeff Kirsher 	int i;
9807ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
9817ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
9827ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
9834a7d666aSGiuseppe CAVALLARO 	unsigned int bfsize = 0;
98456329137SBartlomiej Zolnierkiewicz 	int ret = -ENOMEM;
9857ac6653aSJeff Kirsher 
986286a8372SGiuseppe CAVALLARO 	/* Set the max buffer size according to the DESC mode
987ceb69499SGiuseppe CAVALLARO 	 * and the MTU. Note that RING mode allows 16KiB bsize.
988ceb69499SGiuseppe CAVALLARO 	 */
9894a7d666aSGiuseppe CAVALLARO 	if (priv->mode == STMMAC_RING_MODE)
990286a8372SGiuseppe CAVALLARO 		bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu);
991286a8372SGiuseppe CAVALLARO 
9924a7d666aSGiuseppe CAVALLARO 	if (bfsize < BUF_SIZE_16KiB)
993286a8372SGiuseppe CAVALLARO 		bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz);
9947ac6653aSJeff Kirsher 
99583d7af64SGiuseppe CAVALLARO 	if (netif_msg_probe(priv))
99683d7af64SGiuseppe CAVALLARO 		pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__,
9977ac6653aSJeff Kirsher 			 txsize, rxsize, bfsize);
9987ac6653aSJeff Kirsher 
999c24602efSGiuseppe CAVALLARO 	if (priv->extend_desc) {
1000c24602efSGiuseppe CAVALLARO 		priv->dma_erx = dma_alloc_coherent(priv->device, rxsize *
1001c24602efSGiuseppe CAVALLARO 						   sizeof(struct
1002c24602efSGiuseppe CAVALLARO 							  dma_extended_desc),
1003c24602efSGiuseppe CAVALLARO 						   &priv->dma_rx_phy,
1004c24602efSGiuseppe CAVALLARO 						   GFP_KERNEL);
100556329137SBartlomiej Zolnierkiewicz 		if (!priv->dma_erx)
100656329137SBartlomiej Zolnierkiewicz 			goto err_dma;
100756329137SBartlomiej Zolnierkiewicz 
1008c24602efSGiuseppe CAVALLARO 		priv->dma_etx = dma_alloc_coherent(priv->device, txsize *
1009c24602efSGiuseppe CAVALLARO 						   sizeof(struct
1010c24602efSGiuseppe CAVALLARO 							  dma_extended_desc),
1011c24602efSGiuseppe CAVALLARO 						   &priv->dma_tx_phy,
1012c24602efSGiuseppe CAVALLARO 						   GFP_KERNEL);
101356329137SBartlomiej Zolnierkiewicz 		if (!priv->dma_etx) {
101456329137SBartlomiej Zolnierkiewicz 			dma_free_coherent(priv->device, priv->dma_rx_size *
101556329137SBartlomiej Zolnierkiewicz 					sizeof(struct dma_extended_desc),
101656329137SBartlomiej Zolnierkiewicz 					priv->dma_erx, priv->dma_rx_phy);
101756329137SBartlomiej Zolnierkiewicz 			goto err_dma;
101856329137SBartlomiej Zolnierkiewicz 		}
1019c24602efSGiuseppe CAVALLARO 	} else {
1020c24602efSGiuseppe CAVALLARO 		priv->dma_rx = dma_alloc_coherent(priv->device, rxsize *
1021c24602efSGiuseppe CAVALLARO 						  sizeof(struct dma_desc),
1022c24602efSGiuseppe CAVALLARO 						  &priv->dma_rx_phy,
1023c24602efSGiuseppe CAVALLARO 						  GFP_KERNEL);
102456329137SBartlomiej Zolnierkiewicz 		if (!priv->dma_rx)
102556329137SBartlomiej Zolnierkiewicz 			goto err_dma;
102656329137SBartlomiej Zolnierkiewicz 
1027c24602efSGiuseppe CAVALLARO 		priv->dma_tx = dma_alloc_coherent(priv->device, txsize *
1028c24602efSGiuseppe CAVALLARO 						  sizeof(struct dma_desc),
1029c24602efSGiuseppe CAVALLARO 						  &priv->dma_tx_phy,
1030c24602efSGiuseppe CAVALLARO 						  GFP_KERNEL);
103156329137SBartlomiej Zolnierkiewicz 		if (!priv->dma_tx) {
103256329137SBartlomiej Zolnierkiewicz 			dma_free_coherent(priv->device, priv->dma_rx_size *
103356329137SBartlomiej Zolnierkiewicz 					sizeof(struct dma_desc),
103456329137SBartlomiej Zolnierkiewicz 					priv->dma_rx, priv->dma_rx_phy);
103556329137SBartlomiej Zolnierkiewicz 			goto err_dma;
103656329137SBartlomiej Zolnierkiewicz 		}
1037c24602efSGiuseppe CAVALLARO 	}
1038c24602efSGiuseppe CAVALLARO 
1039b2adaca9SJoe Perches 	priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t),
1040b2adaca9SJoe Perches 					    GFP_KERNEL);
104156329137SBartlomiej Zolnierkiewicz 	if (!priv->rx_skbuff_dma)
104256329137SBartlomiej Zolnierkiewicz 		goto err_rx_skbuff_dma;
104356329137SBartlomiej Zolnierkiewicz 
1044b2adaca9SJoe Perches 	priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *),
1045b2adaca9SJoe Perches 					GFP_KERNEL);
104656329137SBartlomiej Zolnierkiewicz 	if (!priv->rx_skbuff)
104756329137SBartlomiej Zolnierkiewicz 		goto err_rx_skbuff;
104856329137SBartlomiej Zolnierkiewicz 
1049cf32deecSRayagond Kokatanur 	priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
1050cf32deecSRayagond Kokatanur 					    GFP_KERNEL);
105156329137SBartlomiej Zolnierkiewicz 	if (!priv->tx_skbuff_dma)
105256329137SBartlomiej Zolnierkiewicz 		goto err_tx_skbuff_dma;
105356329137SBartlomiej Zolnierkiewicz 
1054b2adaca9SJoe Perches 	priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *),
10557ac6653aSJeff Kirsher 					GFP_KERNEL);
105656329137SBartlomiej Zolnierkiewicz 	if (!priv->tx_skbuff)
105756329137SBartlomiej Zolnierkiewicz 		goto err_tx_skbuff;
105856329137SBartlomiej Zolnierkiewicz 
105983d7af64SGiuseppe CAVALLARO 	if (netif_msg_probe(priv)) {
1060c24602efSGiuseppe CAVALLARO 		pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__,
1061c24602efSGiuseppe CAVALLARO 			 (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy);
10627ac6653aSJeff Kirsher 
10637ac6653aSJeff Kirsher 		/* RX INITIALIZATION */
106483d7af64SGiuseppe CAVALLARO 		pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n");
106583d7af64SGiuseppe CAVALLARO 	}
10667ac6653aSJeff Kirsher 	for (i = 0; i < rxsize; i++) {
1067c24602efSGiuseppe CAVALLARO 		struct dma_desc *p;
1068c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1069c24602efSGiuseppe CAVALLARO 			p = &((priv->dma_erx + i)->basic);
1070c24602efSGiuseppe CAVALLARO 		else
1071c24602efSGiuseppe CAVALLARO 			p = priv->dma_rx + i;
10727ac6653aSJeff Kirsher 
107356329137SBartlomiej Zolnierkiewicz 		ret = stmmac_init_rx_buffers(priv, p, i);
107456329137SBartlomiej Zolnierkiewicz 		if (ret)
107556329137SBartlomiej Zolnierkiewicz 			goto err_init_rx_buffers;
1076286a8372SGiuseppe CAVALLARO 
107783d7af64SGiuseppe CAVALLARO 		if (netif_msg_probe(priv))
107883d7af64SGiuseppe CAVALLARO 			pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
107983d7af64SGiuseppe CAVALLARO 				 priv->rx_skbuff[i]->data,
108083d7af64SGiuseppe CAVALLARO 				 (unsigned int)priv->rx_skbuff_dma[i]);
10817ac6653aSJeff Kirsher 	}
10827ac6653aSJeff Kirsher 	priv->cur_rx = 0;
10837ac6653aSJeff Kirsher 	priv->dirty_rx = (unsigned int)(i - rxsize);
10847ac6653aSJeff Kirsher 	priv->dma_buf_sz = bfsize;
10857ac6653aSJeff Kirsher 	buf_sz = bfsize;
10867ac6653aSJeff Kirsher 
1087c24602efSGiuseppe CAVALLARO 	/* Setup the chained descriptor addresses */
1088c24602efSGiuseppe CAVALLARO 	if (priv->mode == STMMAC_CHAIN_MODE) {
1089c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc) {
1090c24602efSGiuseppe CAVALLARO 			priv->hw->chain->init(priv->dma_erx, priv->dma_rx_phy,
1091c24602efSGiuseppe CAVALLARO 					      rxsize, 1);
1092c24602efSGiuseppe CAVALLARO 			priv->hw->chain->init(priv->dma_etx, priv->dma_tx_phy,
1093c24602efSGiuseppe CAVALLARO 					      txsize, 1);
1094c24602efSGiuseppe CAVALLARO 		} else {
1095c24602efSGiuseppe CAVALLARO 			priv->hw->chain->init(priv->dma_rx, priv->dma_rx_phy,
1096c24602efSGiuseppe CAVALLARO 					      rxsize, 0);
1097c24602efSGiuseppe CAVALLARO 			priv->hw->chain->init(priv->dma_tx, priv->dma_tx_phy,
1098c24602efSGiuseppe CAVALLARO 					      txsize, 0);
1099c24602efSGiuseppe CAVALLARO 		}
11007ac6653aSJeff Kirsher 	}
1101286a8372SGiuseppe CAVALLARO 
1102c24602efSGiuseppe CAVALLARO 	/* TX INITIALIZATION */
1103c24602efSGiuseppe CAVALLARO 	for (i = 0; i < txsize; i++) {
1104c24602efSGiuseppe CAVALLARO 		struct dma_desc *p;
1105c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1106c24602efSGiuseppe CAVALLARO 			p = &((priv->dma_etx + i)->basic);
1107c24602efSGiuseppe CAVALLARO 		else
1108c24602efSGiuseppe CAVALLARO 			p = priv->dma_tx + i;
1109c24602efSGiuseppe CAVALLARO 		p->des2 = 0;
1110cf32deecSRayagond Kokatanur 		priv->tx_skbuff_dma[i] = 0;
1111c24602efSGiuseppe CAVALLARO 		priv->tx_skbuff[i] = NULL;
11124a7d666aSGiuseppe CAVALLARO 	}
1113c24602efSGiuseppe CAVALLARO 
11147ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
11157ac6653aSJeff Kirsher 	priv->cur_tx = 0;
11167ac6653aSJeff Kirsher 
1117c24602efSGiuseppe CAVALLARO 	stmmac_clear_descriptors(priv);
11187ac6653aSJeff Kirsher 
1119c24602efSGiuseppe CAVALLARO 	if (netif_msg_hw(priv))
1120c24602efSGiuseppe CAVALLARO 		stmmac_display_rings(priv);
112156329137SBartlomiej Zolnierkiewicz 
112256329137SBartlomiej Zolnierkiewicz 	return 0;
112356329137SBartlomiej Zolnierkiewicz err_init_rx_buffers:
112456329137SBartlomiej Zolnierkiewicz 	while (--i >= 0)
112556329137SBartlomiej Zolnierkiewicz 		stmmac_free_rx_buffers(priv, i);
112656329137SBartlomiej Zolnierkiewicz 	kfree(priv->tx_skbuff);
112756329137SBartlomiej Zolnierkiewicz err_tx_skbuff:
112856329137SBartlomiej Zolnierkiewicz 	kfree(priv->tx_skbuff_dma);
112956329137SBartlomiej Zolnierkiewicz err_tx_skbuff_dma:
113056329137SBartlomiej Zolnierkiewicz 	kfree(priv->rx_skbuff);
113156329137SBartlomiej Zolnierkiewicz err_rx_skbuff:
113256329137SBartlomiej Zolnierkiewicz 	kfree(priv->rx_skbuff_dma);
113356329137SBartlomiej Zolnierkiewicz err_rx_skbuff_dma:
113456329137SBartlomiej Zolnierkiewicz 	if (priv->extend_desc) {
113556329137SBartlomiej Zolnierkiewicz 		dma_free_coherent(priv->device, priv->dma_tx_size *
113656329137SBartlomiej Zolnierkiewicz 				  sizeof(struct dma_extended_desc),
113756329137SBartlomiej Zolnierkiewicz 				  priv->dma_etx, priv->dma_tx_phy);
113856329137SBartlomiej Zolnierkiewicz 		dma_free_coherent(priv->device, priv->dma_rx_size *
113956329137SBartlomiej Zolnierkiewicz 				  sizeof(struct dma_extended_desc),
114056329137SBartlomiej Zolnierkiewicz 				  priv->dma_erx, priv->dma_rx_phy);
114156329137SBartlomiej Zolnierkiewicz 	} else {
114256329137SBartlomiej Zolnierkiewicz 		dma_free_coherent(priv->device,
114356329137SBartlomiej Zolnierkiewicz 				priv->dma_tx_size * sizeof(struct dma_desc),
114456329137SBartlomiej Zolnierkiewicz 				priv->dma_tx, priv->dma_tx_phy);
114556329137SBartlomiej Zolnierkiewicz 		dma_free_coherent(priv->device,
114656329137SBartlomiej Zolnierkiewicz 				priv->dma_rx_size * sizeof(struct dma_desc),
114756329137SBartlomiej Zolnierkiewicz 				priv->dma_rx, priv->dma_rx_phy);
114856329137SBartlomiej Zolnierkiewicz 	}
114956329137SBartlomiej Zolnierkiewicz err_dma:
115056329137SBartlomiej Zolnierkiewicz 	return ret;
11517ac6653aSJeff Kirsher }
11527ac6653aSJeff Kirsher 
11537ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv)
11547ac6653aSJeff Kirsher {
11557ac6653aSJeff Kirsher 	int i;
11567ac6653aSJeff Kirsher 
115756329137SBartlomiej Zolnierkiewicz 	for (i = 0; i < priv->dma_rx_size; i++)
115856329137SBartlomiej Zolnierkiewicz 		stmmac_free_rx_buffers(priv, i);
11597ac6653aSJeff Kirsher }
11607ac6653aSJeff Kirsher 
11617ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv)
11627ac6653aSJeff Kirsher {
11637ac6653aSJeff Kirsher 	int i;
11647ac6653aSJeff Kirsher 
11657ac6653aSJeff Kirsher 	for (i = 0; i < priv->dma_tx_size; i++) {
11667ac6653aSJeff Kirsher 		if (priv->tx_skbuff[i] != NULL) {
1167c24602efSGiuseppe CAVALLARO 			struct dma_desc *p;
1168c24602efSGiuseppe CAVALLARO 			if (priv->extend_desc)
1169c24602efSGiuseppe CAVALLARO 				p = &((priv->dma_etx + i)->basic);
1170c24602efSGiuseppe CAVALLARO 			else
1171c24602efSGiuseppe CAVALLARO 				p = priv->dma_tx + i;
1172c24602efSGiuseppe CAVALLARO 
1173cf32deecSRayagond Kokatanur 			if (priv->tx_skbuff_dma[i])
1174cf32deecSRayagond Kokatanur 				dma_unmap_single(priv->device,
1175cf32deecSRayagond Kokatanur 						 priv->tx_skbuff_dma[i],
11767ac6653aSJeff Kirsher 						 priv->hw->desc->get_tx_len(p),
11777ac6653aSJeff Kirsher 						 DMA_TO_DEVICE);
11787ac6653aSJeff Kirsher 			dev_kfree_skb_any(priv->tx_skbuff[i]);
11797ac6653aSJeff Kirsher 			priv->tx_skbuff[i] = NULL;
1180cf32deecSRayagond Kokatanur 			priv->tx_skbuff_dma[i] = 0;
11817ac6653aSJeff Kirsher 		}
11827ac6653aSJeff Kirsher 	}
11837ac6653aSJeff Kirsher }
11847ac6653aSJeff Kirsher 
11857ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv)
11867ac6653aSJeff Kirsher {
11877ac6653aSJeff Kirsher 	/* Release the DMA TX/RX socket buffers */
11887ac6653aSJeff Kirsher 	dma_free_rx_skbufs(priv);
11897ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
11907ac6653aSJeff Kirsher 
1191ceb69499SGiuseppe CAVALLARO 	/* Free DMA regions of consistent memory previously allocated */
1192c24602efSGiuseppe CAVALLARO 	if (!priv->extend_desc) {
11937ac6653aSJeff Kirsher 		dma_free_coherent(priv->device,
11947ac6653aSJeff Kirsher 				  priv->dma_tx_size * sizeof(struct dma_desc),
11957ac6653aSJeff Kirsher 				  priv->dma_tx, priv->dma_tx_phy);
11967ac6653aSJeff Kirsher 		dma_free_coherent(priv->device,
11977ac6653aSJeff Kirsher 				  priv->dma_rx_size * sizeof(struct dma_desc),
11987ac6653aSJeff Kirsher 				  priv->dma_rx, priv->dma_rx_phy);
1199c24602efSGiuseppe CAVALLARO 	} else {
1200c24602efSGiuseppe CAVALLARO 		dma_free_coherent(priv->device, priv->dma_tx_size *
1201c24602efSGiuseppe CAVALLARO 				  sizeof(struct dma_extended_desc),
1202c24602efSGiuseppe CAVALLARO 				  priv->dma_etx, priv->dma_tx_phy);
1203c24602efSGiuseppe CAVALLARO 		dma_free_coherent(priv->device, priv->dma_rx_size *
1204c24602efSGiuseppe CAVALLARO 				  sizeof(struct dma_extended_desc),
1205c24602efSGiuseppe CAVALLARO 				  priv->dma_erx, priv->dma_rx_phy);
1206c24602efSGiuseppe CAVALLARO 	}
12077ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff_dma);
12087ac6653aSJeff Kirsher 	kfree(priv->rx_skbuff);
1209cf32deecSRayagond Kokatanur 	kfree(priv->tx_skbuff_dma);
12107ac6653aSJeff Kirsher 	kfree(priv->tx_skbuff);
12117ac6653aSJeff Kirsher }
12127ac6653aSJeff Kirsher 
12137ac6653aSJeff Kirsher /**
12147ac6653aSJeff Kirsher  *  stmmac_dma_operation_mode - HW DMA operation mode
121532ceabcaSGiuseppe CAVALLARO  *  @priv: driver private structure
12167ac6653aSJeff Kirsher  *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
12177ac6653aSJeff Kirsher  *  or Store-And-Forward capability.
12187ac6653aSJeff Kirsher  */
12197ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
12207ac6653aSJeff Kirsher {
1221e2a240c7SSonic Zhang 	if (priv->plat->force_thresh_dma_mode)
1222e2a240c7SSonic Zhang 		priv->hw->dma->dma_mode(priv->ioaddr, tc, tc);
1223e2a240c7SSonic Zhang 	else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
12247ac6653aSJeff Kirsher 		/*
12257ac6653aSJeff Kirsher 		 * In case of GMAC, SF mode can be enabled
12267ac6653aSJeff Kirsher 		 * to perform the TX COE in HW. This depends on:
12277ac6653aSJeff Kirsher 		 * 1) TX COE if actually supported
12287ac6653aSJeff Kirsher 		 * 2) There is no bugged Jumbo frame support
12297ac6653aSJeff Kirsher 		 *    that needs to not insert csum in the TDES.
12307ac6653aSJeff Kirsher 		 */
1231ceb69499SGiuseppe CAVALLARO 		priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE);
12327ac6653aSJeff Kirsher 		tc = SF_DMA_MODE;
12337ac6653aSJeff Kirsher 	} else
12347ac6653aSJeff Kirsher 		priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
12357ac6653aSJeff Kirsher }
12367ac6653aSJeff Kirsher 
12377ac6653aSJeff Kirsher /**
12389125cdd1SGiuseppe CAVALLARO  * stmmac_tx_clean:
123932ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
12407ac6653aSJeff Kirsher  * Description: it reclaims resources after transmission completes.
12417ac6653aSJeff Kirsher  */
12429125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv)
12437ac6653aSJeff Kirsher {
12447ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
12457ac6653aSJeff Kirsher 
1246a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
1247a9097a96SGiuseppe CAVALLARO 
12489125cdd1SGiuseppe CAVALLARO 	priv->xstats.tx_clean++;
12499125cdd1SGiuseppe CAVALLARO 
12507ac6653aSJeff Kirsher 	while (priv->dirty_tx != priv->cur_tx) {
12517ac6653aSJeff Kirsher 		int last;
12527ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_tx % txsize;
12537ac6653aSJeff Kirsher 		struct sk_buff *skb = priv->tx_skbuff[entry];
1254c24602efSGiuseppe CAVALLARO 		struct dma_desc *p;
1255c24602efSGiuseppe CAVALLARO 
1256c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1257c24602efSGiuseppe CAVALLARO 			p = (struct dma_desc *)(priv->dma_etx + entry);
1258c24602efSGiuseppe CAVALLARO 		else
1259c24602efSGiuseppe CAVALLARO 			p = priv->dma_tx + entry;
12607ac6653aSJeff Kirsher 
12617ac6653aSJeff Kirsher 		/* Check if the descriptor is owned by the DMA. */
12627ac6653aSJeff Kirsher 		if (priv->hw->desc->get_tx_owner(p))
12637ac6653aSJeff Kirsher 			break;
12647ac6653aSJeff Kirsher 
1265c24602efSGiuseppe CAVALLARO 		/* Verify tx error by looking at the last segment. */
12667ac6653aSJeff Kirsher 		last = priv->hw->desc->get_tx_ls(p);
12677ac6653aSJeff Kirsher 		if (likely(last)) {
12687ac6653aSJeff Kirsher 			int tx_error =
12697ac6653aSJeff Kirsher 			    priv->hw->desc->tx_status(&priv->dev->stats,
12707ac6653aSJeff Kirsher 						      &priv->xstats, p,
12717ac6653aSJeff Kirsher 						      priv->ioaddr);
12727ac6653aSJeff Kirsher 			if (likely(tx_error == 0)) {
12737ac6653aSJeff Kirsher 				priv->dev->stats.tx_packets++;
12747ac6653aSJeff Kirsher 				priv->xstats.tx_pkt_n++;
12757ac6653aSJeff Kirsher 			} else
12767ac6653aSJeff Kirsher 				priv->dev->stats.tx_errors++;
1277891434b1SRayagond Kokatanur 
1278891434b1SRayagond Kokatanur 			stmmac_get_tx_hwtstamp(priv, entry, skb);
12797ac6653aSJeff Kirsher 		}
128083d7af64SGiuseppe CAVALLARO 		if (netif_msg_tx_done(priv))
128183d7af64SGiuseppe CAVALLARO 			pr_debug("%s: curr %d, dirty %d\n", __func__,
12827ac6653aSJeff Kirsher 				 priv->cur_tx, priv->dirty_tx);
12837ac6653aSJeff Kirsher 
1284cf32deecSRayagond Kokatanur 		if (likely(priv->tx_skbuff_dma[entry])) {
1285cf32deecSRayagond Kokatanur 			dma_unmap_single(priv->device,
1286cf32deecSRayagond Kokatanur 					 priv->tx_skbuff_dma[entry],
12877ac6653aSJeff Kirsher 					 priv->hw->desc->get_tx_len(p),
12887ac6653aSJeff Kirsher 					 DMA_TO_DEVICE);
1289cf32deecSRayagond Kokatanur 			priv->tx_skbuff_dma[entry] = 0;
1290cf32deecSRayagond Kokatanur 		}
1291891434b1SRayagond Kokatanur 		priv->hw->ring->clean_desc3(priv, p);
12927ac6653aSJeff Kirsher 
12937ac6653aSJeff Kirsher 		if (likely(skb != NULL)) {
12947ac6653aSJeff Kirsher 			dev_kfree_skb(skb);
12957ac6653aSJeff Kirsher 			priv->tx_skbuff[entry] = NULL;
12967ac6653aSJeff Kirsher 		}
12977ac6653aSJeff Kirsher 
12984a7d666aSGiuseppe CAVALLARO 		priv->hw->desc->release_tx_desc(p, priv->mode);
12997ac6653aSJeff Kirsher 
130013497f58SGiuseppe CAVALLARO 		priv->dirty_tx++;
13017ac6653aSJeff Kirsher 	}
13027ac6653aSJeff Kirsher 	if (unlikely(netif_queue_stopped(priv->dev) &&
13037ac6653aSJeff Kirsher 		     stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
13047ac6653aSJeff Kirsher 		netif_tx_lock(priv->dev);
13057ac6653aSJeff Kirsher 		if (netif_queue_stopped(priv->dev) &&
13067ac6653aSJeff Kirsher 		    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
130783d7af64SGiuseppe CAVALLARO 			if (netif_msg_tx_done(priv))
130883d7af64SGiuseppe CAVALLARO 				pr_debug("%s: restart transmit\n", __func__);
13097ac6653aSJeff Kirsher 			netif_wake_queue(priv->dev);
13107ac6653aSJeff Kirsher 		}
13117ac6653aSJeff Kirsher 		netif_tx_unlock(priv->dev);
13127ac6653aSJeff Kirsher 	}
1313d765955dSGiuseppe CAVALLARO 
1314d765955dSGiuseppe CAVALLARO 	if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) {
1315d765955dSGiuseppe CAVALLARO 		stmmac_enable_eee_mode(priv);
1316f5351ef7SGiuseppe CAVALLARO 		mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
1317d765955dSGiuseppe CAVALLARO 	}
1318a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
13197ac6653aSJeff Kirsher }
13207ac6653aSJeff Kirsher 
13219125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv)
13227ac6653aSJeff Kirsher {
13237ac6653aSJeff Kirsher 	priv->hw->dma->enable_dma_irq(priv->ioaddr);
13247ac6653aSJeff Kirsher }
13257ac6653aSJeff Kirsher 
13269125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv)
13277ac6653aSJeff Kirsher {
13287ac6653aSJeff Kirsher 	priv->hw->dma->disable_dma_irq(priv->ioaddr);
13297ac6653aSJeff Kirsher }
13307ac6653aSJeff Kirsher 
13317ac6653aSJeff Kirsher /**
133232ceabcaSGiuseppe CAVALLARO  * stmmac_tx_err: irq tx error mng function
133332ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
13347ac6653aSJeff Kirsher  * Description: it cleans the descriptors and restarts the transmission
13357ac6653aSJeff Kirsher  * in case of errors.
13367ac6653aSJeff Kirsher  */
13377ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv)
13387ac6653aSJeff Kirsher {
1339c24602efSGiuseppe CAVALLARO 	int i;
1340c24602efSGiuseppe CAVALLARO 	int txsize = priv->dma_tx_size;
13417ac6653aSJeff Kirsher 	netif_stop_queue(priv->dev);
13427ac6653aSJeff Kirsher 
13437ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
13447ac6653aSJeff Kirsher 	dma_free_tx_skbufs(priv);
1345c24602efSGiuseppe CAVALLARO 	for (i = 0; i < txsize; i++)
1346c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1347c24602efSGiuseppe CAVALLARO 			priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic,
1348c24602efSGiuseppe CAVALLARO 						     priv->mode,
1349c24602efSGiuseppe CAVALLARO 						     (i == txsize - 1));
1350c24602efSGiuseppe CAVALLARO 		else
1351c24602efSGiuseppe CAVALLARO 			priv->hw->desc->init_tx_desc(&priv->dma_tx[i],
1352c24602efSGiuseppe CAVALLARO 						     priv->mode,
1353c24602efSGiuseppe CAVALLARO 						     (i == txsize - 1));
13547ac6653aSJeff Kirsher 	priv->dirty_tx = 0;
13557ac6653aSJeff Kirsher 	priv->cur_tx = 0;
13567ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
13577ac6653aSJeff Kirsher 
13587ac6653aSJeff Kirsher 	priv->dev->stats.tx_errors++;
13597ac6653aSJeff Kirsher 	netif_wake_queue(priv->dev);
13607ac6653aSJeff Kirsher }
13617ac6653aSJeff Kirsher 
136232ceabcaSGiuseppe CAVALLARO /**
136332ceabcaSGiuseppe CAVALLARO  * stmmac_dma_interrupt: DMA ISR
136432ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
136532ceabcaSGiuseppe CAVALLARO  * Description: this is the DMA ISR. It is called by the main ISR.
136632ceabcaSGiuseppe CAVALLARO  * It calls the dwmac dma routine to understand which type of interrupt
136732ceabcaSGiuseppe CAVALLARO  * happened. In case of there is a Normal interrupt and either TX or RX
136832ceabcaSGiuseppe CAVALLARO  * interrupt happened so the NAPI is scheduled.
136932ceabcaSGiuseppe CAVALLARO  */
13707ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv)
13717ac6653aSJeff Kirsher {
13727ac6653aSJeff Kirsher 	int status;
13737ac6653aSJeff Kirsher 
13747ac6653aSJeff Kirsher 	status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
13759125cdd1SGiuseppe CAVALLARO 	if (likely((status & handle_rx)) || (status & handle_tx)) {
13769125cdd1SGiuseppe CAVALLARO 		if (likely(napi_schedule_prep(&priv->napi))) {
13779125cdd1SGiuseppe CAVALLARO 			stmmac_disable_dma_irq(priv);
13789125cdd1SGiuseppe CAVALLARO 			__napi_schedule(&priv->napi);
13799125cdd1SGiuseppe CAVALLARO 		}
13809125cdd1SGiuseppe CAVALLARO 	}
13819125cdd1SGiuseppe CAVALLARO 	if (unlikely(status & tx_hard_error_bump_tc)) {
13827ac6653aSJeff Kirsher 		/* Try to bump up the dma threshold on this failure */
13837ac6653aSJeff Kirsher 		if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
13847ac6653aSJeff Kirsher 			tc += 64;
13857ac6653aSJeff Kirsher 			priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
13867ac6653aSJeff Kirsher 			priv->xstats.threshold = tc;
13877ac6653aSJeff Kirsher 		}
13887ac6653aSJeff Kirsher 	} else if (unlikely(status == tx_hard_error))
13897ac6653aSJeff Kirsher 		stmmac_tx_err(priv);
13907ac6653aSJeff Kirsher }
13917ac6653aSJeff Kirsher 
139232ceabcaSGiuseppe CAVALLARO /**
139332ceabcaSGiuseppe CAVALLARO  * stmmac_mmc_setup: setup the Mac Management Counters (MMC)
139432ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
139532ceabcaSGiuseppe CAVALLARO  * Description: this masks the MMC irq, in fact, the counters are managed in SW.
139632ceabcaSGiuseppe CAVALLARO  */
13971c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv)
13981c901a46SGiuseppe CAVALLARO {
13991c901a46SGiuseppe CAVALLARO 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
14001c901a46SGiuseppe CAVALLARO 	    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
14011c901a46SGiuseppe CAVALLARO 
14021c901a46SGiuseppe CAVALLARO 	dwmac_mmc_intr_all_mask(priv->ioaddr);
14034f795b25SGiuseppe CAVALLARO 
14044f795b25SGiuseppe CAVALLARO 	if (priv->dma_cap.rmon) {
14051c901a46SGiuseppe CAVALLARO 		dwmac_mmc_ctrl(priv->ioaddr, mode);
14061c901a46SGiuseppe CAVALLARO 		memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
14074f795b25SGiuseppe CAVALLARO 	} else
1408aae54cffSStefan Roese 		pr_info(" No MAC Management Counters available\n");
14091c901a46SGiuseppe CAVALLARO }
14101c901a46SGiuseppe CAVALLARO 
1411f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
1412f0b9d786SGiuseppe CAVALLARO {
1413f0b9d786SGiuseppe CAVALLARO 	u32 hwid = priv->hw->synopsys_uid;
1414f0b9d786SGiuseppe CAVALLARO 
1415ceb69499SGiuseppe CAVALLARO 	/* Check Synopsys Id (not available on old chips) */
1416f0b9d786SGiuseppe CAVALLARO 	if (likely(hwid)) {
1417f0b9d786SGiuseppe CAVALLARO 		u32 uid = ((hwid & 0x0000ff00) >> 8);
1418f0b9d786SGiuseppe CAVALLARO 		u32 synid = (hwid & 0x000000ff);
1419f0b9d786SGiuseppe CAVALLARO 
1420cf3f047bSGiuseppe CAVALLARO 		pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n",
1421f0b9d786SGiuseppe CAVALLARO 			uid, synid);
1422f0b9d786SGiuseppe CAVALLARO 
1423f0b9d786SGiuseppe CAVALLARO 		return synid;
1424f0b9d786SGiuseppe CAVALLARO 	}
1425f0b9d786SGiuseppe CAVALLARO 	return 0;
1426f0b9d786SGiuseppe CAVALLARO }
1427e7434821SGiuseppe CAVALLARO 
142819e30c14SGiuseppe CAVALLARO /**
142932ceabcaSGiuseppe CAVALLARO  * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors
143032ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
143132ceabcaSGiuseppe CAVALLARO  * Description: select the Enhanced/Alternate or Normal descriptors.
143232ceabcaSGiuseppe CAVALLARO  * In case of Enhanced/Alternate, it looks at the extended descriptors are
143332ceabcaSGiuseppe CAVALLARO  * supported by the HW cap. register.
1434ff3dd78cSGiuseppe CAVALLARO  */
143519e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv)
143619e30c14SGiuseppe CAVALLARO {
143719e30c14SGiuseppe CAVALLARO 	if (priv->plat->enh_desc) {
143819e30c14SGiuseppe CAVALLARO 		pr_info(" Enhanced/Alternate descriptors\n");
1439c24602efSGiuseppe CAVALLARO 
1440c24602efSGiuseppe CAVALLARO 		/* GMAC older than 3.50 has no extended descriptors */
1441c24602efSGiuseppe CAVALLARO 		if (priv->synopsys_id >= DWMAC_CORE_3_50) {
1442c24602efSGiuseppe CAVALLARO 			pr_info("\tEnabled extended descriptors\n");
1443c24602efSGiuseppe CAVALLARO 			priv->extend_desc = 1;
1444c24602efSGiuseppe CAVALLARO 		} else
1445c24602efSGiuseppe CAVALLARO 			pr_warn("Extended descriptors not supported\n");
1446c24602efSGiuseppe CAVALLARO 
144719e30c14SGiuseppe CAVALLARO 		priv->hw->desc = &enh_desc_ops;
144819e30c14SGiuseppe CAVALLARO 	} else {
144919e30c14SGiuseppe CAVALLARO 		pr_info(" Normal descriptors\n");
145019e30c14SGiuseppe CAVALLARO 		priv->hw->desc = &ndesc_ops;
145119e30c14SGiuseppe CAVALLARO 	}
145219e30c14SGiuseppe CAVALLARO }
145319e30c14SGiuseppe CAVALLARO 
145419e30c14SGiuseppe CAVALLARO /**
145532ceabcaSGiuseppe CAVALLARO  * stmmac_get_hw_features: get MAC capabilities from the HW cap. register.
145632ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
145719e30c14SGiuseppe CAVALLARO  * Description:
145819e30c14SGiuseppe CAVALLARO  *  new GMAC chip generations have a new register to indicate the
1459e7434821SGiuseppe CAVALLARO  *  presence of the optional feature/functions.
146019e30c14SGiuseppe CAVALLARO  *  This can be also used to override the value passed through the
146119e30c14SGiuseppe CAVALLARO  *  platform and necessary for old MAC10/100 and GMAC chips.
1462e7434821SGiuseppe CAVALLARO  */
1463e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv)
1464e7434821SGiuseppe CAVALLARO {
14655e6efe88SGiuseppe CAVALLARO 	u32 hw_cap = 0;
14663c20f72fSGiuseppe CAVALLARO 
14675e6efe88SGiuseppe CAVALLARO 	if (priv->hw->dma->get_hw_feature) {
14685e6efe88SGiuseppe CAVALLARO 		hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr);
1469e7434821SGiuseppe CAVALLARO 
14701db123fbSRayagond Kokatanur 		priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
14711db123fbSRayagond Kokatanur 		priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
14721db123fbSRayagond Kokatanur 		priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
14731db123fbSRayagond Kokatanur 		priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
1474ceb69499SGiuseppe CAVALLARO 		priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5;
14751db123fbSRayagond Kokatanur 		priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
14761db123fbSRayagond Kokatanur 		priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
14771db123fbSRayagond Kokatanur 		priv->dma_cap.pmt_remote_wake_up =
14781db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
14791db123fbSRayagond Kokatanur 		priv->dma_cap.pmt_magic_frame =
14801db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
14811db123fbSRayagond Kokatanur 		/* MMC */
14821db123fbSRayagond Kokatanur 		priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
1483e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2002 */
14841db123fbSRayagond Kokatanur 		priv->dma_cap.time_stamp =
14851db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
1486e7434821SGiuseppe CAVALLARO 		/* IEEE 1588-2008 */
14871db123fbSRayagond Kokatanur 		priv->dma_cap.atime_stamp =
14881db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
1489e7434821SGiuseppe CAVALLARO 		/* 802.3az - Energy-Efficient Ethernet (EEE) */
14901db123fbSRayagond Kokatanur 		priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
14911db123fbSRayagond Kokatanur 		priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
1492e7434821SGiuseppe CAVALLARO 		/* TX and RX csum */
14931db123fbSRayagond Kokatanur 		priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
14941db123fbSRayagond Kokatanur 		priv->dma_cap.rx_coe_type1 =
14951db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
14961db123fbSRayagond Kokatanur 		priv->dma_cap.rx_coe_type2 =
14971db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
14981db123fbSRayagond Kokatanur 		priv->dma_cap.rxfifo_over_2048 =
14991db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
1500e7434821SGiuseppe CAVALLARO 		/* TX and RX number of channels */
15011db123fbSRayagond Kokatanur 		priv->dma_cap.number_rx_channel =
15021db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
15031db123fbSRayagond Kokatanur 		priv->dma_cap.number_tx_channel =
15041db123fbSRayagond Kokatanur 		    (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
1505e7434821SGiuseppe CAVALLARO 		/* Alternate (enhanced) DESC mode */
1506ceb69499SGiuseppe CAVALLARO 		priv->dma_cap.enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
150719e30c14SGiuseppe CAVALLARO 	}
1508e7434821SGiuseppe CAVALLARO 
1509e7434821SGiuseppe CAVALLARO 	return hw_cap;
1510e7434821SGiuseppe CAVALLARO }
1511e7434821SGiuseppe CAVALLARO 
151232ceabcaSGiuseppe CAVALLARO /**
151332ceabcaSGiuseppe CAVALLARO  * stmmac_check_ether_addr: check if the MAC addr is valid
151432ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
151532ceabcaSGiuseppe CAVALLARO  * Description:
151632ceabcaSGiuseppe CAVALLARO  * it is to verify if the MAC address is valid, in case of failures it
151732ceabcaSGiuseppe CAVALLARO  * generates a random MAC address
151832ceabcaSGiuseppe CAVALLARO  */
1519bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv)
1520bfab27a1SGiuseppe CAVALLARO {
1521bfab27a1SGiuseppe CAVALLARO 	if (!is_valid_ether_addr(priv->dev->dev_addr)) {
1522bfab27a1SGiuseppe CAVALLARO 		priv->hw->mac->get_umac_addr((void __iomem *)
1523bfab27a1SGiuseppe CAVALLARO 					     priv->dev->base_addr,
1524bfab27a1SGiuseppe CAVALLARO 					     priv->dev->dev_addr, 0);
1525bfab27a1SGiuseppe CAVALLARO 		if (!is_valid_ether_addr(priv->dev->dev_addr))
1526f2cedb63SDanny Kukawka 			eth_hw_addr_random(priv->dev);
1527bfab27a1SGiuseppe CAVALLARO 	}
1528ceb69499SGiuseppe CAVALLARO 	pr_warn("%s: device MAC address %pM\n", priv->dev->name,
1529bfab27a1SGiuseppe CAVALLARO 		priv->dev->dev_addr);
1530bfab27a1SGiuseppe CAVALLARO }
1531bfab27a1SGiuseppe CAVALLARO 
153232ceabcaSGiuseppe CAVALLARO /**
153332ceabcaSGiuseppe CAVALLARO  * stmmac_init_dma_engine: DMA init.
153432ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
153532ceabcaSGiuseppe CAVALLARO  * Description:
153632ceabcaSGiuseppe CAVALLARO  * It inits the DMA invoking the specific MAC/GMAC callback.
153732ceabcaSGiuseppe CAVALLARO  * Some DMA parameters can be passed from the platform;
153832ceabcaSGiuseppe CAVALLARO  * in case of these are not passed a default is kept for the MAC or GMAC.
153932ceabcaSGiuseppe CAVALLARO  */
15400f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv)
15410f1f88a8SGiuseppe CAVALLARO {
15420f1f88a8SGiuseppe CAVALLARO 	int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
1543b9cde0a8SGiuseppe CAVALLARO 	int mixed_burst = 0;
1544c24602efSGiuseppe CAVALLARO 	int atds = 0;
15450f1f88a8SGiuseppe CAVALLARO 
15460f1f88a8SGiuseppe CAVALLARO 	if (priv->plat->dma_cfg) {
15470f1f88a8SGiuseppe CAVALLARO 		pbl = priv->plat->dma_cfg->pbl;
15480f1f88a8SGiuseppe CAVALLARO 		fixed_burst = priv->plat->dma_cfg->fixed_burst;
1549b9cde0a8SGiuseppe CAVALLARO 		mixed_burst = priv->plat->dma_cfg->mixed_burst;
15500f1f88a8SGiuseppe CAVALLARO 		burst_len = priv->plat->dma_cfg->burst_len;
15510f1f88a8SGiuseppe CAVALLARO 	}
15520f1f88a8SGiuseppe CAVALLARO 
1553c24602efSGiuseppe CAVALLARO 	if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE))
1554c24602efSGiuseppe CAVALLARO 		atds = 1;
1555c24602efSGiuseppe CAVALLARO 
1556b9cde0a8SGiuseppe CAVALLARO 	return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
15570f1f88a8SGiuseppe CAVALLARO 				   burst_len, priv->dma_tx_phy,
1558c24602efSGiuseppe CAVALLARO 				   priv->dma_rx_phy, atds);
15590f1f88a8SGiuseppe CAVALLARO }
15600f1f88a8SGiuseppe CAVALLARO 
1561bfab27a1SGiuseppe CAVALLARO /**
156232ceabcaSGiuseppe CAVALLARO  * stmmac_tx_timer: mitigation sw timer for tx.
15639125cdd1SGiuseppe CAVALLARO  * @data: data pointer
15649125cdd1SGiuseppe CAVALLARO  * Description:
15659125cdd1SGiuseppe CAVALLARO  * This is the timer handler to directly invoke the stmmac_tx_clean.
15669125cdd1SGiuseppe CAVALLARO  */
15679125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data)
15689125cdd1SGiuseppe CAVALLARO {
15699125cdd1SGiuseppe CAVALLARO 	struct stmmac_priv *priv = (struct stmmac_priv *)data;
15709125cdd1SGiuseppe CAVALLARO 
15719125cdd1SGiuseppe CAVALLARO 	stmmac_tx_clean(priv);
15729125cdd1SGiuseppe CAVALLARO }
15739125cdd1SGiuseppe CAVALLARO 
15749125cdd1SGiuseppe CAVALLARO /**
157532ceabcaSGiuseppe CAVALLARO  * stmmac_init_tx_coalesce: init tx mitigation options.
157632ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
15779125cdd1SGiuseppe CAVALLARO  * Description:
15789125cdd1SGiuseppe CAVALLARO  * This inits the transmit coalesce parameters: i.e. timer rate,
15799125cdd1SGiuseppe CAVALLARO  * timer handler and default threshold used for enabling the
15809125cdd1SGiuseppe CAVALLARO  * interrupt on completion bit.
15819125cdd1SGiuseppe CAVALLARO  */
15829125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
15839125cdd1SGiuseppe CAVALLARO {
15849125cdd1SGiuseppe CAVALLARO 	priv->tx_coal_frames = STMMAC_TX_FRAMES;
15859125cdd1SGiuseppe CAVALLARO 	priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
15869125cdd1SGiuseppe CAVALLARO 	init_timer(&priv->txtimer);
15879125cdd1SGiuseppe CAVALLARO 	priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer);
15889125cdd1SGiuseppe CAVALLARO 	priv->txtimer.data = (unsigned long)priv;
15899125cdd1SGiuseppe CAVALLARO 	priv->txtimer.function = stmmac_tx_timer;
15909125cdd1SGiuseppe CAVALLARO 	add_timer(&priv->txtimer);
15919125cdd1SGiuseppe CAVALLARO }
15929125cdd1SGiuseppe CAVALLARO 
15939125cdd1SGiuseppe CAVALLARO /**
15947ac6653aSJeff Kirsher  *  stmmac_open - open entry point of the driver
15957ac6653aSJeff Kirsher  *  @dev : pointer to the device structure.
15967ac6653aSJeff Kirsher  *  Description:
15977ac6653aSJeff Kirsher  *  This function is the open entry point of the driver.
15987ac6653aSJeff Kirsher  *  Return value:
15997ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
16007ac6653aSJeff Kirsher  *  file on failure.
16017ac6653aSJeff Kirsher  */
16027ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev)
16037ac6653aSJeff Kirsher {
16047ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
16057ac6653aSJeff Kirsher 	int ret;
16067ac6653aSJeff Kirsher 
1607a630844dSStefan Roese 	clk_prepare_enable(priv->stmmac_clk);
16084bfcbd7aSFrancesco Virlinzi 
16094bfcbd7aSFrancesco Virlinzi 	stmmac_check_ether_addr(priv);
16104bfcbd7aSFrancesco Virlinzi 
16114d8f0825SByungho An 	if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
16124d8f0825SByungho An 	    priv->pcs != STMMAC_PCS_RTBI) {
16137ac6653aSJeff Kirsher 		ret = stmmac_init_phy(dev);
1614e58bb43fSGiuseppe CAVALLARO 		if (ret) {
1615e58bb43fSGiuseppe CAVALLARO 			pr_err("%s: Cannot attach to PHY (error: %d)\n",
1616e58bb43fSGiuseppe CAVALLARO 			       __func__, ret);
1617c9324d18SGiuseppe CAVALLARO 			goto phy_error;
16187ac6653aSJeff Kirsher 		}
1619e58bb43fSGiuseppe CAVALLARO 	}
16207ac6653aSJeff Kirsher 
16217ac6653aSJeff Kirsher 	/* Create and initialize the TX/RX descriptors chains. */
16227ac6653aSJeff Kirsher 	priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
16237ac6653aSJeff Kirsher 	priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
16247ac6653aSJeff Kirsher 	priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
162556329137SBartlomiej Zolnierkiewicz 
162656329137SBartlomiej Zolnierkiewicz 	ret = init_dma_desc_rings(dev);
162756329137SBartlomiej Zolnierkiewicz 	if (ret < 0) {
162856329137SBartlomiej Zolnierkiewicz 		pr_err("%s: DMA descriptors initialization failed\n", __func__);
162956329137SBartlomiej Zolnierkiewicz 		goto dma_desc_error;
163056329137SBartlomiej Zolnierkiewicz 	}
16317ac6653aSJeff Kirsher 
16327ac6653aSJeff Kirsher 	/* DMA initialization and SW reset */
16330f1f88a8SGiuseppe CAVALLARO 	ret = stmmac_init_dma_engine(priv);
16347ac6653aSJeff Kirsher 	if (ret < 0) {
163556329137SBartlomiej Zolnierkiewicz 		pr_err("%s: DMA engine initialization failed\n", __func__);
1636c9324d18SGiuseppe CAVALLARO 		goto init_error;
16377ac6653aSJeff Kirsher 	}
16387ac6653aSJeff Kirsher 
16397ac6653aSJeff Kirsher 	/* Copy the MAC addr into the HW  */
16407ac6653aSJeff Kirsher 	priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
1641cf3f047bSGiuseppe CAVALLARO 
16427ac6653aSJeff Kirsher 	/* If required, perform hw setup of the bus. */
16437ac6653aSJeff Kirsher 	if (priv->plat->bus_setup)
16447ac6653aSJeff Kirsher 		priv->plat->bus_setup(priv->ioaddr);
1645cf3f047bSGiuseppe CAVALLARO 
16467ac6653aSJeff Kirsher 	/* Initialize the MAC Core */
16477ac6653aSJeff Kirsher 	priv->hw->mac->core_init(priv->ioaddr);
16487ac6653aSJeff Kirsher 
16497ac6653aSJeff Kirsher 	/* Request the IRQ lines */
16507ac6653aSJeff Kirsher 	ret = request_irq(dev->irq, stmmac_interrupt,
16517ac6653aSJeff Kirsher 			  IRQF_SHARED, dev->name, dev);
16527ac6653aSJeff Kirsher 	if (unlikely(ret < 0)) {
16537ac6653aSJeff Kirsher 		pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
16547ac6653aSJeff Kirsher 		       __func__, dev->irq, ret);
1655c9324d18SGiuseppe CAVALLARO 		goto init_error;
16567ac6653aSJeff Kirsher 	}
16577ac6653aSJeff Kirsher 
16587a13f8f5SFrancesco Virlinzi 	/* Request the Wake IRQ in case of another line is used for WoL */
16597a13f8f5SFrancesco Virlinzi 	if (priv->wol_irq != dev->irq) {
16607a13f8f5SFrancesco Virlinzi 		ret = request_irq(priv->wol_irq, stmmac_interrupt,
16617a13f8f5SFrancesco Virlinzi 				  IRQF_SHARED, dev->name, dev);
16627a13f8f5SFrancesco Virlinzi 		if (unlikely(ret < 0)) {
1663ceb69499SGiuseppe CAVALLARO 			pr_err("%s: ERROR: allocating the WoL IRQ %d (%d)\n",
1664ceb69499SGiuseppe CAVALLARO 			       __func__, priv->wol_irq, ret);
1665c9324d18SGiuseppe CAVALLARO 			goto wolirq_error;
16667a13f8f5SFrancesco Virlinzi 		}
16677a13f8f5SFrancesco Virlinzi 	}
16687a13f8f5SFrancesco Virlinzi 
1669d765955dSGiuseppe CAVALLARO 	/* Request the IRQ lines */
1670d765955dSGiuseppe CAVALLARO 	if (priv->lpi_irq != -ENXIO) {
1671d765955dSGiuseppe CAVALLARO 		ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED,
1672d765955dSGiuseppe CAVALLARO 				  dev->name, dev);
1673d765955dSGiuseppe CAVALLARO 		if (unlikely(ret < 0)) {
1674d765955dSGiuseppe CAVALLARO 			pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n",
1675d765955dSGiuseppe CAVALLARO 			       __func__, priv->lpi_irq, ret);
1676c9324d18SGiuseppe CAVALLARO 			goto lpiirq_error;
1677d765955dSGiuseppe CAVALLARO 		}
1678d765955dSGiuseppe CAVALLARO 	}
1679d765955dSGiuseppe CAVALLARO 
16807ac6653aSJeff Kirsher 	/* Enable the MAC Rx/Tx */
1681bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, true);
16827ac6653aSJeff Kirsher 
16837ac6653aSJeff Kirsher 	/* Set the HW DMA mode and the COE */
16847ac6653aSJeff Kirsher 	stmmac_dma_operation_mode(priv);
16857ac6653aSJeff Kirsher 
16867ac6653aSJeff Kirsher 	/* Extra statistics */
16877ac6653aSJeff Kirsher 	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
16887ac6653aSJeff Kirsher 	priv->xstats.threshold = tc;
16897ac6653aSJeff Kirsher 
16901c901a46SGiuseppe CAVALLARO 	stmmac_mmc_setup(priv);
16911c901a46SGiuseppe CAVALLARO 
169292ba6888SRayagond Kokatanur 	ret = stmmac_init_ptp(priv);
169392ba6888SRayagond Kokatanur 	if (ret)
169492ba6888SRayagond Kokatanur 		pr_warn("%s: failed PTP initialisation\n", __func__);
1695891434b1SRayagond Kokatanur 
1696bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
1697bfab27a1SGiuseppe CAVALLARO 	ret = stmmac_init_fs(dev);
1698bfab27a1SGiuseppe CAVALLARO 	if (ret < 0)
1699ceb69499SGiuseppe CAVALLARO 		pr_warn("%s: failed debugFS registration\n", __func__);
1700bfab27a1SGiuseppe CAVALLARO #endif
17017ac6653aSJeff Kirsher 	/* Start the ball rolling... */
170283d7af64SGiuseppe CAVALLARO 	pr_debug("%s: DMA RX/TX processes started...\n", dev->name);
17037ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
17047ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
17057ac6653aSJeff Kirsher 
17067ac6653aSJeff Kirsher 	/* Dump DMA/MAC registers */
17077ac6653aSJeff Kirsher 	if (netif_msg_hw(priv)) {
17087ac6653aSJeff Kirsher 		priv->hw->mac->dump_regs(priv->ioaddr);
17097ac6653aSJeff Kirsher 		priv->hw->dma->dump_regs(priv->ioaddr);
17107ac6653aSJeff Kirsher 	}
17117ac6653aSJeff Kirsher 
17127ac6653aSJeff Kirsher 	if (priv->phydev)
17137ac6653aSJeff Kirsher 		phy_start(priv->phydev);
17147ac6653aSJeff Kirsher 
1715f5351ef7SGiuseppe CAVALLARO 	priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
1716e58bb43fSGiuseppe CAVALLARO 
1717d765955dSGiuseppe CAVALLARO 	priv->eee_enabled = stmmac_eee_init(priv);
1718d765955dSGiuseppe CAVALLARO 
17199125cdd1SGiuseppe CAVALLARO 	stmmac_init_tx_coalesce(priv);
17209125cdd1SGiuseppe CAVALLARO 
172162a2ab93SGiuseppe CAVALLARO 	if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
172262a2ab93SGiuseppe CAVALLARO 		priv->rx_riwt = MAX_DMA_RIWT;
172362a2ab93SGiuseppe CAVALLARO 		priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT);
172462a2ab93SGiuseppe CAVALLARO 	}
172562a2ab93SGiuseppe CAVALLARO 
1726e58bb43fSGiuseppe CAVALLARO 	if (priv->pcs && priv->hw->mac->ctrl_ane)
1727e58bb43fSGiuseppe CAVALLARO 		priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
1728e58bb43fSGiuseppe CAVALLARO 
17297ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
17307ac6653aSJeff Kirsher 	netif_start_queue(dev);
17317ac6653aSJeff Kirsher 
17327ac6653aSJeff Kirsher 	return 0;
17337ac6653aSJeff Kirsher 
1734c9324d18SGiuseppe CAVALLARO lpiirq_error:
1735d765955dSGiuseppe CAVALLARO 	if (priv->wol_irq != dev->irq)
1736d765955dSGiuseppe CAVALLARO 		free_irq(priv->wol_irq, dev);
1737c9324d18SGiuseppe CAVALLARO wolirq_error:
17387a13f8f5SFrancesco Virlinzi 	free_irq(dev->irq, dev);
17397a13f8f5SFrancesco Virlinzi 
1740c9324d18SGiuseppe CAVALLARO init_error:
1741c9324d18SGiuseppe CAVALLARO 	free_dma_desc_resources(priv);
174256329137SBartlomiej Zolnierkiewicz dma_desc_error:
17437ac6653aSJeff Kirsher 	if (priv->phydev)
17447ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
1745c9324d18SGiuseppe CAVALLARO phy_error:
1746a630844dSStefan Roese 	clk_disable_unprepare(priv->stmmac_clk);
17474bfcbd7aSFrancesco Virlinzi 
17487ac6653aSJeff Kirsher 	return ret;
17497ac6653aSJeff Kirsher }
17507ac6653aSJeff Kirsher 
17517ac6653aSJeff Kirsher /**
17527ac6653aSJeff Kirsher  *  stmmac_release - close entry point of the driver
17537ac6653aSJeff Kirsher  *  @dev : device pointer.
17547ac6653aSJeff Kirsher  *  Description:
17557ac6653aSJeff Kirsher  *  This is the stop entry point of the driver.
17567ac6653aSJeff Kirsher  */
17577ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev)
17587ac6653aSJeff Kirsher {
17597ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
17607ac6653aSJeff Kirsher 
1761d765955dSGiuseppe CAVALLARO 	if (priv->eee_enabled)
1762d765955dSGiuseppe CAVALLARO 		del_timer_sync(&priv->eee_ctrl_timer);
1763d765955dSGiuseppe CAVALLARO 
17647ac6653aSJeff Kirsher 	/* Stop and disconnect the PHY */
17657ac6653aSJeff Kirsher 	if (priv->phydev) {
17667ac6653aSJeff Kirsher 		phy_stop(priv->phydev);
17677ac6653aSJeff Kirsher 		phy_disconnect(priv->phydev);
17687ac6653aSJeff Kirsher 		priv->phydev = NULL;
17697ac6653aSJeff Kirsher 	}
17707ac6653aSJeff Kirsher 
17717ac6653aSJeff Kirsher 	netif_stop_queue(dev);
17727ac6653aSJeff Kirsher 
17737ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
17747ac6653aSJeff Kirsher 
17759125cdd1SGiuseppe CAVALLARO 	del_timer_sync(&priv->txtimer);
17769125cdd1SGiuseppe CAVALLARO 
17777ac6653aSJeff Kirsher 	/* Free the IRQ lines */
17787ac6653aSJeff Kirsher 	free_irq(dev->irq, dev);
17797a13f8f5SFrancesco Virlinzi 	if (priv->wol_irq != dev->irq)
17807a13f8f5SFrancesco Virlinzi 		free_irq(priv->wol_irq, dev);
1781d765955dSGiuseppe CAVALLARO 	if (priv->lpi_irq != -ENXIO)
1782d765955dSGiuseppe CAVALLARO 		free_irq(priv->lpi_irq, dev);
17837ac6653aSJeff Kirsher 
17847ac6653aSJeff Kirsher 	/* Stop TX/RX DMA and clear the descriptors */
17857ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
17867ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
17877ac6653aSJeff Kirsher 
17887ac6653aSJeff Kirsher 	/* Release and free the Rx/Tx resources */
17897ac6653aSJeff Kirsher 	free_dma_desc_resources(priv);
17907ac6653aSJeff Kirsher 
17917ac6653aSJeff Kirsher 	/* Disable the MAC Rx/Tx */
1792bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, false);
17937ac6653aSJeff Kirsher 
17947ac6653aSJeff Kirsher 	netif_carrier_off(dev);
17957ac6653aSJeff Kirsher 
1796bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
1797bfab27a1SGiuseppe CAVALLARO 	stmmac_exit_fs();
1798bfab27a1SGiuseppe CAVALLARO #endif
1799a630844dSStefan Roese 	clk_disable_unprepare(priv->stmmac_clk);
1800bfab27a1SGiuseppe CAVALLARO 
180192ba6888SRayagond Kokatanur 	stmmac_release_ptp(priv);
180292ba6888SRayagond Kokatanur 
18037ac6653aSJeff Kirsher 	return 0;
18047ac6653aSJeff Kirsher }
18057ac6653aSJeff Kirsher 
18067ac6653aSJeff Kirsher /**
180732ceabcaSGiuseppe CAVALLARO  *  stmmac_xmit: Tx entry point of the driver
18087ac6653aSJeff Kirsher  *  @skb : the socket buffer
18097ac6653aSJeff Kirsher  *  @dev : device pointer
181032ceabcaSGiuseppe CAVALLARO  *  Description : this is the tx entry point of the driver.
181132ceabcaSGiuseppe CAVALLARO  *  It programs the chain or the ring and supports oversized frames
181232ceabcaSGiuseppe CAVALLARO  *  and SG feature.
18137ac6653aSJeff Kirsher  */
18147ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
18157ac6653aSJeff Kirsher {
18167ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
18177ac6653aSJeff Kirsher 	unsigned int txsize = priv->dma_tx_size;
18187ac6653aSJeff Kirsher 	unsigned int entry;
18194a7d666aSGiuseppe CAVALLARO 	int i, csum_insertion = 0, is_jumbo = 0;
18207ac6653aSJeff Kirsher 	int nfrags = skb_shinfo(skb)->nr_frags;
18217ac6653aSJeff Kirsher 	struct dma_desc *desc, *first;
1822286a8372SGiuseppe CAVALLARO 	unsigned int nopaged_len = skb_headlen(skb);
18237ac6653aSJeff Kirsher 
18247ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
18257ac6653aSJeff Kirsher 		if (!netif_queue_stopped(dev)) {
18267ac6653aSJeff Kirsher 			netif_stop_queue(dev);
18277ac6653aSJeff Kirsher 			/* This is a hard error, log it. */
1828ceb69499SGiuseppe CAVALLARO 			pr_err("%s: Tx Ring full when queue awake\n", __func__);
18297ac6653aSJeff Kirsher 		}
18307ac6653aSJeff Kirsher 		return NETDEV_TX_BUSY;
18317ac6653aSJeff Kirsher 	}
18327ac6653aSJeff Kirsher 
1833a9097a96SGiuseppe CAVALLARO 	spin_lock(&priv->tx_lock);
1834a9097a96SGiuseppe CAVALLARO 
1835d765955dSGiuseppe CAVALLARO 	if (priv->tx_path_in_lpi_mode)
1836d765955dSGiuseppe CAVALLARO 		stmmac_disable_eee_mode(priv);
1837d765955dSGiuseppe CAVALLARO 
18387ac6653aSJeff Kirsher 	entry = priv->cur_tx % txsize;
18397ac6653aSJeff Kirsher 
18407ac6653aSJeff Kirsher 	csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
18417ac6653aSJeff Kirsher 
1842c24602efSGiuseppe CAVALLARO 	if (priv->extend_desc)
1843c24602efSGiuseppe CAVALLARO 		desc = (struct dma_desc *)(priv->dma_etx + entry);
1844c24602efSGiuseppe CAVALLARO 	else
18457ac6653aSJeff Kirsher 		desc = priv->dma_tx + entry;
1846c24602efSGiuseppe CAVALLARO 
18477ac6653aSJeff Kirsher 	first = desc;
18487ac6653aSJeff Kirsher 
18497ac6653aSJeff Kirsher 	priv->tx_skbuff[entry] = skb;
1850286a8372SGiuseppe CAVALLARO 
18514a7d666aSGiuseppe CAVALLARO 	/* To program the descriptors according to the size of the frame */
18524a7d666aSGiuseppe CAVALLARO 	if (priv->mode == STMMAC_RING_MODE) {
18534a7d666aSGiuseppe CAVALLARO 		is_jumbo = priv->hw->ring->is_jumbo_frm(skb->len,
18544a7d666aSGiuseppe CAVALLARO 							priv->plat->enh_desc);
18554a7d666aSGiuseppe CAVALLARO 		if (unlikely(is_jumbo))
18564a7d666aSGiuseppe CAVALLARO 			entry = priv->hw->ring->jumbo_frm(priv, skb,
18574a7d666aSGiuseppe CAVALLARO 							  csum_insertion);
18587ac6653aSJeff Kirsher 	} else {
18594a7d666aSGiuseppe CAVALLARO 		is_jumbo = priv->hw->chain->is_jumbo_frm(skb->len,
18604a7d666aSGiuseppe CAVALLARO 							 priv->plat->enh_desc);
18614a7d666aSGiuseppe CAVALLARO 		if (unlikely(is_jumbo))
18624a7d666aSGiuseppe CAVALLARO 			entry = priv->hw->chain->jumbo_frm(priv, skb,
18634a7d666aSGiuseppe CAVALLARO 							   csum_insertion);
18644a7d666aSGiuseppe CAVALLARO 	}
18654a7d666aSGiuseppe CAVALLARO 	if (likely(!is_jumbo)) {
18667ac6653aSJeff Kirsher 		desc->des2 = dma_map_single(priv->device, skb->data,
18677ac6653aSJeff Kirsher 					    nopaged_len, DMA_TO_DEVICE);
1868cf32deecSRayagond Kokatanur 		priv->tx_skbuff_dma[entry] = desc->des2;
18697ac6653aSJeff Kirsher 		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
18704a7d666aSGiuseppe CAVALLARO 						csum_insertion, priv->mode);
18714a7d666aSGiuseppe CAVALLARO 	} else
1872c24602efSGiuseppe CAVALLARO 		desc = first;
18737ac6653aSJeff Kirsher 
18747ac6653aSJeff Kirsher 	for (i = 0; i < nfrags; i++) {
18759e903e08SEric Dumazet 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
18769e903e08SEric Dumazet 		int len = skb_frag_size(frag);
18777ac6653aSJeff Kirsher 
18787ac6653aSJeff Kirsher 		entry = (++priv->cur_tx) % txsize;
1879c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1880c24602efSGiuseppe CAVALLARO 			desc = (struct dma_desc *)(priv->dma_etx + entry);
1881c24602efSGiuseppe CAVALLARO 		else
18827ac6653aSJeff Kirsher 			desc = priv->dma_tx + entry;
18837ac6653aSJeff Kirsher 
1884f722380dSIan Campbell 		desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
1885f722380dSIan Campbell 					      DMA_TO_DEVICE);
1886cf32deecSRayagond Kokatanur 		priv->tx_skbuff_dma[entry] = desc->des2;
18877ac6653aSJeff Kirsher 		priv->tx_skbuff[entry] = NULL;
18884a7d666aSGiuseppe CAVALLARO 		priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion,
18894a7d666aSGiuseppe CAVALLARO 						priv->mode);
18907ac6653aSJeff Kirsher 		wmb();
18917ac6653aSJeff Kirsher 		priv->hw->desc->set_tx_owner(desc);
18928e839891SDeepak Sikri 		wmb();
18937ac6653aSJeff Kirsher 	}
18947ac6653aSJeff Kirsher 
18959125cdd1SGiuseppe CAVALLARO 	/* Finalize the latest segment. */
18967ac6653aSJeff Kirsher 	priv->hw->desc->close_tx_desc(desc);
18977ac6653aSJeff Kirsher 
18987ac6653aSJeff Kirsher 	wmb();
18999125cdd1SGiuseppe CAVALLARO 	/* According to the coalesce parameter the IC bit for the latest
19009125cdd1SGiuseppe CAVALLARO 	 * segment could be reset and the timer re-started to invoke the
19019125cdd1SGiuseppe CAVALLARO 	 * stmmac_tx function. This approach takes care about the fragments.
19029125cdd1SGiuseppe CAVALLARO 	 */
19039125cdd1SGiuseppe CAVALLARO 	priv->tx_count_frames += nfrags + 1;
19049125cdd1SGiuseppe CAVALLARO 	if (priv->tx_coal_frames > priv->tx_count_frames) {
19059125cdd1SGiuseppe CAVALLARO 		priv->hw->desc->clear_tx_ic(desc);
19069125cdd1SGiuseppe CAVALLARO 		priv->xstats.tx_reset_ic_bit++;
19079125cdd1SGiuseppe CAVALLARO 		mod_timer(&priv->txtimer,
19089125cdd1SGiuseppe CAVALLARO 			  STMMAC_COAL_TIMER(priv->tx_coal_timer));
19099125cdd1SGiuseppe CAVALLARO 	} else
19109125cdd1SGiuseppe CAVALLARO 		priv->tx_count_frames = 0;
19117ac6653aSJeff Kirsher 
19127ac6653aSJeff Kirsher 	/* To avoid raise condition */
19137ac6653aSJeff Kirsher 	priv->hw->desc->set_tx_owner(first);
19148e839891SDeepak Sikri 	wmb();
19157ac6653aSJeff Kirsher 
19167ac6653aSJeff Kirsher 	priv->cur_tx++;
19177ac6653aSJeff Kirsher 
19187ac6653aSJeff Kirsher 	if (netif_msg_pktdata(priv)) {
191983d7af64SGiuseppe CAVALLARO 		pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d",
1920ceb69499SGiuseppe CAVALLARO 			__func__, (priv->cur_tx % txsize),
1921ceb69499SGiuseppe CAVALLARO 			(priv->dirty_tx % txsize), entry, first, nfrags);
192283d7af64SGiuseppe CAVALLARO 
1923c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1924c24602efSGiuseppe CAVALLARO 			stmmac_display_ring((void *)priv->dma_etx, txsize, 1);
1925c24602efSGiuseppe CAVALLARO 		else
1926c24602efSGiuseppe CAVALLARO 			stmmac_display_ring((void *)priv->dma_tx, txsize, 0);
1927c24602efSGiuseppe CAVALLARO 
192883d7af64SGiuseppe CAVALLARO 		pr_debug(">>> frame to be transmitted: ");
19297ac6653aSJeff Kirsher 		print_pkt(skb->data, skb->len);
19307ac6653aSJeff Kirsher 	}
19317ac6653aSJeff Kirsher 	if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
193283d7af64SGiuseppe CAVALLARO 		if (netif_msg_hw(priv))
193383d7af64SGiuseppe CAVALLARO 			pr_debug("%s: stop transmitted packets\n", __func__);
19347ac6653aSJeff Kirsher 		netif_stop_queue(dev);
19357ac6653aSJeff Kirsher 	}
19367ac6653aSJeff Kirsher 
19377ac6653aSJeff Kirsher 	dev->stats.tx_bytes += skb->len;
19387ac6653aSJeff Kirsher 
1939891434b1SRayagond Kokatanur 	if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
1940891434b1SRayagond Kokatanur 		     priv->hwts_tx_en)) {
1941891434b1SRayagond Kokatanur 		/* declare that device is doing timestamping */
1942891434b1SRayagond Kokatanur 		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
1943891434b1SRayagond Kokatanur 		priv->hw->desc->enable_tx_timestamp(first);
1944891434b1SRayagond Kokatanur 	}
1945891434b1SRayagond Kokatanur 
1946891434b1SRayagond Kokatanur 	if (!priv->hwts_tx_en)
19477ac6653aSJeff Kirsher 		skb_tx_timestamp(skb);
19487ac6653aSJeff Kirsher 
19497ac6653aSJeff Kirsher 	priv->hw->dma->enable_dma_transmission(priv->ioaddr);
19507ac6653aSJeff Kirsher 
1951a9097a96SGiuseppe CAVALLARO 	spin_unlock(&priv->tx_lock);
1952a9097a96SGiuseppe CAVALLARO 
19537ac6653aSJeff Kirsher 	return NETDEV_TX_OK;
19547ac6653aSJeff Kirsher }
19557ac6653aSJeff Kirsher 
195632ceabcaSGiuseppe CAVALLARO /**
195732ceabcaSGiuseppe CAVALLARO  * stmmac_rx_refill: refill used skb preallocated buffers
195832ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
195932ceabcaSGiuseppe CAVALLARO  * Description : this is to reallocate the skb for the reception process
196032ceabcaSGiuseppe CAVALLARO  * that is based on zero-copy.
196132ceabcaSGiuseppe CAVALLARO  */
19627ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv)
19637ac6653aSJeff Kirsher {
19647ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
19657ac6653aSJeff Kirsher 	int bfsize = priv->dma_buf_sz;
19667ac6653aSJeff Kirsher 
19677ac6653aSJeff Kirsher 	for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
19687ac6653aSJeff Kirsher 		unsigned int entry = priv->dirty_rx % rxsize;
1969c24602efSGiuseppe CAVALLARO 		struct dma_desc *p;
1970c24602efSGiuseppe CAVALLARO 
1971c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
1972c24602efSGiuseppe CAVALLARO 			p = (struct dma_desc *)(priv->dma_erx + entry);
1973c24602efSGiuseppe CAVALLARO 		else
1974c24602efSGiuseppe CAVALLARO 			p = priv->dma_rx + entry;
1975c24602efSGiuseppe CAVALLARO 
19767ac6653aSJeff Kirsher 		if (likely(priv->rx_skbuff[entry] == NULL)) {
19777ac6653aSJeff Kirsher 			struct sk_buff *skb;
19787ac6653aSJeff Kirsher 
1979acb600deSEric Dumazet 			skb = netdev_alloc_skb_ip_align(priv->dev, bfsize);
19807ac6653aSJeff Kirsher 
19817ac6653aSJeff Kirsher 			if (unlikely(skb == NULL))
19827ac6653aSJeff Kirsher 				break;
19837ac6653aSJeff Kirsher 
19847ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = skb;
19857ac6653aSJeff Kirsher 			priv->rx_skbuff_dma[entry] =
19867ac6653aSJeff Kirsher 			    dma_map_single(priv->device, skb->data, bfsize,
19877ac6653aSJeff Kirsher 					   DMA_FROM_DEVICE);
19887ac6653aSJeff Kirsher 
1989c24602efSGiuseppe CAVALLARO 			p->des2 = priv->rx_skbuff_dma[entry];
1990286a8372SGiuseppe CAVALLARO 
1991891434b1SRayagond Kokatanur 			priv->hw->ring->refill_desc3(priv, p);
1992286a8372SGiuseppe CAVALLARO 
199383d7af64SGiuseppe CAVALLARO 			if (netif_msg_rx_status(priv))
199483d7af64SGiuseppe CAVALLARO 				pr_debug("\trefill entry #%d\n", entry);
19957ac6653aSJeff Kirsher 		}
19967ac6653aSJeff Kirsher 		wmb();
1997c24602efSGiuseppe CAVALLARO 		priv->hw->desc->set_rx_owner(p);
19988e839891SDeepak Sikri 		wmb();
19997ac6653aSJeff Kirsher 	}
20007ac6653aSJeff Kirsher }
20017ac6653aSJeff Kirsher 
200232ceabcaSGiuseppe CAVALLARO /**
200332ceabcaSGiuseppe CAVALLARO  * stmmac_rx_refill: refill used skb preallocated buffers
200432ceabcaSGiuseppe CAVALLARO  * @priv: driver private structure
200532ceabcaSGiuseppe CAVALLARO  * @limit: napi bugget.
200632ceabcaSGiuseppe CAVALLARO  * Description :  this the function called by the napi poll method.
200732ceabcaSGiuseppe CAVALLARO  * It gets all the frames inside the ring.
200832ceabcaSGiuseppe CAVALLARO  */
20097ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit)
20107ac6653aSJeff Kirsher {
20117ac6653aSJeff Kirsher 	unsigned int rxsize = priv->dma_rx_size;
20127ac6653aSJeff Kirsher 	unsigned int entry = priv->cur_rx % rxsize;
20137ac6653aSJeff Kirsher 	unsigned int next_entry;
20147ac6653aSJeff Kirsher 	unsigned int count = 0;
2015ceb69499SGiuseppe CAVALLARO 	int coe = priv->plat->rx_coe;
20167ac6653aSJeff Kirsher 
201783d7af64SGiuseppe CAVALLARO 	if (netif_msg_rx_status(priv)) {
201883d7af64SGiuseppe CAVALLARO 		pr_debug("%s: descriptor ring:\n", __func__);
2019c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
2020c24602efSGiuseppe CAVALLARO 			stmmac_display_ring((void *)priv->dma_erx, rxsize, 1);
2021c24602efSGiuseppe CAVALLARO 		else
2022c24602efSGiuseppe CAVALLARO 			stmmac_display_ring((void *)priv->dma_rx, rxsize, 0);
20237ac6653aSJeff Kirsher 	}
2024c24602efSGiuseppe CAVALLARO 	while (count < limit) {
20257ac6653aSJeff Kirsher 		int status;
20269401bb5cSGiuseppe CAVALLARO 		struct dma_desc *p;
20277ac6653aSJeff Kirsher 
2028c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
2029c24602efSGiuseppe CAVALLARO 			p = (struct dma_desc *)(priv->dma_erx + entry);
2030c24602efSGiuseppe CAVALLARO 		else
2031c24602efSGiuseppe CAVALLARO 			p = priv->dma_rx + entry;
2032c24602efSGiuseppe CAVALLARO 
2033c24602efSGiuseppe CAVALLARO 		if (priv->hw->desc->get_rx_owner(p))
20347ac6653aSJeff Kirsher 			break;
20357ac6653aSJeff Kirsher 
20367ac6653aSJeff Kirsher 		count++;
20377ac6653aSJeff Kirsher 
20387ac6653aSJeff Kirsher 		next_entry = (++priv->cur_rx) % rxsize;
2039c24602efSGiuseppe CAVALLARO 		if (priv->extend_desc)
20409401bb5cSGiuseppe CAVALLARO 			prefetch(priv->dma_erx + next_entry);
2041c24602efSGiuseppe CAVALLARO 		else
20429401bb5cSGiuseppe CAVALLARO 			prefetch(priv->dma_rx + next_entry);
20437ac6653aSJeff Kirsher 
20447ac6653aSJeff Kirsher 		/* read the status of the incoming frame */
2045c24602efSGiuseppe CAVALLARO 		status = priv->hw->desc->rx_status(&priv->dev->stats,
2046c24602efSGiuseppe CAVALLARO 						   &priv->xstats, p);
2047c24602efSGiuseppe CAVALLARO 		if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status))
2048c24602efSGiuseppe CAVALLARO 			priv->hw->desc->rx_extended_status(&priv->dev->stats,
2049c24602efSGiuseppe CAVALLARO 							   &priv->xstats,
2050c24602efSGiuseppe CAVALLARO 							   priv->dma_erx +
2051c24602efSGiuseppe CAVALLARO 							   entry);
2052891434b1SRayagond Kokatanur 		if (unlikely(status == discard_frame)) {
20537ac6653aSJeff Kirsher 			priv->dev->stats.rx_errors++;
2054891434b1SRayagond Kokatanur 			if (priv->hwts_rx_en && !priv->extend_desc) {
2055891434b1SRayagond Kokatanur 				/* DESC2 & DESC3 will be overwitten by device
2056891434b1SRayagond Kokatanur 				 * with timestamp value, hence reinitialize
2057891434b1SRayagond Kokatanur 				 * them in stmmac_rx_refill() function so that
2058891434b1SRayagond Kokatanur 				 * device can reuse it.
2059891434b1SRayagond Kokatanur 				 */
2060891434b1SRayagond Kokatanur 				priv->rx_skbuff[entry] = NULL;
2061891434b1SRayagond Kokatanur 				dma_unmap_single(priv->device,
2062891434b1SRayagond Kokatanur 						 priv->rx_skbuff_dma[entry],
2063ceb69499SGiuseppe CAVALLARO 						 priv->dma_buf_sz,
2064ceb69499SGiuseppe CAVALLARO 						 DMA_FROM_DEVICE);
2065891434b1SRayagond Kokatanur 			}
2066891434b1SRayagond Kokatanur 		} else {
20677ac6653aSJeff Kirsher 			struct sk_buff *skb;
20687ac6653aSJeff Kirsher 			int frame_len;
20697ac6653aSJeff Kirsher 
2070ceb69499SGiuseppe CAVALLARO 			frame_len = priv->hw->desc->get_rx_frame_len(p, coe);
2071ceb69499SGiuseppe CAVALLARO 
20727ac6653aSJeff Kirsher 			/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
2073ceb69499SGiuseppe CAVALLARO 			 * Type frames (LLC/LLC-SNAP)
2074ceb69499SGiuseppe CAVALLARO 			 */
20757ac6653aSJeff Kirsher 			if (unlikely(status != llc_snap))
20767ac6653aSJeff Kirsher 				frame_len -= ETH_FCS_LEN;
20777ac6653aSJeff Kirsher 
207883d7af64SGiuseppe CAVALLARO 			if (netif_msg_rx_status(priv)) {
20797ac6653aSJeff Kirsher 				pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
20807ac6653aSJeff Kirsher 					 p, entry, p->des2);
208183d7af64SGiuseppe CAVALLARO 				if (frame_len > ETH_FRAME_LEN)
208283d7af64SGiuseppe CAVALLARO 					pr_debug("\tframe size %d, COE: %d\n",
208383d7af64SGiuseppe CAVALLARO 						 frame_len, status);
208483d7af64SGiuseppe CAVALLARO 			}
20857ac6653aSJeff Kirsher 			skb = priv->rx_skbuff[entry];
20867ac6653aSJeff Kirsher 			if (unlikely(!skb)) {
20877ac6653aSJeff Kirsher 				pr_err("%s: Inconsistent Rx descriptor chain\n",
20887ac6653aSJeff Kirsher 				       priv->dev->name);
20897ac6653aSJeff Kirsher 				priv->dev->stats.rx_dropped++;
20907ac6653aSJeff Kirsher 				break;
20917ac6653aSJeff Kirsher 			}
20927ac6653aSJeff Kirsher 			prefetch(skb->data - NET_IP_ALIGN);
20937ac6653aSJeff Kirsher 			priv->rx_skbuff[entry] = NULL;
20947ac6653aSJeff Kirsher 
2095891434b1SRayagond Kokatanur 			stmmac_get_rx_hwtstamp(priv, entry, skb);
2096891434b1SRayagond Kokatanur 
20977ac6653aSJeff Kirsher 			skb_put(skb, frame_len);
20987ac6653aSJeff Kirsher 			dma_unmap_single(priv->device,
20997ac6653aSJeff Kirsher 					 priv->rx_skbuff_dma[entry],
21007ac6653aSJeff Kirsher 					 priv->dma_buf_sz, DMA_FROM_DEVICE);
210183d7af64SGiuseppe CAVALLARO 
21027ac6653aSJeff Kirsher 			if (netif_msg_pktdata(priv)) {
210383d7af64SGiuseppe CAVALLARO 				pr_debug("frame received (%dbytes)", frame_len);
21047ac6653aSJeff Kirsher 				print_pkt(skb->data, frame_len);
21057ac6653aSJeff Kirsher 			}
210683d7af64SGiuseppe CAVALLARO 
21077ac6653aSJeff Kirsher 			skb->protocol = eth_type_trans(skb, priv->dev);
21087ac6653aSJeff Kirsher 
2109ceb69499SGiuseppe CAVALLARO 			if (unlikely(!coe))
21107ac6653aSJeff Kirsher 				skb_checksum_none_assert(skb);
211162a2ab93SGiuseppe CAVALLARO 			else
21127ac6653aSJeff Kirsher 				skb->ip_summed = CHECKSUM_UNNECESSARY;
211362a2ab93SGiuseppe CAVALLARO 
21147ac6653aSJeff Kirsher 			napi_gro_receive(&priv->napi, skb);
21157ac6653aSJeff Kirsher 
21167ac6653aSJeff Kirsher 			priv->dev->stats.rx_packets++;
21177ac6653aSJeff Kirsher 			priv->dev->stats.rx_bytes += frame_len;
21187ac6653aSJeff Kirsher 		}
21197ac6653aSJeff Kirsher 		entry = next_entry;
21207ac6653aSJeff Kirsher 	}
21217ac6653aSJeff Kirsher 
21227ac6653aSJeff Kirsher 	stmmac_rx_refill(priv);
21237ac6653aSJeff Kirsher 
21247ac6653aSJeff Kirsher 	priv->xstats.rx_pkt_n += count;
21257ac6653aSJeff Kirsher 
21267ac6653aSJeff Kirsher 	return count;
21277ac6653aSJeff Kirsher }
21287ac6653aSJeff Kirsher 
21297ac6653aSJeff Kirsher /**
21307ac6653aSJeff Kirsher  *  stmmac_poll - stmmac poll method (NAPI)
21317ac6653aSJeff Kirsher  *  @napi : pointer to the napi structure.
21327ac6653aSJeff Kirsher  *  @budget : maximum number of packets that the current CPU can receive from
21337ac6653aSJeff Kirsher  *	      all interfaces.
21347ac6653aSJeff Kirsher  *  Description :
21359125cdd1SGiuseppe CAVALLARO  *  To look at the incoming frames and clear the tx resources.
21367ac6653aSJeff Kirsher  */
21377ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget)
21387ac6653aSJeff Kirsher {
21397ac6653aSJeff Kirsher 	struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
21407ac6653aSJeff Kirsher 	int work_done = 0;
21417ac6653aSJeff Kirsher 
21429125cdd1SGiuseppe CAVALLARO 	priv->xstats.napi_poll++;
21439125cdd1SGiuseppe CAVALLARO 	stmmac_tx_clean(priv);
21447ac6653aSJeff Kirsher 
21459125cdd1SGiuseppe CAVALLARO 	work_done = stmmac_rx(priv, budget);
21467ac6653aSJeff Kirsher 	if (work_done < budget) {
21477ac6653aSJeff Kirsher 		napi_complete(napi);
21489125cdd1SGiuseppe CAVALLARO 		stmmac_enable_dma_irq(priv);
21497ac6653aSJeff Kirsher 	}
21507ac6653aSJeff Kirsher 	return work_done;
21517ac6653aSJeff Kirsher }
21527ac6653aSJeff Kirsher 
21537ac6653aSJeff Kirsher /**
21547ac6653aSJeff Kirsher  *  stmmac_tx_timeout
21557ac6653aSJeff Kirsher  *  @dev : Pointer to net device structure
21567ac6653aSJeff Kirsher  *  Description: this function is called when a packet transmission fails to
21577284a3f1SGiuseppe CAVALLARO  *   complete within a reasonable time. The driver will mark the error in the
21587ac6653aSJeff Kirsher  *   netdev structure and arrange for the device to be reset to a sane state
21597ac6653aSJeff Kirsher  *   in order to transmit a new packet.
21607ac6653aSJeff Kirsher  */
21617ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev)
21627ac6653aSJeff Kirsher {
21637ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
21647ac6653aSJeff Kirsher 
21657ac6653aSJeff Kirsher 	/* Clear Tx resources and restart transmitting again */
21667ac6653aSJeff Kirsher 	stmmac_tx_err(priv);
21677ac6653aSJeff Kirsher }
21687ac6653aSJeff Kirsher 
21697ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */
21707ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map)
21717ac6653aSJeff Kirsher {
21727ac6653aSJeff Kirsher 	if (dev->flags & IFF_UP)	/* can't act on a running interface */
21737ac6653aSJeff Kirsher 		return -EBUSY;
21747ac6653aSJeff Kirsher 
21757ac6653aSJeff Kirsher 	/* Don't allow changing the I/O address */
21767ac6653aSJeff Kirsher 	if (map->base_addr != dev->base_addr) {
2177ceb69499SGiuseppe CAVALLARO 		pr_warn("%s: can't change I/O address\n", dev->name);
21787ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
21797ac6653aSJeff Kirsher 	}
21807ac6653aSJeff Kirsher 
21817ac6653aSJeff Kirsher 	/* Don't allow changing the IRQ */
21827ac6653aSJeff Kirsher 	if (map->irq != dev->irq) {
2183ceb69499SGiuseppe CAVALLARO 		pr_warn("%s: not change IRQ number %d\n", dev->name, dev->irq);
21847ac6653aSJeff Kirsher 		return -EOPNOTSUPP;
21857ac6653aSJeff Kirsher 	}
21867ac6653aSJeff Kirsher 
21877ac6653aSJeff Kirsher 	return 0;
21887ac6653aSJeff Kirsher }
21897ac6653aSJeff Kirsher 
21907ac6653aSJeff Kirsher /**
219101789349SJiri Pirko  *  stmmac_set_rx_mode - entry point for multicast addressing
21927ac6653aSJeff Kirsher  *  @dev : pointer to the device structure
21937ac6653aSJeff Kirsher  *  Description:
21947ac6653aSJeff Kirsher  *  This function is a driver entry point which gets called by the kernel
21957ac6653aSJeff Kirsher  *  whenever multicast addresses must be enabled/disabled.
21967ac6653aSJeff Kirsher  *  Return value:
21977ac6653aSJeff Kirsher  *  void.
21987ac6653aSJeff Kirsher  */
219901789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev)
22007ac6653aSJeff Kirsher {
22017ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
22027ac6653aSJeff Kirsher 
22037ac6653aSJeff Kirsher 	spin_lock(&priv->lock);
2204cffb13f4SGiuseppe CAVALLARO 	priv->hw->mac->set_filter(dev, priv->synopsys_id);
22057ac6653aSJeff Kirsher 	spin_unlock(&priv->lock);
22067ac6653aSJeff Kirsher }
22077ac6653aSJeff Kirsher 
22087ac6653aSJeff Kirsher /**
22097ac6653aSJeff Kirsher  *  stmmac_change_mtu - entry point to change MTU size for the device.
22107ac6653aSJeff Kirsher  *  @dev : device pointer.
22117ac6653aSJeff Kirsher  *  @new_mtu : the new MTU size for the device.
22127ac6653aSJeff Kirsher  *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
22137ac6653aSJeff Kirsher  *  to drive packet transmission. Ethernet has an MTU of 1500 octets
22147ac6653aSJeff Kirsher  *  (ETH_DATA_LEN). This value can be changed with ifconfig.
22157ac6653aSJeff Kirsher  *  Return value:
22167ac6653aSJeff Kirsher  *  0 on success and an appropriate (-)ve integer as defined in errno.h
22177ac6653aSJeff Kirsher  *  file on failure.
22187ac6653aSJeff Kirsher  */
22197ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
22207ac6653aSJeff Kirsher {
22217ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
22227ac6653aSJeff Kirsher 	int max_mtu;
22237ac6653aSJeff Kirsher 
22247ac6653aSJeff Kirsher 	if (netif_running(dev)) {
22257ac6653aSJeff Kirsher 		pr_err("%s: must be stopped to change its MTU\n", dev->name);
22267ac6653aSJeff Kirsher 		return -EBUSY;
22277ac6653aSJeff Kirsher 	}
22287ac6653aSJeff Kirsher 
222948febf7eSGiuseppe CAVALLARO 	if (priv->plat->enh_desc)
22307ac6653aSJeff Kirsher 		max_mtu = JUMBO_LEN;
22317ac6653aSJeff Kirsher 	else
223245db81e1SGiuseppe CAVALLARO 		max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN);
22337ac6653aSJeff Kirsher 
22347ac6653aSJeff Kirsher 	if ((new_mtu < 46) || (new_mtu > max_mtu)) {
22357ac6653aSJeff Kirsher 		pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
22367ac6653aSJeff Kirsher 		return -EINVAL;
22377ac6653aSJeff Kirsher 	}
22387ac6653aSJeff Kirsher 
22397ac6653aSJeff Kirsher 	dev->mtu = new_mtu;
22407ac6653aSJeff Kirsher 	netdev_update_features(dev);
22417ac6653aSJeff Kirsher 
22427ac6653aSJeff Kirsher 	return 0;
22437ac6653aSJeff Kirsher }
22447ac6653aSJeff Kirsher 
2245c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev,
2246c8f44affSMichał Mirosław 					     netdev_features_t features)
22477ac6653aSJeff Kirsher {
22487ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
22497ac6653aSJeff Kirsher 
225038912bdbSDeepak SIKRI 	if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
22517ac6653aSJeff Kirsher 		features &= ~NETIF_F_RXCSUM;
225238912bdbSDeepak SIKRI 	else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
225338912bdbSDeepak SIKRI 		features &= ~NETIF_F_IPV6_CSUM;
22547ac6653aSJeff Kirsher 	if (!priv->plat->tx_coe)
22557ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
22567ac6653aSJeff Kirsher 
22577ac6653aSJeff Kirsher 	/* Some GMAC devices have a bugged Jumbo frame support that
22587ac6653aSJeff Kirsher 	 * needs to have the Tx COE disabled for oversized frames
22597ac6653aSJeff Kirsher 	 * (due to limited buffer sizes). In this case we disable
2260ceb69499SGiuseppe CAVALLARO 	 * the TX csum insertionin the TDES and not use SF.
2261ceb69499SGiuseppe CAVALLARO 	 */
22627ac6653aSJeff Kirsher 	if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
22637ac6653aSJeff Kirsher 		features &= ~NETIF_F_ALL_CSUM;
22647ac6653aSJeff Kirsher 
22657ac6653aSJeff Kirsher 	return features;
22667ac6653aSJeff Kirsher }
22677ac6653aSJeff Kirsher 
226832ceabcaSGiuseppe CAVALLARO /**
226932ceabcaSGiuseppe CAVALLARO  *  stmmac_interrupt - main ISR
227032ceabcaSGiuseppe CAVALLARO  *  @irq: interrupt number.
227132ceabcaSGiuseppe CAVALLARO  *  @dev_id: to pass the net device pointer.
227232ceabcaSGiuseppe CAVALLARO  *  Description: this is the main driver interrupt service routine.
227332ceabcaSGiuseppe CAVALLARO  *  It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI
227432ceabcaSGiuseppe CAVALLARO  *  interrupts.
227532ceabcaSGiuseppe CAVALLARO  */
22767ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
22777ac6653aSJeff Kirsher {
22787ac6653aSJeff Kirsher 	struct net_device *dev = (struct net_device *)dev_id;
22797ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
22807ac6653aSJeff Kirsher 
22817ac6653aSJeff Kirsher 	if (unlikely(!dev)) {
22827ac6653aSJeff Kirsher 		pr_err("%s: invalid dev pointer\n", __func__);
22837ac6653aSJeff Kirsher 		return IRQ_NONE;
22847ac6653aSJeff Kirsher 	}
22857ac6653aSJeff Kirsher 
22867ac6653aSJeff Kirsher 	/* To handle GMAC own interrupts */
2287d765955dSGiuseppe CAVALLARO 	if (priv->plat->has_gmac) {
2288d765955dSGiuseppe CAVALLARO 		int status = priv->hw->mac->host_irq_status((void __iomem *)
22890982a0f6SGiuseppe CAVALLARO 							    dev->base_addr,
22900982a0f6SGiuseppe CAVALLARO 							    &priv->xstats);
2291d765955dSGiuseppe CAVALLARO 		if (unlikely(status)) {
2292d765955dSGiuseppe CAVALLARO 			/* For LPI we need to save the tx status */
22930982a0f6SGiuseppe CAVALLARO 			if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE)
2294d765955dSGiuseppe CAVALLARO 				priv->tx_path_in_lpi_mode = true;
22950982a0f6SGiuseppe CAVALLARO 			if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE)
2296d765955dSGiuseppe CAVALLARO 				priv->tx_path_in_lpi_mode = false;
2297d765955dSGiuseppe CAVALLARO 		}
2298d765955dSGiuseppe CAVALLARO 	}
2299d765955dSGiuseppe CAVALLARO 
2300d765955dSGiuseppe CAVALLARO 	/* To handle DMA interrupts */
23017ac6653aSJeff Kirsher 	stmmac_dma_interrupt(priv);
23027ac6653aSJeff Kirsher 
23037ac6653aSJeff Kirsher 	return IRQ_HANDLED;
23047ac6653aSJeff Kirsher }
23057ac6653aSJeff Kirsher 
23067ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
23077ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools
2308ceb69499SGiuseppe CAVALLARO  * to allow network I/O with interrupts disabled.
2309ceb69499SGiuseppe CAVALLARO  */
23107ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev)
23117ac6653aSJeff Kirsher {
23127ac6653aSJeff Kirsher 	disable_irq(dev->irq);
23137ac6653aSJeff Kirsher 	stmmac_interrupt(dev->irq, dev);
23147ac6653aSJeff Kirsher 	enable_irq(dev->irq);
23157ac6653aSJeff Kirsher }
23167ac6653aSJeff Kirsher #endif
23177ac6653aSJeff Kirsher 
23187ac6653aSJeff Kirsher /**
23197ac6653aSJeff Kirsher  *  stmmac_ioctl - Entry point for the Ioctl
23207ac6653aSJeff Kirsher  *  @dev: Device pointer.
23217ac6653aSJeff Kirsher  *  @rq: An IOCTL specefic structure, that can contain a pointer to
23227ac6653aSJeff Kirsher  *  a proprietary structure used to pass information to the driver.
23237ac6653aSJeff Kirsher  *  @cmd: IOCTL command
23247ac6653aSJeff Kirsher  *  Description:
232532ceabcaSGiuseppe CAVALLARO  *  Currently it supports the phy_mii_ioctl(...) and HW time stamping.
23267ac6653aSJeff Kirsher  */
23277ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
23287ac6653aSJeff Kirsher {
23297ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(dev);
2330891434b1SRayagond Kokatanur 	int ret = -EOPNOTSUPP;
23317ac6653aSJeff Kirsher 
23327ac6653aSJeff Kirsher 	if (!netif_running(dev))
23337ac6653aSJeff Kirsher 		return -EINVAL;
23347ac6653aSJeff Kirsher 
2335891434b1SRayagond Kokatanur 	switch (cmd) {
2336891434b1SRayagond Kokatanur 	case SIOCGMIIPHY:
2337891434b1SRayagond Kokatanur 	case SIOCGMIIREG:
2338891434b1SRayagond Kokatanur 	case SIOCSMIIREG:
23397ac6653aSJeff Kirsher 		if (!priv->phydev)
23407ac6653aSJeff Kirsher 			return -EINVAL;
23417ac6653aSJeff Kirsher 		ret = phy_mii_ioctl(priv->phydev, rq, cmd);
2342891434b1SRayagond Kokatanur 		break;
2343891434b1SRayagond Kokatanur 	case SIOCSHWTSTAMP:
2344891434b1SRayagond Kokatanur 		ret = stmmac_hwtstamp_ioctl(dev, rq);
2345891434b1SRayagond Kokatanur 		break;
2346891434b1SRayagond Kokatanur 	default:
2347891434b1SRayagond Kokatanur 		break;
2348891434b1SRayagond Kokatanur 	}
23497ac6653aSJeff Kirsher 
23507ac6653aSJeff Kirsher 	return ret;
23517ac6653aSJeff Kirsher }
23527ac6653aSJeff Kirsher 
23537ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS
23547ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir;
23557ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status;
2356e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap;
23577ac29055SGiuseppe CAVALLARO 
2358c24602efSGiuseppe CAVALLARO static void sysfs_display_ring(void *head, int size, int extend_desc,
2359c24602efSGiuseppe CAVALLARO 			       struct seq_file *seq)
23607ac29055SGiuseppe CAVALLARO {
23617ac29055SGiuseppe CAVALLARO 	int i;
2362c24602efSGiuseppe CAVALLARO 	struct dma_extended_desc *ep = (struct dma_extended_desc *)head;
2363c24602efSGiuseppe CAVALLARO 	struct dma_desc *p = (struct dma_desc *)head;
23647ac29055SGiuseppe CAVALLARO 
2365c24602efSGiuseppe CAVALLARO 	for (i = 0; i < size; i++) {
2366c24602efSGiuseppe CAVALLARO 		u64 x;
2367c24602efSGiuseppe CAVALLARO 		if (extend_desc) {
2368c24602efSGiuseppe CAVALLARO 			x = *(u64 *) ep;
2369c24602efSGiuseppe CAVALLARO 			seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
2370c24602efSGiuseppe CAVALLARO 				   i, (unsigned int)virt_to_phys(ep),
2371c24602efSGiuseppe CAVALLARO 				   (unsigned int)x, (unsigned int)(x >> 32),
2372c24602efSGiuseppe CAVALLARO 				   ep->basic.des2, ep->basic.des3);
2373c24602efSGiuseppe CAVALLARO 			ep++;
2374c24602efSGiuseppe CAVALLARO 		} else {
2375c24602efSGiuseppe CAVALLARO 			x = *(u64 *) p;
2376c24602efSGiuseppe CAVALLARO 			seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
2377c24602efSGiuseppe CAVALLARO 				   i, (unsigned int)virt_to_phys(ep),
2378c24602efSGiuseppe CAVALLARO 				   (unsigned int)x, (unsigned int)(x >> 32),
2379c24602efSGiuseppe CAVALLARO 				   p->des2, p->des3);
2380c24602efSGiuseppe CAVALLARO 			p++;
2381c24602efSGiuseppe CAVALLARO 		}
23827ac29055SGiuseppe CAVALLARO 		seq_printf(seq, "\n");
23837ac29055SGiuseppe CAVALLARO 	}
2384c24602efSGiuseppe CAVALLARO }
23857ac29055SGiuseppe CAVALLARO 
2386c24602efSGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v)
2387c24602efSGiuseppe CAVALLARO {
2388c24602efSGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
2389c24602efSGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
2390c24602efSGiuseppe CAVALLARO 	unsigned int txsize = priv->dma_tx_size;
2391c24602efSGiuseppe CAVALLARO 	unsigned int rxsize = priv->dma_rx_size;
23927ac29055SGiuseppe CAVALLARO 
2393c24602efSGiuseppe CAVALLARO 	if (priv->extend_desc) {
2394c24602efSGiuseppe CAVALLARO 		seq_printf(seq, "Extended RX descriptor ring:\n");
2395c24602efSGiuseppe CAVALLARO 		sysfs_display_ring((void *)priv->dma_erx, rxsize, 1, seq);
2396c24602efSGiuseppe CAVALLARO 		seq_printf(seq, "Extended TX descriptor ring:\n");
2397c24602efSGiuseppe CAVALLARO 		sysfs_display_ring((void *)priv->dma_etx, txsize, 1, seq);
2398c24602efSGiuseppe CAVALLARO 	} else {
2399c24602efSGiuseppe CAVALLARO 		seq_printf(seq, "RX descriptor ring:\n");
2400c24602efSGiuseppe CAVALLARO 		sysfs_display_ring((void *)priv->dma_rx, rxsize, 0, seq);
2401c24602efSGiuseppe CAVALLARO 		seq_printf(seq, "TX descriptor ring:\n");
2402c24602efSGiuseppe CAVALLARO 		sysfs_display_ring((void *)priv->dma_tx, txsize, 0, seq);
24037ac29055SGiuseppe CAVALLARO 	}
24047ac29055SGiuseppe CAVALLARO 
24057ac29055SGiuseppe CAVALLARO 	return 0;
24067ac29055SGiuseppe CAVALLARO }
24077ac29055SGiuseppe CAVALLARO 
24087ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file)
24097ac29055SGiuseppe CAVALLARO {
24107ac29055SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_ring_read, inode->i_private);
24117ac29055SGiuseppe CAVALLARO }
24127ac29055SGiuseppe CAVALLARO 
24137ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = {
24147ac29055SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
24157ac29055SGiuseppe CAVALLARO 	.open = stmmac_sysfs_ring_open,
24167ac29055SGiuseppe CAVALLARO 	.read = seq_read,
24177ac29055SGiuseppe CAVALLARO 	.llseek = seq_lseek,
241874863948SDjalal Harouni 	.release = single_release,
24197ac29055SGiuseppe CAVALLARO };
24207ac29055SGiuseppe CAVALLARO 
2421e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
2422e7434821SGiuseppe CAVALLARO {
2423e7434821SGiuseppe CAVALLARO 	struct net_device *dev = seq->private;
2424e7434821SGiuseppe CAVALLARO 	struct stmmac_priv *priv = netdev_priv(dev);
2425e7434821SGiuseppe CAVALLARO 
242619e30c14SGiuseppe CAVALLARO 	if (!priv->hw_cap_support) {
2427e7434821SGiuseppe CAVALLARO 		seq_printf(seq, "DMA HW features not supported\n");
2428e7434821SGiuseppe CAVALLARO 		return 0;
2429e7434821SGiuseppe CAVALLARO 	}
2430e7434821SGiuseppe CAVALLARO 
2431e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
2432e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tDMA HW features\n");
2433e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "==============================\n");
2434e7434821SGiuseppe CAVALLARO 
2435e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t10/100 Mbps %s\n",
2436e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_10_100) ? "Y" : "N");
2437e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t1000 Mbps %s\n",
2438e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.mbps_1000) ? "Y" : "N");
2439e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHalf duple %s\n",
2440e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.half_duplex) ? "Y" : "N");
2441e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tHash Filter: %s\n",
2442e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.hash_filter) ? "Y" : "N");
2443e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tMultiple MAC address registers: %s\n",
2444e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.multi_addr) ? "Y" : "N");
2445e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n",
2446e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pcs) ? "Y" : "N");
2447e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tSMA (MDIO) Interface: %s\n",
2448e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.sma_mdio) ? "Y" : "N");
2449e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Remote wake up: %s\n",
2450e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N");
2451e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tPMT Magic Frame: %s\n",
2452e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.pmt_magic_frame) ? "Y" : "N");
2453e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRMON module: %s\n",
2454e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rmon) ? "Y" : "N");
2455e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n",
2456e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.time_stamp) ? "Y" : "N");
2457e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n",
2458e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.atime_stamp) ? "Y" : "N");
2459e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n",
2460e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.eee) ? "Y" : "N");
2461e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N");
2462e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tChecksum Offload in TX: %s\n",
2463e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.tx_coe) ? "Y" : "N");
2464e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n",
2465e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type1) ? "Y" : "N");
2466e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n",
2467e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rx_coe_type2) ? "Y" : "N");
2468e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n",
2469e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N");
2470e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional RX channel: %d\n",
2471e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_rx_channel);
2472e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tNumber of Additional TX channel: %d\n",
2473e7434821SGiuseppe CAVALLARO 		   priv->dma_cap.number_tx_channel);
2474e7434821SGiuseppe CAVALLARO 	seq_printf(seq, "\tEnhanced descriptors: %s\n",
2475e7434821SGiuseppe CAVALLARO 		   (priv->dma_cap.enh_desc) ? "Y" : "N");
2476e7434821SGiuseppe CAVALLARO 
2477e7434821SGiuseppe CAVALLARO 	return 0;
2478e7434821SGiuseppe CAVALLARO }
2479e7434821SGiuseppe CAVALLARO 
2480e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file)
2481e7434821SGiuseppe CAVALLARO {
2482e7434821SGiuseppe CAVALLARO 	return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private);
2483e7434821SGiuseppe CAVALLARO }
2484e7434821SGiuseppe CAVALLARO 
2485e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = {
2486e7434821SGiuseppe CAVALLARO 	.owner = THIS_MODULE,
2487e7434821SGiuseppe CAVALLARO 	.open = stmmac_sysfs_dma_cap_open,
2488e7434821SGiuseppe CAVALLARO 	.read = seq_read,
2489e7434821SGiuseppe CAVALLARO 	.llseek = seq_lseek,
249074863948SDjalal Harouni 	.release = single_release,
2491e7434821SGiuseppe CAVALLARO };
2492e7434821SGiuseppe CAVALLARO 
24937ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev)
24947ac29055SGiuseppe CAVALLARO {
24957ac29055SGiuseppe CAVALLARO 	/* Create debugfs entries */
24967ac29055SGiuseppe CAVALLARO 	stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
24977ac29055SGiuseppe CAVALLARO 
24987ac29055SGiuseppe CAVALLARO 	if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
24997ac29055SGiuseppe CAVALLARO 		pr_err("ERROR %s, debugfs create directory failed\n",
25007ac29055SGiuseppe CAVALLARO 		       STMMAC_RESOURCE_NAME);
25017ac29055SGiuseppe CAVALLARO 
25027ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
25037ac29055SGiuseppe CAVALLARO 	}
25047ac29055SGiuseppe CAVALLARO 
25057ac29055SGiuseppe CAVALLARO 	/* Entry to report DMA RX/TX rings */
25067ac29055SGiuseppe CAVALLARO 	stmmac_rings_status = debugfs_create_file("descriptors_status",
25077ac29055SGiuseppe CAVALLARO 						  S_IRUGO, stmmac_fs_dir, dev,
25087ac29055SGiuseppe CAVALLARO 						  &stmmac_rings_status_fops);
25097ac29055SGiuseppe CAVALLARO 
25107ac29055SGiuseppe CAVALLARO 	if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
25117ac29055SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac ring debugfs file\n");
25127ac29055SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
25137ac29055SGiuseppe CAVALLARO 
25147ac29055SGiuseppe CAVALLARO 		return -ENOMEM;
25157ac29055SGiuseppe CAVALLARO 	}
25167ac29055SGiuseppe CAVALLARO 
2517e7434821SGiuseppe CAVALLARO 	/* Entry to report the DMA HW features */
2518e7434821SGiuseppe CAVALLARO 	stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
2519e7434821SGiuseppe CAVALLARO 					     dev, &stmmac_dma_cap_fops);
2520e7434821SGiuseppe CAVALLARO 
2521e7434821SGiuseppe CAVALLARO 	if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
2522e7434821SGiuseppe CAVALLARO 		pr_info("ERROR creating stmmac MMC debugfs file\n");
2523e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_rings_status);
2524e7434821SGiuseppe CAVALLARO 		debugfs_remove(stmmac_fs_dir);
2525e7434821SGiuseppe CAVALLARO 
2526e7434821SGiuseppe CAVALLARO 		return -ENOMEM;
2527e7434821SGiuseppe CAVALLARO 	}
2528e7434821SGiuseppe CAVALLARO 
25297ac29055SGiuseppe CAVALLARO 	return 0;
25307ac29055SGiuseppe CAVALLARO }
25317ac29055SGiuseppe CAVALLARO 
25327ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void)
25337ac29055SGiuseppe CAVALLARO {
25347ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_rings_status);
2535e7434821SGiuseppe CAVALLARO 	debugfs_remove(stmmac_dma_cap);
25367ac29055SGiuseppe CAVALLARO 	debugfs_remove(stmmac_fs_dir);
25377ac29055SGiuseppe CAVALLARO }
25387ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */
25397ac29055SGiuseppe CAVALLARO 
25407ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = {
25417ac6653aSJeff Kirsher 	.ndo_open = stmmac_open,
25427ac6653aSJeff Kirsher 	.ndo_start_xmit = stmmac_xmit,
25437ac6653aSJeff Kirsher 	.ndo_stop = stmmac_release,
25447ac6653aSJeff Kirsher 	.ndo_change_mtu = stmmac_change_mtu,
25457ac6653aSJeff Kirsher 	.ndo_fix_features = stmmac_fix_features,
254601789349SJiri Pirko 	.ndo_set_rx_mode = stmmac_set_rx_mode,
25477ac6653aSJeff Kirsher 	.ndo_tx_timeout = stmmac_tx_timeout,
25487ac6653aSJeff Kirsher 	.ndo_do_ioctl = stmmac_ioctl,
25497ac6653aSJeff Kirsher 	.ndo_set_config = stmmac_config,
25507ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER
25517ac6653aSJeff Kirsher 	.ndo_poll_controller = stmmac_poll_controller,
25527ac6653aSJeff Kirsher #endif
25537ac6653aSJeff Kirsher 	.ndo_set_mac_address = eth_mac_addr,
25547ac6653aSJeff Kirsher };
25557ac6653aSJeff Kirsher 
25567ac6653aSJeff Kirsher /**
2557cf3f047bSGiuseppe CAVALLARO  *  stmmac_hw_init - Init the MAC device
255832ceabcaSGiuseppe CAVALLARO  *  @priv: driver private structure
2559cf3f047bSGiuseppe CAVALLARO  *  Description: this function detects which MAC device
2560cf3f047bSGiuseppe CAVALLARO  *  (GMAC/MAC10-100) has to attached, checks the HW capability
2561cf3f047bSGiuseppe CAVALLARO  *  (if supported) and sets the driver's features (for example
2562cf3f047bSGiuseppe CAVALLARO  *  to use the ring or chaine mode or support the normal/enh
2563cf3f047bSGiuseppe CAVALLARO  *  descriptor structure).
2564cf3f047bSGiuseppe CAVALLARO  */
2565cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv)
2566cf3f047bSGiuseppe CAVALLARO {
2567c24602efSGiuseppe CAVALLARO 	int ret;
2568cf3f047bSGiuseppe CAVALLARO 	struct mac_device_info *mac;
2569cf3f047bSGiuseppe CAVALLARO 
2570cf3f047bSGiuseppe CAVALLARO 	/* Identify the MAC HW device */
257103f2eecdSMarc Kleine-Budde 	if (priv->plat->has_gmac) {
257203f2eecdSMarc Kleine-Budde 		priv->dev->priv_flags |= IFF_UNICAST_FLT;
2573cf3f047bSGiuseppe CAVALLARO 		mac = dwmac1000_setup(priv->ioaddr);
257403f2eecdSMarc Kleine-Budde 	} else {
2575cf3f047bSGiuseppe CAVALLARO 		mac = dwmac100_setup(priv->ioaddr);
257603f2eecdSMarc Kleine-Budde 	}
2577cf3f047bSGiuseppe CAVALLARO 	if (!mac)
2578cf3f047bSGiuseppe CAVALLARO 		return -ENOMEM;
2579cf3f047bSGiuseppe CAVALLARO 
2580cf3f047bSGiuseppe CAVALLARO 	priv->hw = mac;
2581cf3f047bSGiuseppe CAVALLARO 
2582cf3f047bSGiuseppe CAVALLARO 	/* Get and dump the chip ID */
2583cffb13f4SGiuseppe CAVALLARO 	priv->synopsys_id = stmmac_get_synopsys_id(priv);
2584cf3f047bSGiuseppe CAVALLARO 
25854a7d666aSGiuseppe CAVALLARO 	/* To use the chained or ring mode */
25864a7d666aSGiuseppe CAVALLARO 	if (chain_mode) {
25874a7d666aSGiuseppe CAVALLARO 		priv->hw->chain = &chain_mode_ops;
25884a7d666aSGiuseppe CAVALLARO 		pr_info(" Chain mode enabled\n");
25894a7d666aSGiuseppe CAVALLARO 		priv->mode = STMMAC_CHAIN_MODE;
25904a7d666aSGiuseppe CAVALLARO 	} else {
25914a7d666aSGiuseppe CAVALLARO 		priv->hw->ring = &ring_mode_ops;
25924a7d666aSGiuseppe CAVALLARO 		pr_info(" Ring mode enabled\n");
25934a7d666aSGiuseppe CAVALLARO 		priv->mode = STMMAC_RING_MODE;
25944a7d666aSGiuseppe CAVALLARO 	}
25954a7d666aSGiuseppe CAVALLARO 
2596cf3f047bSGiuseppe CAVALLARO 	/* Get the HW capability (new GMAC newer than 3.50a) */
2597cf3f047bSGiuseppe CAVALLARO 	priv->hw_cap_support = stmmac_get_hw_features(priv);
2598cf3f047bSGiuseppe CAVALLARO 	if (priv->hw_cap_support) {
2599cf3f047bSGiuseppe CAVALLARO 		pr_info(" DMA HW capability register supported");
2600cf3f047bSGiuseppe CAVALLARO 
2601cf3f047bSGiuseppe CAVALLARO 		/* We can override some gmac/dma configuration fields: e.g.
2602cf3f047bSGiuseppe CAVALLARO 		 * enh_desc, tx_coe (e.g. that are passed through the
2603cf3f047bSGiuseppe CAVALLARO 		 * platform) with the values from the HW capability
2604cf3f047bSGiuseppe CAVALLARO 		 * register (if supported).
2605cf3f047bSGiuseppe CAVALLARO 		 */
2606cf3f047bSGiuseppe CAVALLARO 		priv->plat->enh_desc = priv->dma_cap.enh_desc;
2607cf3f047bSGiuseppe CAVALLARO 		priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
260838912bdbSDeepak SIKRI 
260938912bdbSDeepak SIKRI 		priv->plat->tx_coe = priv->dma_cap.tx_coe;
261038912bdbSDeepak SIKRI 
261138912bdbSDeepak SIKRI 		if (priv->dma_cap.rx_coe_type2)
261238912bdbSDeepak SIKRI 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
261338912bdbSDeepak SIKRI 		else if (priv->dma_cap.rx_coe_type1)
261438912bdbSDeepak SIKRI 			priv->plat->rx_coe = STMMAC_RX_COE_TYPE1;
261538912bdbSDeepak SIKRI 
2616cf3f047bSGiuseppe CAVALLARO 	} else
2617cf3f047bSGiuseppe CAVALLARO 		pr_info(" No HW DMA feature register supported");
2618cf3f047bSGiuseppe CAVALLARO 
261961369d02SByungho An 	/* To use alternate (extended) or normal descriptor structures */
262061369d02SByungho An 	stmmac_selec_desc_mode(priv);
262161369d02SByungho An 
262238912bdbSDeepak SIKRI 	ret = priv->hw->mac->rx_ipc(priv->ioaddr);
262338912bdbSDeepak SIKRI 	if (!ret) {
2624ceb69499SGiuseppe CAVALLARO 		pr_warn(" RX IPC Checksum Offload not configured.\n");
262538912bdbSDeepak SIKRI 		priv->plat->rx_coe = STMMAC_RX_COE_NONE;
262638912bdbSDeepak SIKRI 	}
262738912bdbSDeepak SIKRI 
262838912bdbSDeepak SIKRI 	if (priv->plat->rx_coe)
262938912bdbSDeepak SIKRI 		pr_info(" RX Checksum Offload Engine supported (type %d)\n",
263038912bdbSDeepak SIKRI 			priv->plat->rx_coe);
2631cf3f047bSGiuseppe CAVALLARO 	if (priv->plat->tx_coe)
2632cf3f047bSGiuseppe CAVALLARO 		pr_info(" TX Checksum insertion supported\n");
2633cf3f047bSGiuseppe CAVALLARO 
2634cf3f047bSGiuseppe CAVALLARO 	if (priv->plat->pmt) {
2635cf3f047bSGiuseppe CAVALLARO 		pr_info(" Wake-Up On Lan supported\n");
2636cf3f047bSGiuseppe CAVALLARO 		device_set_wakeup_capable(priv->device, 1);
2637cf3f047bSGiuseppe CAVALLARO 	}
2638cf3f047bSGiuseppe CAVALLARO 
2639c24602efSGiuseppe CAVALLARO 	return 0;
2640cf3f047bSGiuseppe CAVALLARO }
2641cf3f047bSGiuseppe CAVALLARO 
2642cf3f047bSGiuseppe CAVALLARO /**
2643bfab27a1SGiuseppe CAVALLARO  * stmmac_dvr_probe
2644bfab27a1SGiuseppe CAVALLARO  * @device: device pointer
2645ff3dd78cSGiuseppe CAVALLARO  * @plat_dat: platform data pointer
2646ff3dd78cSGiuseppe CAVALLARO  * @addr: iobase memory address
2647bfab27a1SGiuseppe CAVALLARO  * Description: this is the main probe function used to
2648bfab27a1SGiuseppe CAVALLARO  * call the alloc_etherdev, allocate the priv structure.
26497ac6653aSJeff Kirsher  */
2650bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device,
2651cf3f047bSGiuseppe CAVALLARO 				     struct plat_stmmacenet_data *plat_dat,
2652cf3f047bSGiuseppe CAVALLARO 				     void __iomem *addr)
26537ac6653aSJeff Kirsher {
26547ac6653aSJeff Kirsher 	int ret = 0;
2655bfab27a1SGiuseppe CAVALLARO 	struct net_device *ndev = NULL;
2656bfab27a1SGiuseppe CAVALLARO 	struct stmmac_priv *priv;
26577ac6653aSJeff Kirsher 
2658bfab27a1SGiuseppe CAVALLARO 	ndev = alloc_etherdev(sizeof(struct stmmac_priv));
265941de8d4cSJoe Perches 	if (!ndev)
2660bfab27a1SGiuseppe CAVALLARO 		return NULL;
26617ac6653aSJeff Kirsher 
2662bfab27a1SGiuseppe CAVALLARO 	SET_NETDEV_DEV(ndev, device);
26637ac6653aSJeff Kirsher 
2664bfab27a1SGiuseppe CAVALLARO 	priv = netdev_priv(ndev);
2665bfab27a1SGiuseppe CAVALLARO 	priv->device = device;
2666bfab27a1SGiuseppe CAVALLARO 	priv->dev = ndev;
2667bfab27a1SGiuseppe CAVALLARO 
2668bfab27a1SGiuseppe CAVALLARO 	ether_setup(ndev);
2669bfab27a1SGiuseppe CAVALLARO 
2670bfab27a1SGiuseppe CAVALLARO 	stmmac_set_ethtool_ops(ndev);
2671cf3f047bSGiuseppe CAVALLARO 	priv->pause = pause;
2672cf3f047bSGiuseppe CAVALLARO 	priv->plat = plat_dat;
2673cf3f047bSGiuseppe CAVALLARO 	priv->ioaddr = addr;
2674cf3f047bSGiuseppe CAVALLARO 	priv->dev->base_addr = (unsigned long)addr;
2675bfab27a1SGiuseppe CAVALLARO 
2676cf3f047bSGiuseppe CAVALLARO 	/* Verify driver arguments */
2677cf3f047bSGiuseppe CAVALLARO 	stmmac_verify_args();
2678cf3f047bSGiuseppe CAVALLARO 
2679cf3f047bSGiuseppe CAVALLARO 	/* Override with kernel parameters if supplied XXX CRS XXX
2680ceb69499SGiuseppe CAVALLARO 	 * this needs to have multiple instances
2681ceb69499SGiuseppe CAVALLARO 	 */
2682cf3f047bSGiuseppe CAVALLARO 	if ((phyaddr >= 0) && (phyaddr <= 31))
2683cf3f047bSGiuseppe CAVALLARO 		priv->plat->phy_addr = phyaddr;
2684cf3f047bSGiuseppe CAVALLARO 
2685cf3f047bSGiuseppe CAVALLARO 	/* Init MAC and get the capabilities */
2686c24602efSGiuseppe CAVALLARO 	ret = stmmac_hw_init(priv);
2687c24602efSGiuseppe CAVALLARO 	if (ret)
2688c24602efSGiuseppe CAVALLARO 		goto error_free_netdev;
2689cf3f047bSGiuseppe CAVALLARO 
2690cf3f047bSGiuseppe CAVALLARO 	ndev->netdev_ops = &stmmac_netdev_ops;
2691cf3f047bSGiuseppe CAVALLARO 
2692cf3f047bSGiuseppe CAVALLARO 	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2693cf3f047bSGiuseppe CAVALLARO 			    NETIF_F_RXCSUM;
2694bfab27a1SGiuseppe CAVALLARO 	ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
2695bfab27a1SGiuseppe CAVALLARO 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
26967ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED
26977ac6653aSJeff Kirsher 	/* Both mac100 and gmac support receive VLAN tag detection */
2698f646968fSPatrick McHardy 	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
26997ac6653aSJeff Kirsher #endif
27007ac6653aSJeff Kirsher 	priv->msg_enable = netif_msg_init(debug, default_msg_level);
27017ac6653aSJeff Kirsher 
27027ac6653aSJeff Kirsher 	if (flow_ctrl)
27037ac6653aSJeff Kirsher 		priv->flow_ctrl = FLOW_AUTO;	/* RX/TX pause on */
27047ac6653aSJeff Kirsher 
270562a2ab93SGiuseppe CAVALLARO 	/* Rx Watchdog is available in the COREs newer than the 3.40.
270662a2ab93SGiuseppe CAVALLARO 	 * In some case, for example on bugged HW this feature
270762a2ab93SGiuseppe CAVALLARO 	 * has to be disable and this can be done by passing the
270862a2ab93SGiuseppe CAVALLARO 	 * riwt_off field from the platform.
270962a2ab93SGiuseppe CAVALLARO 	 */
271062a2ab93SGiuseppe CAVALLARO 	if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) {
271162a2ab93SGiuseppe CAVALLARO 		priv->use_riwt = 1;
271262a2ab93SGiuseppe CAVALLARO 		pr_info(" Enable RX Mitigation via HW Watchdog Timer\n");
271362a2ab93SGiuseppe CAVALLARO 	}
271462a2ab93SGiuseppe CAVALLARO 
2715bfab27a1SGiuseppe CAVALLARO 	netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
27167ac6653aSJeff Kirsher 
27177ac6653aSJeff Kirsher 	spin_lock_init(&priv->lock);
2718a9097a96SGiuseppe CAVALLARO 	spin_lock_init(&priv->tx_lock);
27197ac6653aSJeff Kirsher 
2720bfab27a1SGiuseppe CAVALLARO 	ret = register_netdev(ndev);
27217ac6653aSJeff Kirsher 	if (ret) {
2722cf3f047bSGiuseppe CAVALLARO 		pr_err("%s: ERROR %i registering the device\n", __func__, ret);
27236a81c26fSViresh Kumar 		goto error_netdev_register;
27247ac6653aSJeff Kirsher 	}
27257ac6653aSJeff Kirsher 
2726ae4d8cf2SKelvin Cheung 	priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
27276a81c26fSViresh Kumar 	if (IS_ERR(priv->stmmac_clk)) {
2728ceb69499SGiuseppe CAVALLARO 		pr_warn("%s: warning: cannot get CSR clock\n", __func__);
27296a81c26fSViresh Kumar 		goto error_clk_get;
27306a81c26fSViresh Kumar 	}
2731ba1377ffSGiuseppe CAVALLARO 
2732cd7201f4SGiuseppe CAVALLARO 	/* If a specific clk_csr value is passed from the platform
2733cd7201f4SGiuseppe CAVALLARO 	 * this means that the CSR Clock Range selection cannot be
2734cd7201f4SGiuseppe CAVALLARO 	 * changed at run-time and it is fixed. Viceversa the driver'll try to
2735cd7201f4SGiuseppe CAVALLARO 	 * set the MDC clock dynamically according to the csr actual
2736cd7201f4SGiuseppe CAVALLARO 	 * clock input.
2737cd7201f4SGiuseppe CAVALLARO 	 */
2738cd7201f4SGiuseppe CAVALLARO 	if (!priv->plat->clk_csr)
2739cd7201f4SGiuseppe CAVALLARO 		stmmac_clk_csr_set(priv);
2740cd7201f4SGiuseppe CAVALLARO 	else
2741cd7201f4SGiuseppe CAVALLARO 		priv->clk_csr = priv->plat->clk_csr;
2742cd7201f4SGiuseppe CAVALLARO 
2743e58bb43fSGiuseppe CAVALLARO 	stmmac_check_pcs_mode(priv);
2744e58bb43fSGiuseppe CAVALLARO 
27454d8f0825SByungho An 	if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
27464d8f0825SByungho An 	    priv->pcs != STMMAC_PCS_RTBI) {
27474bfcbd7aSFrancesco Virlinzi 		/* MDIO bus Registration */
27484bfcbd7aSFrancesco Virlinzi 		ret = stmmac_mdio_register(ndev);
27494bfcbd7aSFrancesco Virlinzi 		if (ret < 0) {
27504bfcbd7aSFrancesco Virlinzi 			pr_debug("%s: MDIO bus (id: %d) registration failed",
27514bfcbd7aSFrancesco Virlinzi 				 __func__, priv->plat->bus_id);
27526a81c26fSViresh Kumar 			goto error_mdio_register;
27534bfcbd7aSFrancesco Virlinzi 		}
2754e58bb43fSGiuseppe CAVALLARO 	}
27554bfcbd7aSFrancesco Virlinzi 
2756bfab27a1SGiuseppe CAVALLARO 	return priv;
27577ac6653aSJeff Kirsher 
27586a81c26fSViresh Kumar error_mdio_register:
27596a81c26fSViresh Kumar 	clk_put(priv->stmmac_clk);
27606a81c26fSViresh Kumar error_clk_get:
27617ac6653aSJeff Kirsher 	unregister_netdev(ndev);
27626a81c26fSViresh Kumar error_netdev_register:
27636a81c26fSViresh Kumar 	netif_napi_del(&priv->napi);
2764c24602efSGiuseppe CAVALLARO error_free_netdev:
27657ac6653aSJeff Kirsher 	free_netdev(ndev);
27667ac6653aSJeff Kirsher 
2767bfab27a1SGiuseppe CAVALLARO 	return NULL;
27687ac6653aSJeff Kirsher }
27697ac6653aSJeff Kirsher 
27707ac6653aSJeff Kirsher /**
27717ac6653aSJeff Kirsher  * stmmac_dvr_remove
2772bfab27a1SGiuseppe CAVALLARO  * @ndev: net device pointer
27737ac6653aSJeff Kirsher  * Description: this function resets the TX/RX processes, disables the MAC RX/TX
2774bfab27a1SGiuseppe CAVALLARO  * changes the link status, releases the DMA descriptor rings.
27757ac6653aSJeff Kirsher  */
2776bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev)
27777ac6653aSJeff Kirsher {
27787ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
27797ac6653aSJeff Kirsher 
27807ac6653aSJeff Kirsher 	pr_info("%s:\n\tremoving driver", __func__);
27817ac6653aSJeff Kirsher 
27827ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
27837ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
27847ac6653aSJeff Kirsher 
2785bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, false);
27864d8f0825SByungho An 	if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
27874d8f0825SByungho An 	    priv->pcs != STMMAC_PCS_RTBI)
27884bfcbd7aSFrancesco Virlinzi 		stmmac_mdio_unregister(ndev);
27897ac6653aSJeff Kirsher 	netif_carrier_off(ndev);
27907ac6653aSJeff Kirsher 	unregister_netdev(ndev);
27917ac6653aSJeff Kirsher 	free_netdev(ndev);
27927ac6653aSJeff Kirsher 
27937ac6653aSJeff Kirsher 	return 0;
27947ac6653aSJeff Kirsher }
27957ac6653aSJeff Kirsher 
27967ac6653aSJeff Kirsher #ifdef CONFIG_PM
2797bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev)
27987ac6653aSJeff Kirsher {
27997ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
2800f8c5a875SGiuseppe CAVALLARO 	unsigned long flags;
28017ac6653aSJeff Kirsher 
28027ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
28037ac6653aSJeff Kirsher 		return 0;
28047ac6653aSJeff Kirsher 
2805102463b1SFrancesco Virlinzi 	if (priv->phydev)
2806102463b1SFrancesco Virlinzi 		phy_stop(priv->phydev);
2807102463b1SFrancesco Virlinzi 
2808f8c5a875SGiuseppe CAVALLARO 	spin_lock_irqsave(&priv->lock, flags);
28097ac6653aSJeff Kirsher 
28107ac6653aSJeff Kirsher 	netif_device_detach(ndev);
28117ac6653aSJeff Kirsher 	netif_stop_queue(ndev);
28127ac6653aSJeff Kirsher 
28137ac6653aSJeff Kirsher 	napi_disable(&priv->napi);
28147ac6653aSJeff Kirsher 
28157ac6653aSJeff Kirsher 	/* Stop TX/RX DMA */
28167ac6653aSJeff Kirsher 	priv->hw->dma->stop_tx(priv->ioaddr);
28177ac6653aSJeff Kirsher 	priv->hw->dma->stop_rx(priv->ioaddr);
2818c24602efSGiuseppe CAVALLARO 
2819c24602efSGiuseppe CAVALLARO 	stmmac_clear_descriptors(priv);
28207ac6653aSJeff Kirsher 
28217ac6653aSJeff Kirsher 	/* Enable Power down mode by programming the PMT regs */
28227ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
28237ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
2824ba1377ffSGiuseppe CAVALLARO 	else {
2825bfab27a1SGiuseppe CAVALLARO 		stmmac_set_mac(priv->ioaddr, false);
2826ba1377ffSGiuseppe CAVALLARO 		/* Disable clock in case of PWM is off */
2827a630844dSStefan Roese 		clk_disable_unprepare(priv->stmmac_clk);
2828ba1377ffSGiuseppe CAVALLARO 	}
2829f8c5a875SGiuseppe CAVALLARO 	spin_unlock_irqrestore(&priv->lock, flags);
28307ac6653aSJeff Kirsher 	return 0;
28317ac6653aSJeff Kirsher }
28327ac6653aSJeff Kirsher 
2833bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev)
28347ac6653aSJeff Kirsher {
28357ac6653aSJeff Kirsher 	struct stmmac_priv *priv = netdev_priv(ndev);
2836f8c5a875SGiuseppe CAVALLARO 	unsigned long flags;
28377ac6653aSJeff Kirsher 
28387ac6653aSJeff Kirsher 	if (!netif_running(ndev))
28397ac6653aSJeff Kirsher 		return 0;
28407ac6653aSJeff Kirsher 
2841f8c5a875SGiuseppe CAVALLARO 	spin_lock_irqsave(&priv->lock, flags);
28427ac6653aSJeff Kirsher 
28437ac6653aSJeff Kirsher 	/* Power Down bit, into the PM register, is cleared
28447ac6653aSJeff Kirsher 	 * automatically as soon as a magic packet or a Wake-up frame
28457ac6653aSJeff Kirsher 	 * is received. Anyway, it's better to manually clear
28467ac6653aSJeff Kirsher 	 * this bit because it can generate problems while resuming
2847ceb69499SGiuseppe CAVALLARO 	 * from another devices (e.g. serial console).
2848ceb69499SGiuseppe CAVALLARO 	 */
28497ac6653aSJeff Kirsher 	if (device_may_wakeup(priv->device))
28507ac6653aSJeff Kirsher 		priv->hw->mac->pmt(priv->ioaddr, 0);
2851ba1377ffSGiuseppe CAVALLARO 	else
2852ba1377ffSGiuseppe CAVALLARO 		/* enable the clk prevously disabled */
2853a630844dSStefan Roese 		clk_prepare_enable(priv->stmmac_clk);
28547ac6653aSJeff Kirsher 
28557ac6653aSJeff Kirsher 	netif_device_attach(ndev);
28567ac6653aSJeff Kirsher 
28577ac6653aSJeff Kirsher 	/* Enable the MAC and DMA */
2858bfab27a1SGiuseppe CAVALLARO 	stmmac_set_mac(priv->ioaddr, true);
28597ac6653aSJeff Kirsher 	priv->hw->dma->start_tx(priv->ioaddr);
28607ac6653aSJeff Kirsher 	priv->hw->dma->start_rx(priv->ioaddr);
28617ac6653aSJeff Kirsher 
28627ac6653aSJeff Kirsher 	napi_enable(&priv->napi);
28637ac6653aSJeff Kirsher 
28647ac6653aSJeff Kirsher 	netif_start_queue(ndev);
28657ac6653aSJeff Kirsher 
2866f8c5a875SGiuseppe CAVALLARO 	spin_unlock_irqrestore(&priv->lock, flags);
2867102463b1SFrancesco Virlinzi 
2868102463b1SFrancesco Virlinzi 	if (priv->phydev)
2869102463b1SFrancesco Virlinzi 		phy_start(priv->phydev);
2870102463b1SFrancesco Virlinzi 
28717ac6653aSJeff Kirsher 	return 0;
28727ac6653aSJeff Kirsher }
28737ac6653aSJeff Kirsher 
2874bfab27a1SGiuseppe CAVALLARO int stmmac_freeze(struct net_device *ndev)
28757ac6653aSJeff Kirsher {
28767ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
28777ac6653aSJeff Kirsher 		return 0;
28787ac6653aSJeff Kirsher 
28797ac6653aSJeff Kirsher 	return stmmac_release(ndev);
28807ac6653aSJeff Kirsher }
28817ac6653aSJeff Kirsher 
2882bfab27a1SGiuseppe CAVALLARO int stmmac_restore(struct net_device *ndev)
28837ac6653aSJeff Kirsher {
28847ac6653aSJeff Kirsher 	if (!ndev || !netif_running(ndev))
28857ac6653aSJeff Kirsher 		return 0;
28867ac6653aSJeff Kirsher 
28877ac6653aSJeff Kirsher 	return stmmac_open(ndev);
28887ac6653aSJeff Kirsher }
28897ac6653aSJeff Kirsher #endif /* CONFIG_PM */
28907ac6653aSJeff Kirsher 
289133d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers
289233d5e332SGiuseppe CAVALLARO  * depending on the configuration selected.
289333d5e332SGiuseppe CAVALLARO  */
2894ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void)
2895ba27ec66SGiuseppe CAVALLARO {
2896493682b8SKonstantin Khlebnikov 	int ret;
2897ba27ec66SGiuseppe CAVALLARO 
2898493682b8SKonstantin Khlebnikov 	ret = stmmac_register_platform();
2899493682b8SKonstantin Khlebnikov 	if (ret)
2900493682b8SKonstantin Khlebnikov 		goto err;
2901493682b8SKonstantin Khlebnikov 	ret = stmmac_register_pci();
2902493682b8SKonstantin Khlebnikov 	if (ret)
2903493682b8SKonstantin Khlebnikov 		goto err_pci;
290433d5e332SGiuseppe CAVALLARO 	return 0;
2905493682b8SKonstantin Khlebnikov err_pci:
2906493682b8SKonstantin Khlebnikov 	stmmac_unregister_platform();
2907493682b8SKonstantin Khlebnikov err:
2908493682b8SKonstantin Khlebnikov 	pr_err("stmmac: driver registration failed\n");
2909493682b8SKonstantin Khlebnikov 	return ret;
2910ba27ec66SGiuseppe CAVALLARO }
2911ba27ec66SGiuseppe CAVALLARO 
2912ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void)
2913ba27ec66SGiuseppe CAVALLARO {
291433d5e332SGiuseppe CAVALLARO 	stmmac_unregister_platform();
291533d5e332SGiuseppe CAVALLARO 	stmmac_unregister_pci();
2916ba27ec66SGiuseppe CAVALLARO }
2917ba27ec66SGiuseppe CAVALLARO 
2918ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init);
2919ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit);
2920ba27ec66SGiuseppe CAVALLARO 
29217ac6653aSJeff Kirsher #ifndef MODULE
29227ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str)
29237ac6653aSJeff Kirsher {
29247ac6653aSJeff Kirsher 	char *opt;
29257ac6653aSJeff Kirsher 
29267ac6653aSJeff Kirsher 	if (!str || !*str)
29277ac6653aSJeff Kirsher 		return -EINVAL;
29287ac6653aSJeff Kirsher 	while ((opt = strsep(&str, ",")) != NULL) {
29297ac6653aSJeff Kirsher 		if (!strncmp(opt, "debug:", 6)) {
2930ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 6, 0, &debug))
29317ac6653aSJeff Kirsher 				goto err;
29327ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "phyaddr:", 8)) {
2933ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 8, 0, &phyaddr))
29347ac6653aSJeff Kirsher 				goto err;
29357ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_txsize:", 11)) {
2936ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &dma_txsize))
29377ac6653aSJeff Kirsher 				goto err;
29387ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "dma_rxsize:", 11)) {
2939ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &dma_rxsize))
29407ac6653aSJeff Kirsher 				goto err;
29417ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "buf_sz:", 7)) {
2942ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 7, 0, &buf_sz))
29437ac6653aSJeff Kirsher 				goto err;
29447ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "tc:", 3)) {
2945ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 3, 0, &tc))
29467ac6653aSJeff Kirsher 				goto err;
29477ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "watchdog:", 9)) {
2948ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 9, 0, &watchdog))
29497ac6653aSJeff Kirsher 				goto err;
29507ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "flow_ctrl:", 10)) {
2951ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 10, 0, &flow_ctrl))
29527ac6653aSJeff Kirsher 				goto err;
29537ac6653aSJeff Kirsher 		} else if (!strncmp(opt, "pause:", 6)) {
2954ea2ab871SGiuseppe CAVALLARO 			if (kstrtoint(opt + 6, 0, &pause))
29557ac6653aSJeff Kirsher 				goto err;
2956506f669cSGiuseppe CAVALLARO 		} else if (!strncmp(opt, "eee_timer:", 10)) {
2957d765955dSGiuseppe CAVALLARO 			if (kstrtoint(opt + 10, 0, &eee_timer))
2958d765955dSGiuseppe CAVALLARO 				goto err;
29594a7d666aSGiuseppe CAVALLARO 		} else if (!strncmp(opt, "chain_mode:", 11)) {
29604a7d666aSGiuseppe CAVALLARO 			if (kstrtoint(opt + 11, 0, &chain_mode))
29614a7d666aSGiuseppe CAVALLARO 				goto err;
29627ac6653aSJeff Kirsher 		}
29637ac6653aSJeff Kirsher 	}
29647ac6653aSJeff Kirsher 	return 0;
29657ac6653aSJeff Kirsher 
29667ac6653aSJeff Kirsher err:
29677ac6653aSJeff Kirsher 	pr_err("%s: ERROR broken module parameter conversion", __func__);
29687ac6653aSJeff Kirsher 	return -EINVAL;
29697ac6653aSJeff Kirsher }
29707ac6653aSJeff Kirsher 
29717ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt);
2972ceb69499SGiuseppe CAVALLARO #endif /* MODULE */
29736fc0d0f2SGiuseppe Cavallaro 
29746fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
29756fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
29766fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL");
2977