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> 46db88f10aSSrinivas Kandagatla #include <linux/pinctrl/consumer.h> 477ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 487ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h> 497ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h> 50ceb69499SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 51891434b1SRayagond Kokatanur #include <linux/net_tstamp.h> 52891434b1SRayagond Kokatanur #include "stmmac_ptp.h" 53286a8372SGiuseppe CAVALLARO #include "stmmac.h" 54c5e4ddbdSChen-Yu Tsai #include <linux/reset.h> 557ac6653aSJeff Kirsher 567ac6653aSJeff Kirsher #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) 577ac6653aSJeff Kirsher 587ac6653aSJeff Kirsher /* Module parameters */ 5932ceabcaSGiuseppe CAVALLARO #define TX_TIMEO 5000 607ac6653aSJeff Kirsher static int watchdog = TX_TIMEO; 617ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR); 6232ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds (default 5s)"); 637ac6653aSJeff Kirsher 6432ceabcaSGiuseppe CAVALLARO static int debug = -1; 657ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR); 6632ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); 677ac6653aSJeff Kirsher 6847d1f71fSstephen hemminger static int phyaddr = -1; 697ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO); 707ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address"); 717ac6653aSJeff Kirsher 727ac6653aSJeff Kirsher #define DMA_TX_SIZE 256 737ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE; 747ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR); 757ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list"); 767ac6653aSJeff Kirsher 777ac6653aSJeff Kirsher #define DMA_RX_SIZE 256 787ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE; 797ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR); 807ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list"); 817ac6653aSJeff Kirsher 827ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF; 837ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); 847ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); 857ac6653aSJeff Kirsher 867ac6653aSJeff Kirsher static int pause = PAUSE_TIME; 877ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR); 887ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time"); 897ac6653aSJeff Kirsher 907ac6653aSJeff Kirsher #define TC_DEFAULT 64 917ac6653aSJeff Kirsher static int tc = TC_DEFAULT; 927ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR); 937ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value"); 947ac6653aSJeff Kirsher 95d916701cSGiuseppe CAVALLARO #define DEFAULT_BUFSIZE 1536 96d916701cSGiuseppe CAVALLARO static int buf_sz = DEFAULT_BUFSIZE; 977ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 987ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 997ac6653aSJeff Kirsher 1007ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1017ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1027ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1037ac6653aSJeff Kirsher 104d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER 1000 105d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; 106d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR); 107d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); 108f5351ef7SGiuseppe CAVALLARO #define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x)) 109d765955dSGiuseppe CAVALLARO 1104a7d666aSGiuseppe CAVALLARO /* By default the driver will use the ring mode to manage tx and rx descriptors 1114a7d666aSGiuseppe CAVALLARO * but passing this value so user can force to use the chain instead of the ring 1124a7d666aSGiuseppe CAVALLARO */ 1134a7d666aSGiuseppe CAVALLARO static unsigned int chain_mode; 1144a7d666aSGiuseppe CAVALLARO module_param(chain_mode, int, S_IRUGO); 1154a7d666aSGiuseppe CAVALLARO MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode"); 1164a7d666aSGiuseppe CAVALLARO 1177ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1187ac6653aSJeff Kirsher 119bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 120bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev); 121bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void); 122bfab27a1SGiuseppe CAVALLARO #endif 123bfab27a1SGiuseppe CAVALLARO 1249125cdd1SGiuseppe CAVALLARO #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) 1259125cdd1SGiuseppe CAVALLARO 1267ac6653aSJeff Kirsher /** 1277ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1287ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1297ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1307ac6653aSJeff Kirsher */ 1317ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1327ac6653aSJeff Kirsher { 1337ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1347ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1357ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1367ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1377ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1387ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 139d916701cSGiuseppe CAVALLARO if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB))) 140d916701cSGiuseppe CAVALLARO buf_sz = DEFAULT_BUFSIZE; 1417ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1427ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1437ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1447ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1457ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1467ac6653aSJeff Kirsher pause = PAUSE_TIME; 147d765955dSGiuseppe CAVALLARO if (eee_timer < 0) 148d765955dSGiuseppe CAVALLARO eee_timer = STMMAC_DEFAULT_LPI_TIMER; 1497ac6653aSJeff Kirsher } 1507ac6653aSJeff Kirsher 15132ceabcaSGiuseppe CAVALLARO /** 15232ceabcaSGiuseppe CAVALLARO * stmmac_clk_csr_set - dynamically set the MDC clock 15332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 15432ceabcaSGiuseppe CAVALLARO * Description: this is to dynamically set the MDC clock according to the csr 15532ceabcaSGiuseppe CAVALLARO * clock input. 15632ceabcaSGiuseppe CAVALLARO * Note: 15732ceabcaSGiuseppe CAVALLARO * If a specific clk_csr value is passed from the platform 15832ceabcaSGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 15932ceabcaSGiuseppe CAVALLARO * changed at run-time and it is fixed (as reported in the driver 16032ceabcaSGiuseppe CAVALLARO * documentation). Viceversa the driver will try to set the MDC 16132ceabcaSGiuseppe CAVALLARO * clock dynamically according to the actual clock input. 16232ceabcaSGiuseppe CAVALLARO */ 163cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv) 164cd7201f4SGiuseppe CAVALLARO { 165cd7201f4SGiuseppe CAVALLARO u32 clk_rate; 166cd7201f4SGiuseppe CAVALLARO 167cd7201f4SGiuseppe CAVALLARO clk_rate = clk_get_rate(priv->stmmac_clk); 168cd7201f4SGiuseppe CAVALLARO 169cd7201f4SGiuseppe CAVALLARO /* Platform provided default clk_csr would be assumed valid 170ceb69499SGiuseppe CAVALLARO * for all other cases except for the below mentioned ones. 171ceb69499SGiuseppe CAVALLARO * For values higher than the IEEE 802.3 specified frequency 172ceb69499SGiuseppe CAVALLARO * we can not estimate the proper divider as it is not known 173ceb69499SGiuseppe CAVALLARO * the frequency of clk_csr_i. So we do not change the default 174ceb69499SGiuseppe CAVALLARO * divider. 175ceb69499SGiuseppe CAVALLARO */ 176cd7201f4SGiuseppe CAVALLARO if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) { 177cd7201f4SGiuseppe CAVALLARO if (clk_rate < CSR_F_35M) 178cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_20_35M; 179cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M)) 180cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_35_60M; 181cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M)) 182cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_60_100M; 183cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M)) 184cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_100_150M; 185cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) 186cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_150_250M; 187cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) 188cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_250_300M; 189ceb69499SGiuseppe CAVALLARO } 190cd7201f4SGiuseppe CAVALLARO } 191cd7201f4SGiuseppe CAVALLARO 1927ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1937ac6653aSJeff Kirsher { 1947ac6653aSJeff Kirsher int j; 19583d7af64SGiuseppe CAVALLARO pr_debug("len = %d byte, buf addr: 0x%p", len, buf); 1967ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 1977ac6653aSJeff Kirsher if ((j % 16) == 0) 19883d7af64SGiuseppe CAVALLARO pr_debug("\n %03x:", j); 19983d7af64SGiuseppe CAVALLARO pr_debug(" %02x", buf[j]); 2007ac6653aSJeff Kirsher } 20183d7af64SGiuseppe CAVALLARO pr_debug("\n"); 2027ac6653aSJeff Kirsher } 2037ac6653aSJeff Kirsher 2047ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 2057ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 2067ac6653aSJeff Kirsher 2077ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 2087ac6653aSJeff Kirsher { 2097ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 2107ac6653aSJeff Kirsher } 2117ac6653aSJeff Kirsher 21232ceabcaSGiuseppe CAVALLARO /** 21332ceabcaSGiuseppe CAVALLARO * stmmac_hw_fix_mac_speed: callback for speed selection 21432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 21532ceabcaSGiuseppe CAVALLARO * Description: on some platforms (e.g. ST), some HW system configuraton 21632ceabcaSGiuseppe CAVALLARO * registers have to be set according to the link speed negotiated. 2177ac6653aSJeff Kirsher */ 2187ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 2197ac6653aSJeff Kirsher { 2207ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2217ac6653aSJeff Kirsher 2227ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 223ceb69499SGiuseppe CAVALLARO priv->plat->fix_mac_speed(priv->plat->bsp_priv, phydev->speed); 2247ac6653aSJeff Kirsher } 2257ac6653aSJeff Kirsher 22632ceabcaSGiuseppe CAVALLARO /** 22732ceabcaSGiuseppe CAVALLARO * stmmac_enable_eee_mode: Check and enter in LPI mode 22832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 22932ceabcaSGiuseppe CAVALLARO * Description: this function is to verify and enter in LPI mode for EEE. 23032ceabcaSGiuseppe CAVALLARO */ 231d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv) 232d765955dSGiuseppe CAVALLARO { 233d765955dSGiuseppe CAVALLARO /* Check and enter in LPI mode */ 234d765955dSGiuseppe CAVALLARO if ((priv->dirty_tx == priv->cur_tx) && 235d765955dSGiuseppe CAVALLARO (priv->tx_path_in_lpi_mode == false)) 236d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_mode(priv->ioaddr); 237d765955dSGiuseppe CAVALLARO } 238d765955dSGiuseppe CAVALLARO 23932ceabcaSGiuseppe CAVALLARO /** 24032ceabcaSGiuseppe CAVALLARO * stmmac_disable_eee_mode: disable/exit from EEE 24132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 24232ceabcaSGiuseppe CAVALLARO * Description: this function is to exit and disable EEE in case of 24332ceabcaSGiuseppe CAVALLARO * LPI state is true. This is called by the xmit. 24432ceabcaSGiuseppe CAVALLARO */ 245d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv) 246d765955dSGiuseppe CAVALLARO { 247d765955dSGiuseppe CAVALLARO priv->hw->mac->reset_eee_mode(priv->ioaddr); 248d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 249d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 250d765955dSGiuseppe CAVALLARO } 251d765955dSGiuseppe CAVALLARO 252d765955dSGiuseppe CAVALLARO /** 25332ceabcaSGiuseppe CAVALLARO * stmmac_eee_ctrl_timer: EEE TX SW timer. 254d765955dSGiuseppe CAVALLARO * @arg : data hook 255d765955dSGiuseppe CAVALLARO * Description: 25632ceabcaSGiuseppe CAVALLARO * if there is no data transfer and if we are not in LPI state, 257d765955dSGiuseppe CAVALLARO * then MAC Transmitter can be moved to LPI state. 258d765955dSGiuseppe CAVALLARO */ 259d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg) 260d765955dSGiuseppe CAVALLARO { 261d765955dSGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)arg; 262d765955dSGiuseppe CAVALLARO 263d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 264f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 265d765955dSGiuseppe CAVALLARO } 266d765955dSGiuseppe CAVALLARO 267d765955dSGiuseppe CAVALLARO /** 26832ceabcaSGiuseppe CAVALLARO * stmmac_eee_init: init EEE 26932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 270d765955dSGiuseppe CAVALLARO * Description: 271d765955dSGiuseppe CAVALLARO * If the EEE support has been enabled while configuring the driver, 272d765955dSGiuseppe CAVALLARO * if the GMAC actually supports the EEE (from the HW cap reg) and the 273d765955dSGiuseppe CAVALLARO * phy can also manage EEE, so enable the LPI state and start the timer 274d765955dSGiuseppe CAVALLARO * to verify if the tx path can enter in LPI state. 275d765955dSGiuseppe CAVALLARO */ 276d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv) 277d765955dSGiuseppe CAVALLARO { 278d765955dSGiuseppe CAVALLARO bool ret = false; 279d765955dSGiuseppe CAVALLARO 280f5351ef7SGiuseppe CAVALLARO /* Using PCS we cannot dial with the phy registers at this stage 281f5351ef7SGiuseppe CAVALLARO * so we do not support extra feature like EEE. 282f5351ef7SGiuseppe CAVALLARO */ 283f5351ef7SGiuseppe CAVALLARO if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) || 284f5351ef7SGiuseppe CAVALLARO (priv->pcs == STMMAC_PCS_RTBI)) 285f5351ef7SGiuseppe CAVALLARO goto out; 286f5351ef7SGiuseppe CAVALLARO 287d765955dSGiuseppe CAVALLARO /* MAC core supports the EEE feature. */ 288d765955dSGiuseppe CAVALLARO if (priv->dma_cap.eee) { 28983bf79b6SGiuseppe CAVALLARO int tx_lpi_timer = priv->tx_lpi_timer; 290d765955dSGiuseppe CAVALLARO 29183bf79b6SGiuseppe CAVALLARO /* Check if the PHY supports EEE */ 29283bf79b6SGiuseppe CAVALLARO if (phy_init_eee(priv->phydev, 1)) { 29383bf79b6SGiuseppe CAVALLARO /* To manage at run-time if the EEE cannot be supported 29483bf79b6SGiuseppe CAVALLARO * anymore (for example because the lp caps have been 29583bf79b6SGiuseppe CAVALLARO * changed). 29683bf79b6SGiuseppe CAVALLARO * In that case the driver disable own timers. 29783bf79b6SGiuseppe CAVALLARO */ 29883bf79b6SGiuseppe CAVALLARO if (priv->eee_active) { 29983bf79b6SGiuseppe CAVALLARO pr_debug("stmmac: disable EEE\n"); 30083bf79b6SGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 30183bf79b6SGiuseppe CAVALLARO priv->hw->mac->set_eee_timer(priv->ioaddr, 0, 30283bf79b6SGiuseppe CAVALLARO tx_lpi_timer); 30383bf79b6SGiuseppe CAVALLARO } 30483bf79b6SGiuseppe CAVALLARO priv->eee_active = 0; 30583bf79b6SGiuseppe CAVALLARO goto out; 30683bf79b6SGiuseppe CAVALLARO } 30783bf79b6SGiuseppe CAVALLARO /* Activate the EEE and start timers */ 308f5351ef7SGiuseppe CAVALLARO if (!priv->eee_active) { 309d765955dSGiuseppe CAVALLARO priv->eee_active = 1; 310d765955dSGiuseppe CAVALLARO init_timer(&priv->eee_ctrl_timer); 311d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; 312d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.data = (unsigned long)priv; 313f5351ef7SGiuseppe CAVALLARO priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer); 314d765955dSGiuseppe CAVALLARO add_timer(&priv->eee_ctrl_timer); 315d765955dSGiuseppe CAVALLARO 316d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_timer(priv->ioaddr, 317f5351ef7SGiuseppe CAVALLARO STMMAC_DEFAULT_LIT_LS, 31883bf79b6SGiuseppe CAVALLARO tx_lpi_timer); 319f5351ef7SGiuseppe CAVALLARO } else 320f5351ef7SGiuseppe CAVALLARO /* Set HW EEE according to the speed */ 321f5351ef7SGiuseppe CAVALLARO priv->hw->mac->set_eee_pls(priv->ioaddr, 322f5351ef7SGiuseppe CAVALLARO priv->phydev->link); 323d765955dSGiuseppe CAVALLARO 32483bf79b6SGiuseppe CAVALLARO pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); 325d765955dSGiuseppe CAVALLARO 326d765955dSGiuseppe CAVALLARO ret = true; 327d765955dSGiuseppe CAVALLARO } 328d765955dSGiuseppe CAVALLARO out: 329d765955dSGiuseppe CAVALLARO return ret; 330d765955dSGiuseppe CAVALLARO } 331d765955dSGiuseppe CAVALLARO 33232ceabcaSGiuseppe CAVALLARO /* stmmac_get_tx_hwtstamp: get HW TX timestamps 33332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 334891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 335891434b1SRayagond Kokatanur * @skb : the socket buffer 336891434b1SRayagond Kokatanur * Description : 337891434b1SRayagond Kokatanur * This function will read timestamp from the descriptor & pass it to stack. 338891434b1SRayagond Kokatanur * and also perform some sanity checks. 339891434b1SRayagond Kokatanur */ 340891434b1SRayagond Kokatanur static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, 341ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 342891434b1SRayagond Kokatanur { 343891434b1SRayagond Kokatanur struct skb_shared_hwtstamps shhwtstamp; 344891434b1SRayagond Kokatanur u64 ns; 345891434b1SRayagond Kokatanur void *desc = NULL; 346891434b1SRayagond Kokatanur 347891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 348891434b1SRayagond Kokatanur return; 349891434b1SRayagond Kokatanur 350ceb69499SGiuseppe CAVALLARO /* exit if skb doesn't support hw tstamp */ 35175e4364fSdamuzi000 if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))) 352891434b1SRayagond Kokatanur return; 353891434b1SRayagond Kokatanur 354891434b1SRayagond Kokatanur if (priv->adv_ts) 355891434b1SRayagond Kokatanur desc = (priv->dma_etx + entry); 356891434b1SRayagond Kokatanur else 357891434b1SRayagond Kokatanur desc = (priv->dma_tx + entry); 358891434b1SRayagond Kokatanur 359891434b1SRayagond Kokatanur /* check tx tstamp status */ 360891434b1SRayagond Kokatanur if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc)) 361891434b1SRayagond Kokatanur return; 362891434b1SRayagond Kokatanur 363891434b1SRayagond Kokatanur /* get the valid tstamp */ 364891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 365891434b1SRayagond Kokatanur 366891434b1SRayagond Kokatanur memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 367891434b1SRayagond Kokatanur shhwtstamp.hwtstamp = ns_to_ktime(ns); 368891434b1SRayagond Kokatanur /* pass tstamp to stack */ 369891434b1SRayagond Kokatanur skb_tstamp_tx(skb, &shhwtstamp); 370891434b1SRayagond Kokatanur 371891434b1SRayagond Kokatanur return; 372891434b1SRayagond Kokatanur } 373891434b1SRayagond Kokatanur 37432ceabcaSGiuseppe CAVALLARO /* stmmac_get_rx_hwtstamp: get HW RX timestamps 37532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 376891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 377891434b1SRayagond Kokatanur * @skb : the socket buffer 378891434b1SRayagond Kokatanur * Description : 379891434b1SRayagond Kokatanur * This function will read received packet's timestamp from the descriptor 380891434b1SRayagond Kokatanur * and pass it to stack. It also perform some sanity checks. 381891434b1SRayagond Kokatanur */ 382891434b1SRayagond Kokatanur static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, 383ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 384891434b1SRayagond Kokatanur { 385891434b1SRayagond Kokatanur struct skb_shared_hwtstamps *shhwtstamp = NULL; 386891434b1SRayagond Kokatanur u64 ns; 387891434b1SRayagond Kokatanur void *desc = NULL; 388891434b1SRayagond Kokatanur 389891434b1SRayagond Kokatanur if (!priv->hwts_rx_en) 390891434b1SRayagond Kokatanur return; 391891434b1SRayagond Kokatanur 392891434b1SRayagond Kokatanur if (priv->adv_ts) 393891434b1SRayagond Kokatanur desc = (priv->dma_erx + entry); 394891434b1SRayagond Kokatanur else 395891434b1SRayagond Kokatanur desc = (priv->dma_rx + entry); 396891434b1SRayagond Kokatanur 397ceb69499SGiuseppe CAVALLARO /* exit if rx tstamp is not valid */ 398891434b1SRayagond Kokatanur if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) 399891434b1SRayagond Kokatanur return; 400891434b1SRayagond Kokatanur 401891434b1SRayagond Kokatanur /* get valid tstamp */ 402891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 403891434b1SRayagond Kokatanur shhwtstamp = skb_hwtstamps(skb); 404891434b1SRayagond Kokatanur memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 405891434b1SRayagond Kokatanur shhwtstamp->hwtstamp = ns_to_ktime(ns); 406891434b1SRayagond Kokatanur } 407891434b1SRayagond Kokatanur 408891434b1SRayagond Kokatanur /** 409891434b1SRayagond Kokatanur * stmmac_hwtstamp_ioctl - control hardware timestamping. 410891434b1SRayagond Kokatanur * @dev: device pointer. 411891434b1SRayagond Kokatanur * @ifr: An IOCTL specefic structure, that can contain a pointer to 412891434b1SRayagond Kokatanur * a proprietary structure used to pass information to the driver. 413891434b1SRayagond Kokatanur * Description: 414891434b1SRayagond Kokatanur * This function configures the MAC to enable/disable both outgoing(TX) 415891434b1SRayagond Kokatanur * and incoming(RX) packets time stamping based on user input. 416891434b1SRayagond Kokatanur * Return Value: 417891434b1SRayagond Kokatanur * 0 on success and an appropriate -ve integer on failure. 418891434b1SRayagond Kokatanur */ 419891434b1SRayagond Kokatanur static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) 420891434b1SRayagond Kokatanur { 421891434b1SRayagond Kokatanur struct stmmac_priv *priv = netdev_priv(dev); 422891434b1SRayagond Kokatanur struct hwtstamp_config config; 423891434b1SRayagond Kokatanur struct timespec now; 424891434b1SRayagond Kokatanur u64 temp = 0; 425891434b1SRayagond Kokatanur u32 ptp_v2 = 0; 426891434b1SRayagond Kokatanur u32 tstamp_all = 0; 427891434b1SRayagond Kokatanur u32 ptp_over_ipv4_udp = 0; 428891434b1SRayagond Kokatanur u32 ptp_over_ipv6_udp = 0; 429891434b1SRayagond Kokatanur u32 ptp_over_ethernet = 0; 430891434b1SRayagond Kokatanur u32 snap_type_sel = 0; 431891434b1SRayagond Kokatanur u32 ts_master_en = 0; 432891434b1SRayagond Kokatanur u32 ts_event_en = 0; 433891434b1SRayagond Kokatanur u32 value = 0; 434891434b1SRayagond Kokatanur 435891434b1SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { 436891434b1SRayagond Kokatanur netdev_alert(priv->dev, "No support for HW time stamping\n"); 437891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 438891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 439891434b1SRayagond Kokatanur 440891434b1SRayagond Kokatanur return -EOPNOTSUPP; 441891434b1SRayagond Kokatanur } 442891434b1SRayagond Kokatanur 443891434b1SRayagond Kokatanur if (copy_from_user(&config, ifr->ifr_data, 444891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config))) 445891434b1SRayagond Kokatanur return -EFAULT; 446891434b1SRayagond Kokatanur 447891434b1SRayagond Kokatanur pr_debug("%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n", 448891434b1SRayagond Kokatanur __func__, config.flags, config.tx_type, config.rx_filter); 449891434b1SRayagond Kokatanur 450891434b1SRayagond Kokatanur /* reserved for future extensions */ 451891434b1SRayagond Kokatanur if (config.flags) 452891434b1SRayagond Kokatanur return -EINVAL; 453891434b1SRayagond Kokatanur 4545f3da328SBen Hutchings if (config.tx_type != HWTSTAMP_TX_OFF && 4555f3da328SBen Hutchings config.tx_type != HWTSTAMP_TX_ON) 456891434b1SRayagond Kokatanur return -ERANGE; 457891434b1SRayagond Kokatanur 458891434b1SRayagond Kokatanur if (priv->adv_ts) { 459891434b1SRayagond Kokatanur switch (config.rx_filter) { 460891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 461ceb69499SGiuseppe CAVALLARO /* time stamp no incoming packet at all */ 462891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 463891434b1SRayagond Kokatanur break; 464891434b1SRayagond Kokatanur 465891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 466ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, any kind of event packet */ 467891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 468891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 469891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 470891434b1SRayagond Kokatanur 471891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 472891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 473891434b1SRayagond Kokatanur break; 474891434b1SRayagond Kokatanur 475891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 476ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Sync packet */ 477891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; 478891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 479891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 480891434b1SRayagond Kokatanur 481891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 482891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 483891434b1SRayagond Kokatanur break; 484891434b1SRayagond Kokatanur 485891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 486ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Delay_req packet */ 487891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; 488891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 489891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 490891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 491891434b1SRayagond Kokatanur 492891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 493891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 494891434b1SRayagond Kokatanur break; 495891434b1SRayagond Kokatanur 496891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 497ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, any kind of event packet */ 498891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 499891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 500891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 501891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 502891434b1SRayagond Kokatanur 503891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 504891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 505891434b1SRayagond Kokatanur break; 506891434b1SRayagond Kokatanur 507891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 508ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Sync packet */ 509891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; 510891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 511891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 512891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 513891434b1SRayagond Kokatanur 514891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 515891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 516891434b1SRayagond Kokatanur break; 517891434b1SRayagond Kokatanur 518891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 519ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Delay_req packet */ 520891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; 521891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 522891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 523891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 524891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 525891434b1SRayagond Kokatanur 526891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 527891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 528891434b1SRayagond Kokatanur break; 529891434b1SRayagond Kokatanur 530891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_EVENT: 531ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1 any layer, any kind of event packet */ 532891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 533891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 534891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 535891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 536891434b1SRayagond Kokatanur 537891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 538891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 539891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 540891434b1SRayagond Kokatanur break; 541891434b1SRayagond Kokatanur 542891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_SYNC: 543ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Sync packet */ 544891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 545891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 546891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 547891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 548891434b1SRayagond Kokatanur 549891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 550891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 551891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 552891434b1SRayagond Kokatanur break; 553891434b1SRayagond Kokatanur 554891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 555ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Delay_req packet */ 556891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 557891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 558891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 559891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 560891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 561891434b1SRayagond Kokatanur 562891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 563891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 564891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 565891434b1SRayagond Kokatanur break; 566891434b1SRayagond Kokatanur 567891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_ALL: 568ceb69499SGiuseppe CAVALLARO /* time stamp any incoming packet */ 569891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_ALL; 570891434b1SRayagond Kokatanur tstamp_all = PTP_TCR_TSENALL; 571891434b1SRayagond Kokatanur break; 572891434b1SRayagond Kokatanur 573891434b1SRayagond Kokatanur default: 574891434b1SRayagond Kokatanur return -ERANGE; 575891434b1SRayagond Kokatanur } 576891434b1SRayagond Kokatanur } else { 577891434b1SRayagond Kokatanur switch (config.rx_filter) { 578891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 579891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 580891434b1SRayagond Kokatanur break; 581891434b1SRayagond Kokatanur default: 582891434b1SRayagond Kokatanur /* PTP v1, UDP, any kind of event packet */ 583891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 584891434b1SRayagond Kokatanur break; 585891434b1SRayagond Kokatanur } 586891434b1SRayagond Kokatanur } 587891434b1SRayagond Kokatanur priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1); 5885f3da328SBen Hutchings priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; 589891434b1SRayagond Kokatanur 590891434b1SRayagond Kokatanur if (!priv->hwts_tx_en && !priv->hwts_rx_en) 591891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0); 592891434b1SRayagond Kokatanur else { 593891434b1SRayagond Kokatanur value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR | 594891434b1SRayagond Kokatanur tstamp_all | ptp_v2 | ptp_over_ethernet | 595891434b1SRayagond Kokatanur ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en | 596891434b1SRayagond Kokatanur ts_master_en | snap_type_sel); 597891434b1SRayagond Kokatanur 598891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value); 599891434b1SRayagond Kokatanur 600891434b1SRayagond Kokatanur /* program Sub Second Increment reg */ 601891434b1SRayagond Kokatanur priv->hw->ptp->config_sub_second_increment(priv->ioaddr); 602891434b1SRayagond Kokatanur 603891434b1SRayagond Kokatanur /* calculate default added value: 604891434b1SRayagond Kokatanur * formula is : 605891434b1SRayagond Kokatanur * addend = (2^32)/freq_div_ratio; 606891434b1SRayagond Kokatanur * where, freq_div_ratio = STMMAC_SYSCLOCK/50MHz 607891434b1SRayagond Kokatanur * hence, addend = ((2^32) * 50MHz)/STMMAC_SYSCLOCK; 608891434b1SRayagond Kokatanur * NOTE: STMMAC_SYSCLOCK should be >= 50MHz to 609891434b1SRayagond Kokatanur * achive 20ns accuracy. 610891434b1SRayagond Kokatanur * 611891434b1SRayagond Kokatanur * 2^x * y == (y << x), hence 612891434b1SRayagond Kokatanur * 2^32 * 50000000 ==> (50000000 << 32) 613891434b1SRayagond Kokatanur */ 614891434b1SRayagond Kokatanur temp = (u64) (50000000ULL << 32); 615891434b1SRayagond Kokatanur priv->default_addend = div_u64(temp, STMMAC_SYSCLOCK); 616891434b1SRayagond Kokatanur priv->hw->ptp->config_addend(priv->ioaddr, 617891434b1SRayagond Kokatanur priv->default_addend); 618891434b1SRayagond Kokatanur 619891434b1SRayagond Kokatanur /* initialize system time */ 620891434b1SRayagond Kokatanur getnstimeofday(&now); 621891434b1SRayagond Kokatanur priv->hw->ptp->init_systime(priv->ioaddr, now.tv_sec, 622891434b1SRayagond Kokatanur now.tv_nsec); 623891434b1SRayagond Kokatanur } 624891434b1SRayagond Kokatanur 625891434b1SRayagond Kokatanur return copy_to_user(ifr->ifr_data, &config, 626891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config)) ? -EFAULT : 0; 627891434b1SRayagond Kokatanur } 628891434b1SRayagond Kokatanur 62932ceabcaSGiuseppe CAVALLARO /** 63032ceabcaSGiuseppe CAVALLARO * stmmac_init_ptp: init PTP 63132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 63232ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PTPv1 or v2. 63332ceabcaSGiuseppe CAVALLARO * This is done by looking at the HW cap. register. 63432ceabcaSGiuseppe CAVALLARO * Also it registers the ptp driver. 63532ceabcaSGiuseppe CAVALLARO */ 63692ba6888SRayagond Kokatanur static int stmmac_init_ptp(struct stmmac_priv *priv) 637891434b1SRayagond Kokatanur { 63892ba6888SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) 63992ba6888SRayagond Kokatanur return -EOPNOTSUPP; 64092ba6888SRayagond Kokatanur 641891434b1SRayagond Kokatanur priv->adv_ts = 0; 6427cd01399SVince Bridgers if (priv->dma_cap.atime_stamp && priv->extend_desc) 643891434b1SRayagond Kokatanur priv->adv_ts = 1; 6447cd01399SVince Bridgers 6457cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->dma_cap.time_stamp) 6467cd01399SVince Bridgers pr_debug("IEEE 1588-2002 Time Stamp supported\n"); 6477cd01399SVince Bridgers 6487cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->adv_ts) 6497cd01399SVince Bridgers pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); 650891434b1SRayagond Kokatanur 651891434b1SRayagond Kokatanur priv->hw->ptp = &stmmac_ptp; 652891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 653891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 65492ba6888SRayagond Kokatanur 65592ba6888SRayagond Kokatanur return stmmac_ptp_register(priv); 65692ba6888SRayagond Kokatanur } 65792ba6888SRayagond Kokatanur 65892ba6888SRayagond Kokatanur static void stmmac_release_ptp(struct stmmac_priv *priv) 65992ba6888SRayagond Kokatanur { 66092ba6888SRayagond Kokatanur stmmac_ptp_unregister(priv); 661891434b1SRayagond Kokatanur } 662891434b1SRayagond Kokatanur 6637ac6653aSJeff Kirsher /** 6647ac6653aSJeff Kirsher * stmmac_adjust_link 6657ac6653aSJeff Kirsher * @dev: net device structure 6667ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 6677ac6653aSJeff Kirsher */ 6687ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 6697ac6653aSJeff Kirsher { 6707ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 6717ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 6727ac6653aSJeff Kirsher unsigned long flags; 6737ac6653aSJeff Kirsher int new_state = 0; 6747ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 6757ac6653aSJeff Kirsher 6767ac6653aSJeff Kirsher if (phydev == NULL) 6777ac6653aSJeff Kirsher return; 6787ac6653aSJeff Kirsher 6797ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 680d765955dSGiuseppe CAVALLARO 6817ac6653aSJeff Kirsher if (phydev->link) { 6827ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 6837ac6653aSJeff Kirsher 6847ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 6857ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 6867ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 6877ac6653aSJeff Kirsher new_state = 1; 6887ac6653aSJeff Kirsher if (!(phydev->duplex)) 6897ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 6907ac6653aSJeff Kirsher else 6917ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 6927ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 6937ac6653aSJeff Kirsher } 6947ac6653aSJeff Kirsher /* Flow Control operation */ 6957ac6653aSJeff Kirsher if (phydev->pause) 6967ac6653aSJeff Kirsher priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, 6977ac6653aSJeff Kirsher fc, pause_time); 6987ac6653aSJeff Kirsher 6997ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 7007ac6653aSJeff Kirsher new_state = 1; 7017ac6653aSJeff Kirsher switch (phydev->speed) { 7027ac6653aSJeff Kirsher case 1000: 7037ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 7047ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7057ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7067ac6653aSJeff Kirsher break; 7077ac6653aSJeff Kirsher case 100: 7087ac6653aSJeff Kirsher case 10: 7097ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 7107ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 7117ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 7127ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 7137ac6653aSJeff Kirsher } else { 7147ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 7157ac6653aSJeff Kirsher } 7167ac6653aSJeff Kirsher } else { 7177ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7187ac6653aSJeff Kirsher } 7197ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7207ac6653aSJeff Kirsher break; 7217ac6653aSJeff Kirsher default: 7227ac6653aSJeff Kirsher if (netif_msg_link(priv)) 723ceb69499SGiuseppe CAVALLARO pr_warn("%s: Speed (%d) not 10/100\n", 724ceb69499SGiuseppe CAVALLARO dev->name, phydev->speed); 7257ac6653aSJeff Kirsher break; 7267ac6653aSJeff Kirsher } 7277ac6653aSJeff Kirsher 7287ac6653aSJeff Kirsher priv->speed = phydev->speed; 7297ac6653aSJeff Kirsher } 7307ac6653aSJeff Kirsher 7317ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 7327ac6653aSJeff Kirsher 7337ac6653aSJeff Kirsher if (!priv->oldlink) { 7347ac6653aSJeff Kirsher new_state = 1; 7357ac6653aSJeff Kirsher priv->oldlink = 1; 7367ac6653aSJeff Kirsher } 7377ac6653aSJeff Kirsher } else if (priv->oldlink) { 7387ac6653aSJeff Kirsher new_state = 1; 7397ac6653aSJeff Kirsher priv->oldlink = 0; 7407ac6653aSJeff Kirsher priv->speed = 0; 7417ac6653aSJeff Kirsher priv->oldduplex = -1; 7427ac6653aSJeff Kirsher } 7437ac6653aSJeff Kirsher 7447ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 7457ac6653aSJeff Kirsher phy_print_status(phydev); 7467ac6653aSJeff Kirsher 747f5351ef7SGiuseppe CAVALLARO /* At this stage, it could be needed to setup the EEE or adjust some 748f5351ef7SGiuseppe CAVALLARO * MAC related HW registers. 749f5351ef7SGiuseppe CAVALLARO */ 750f5351ef7SGiuseppe CAVALLARO priv->eee_enabled = stmmac_eee_init(priv); 751d765955dSGiuseppe CAVALLARO 7527ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 7537ac6653aSJeff Kirsher } 7547ac6653aSJeff Kirsher 75532ceabcaSGiuseppe CAVALLARO /** 75632ceabcaSGiuseppe CAVALLARO * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported 75732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 75832ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PCS. 75932ceabcaSGiuseppe CAVALLARO * Physical Coding Sublayer (PCS) interface that can be used when the MAC is 76032ceabcaSGiuseppe CAVALLARO * configured for the TBI, RTBI, or SGMII PHY interface. 76132ceabcaSGiuseppe CAVALLARO */ 762e58bb43fSGiuseppe CAVALLARO static void stmmac_check_pcs_mode(struct stmmac_priv *priv) 763e58bb43fSGiuseppe CAVALLARO { 764e58bb43fSGiuseppe CAVALLARO int interface = priv->plat->interface; 765e58bb43fSGiuseppe CAVALLARO 766e58bb43fSGiuseppe CAVALLARO if (priv->dma_cap.pcs) { 7670d909dcdSByungho An if ((interface == PHY_INTERFACE_MODE_RGMII) || 7680d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_ID) || 7690d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_RXID) || 7700d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_TXID)) { 771e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS RGMII support enable\n"); 772e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_RGMII; 7730d909dcdSByungho An } else if (interface == PHY_INTERFACE_MODE_SGMII) { 774e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS SGMII support enable\n"); 775e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_SGMII; 776e58bb43fSGiuseppe CAVALLARO } 777e58bb43fSGiuseppe CAVALLARO } 778e58bb43fSGiuseppe CAVALLARO } 779e58bb43fSGiuseppe CAVALLARO 7807ac6653aSJeff Kirsher /** 7817ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 7827ac6653aSJeff Kirsher * @dev: net device structure 7837ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 7847ac6653aSJeff Kirsher * to the mac driver. 7857ac6653aSJeff Kirsher * Return value: 7867ac6653aSJeff Kirsher * 0 on success 7877ac6653aSJeff Kirsher */ 7887ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 7897ac6653aSJeff Kirsher { 7907ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 7917ac6653aSJeff Kirsher struct phy_device *phydev; 792d765955dSGiuseppe CAVALLARO char phy_id_fmt[MII_BUS_ID_SIZE + 3]; 7937ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 79479ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 7959cbadf09SSrinivas Kandagatla int max_speed = priv->plat->max_speed; 7967ac6653aSJeff Kirsher priv->oldlink = 0; 7977ac6653aSJeff Kirsher priv->speed = 0; 7987ac6653aSJeff Kirsher priv->oldduplex = -1; 7997ac6653aSJeff Kirsher 800f142af2eSSrinivas Kandagatla if (priv->plat->phy_bus_name) 801f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", 802f142af2eSSrinivas Kandagatla priv->plat->phy_bus_name, priv->plat->bus_id); 803f142af2eSSrinivas Kandagatla else 804f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", 805f142af2eSSrinivas Kandagatla priv->plat->bus_id); 806f142af2eSSrinivas Kandagatla 807d765955dSGiuseppe CAVALLARO snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 8087ac6653aSJeff Kirsher priv->plat->phy_addr); 809d765955dSGiuseppe CAVALLARO pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 8107ac6653aSJeff Kirsher 811f9a8f83bSFlorian Fainelli phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface); 8127ac6653aSJeff Kirsher 8137ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 8147ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 8157ac6653aSJeff Kirsher return PTR_ERR(phydev); 8167ac6653aSJeff Kirsher } 8177ac6653aSJeff Kirsher 81879ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 819c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 8209cbadf09SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII) || 8219cbadf09SSrinivas Kandagatla (max_speed < 1000 && max_speed > 0)) 822c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 823c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 82479ee1dc3SSrinivas Kandagatla 8257ac6653aSJeff Kirsher /* 8267ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 8277ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 8287ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 8297ac6653aSJeff Kirsher * device as well. 8307ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 8317ac6653aSJeff Kirsher */ 8327ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 8337ac6653aSJeff Kirsher phy_disconnect(phydev); 8347ac6653aSJeff Kirsher return -ENODEV; 8357ac6653aSJeff Kirsher } 8367ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 8377ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 8387ac6653aSJeff Kirsher 8397ac6653aSJeff Kirsher priv->phydev = phydev; 8407ac6653aSJeff Kirsher 8417ac6653aSJeff Kirsher return 0; 8427ac6653aSJeff Kirsher } 8437ac6653aSJeff Kirsher 8447ac6653aSJeff Kirsher /** 84532ceabcaSGiuseppe CAVALLARO * stmmac_display_ring: display ring 84632ceabcaSGiuseppe CAVALLARO * @head: pointer to the head of the ring passed. 8477ac6653aSJeff Kirsher * @size: size of the ring. 84832ceabcaSGiuseppe CAVALLARO * @extend_desc: to verify if extended descriptors are used. 849c24602efSGiuseppe CAVALLARO * Description: display the control/status and buffer descriptors. 8507ac6653aSJeff Kirsher */ 851c24602efSGiuseppe CAVALLARO static void stmmac_display_ring(void *head, int size, int extend_desc) 8527ac6653aSJeff Kirsher { 8537ac6653aSJeff Kirsher int i; 854c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 855c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 856c24602efSGiuseppe CAVALLARO 8577ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 858c24602efSGiuseppe CAVALLARO u64 x; 859c24602efSGiuseppe CAVALLARO if (extend_desc) { 860c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 861c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 862c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 863c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 864c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 865c24602efSGiuseppe CAVALLARO ep++; 866c24602efSGiuseppe CAVALLARO } else { 867c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 868c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", 869c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(p), 870c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 871c24602efSGiuseppe CAVALLARO p->des2, p->des3); 872c24602efSGiuseppe CAVALLARO p++; 873c24602efSGiuseppe CAVALLARO } 8747ac6653aSJeff Kirsher pr_info("\n"); 8757ac6653aSJeff Kirsher } 8767ac6653aSJeff Kirsher } 8777ac6653aSJeff Kirsher 878c24602efSGiuseppe CAVALLARO static void stmmac_display_rings(struct stmmac_priv *priv) 879c24602efSGiuseppe CAVALLARO { 880c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 881c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 882c24602efSGiuseppe CAVALLARO 883c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 884c24602efSGiuseppe CAVALLARO pr_info("Extended RX descriptor ring:\n"); 885c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 886c24602efSGiuseppe CAVALLARO pr_info("Extended TX descriptor ring:\n"); 887c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 888c24602efSGiuseppe CAVALLARO } else { 889c24602efSGiuseppe CAVALLARO pr_info("RX descriptor ring:\n"); 890c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 891c24602efSGiuseppe CAVALLARO pr_info("TX descriptor ring:\n"); 892c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 893c24602efSGiuseppe CAVALLARO } 894c24602efSGiuseppe CAVALLARO } 895c24602efSGiuseppe CAVALLARO 896286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 897286a8372SGiuseppe CAVALLARO { 898286a8372SGiuseppe CAVALLARO int ret = bufsize; 899286a8372SGiuseppe CAVALLARO 900286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 901286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 902286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 903286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 904d916701cSGiuseppe CAVALLARO else if (mtu > DEFAULT_BUFSIZE) 905286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 906286a8372SGiuseppe CAVALLARO else 907d916701cSGiuseppe CAVALLARO ret = DEFAULT_BUFSIZE; 908286a8372SGiuseppe CAVALLARO 909286a8372SGiuseppe CAVALLARO return ret; 910286a8372SGiuseppe CAVALLARO } 911286a8372SGiuseppe CAVALLARO 91232ceabcaSGiuseppe CAVALLARO /** 91332ceabcaSGiuseppe CAVALLARO * stmmac_clear_descriptors: clear descriptors 91432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 91532ceabcaSGiuseppe CAVALLARO * Description: this function is called to clear the tx and rx descriptors 91632ceabcaSGiuseppe CAVALLARO * in case of both basic and extended descriptors are used. 91732ceabcaSGiuseppe CAVALLARO */ 918c24602efSGiuseppe CAVALLARO static void stmmac_clear_descriptors(struct stmmac_priv *priv) 919c24602efSGiuseppe CAVALLARO { 920c24602efSGiuseppe CAVALLARO int i; 921c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 922c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 923c24602efSGiuseppe CAVALLARO 924c24602efSGiuseppe CAVALLARO /* Clear the Rx/Tx descriptors */ 925c24602efSGiuseppe CAVALLARO for (i = 0; i < rxsize; i++) 926c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 927c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_erx[i].basic, 928c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 929c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 930c24602efSGiuseppe CAVALLARO else 931c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_rx[i], 932c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 933c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 934c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 935c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 936c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 937c24602efSGiuseppe CAVALLARO priv->mode, 938c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 939c24602efSGiuseppe CAVALLARO else 940c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 941c24602efSGiuseppe CAVALLARO priv->mode, 942c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 943c24602efSGiuseppe CAVALLARO } 944c24602efSGiuseppe CAVALLARO 945c24602efSGiuseppe CAVALLARO static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, 946c24602efSGiuseppe CAVALLARO int i) 947c24602efSGiuseppe CAVALLARO { 948c24602efSGiuseppe CAVALLARO struct sk_buff *skb; 949c24602efSGiuseppe CAVALLARO 950c24602efSGiuseppe CAVALLARO skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, 951c24602efSGiuseppe CAVALLARO GFP_KERNEL); 95256329137SBartlomiej Zolnierkiewicz if (!skb) { 953c24602efSGiuseppe CAVALLARO pr_err("%s: Rx init fails; skb is NULL\n", __func__); 95456329137SBartlomiej Zolnierkiewicz return -ENOMEM; 955c24602efSGiuseppe CAVALLARO } 956c24602efSGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 957c24602efSGiuseppe CAVALLARO priv->rx_skbuff[i] = skb; 958c24602efSGiuseppe CAVALLARO priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 959c24602efSGiuseppe CAVALLARO priv->dma_buf_sz, 960c24602efSGiuseppe CAVALLARO DMA_FROM_DEVICE); 96156329137SBartlomiej Zolnierkiewicz if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) { 96256329137SBartlomiej Zolnierkiewicz pr_err("%s: DMA mapping error\n", __func__); 96356329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(skb); 96456329137SBartlomiej Zolnierkiewicz return -EINVAL; 96556329137SBartlomiej Zolnierkiewicz } 966c24602efSGiuseppe CAVALLARO 967c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[i]; 968c24602efSGiuseppe CAVALLARO 96929896a67SGiuseppe CAVALLARO if ((priv->hw->mode->init_desc3) && 970c24602efSGiuseppe CAVALLARO (priv->dma_buf_sz == BUF_SIZE_16KiB)) 97129896a67SGiuseppe CAVALLARO priv->hw->mode->init_desc3(p); 972c24602efSGiuseppe CAVALLARO 973c24602efSGiuseppe CAVALLARO return 0; 974c24602efSGiuseppe CAVALLARO } 975c24602efSGiuseppe CAVALLARO 97656329137SBartlomiej Zolnierkiewicz static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) 97756329137SBartlomiej Zolnierkiewicz { 97856329137SBartlomiej Zolnierkiewicz if (priv->rx_skbuff[i]) { 97956329137SBartlomiej Zolnierkiewicz dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 98056329137SBartlomiej Zolnierkiewicz priv->dma_buf_sz, DMA_FROM_DEVICE); 98156329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(priv->rx_skbuff[i]); 98256329137SBartlomiej Zolnierkiewicz } 98356329137SBartlomiej Zolnierkiewicz priv->rx_skbuff[i] = NULL; 98456329137SBartlomiej Zolnierkiewicz } 98556329137SBartlomiej Zolnierkiewicz 9867ac6653aSJeff Kirsher /** 9877ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 9887ac6653aSJeff Kirsher * @dev: net device structure 9897ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 990286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 991286a8372SGiuseppe CAVALLARO * modes. 9927ac6653aSJeff Kirsher */ 99356329137SBartlomiej Zolnierkiewicz static int init_dma_desc_rings(struct net_device *dev) 9947ac6653aSJeff Kirsher { 9957ac6653aSJeff Kirsher int i; 9967ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 9977ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 9987ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 9994a7d666aSGiuseppe CAVALLARO unsigned int bfsize = 0; 100056329137SBartlomiej Zolnierkiewicz int ret = -ENOMEM; 10017ac6653aSJeff Kirsher 100229896a67SGiuseppe CAVALLARO if (priv->hw->mode->set_16kib_bfsize) 100329896a67SGiuseppe CAVALLARO bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu); 1004286a8372SGiuseppe CAVALLARO 10054a7d666aSGiuseppe CAVALLARO if (bfsize < BUF_SIZE_16KiB) 1006286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 10077ac6653aSJeff Kirsher 10082618abb7SVince Bridgers priv->dma_buf_sz = bfsize; 10092618abb7SVince Bridgers 101083d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 101183d7af64SGiuseppe CAVALLARO pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__, 10127ac6653aSJeff Kirsher txsize, rxsize, bfsize); 10137ac6653aSJeff Kirsher 101483d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) { 1015c24602efSGiuseppe CAVALLARO pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__, 1016c24602efSGiuseppe CAVALLARO (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy); 10177ac6653aSJeff Kirsher 10187ac6653aSJeff Kirsher /* RX INITIALIZATION */ 101983d7af64SGiuseppe CAVALLARO pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n"); 102083d7af64SGiuseppe CAVALLARO } 10217ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 1022c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1023c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1024c24602efSGiuseppe CAVALLARO p = &((priv->dma_erx + i)->basic); 1025c24602efSGiuseppe CAVALLARO else 1026c24602efSGiuseppe CAVALLARO p = priv->dma_rx + i; 10277ac6653aSJeff Kirsher 102856329137SBartlomiej Zolnierkiewicz ret = stmmac_init_rx_buffers(priv, p, i); 102956329137SBartlomiej Zolnierkiewicz if (ret) 103056329137SBartlomiej Zolnierkiewicz goto err_init_rx_buffers; 1031286a8372SGiuseppe CAVALLARO 103283d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 103383d7af64SGiuseppe CAVALLARO pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 103483d7af64SGiuseppe CAVALLARO priv->rx_skbuff[i]->data, 103583d7af64SGiuseppe CAVALLARO (unsigned int)priv->rx_skbuff_dma[i]); 10367ac6653aSJeff Kirsher } 10377ac6653aSJeff Kirsher priv->cur_rx = 0; 10387ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 10397ac6653aSJeff Kirsher buf_sz = bfsize; 10407ac6653aSJeff Kirsher 1041c24602efSGiuseppe CAVALLARO /* Setup the chained descriptor addresses */ 1042c24602efSGiuseppe CAVALLARO if (priv->mode == STMMAC_CHAIN_MODE) { 1043c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 104429896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_erx, priv->dma_rx_phy, 1045c24602efSGiuseppe CAVALLARO rxsize, 1); 104629896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_etx, priv->dma_tx_phy, 1047c24602efSGiuseppe CAVALLARO txsize, 1); 1048c24602efSGiuseppe CAVALLARO } else { 104929896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_rx, priv->dma_rx_phy, 1050c24602efSGiuseppe CAVALLARO rxsize, 0); 105129896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_tx, priv->dma_tx_phy, 1052c24602efSGiuseppe CAVALLARO txsize, 0); 1053c24602efSGiuseppe CAVALLARO } 10547ac6653aSJeff Kirsher } 1055286a8372SGiuseppe CAVALLARO 1056c24602efSGiuseppe CAVALLARO /* TX INITIALIZATION */ 1057c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) { 1058c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1059c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1060c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1061c24602efSGiuseppe CAVALLARO else 1062c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1063c24602efSGiuseppe CAVALLARO p->des2 = 0; 1064cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[i] = 0; 1065c24602efSGiuseppe CAVALLARO priv->tx_skbuff[i] = NULL; 10664a7d666aSGiuseppe CAVALLARO } 1067c24602efSGiuseppe CAVALLARO 10687ac6653aSJeff Kirsher priv->dirty_tx = 0; 10697ac6653aSJeff Kirsher priv->cur_tx = 0; 10707ac6653aSJeff Kirsher 1071c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 10727ac6653aSJeff Kirsher 1073c24602efSGiuseppe CAVALLARO if (netif_msg_hw(priv)) 1074c24602efSGiuseppe CAVALLARO stmmac_display_rings(priv); 107556329137SBartlomiej Zolnierkiewicz 107656329137SBartlomiej Zolnierkiewicz return 0; 107756329137SBartlomiej Zolnierkiewicz err_init_rx_buffers: 107856329137SBartlomiej Zolnierkiewicz while (--i >= 0) 107956329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 108056329137SBartlomiej Zolnierkiewicz return ret; 10817ac6653aSJeff Kirsher } 10827ac6653aSJeff Kirsher 10837ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 10847ac6653aSJeff Kirsher { 10857ac6653aSJeff Kirsher int i; 10867ac6653aSJeff Kirsher 108756329137SBartlomiej Zolnierkiewicz for (i = 0; i < priv->dma_rx_size; i++) 108856329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 10897ac6653aSJeff Kirsher } 10907ac6653aSJeff Kirsher 10917ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 10927ac6653aSJeff Kirsher { 10937ac6653aSJeff Kirsher int i; 10947ac6653aSJeff Kirsher 10957ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 1096c24602efSGiuseppe CAVALLARO struct dma_desc *p; 109775e4364fSdamuzi000 1098c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1099c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1100c24602efSGiuseppe CAVALLARO else 1101c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1102c24602efSGiuseppe CAVALLARO 110375e4364fSdamuzi000 if (priv->tx_skbuff_dma[i]) { 1104cf32deecSRayagond Kokatanur dma_unmap_single(priv->device, 1105cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[i], 11067ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 11077ac6653aSJeff Kirsher DMA_TO_DEVICE); 110875e4364fSdamuzi000 priv->tx_skbuff_dma[i] = 0; 110975e4364fSdamuzi000 } 111075e4364fSdamuzi000 111175e4364fSdamuzi000 if (priv->tx_skbuff[i] != NULL) { 11127ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 11137ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 11147ac6653aSJeff Kirsher } 11157ac6653aSJeff Kirsher } 11167ac6653aSJeff Kirsher } 11177ac6653aSJeff Kirsher 111809f8d696SSrinivas Kandagatla static int alloc_dma_desc_resources(struct stmmac_priv *priv) 111909f8d696SSrinivas Kandagatla { 112009f8d696SSrinivas Kandagatla unsigned int txsize = priv->dma_tx_size; 112109f8d696SSrinivas Kandagatla unsigned int rxsize = priv->dma_rx_size; 112209f8d696SSrinivas Kandagatla int ret = -ENOMEM; 112309f8d696SSrinivas Kandagatla 112409f8d696SSrinivas Kandagatla priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t), 112509f8d696SSrinivas Kandagatla GFP_KERNEL); 112609f8d696SSrinivas Kandagatla if (!priv->rx_skbuff_dma) 112709f8d696SSrinivas Kandagatla return -ENOMEM; 112809f8d696SSrinivas Kandagatla 112909f8d696SSrinivas Kandagatla priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), 113009f8d696SSrinivas Kandagatla GFP_KERNEL); 113109f8d696SSrinivas Kandagatla if (!priv->rx_skbuff) 113209f8d696SSrinivas Kandagatla goto err_rx_skbuff; 113309f8d696SSrinivas Kandagatla 113409f8d696SSrinivas Kandagatla priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t), 113509f8d696SSrinivas Kandagatla GFP_KERNEL); 113609f8d696SSrinivas Kandagatla if (!priv->tx_skbuff_dma) 113709f8d696SSrinivas Kandagatla goto err_tx_skbuff_dma; 113809f8d696SSrinivas Kandagatla 113909f8d696SSrinivas Kandagatla priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), 114009f8d696SSrinivas Kandagatla GFP_KERNEL); 114109f8d696SSrinivas Kandagatla if (!priv->tx_skbuff) 114209f8d696SSrinivas Kandagatla goto err_tx_skbuff; 114309f8d696SSrinivas Kandagatla 114409f8d696SSrinivas Kandagatla if (priv->extend_desc) { 114509f8d696SSrinivas Kandagatla priv->dma_erx = dma_alloc_coherent(priv->device, rxsize * 114609f8d696SSrinivas Kandagatla sizeof(struct 114709f8d696SSrinivas Kandagatla dma_extended_desc), 114809f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 114909f8d696SSrinivas Kandagatla GFP_KERNEL); 115009f8d696SSrinivas Kandagatla if (!priv->dma_erx) 115109f8d696SSrinivas Kandagatla goto err_dma; 115209f8d696SSrinivas Kandagatla 115309f8d696SSrinivas Kandagatla priv->dma_etx = dma_alloc_coherent(priv->device, txsize * 115409f8d696SSrinivas Kandagatla sizeof(struct 115509f8d696SSrinivas Kandagatla dma_extended_desc), 115609f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 115709f8d696SSrinivas Kandagatla GFP_KERNEL); 115809f8d696SSrinivas Kandagatla if (!priv->dma_etx) { 115909f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 116009f8d696SSrinivas Kandagatla sizeof(struct dma_extended_desc), 116109f8d696SSrinivas Kandagatla priv->dma_erx, priv->dma_rx_phy); 116209f8d696SSrinivas Kandagatla goto err_dma; 116309f8d696SSrinivas Kandagatla } 116409f8d696SSrinivas Kandagatla } else { 116509f8d696SSrinivas Kandagatla priv->dma_rx = dma_alloc_coherent(priv->device, rxsize * 116609f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 116709f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 116809f8d696SSrinivas Kandagatla GFP_KERNEL); 116909f8d696SSrinivas Kandagatla if (!priv->dma_rx) 117009f8d696SSrinivas Kandagatla goto err_dma; 117109f8d696SSrinivas Kandagatla 117209f8d696SSrinivas Kandagatla priv->dma_tx = dma_alloc_coherent(priv->device, txsize * 117309f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 117409f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 117509f8d696SSrinivas Kandagatla GFP_KERNEL); 117609f8d696SSrinivas Kandagatla if (!priv->dma_tx) { 117709f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 117809f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 117909f8d696SSrinivas Kandagatla priv->dma_rx, priv->dma_rx_phy); 118009f8d696SSrinivas Kandagatla goto err_dma; 118109f8d696SSrinivas Kandagatla } 118209f8d696SSrinivas Kandagatla } 118309f8d696SSrinivas Kandagatla 118409f8d696SSrinivas Kandagatla return 0; 118509f8d696SSrinivas Kandagatla 118609f8d696SSrinivas Kandagatla err_dma: 118709f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff); 118809f8d696SSrinivas Kandagatla err_tx_skbuff: 118909f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff_dma); 119009f8d696SSrinivas Kandagatla err_tx_skbuff_dma: 119109f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff); 119209f8d696SSrinivas Kandagatla err_rx_skbuff: 119309f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff_dma); 119409f8d696SSrinivas Kandagatla return ret; 119509f8d696SSrinivas Kandagatla } 119609f8d696SSrinivas Kandagatla 11977ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 11987ac6653aSJeff Kirsher { 11997ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 12007ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 12017ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 12027ac6653aSJeff Kirsher 1203ceb69499SGiuseppe CAVALLARO /* Free DMA regions of consistent memory previously allocated */ 1204c24602efSGiuseppe CAVALLARO if (!priv->extend_desc) { 12057ac6653aSJeff Kirsher dma_free_coherent(priv->device, 12067ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 12077ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 12087ac6653aSJeff Kirsher dma_free_coherent(priv->device, 12097ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 12107ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 1211c24602efSGiuseppe CAVALLARO } else { 1212c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_tx_size * 1213c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1214c24602efSGiuseppe CAVALLARO priv->dma_etx, priv->dma_tx_phy); 1215c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_rx_size * 1216c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1217c24602efSGiuseppe CAVALLARO priv->dma_erx, priv->dma_rx_phy); 1218c24602efSGiuseppe CAVALLARO } 12197ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 12207ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 1221cf32deecSRayagond Kokatanur kfree(priv->tx_skbuff_dma); 12227ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 12237ac6653aSJeff Kirsher } 12247ac6653aSJeff Kirsher 12257ac6653aSJeff Kirsher /** 12267ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 122732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12287ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 12297ac6653aSJeff Kirsher * or Store-And-Forward capability. 12307ac6653aSJeff Kirsher */ 12317ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 12327ac6653aSJeff Kirsher { 1233e2a240c7SSonic Zhang if (priv->plat->force_thresh_dma_mode) 1234e2a240c7SSonic Zhang priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); 1235e2a240c7SSonic Zhang else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { 12367ac6653aSJeff Kirsher /* 12377ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 12387ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 12397ac6653aSJeff Kirsher * 1) TX COE if actually supported 12407ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 12417ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 12427ac6653aSJeff Kirsher */ 1243ceb69499SGiuseppe CAVALLARO priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); 12447ac6653aSJeff Kirsher tc = SF_DMA_MODE; 12457ac6653aSJeff Kirsher } else 12467ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 12477ac6653aSJeff Kirsher } 12487ac6653aSJeff Kirsher 12497ac6653aSJeff Kirsher /** 12509125cdd1SGiuseppe CAVALLARO * stmmac_tx_clean: 125132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12527ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 12537ac6653aSJeff Kirsher */ 12549125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv) 12557ac6653aSJeff Kirsher { 12567ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 12577ac6653aSJeff Kirsher 1258a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1259a9097a96SGiuseppe CAVALLARO 12609125cdd1SGiuseppe CAVALLARO priv->xstats.tx_clean++; 12619125cdd1SGiuseppe CAVALLARO 12627ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 12637ac6653aSJeff Kirsher int last; 12647ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 12657ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 1266c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1267c24602efSGiuseppe CAVALLARO 1268c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1269c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_etx + entry); 1270c24602efSGiuseppe CAVALLARO else 1271c24602efSGiuseppe CAVALLARO p = priv->dma_tx + entry; 12727ac6653aSJeff Kirsher 12737ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 12747ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 12757ac6653aSJeff Kirsher break; 12767ac6653aSJeff Kirsher 1277c24602efSGiuseppe CAVALLARO /* Verify tx error by looking at the last segment. */ 12787ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 12797ac6653aSJeff Kirsher if (likely(last)) { 12807ac6653aSJeff Kirsher int tx_error = 12817ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 12827ac6653aSJeff Kirsher &priv->xstats, p, 12837ac6653aSJeff Kirsher priv->ioaddr); 12847ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 12857ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 12867ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 12877ac6653aSJeff Kirsher } else 12887ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 1289891434b1SRayagond Kokatanur 1290891434b1SRayagond Kokatanur stmmac_get_tx_hwtstamp(priv, entry, skb); 12917ac6653aSJeff Kirsher } 129283d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 129383d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d, dirty %d\n", __func__, 12947ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 12957ac6653aSJeff Kirsher 1296cf32deecSRayagond Kokatanur if (likely(priv->tx_skbuff_dma[entry])) { 1297cf32deecSRayagond Kokatanur dma_unmap_single(priv->device, 1298cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry], 12997ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 13007ac6653aSJeff Kirsher DMA_TO_DEVICE); 1301cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = 0; 1302cf32deecSRayagond Kokatanur } 130329896a67SGiuseppe CAVALLARO priv->hw->mode->clean_desc3(priv, p); 13047ac6653aSJeff Kirsher 13057ac6653aSJeff Kirsher if (likely(skb != NULL)) { 13067c565c33SEric W. Biederman dev_consume_skb_any(skb); 13077ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 13087ac6653aSJeff Kirsher } 13097ac6653aSJeff Kirsher 13104a7d666aSGiuseppe CAVALLARO priv->hw->desc->release_tx_desc(p, priv->mode); 13117ac6653aSJeff Kirsher 131213497f58SGiuseppe CAVALLARO priv->dirty_tx++; 13137ac6653aSJeff Kirsher } 13147ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 13157ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 13167ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 13177ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 13187ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 131983d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 132083d7af64SGiuseppe CAVALLARO pr_debug("%s: restart transmit\n", __func__); 13217ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13227ac6653aSJeff Kirsher } 13237ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 13247ac6653aSJeff Kirsher } 1325d765955dSGiuseppe CAVALLARO 1326d765955dSGiuseppe CAVALLARO if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { 1327d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 1328f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 1329d765955dSGiuseppe CAVALLARO } 1330a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 13317ac6653aSJeff Kirsher } 13327ac6653aSJeff Kirsher 13339125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv) 13347ac6653aSJeff Kirsher { 13357ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 13367ac6653aSJeff Kirsher } 13377ac6653aSJeff Kirsher 13389125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv) 13397ac6653aSJeff Kirsher { 13407ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 13417ac6653aSJeff Kirsher } 13427ac6653aSJeff Kirsher 13437ac6653aSJeff Kirsher /** 134432ceabcaSGiuseppe CAVALLARO * stmmac_tx_err: irq tx error mng function 134532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 13467ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 13477ac6653aSJeff Kirsher * in case of errors. 13487ac6653aSJeff Kirsher */ 13497ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 13507ac6653aSJeff Kirsher { 1351c24602efSGiuseppe CAVALLARO int i; 1352c24602efSGiuseppe CAVALLARO int txsize = priv->dma_tx_size; 13537ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 13547ac6653aSJeff Kirsher 13557ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 13567ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 1357c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 1358c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1359c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 1360c24602efSGiuseppe CAVALLARO priv->mode, 1361c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 1362c24602efSGiuseppe CAVALLARO else 1363c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 1364c24602efSGiuseppe CAVALLARO priv->mode, 1365c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 13667ac6653aSJeff Kirsher priv->dirty_tx = 0; 13677ac6653aSJeff Kirsher priv->cur_tx = 0; 13687ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 13697ac6653aSJeff Kirsher 13707ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 13717ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13727ac6653aSJeff Kirsher } 13737ac6653aSJeff Kirsher 137432ceabcaSGiuseppe CAVALLARO /** 137532ceabcaSGiuseppe CAVALLARO * stmmac_dma_interrupt: DMA ISR 137632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 137732ceabcaSGiuseppe CAVALLARO * Description: this is the DMA ISR. It is called by the main ISR. 137832ceabcaSGiuseppe CAVALLARO * It calls the dwmac dma routine to understand which type of interrupt 137932ceabcaSGiuseppe CAVALLARO * happened. In case of there is a Normal interrupt and either TX or RX 138032ceabcaSGiuseppe CAVALLARO * interrupt happened so the NAPI is scheduled. 138132ceabcaSGiuseppe CAVALLARO */ 13827ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 13837ac6653aSJeff Kirsher { 13847ac6653aSJeff Kirsher int status; 13857ac6653aSJeff Kirsher 13867ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 13879125cdd1SGiuseppe CAVALLARO if (likely((status & handle_rx)) || (status & handle_tx)) { 13889125cdd1SGiuseppe CAVALLARO if (likely(napi_schedule_prep(&priv->napi))) { 13899125cdd1SGiuseppe CAVALLARO stmmac_disable_dma_irq(priv); 13909125cdd1SGiuseppe CAVALLARO __napi_schedule(&priv->napi); 13919125cdd1SGiuseppe CAVALLARO } 13929125cdd1SGiuseppe CAVALLARO } 13939125cdd1SGiuseppe CAVALLARO if (unlikely(status & tx_hard_error_bump_tc)) { 13947ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 13957ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 13967ac6653aSJeff Kirsher tc += 64; 13977ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 13987ac6653aSJeff Kirsher priv->xstats.threshold = tc; 13997ac6653aSJeff Kirsher } 14007ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 14017ac6653aSJeff Kirsher stmmac_tx_err(priv); 14027ac6653aSJeff Kirsher } 14037ac6653aSJeff Kirsher 140432ceabcaSGiuseppe CAVALLARO /** 140532ceabcaSGiuseppe CAVALLARO * stmmac_mmc_setup: setup the Mac Management Counters (MMC) 140632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 140732ceabcaSGiuseppe CAVALLARO * Description: this masks the MMC irq, in fact, the counters are managed in SW. 140832ceabcaSGiuseppe CAVALLARO */ 14091c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 14101c901a46SGiuseppe CAVALLARO { 14111c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 14121c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 14131c901a46SGiuseppe CAVALLARO 14141c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 14154f795b25SGiuseppe CAVALLARO 14164f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 14171c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 14181c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 14194f795b25SGiuseppe CAVALLARO } else 1420aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 14211c901a46SGiuseppe CAVALLARO } 14221c901a46SGiuseppe CAVALLARO 1423f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 1424f0b9d786SGiuseppe CAVALLARO { 1425f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 1426f0b9d786SGiuseppe CAVALLARO 1427ceb69499SGiuseppe CAVALLARO /* Check Synopsys Id (not available on old chips) */ 1428f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 1429f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 1430f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 1431f0b9d786SGiuseppe CAVALLARO 1432cf3f047bSGiuseppe CAVALLARO pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", 1433f0b9d786SGiuseppe CAVALLARO uid, synid); 1434f0b9d786SGiuseppe CAVALLARO 1435f0b9d786SGiuseppe CAVALLARO return synid; 1436f0b9d786SGiuseppe CAVALLARO } 1437f0b9d786SGiuseppe CAVALLARO return 0; 1438f0b9d786SGiuseppe CAVALLARO } 1439e7434821SGiuseppe CAVALLARO 144019e30c14SGiuseppe CAVALLARO /** 144132ceabcaSGiuseppe CAVALLARO * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors 144232ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 144332ceabcaSGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors. 144432ceabcaSGiuseppe CAVALLARO * In case of Enhanced/Alternate, it looks at the extended descriptors are 144532ceabcaSGiuseppe CAVALLARO * supported by the HW cap. register. 1446ff3dd78cSGiuseppe CAVALLARO */ 144719e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 144819e30c14SGiuseppe CAVALLARO { 144919e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 145019e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 1451c24602efSGiuseppe CAVALLARO 1452c24602efSGiuseppe CAVALLARO /* GMAC older than 3.50 has no extended descriptors */ 1453c24602efSGiuseppe CAVALLARO if (priv->synopsys_id >= DWMAC_CORE_3_50) { 1454c24602efSGiuseppe CAVALLARO pr_info("\tEnabled extended descriptors\n"); 1455c24602efSGiuseppe CAVALLARO priv->extend_desc = 1; 1456c24602efSGiuseppe CAVALLARO } else 1457c24602efSGiuseppe CAVALLARO pr_warn("Extended descriptors not supported\n"); 1458c24602efSGiuseppe CAVALLARO 145919e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 146019e30c14SGiuseppe CAVALLARO } else { 146119e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 146219e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 146319e30c14SGiuseppe CAVALLARO } 146419e30c14SGiuseppe CAVALLARO } 146519e30c14SGiuseppe CAVALLARO 146619e30c14SGiuseppe CAVALLARO /** 146732ceabcaSGiuseppe CAVALLARO * stmmac_get_hw_features: get MAC capabilities from the HW cap. register. 146832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 146919e30c14SGiuseppe CAVALLARO * Description: 147019e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 1471e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 147219e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 147319e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 1474e7434821SGiuseppe CAVALLARO */ 1475e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 1476e7434821SGiuseppe CAVALLARO { 14775e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 14783c20f72fSGiuseppe CAVALLARO 14795e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 14805e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 1481e7434821SGiuseppe CAVALLARO 14821db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 14831db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 14841db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 14851db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 1486ceb69499SGiuseppe CAVALLARO priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; 14871db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 14881db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 14891db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 14901db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 14911db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 14921db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 14931db123fbSRayagond Kokatanur /* MMC */ 14941db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 1495e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002 */ 14961db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 14971db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 1498e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008 */ 14991db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 15001db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 1501e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 15021db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 15031db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 1504e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 15051db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 15061db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 15071db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 15081db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 15091db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 15101db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 15111db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 1512e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 15131db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 15141db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 15151db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 15161db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 1517e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode */ 1518ceb69499SGiuseppe CAVALLARO priv->dma_cap.enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 151919e30c14SGiuseppe CAVALLARO } 1520e7434821SGiuseppe CAVALLARO 1521e7434821SGiuseppe CAVALLARO return hw_cap; 1522e7434821SGiuseppe CAVALLARO } 1523e7434821SGiuseppe CAVALLARO 152432ceabcaSGiuseppe CAVALLARO /** 152532ceabcaSGiuseppe CAVALLARO * stmmac_check_ether_addr: check if the MAC addr is valid 152632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 152732ceabcaSGiuseppe CAVALLARO * Description: 152832ceabcaSGiuseppe CAVALLARO * it is to verify if the MAC address is valid, in case of failures it 152932ceabcaSGiuseppe CAVALLARO * generates a random MAC address 153032ceabcaSGiuseppe CAVALLARO */ 1531bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 1532bfab27a1SGiuseppe CAVALLARO { 1533bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 1534bfab27a1SGiuseppe CAVALLARO priv->hw->mac->get_umac_addr((void __iomem *) 1535bfab27a1SGiuseppe CAVALLARO priv->dev->base_addr, 1536bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 1537bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 1538f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 1539c88460b7SHans de Goede pr_info("%s: device MAC address %pM\n", priv->dev->name, 1540bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 1541bfab27a1SGiuseppe CAVALLARO } 1542c88460b7SHans de Goede } 1543bfab27a1SGiuseppe CAVALLARO 154432ceabcaSGiuseppe CAVALLARO /** 154532ceabcaSGiuseppe CAVALLARO * stmmac_init_dma_engine: DMA init. 154632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 154732ceabcaSGiuseppe CAVALLARO * Description: 154832ceabcaSGiuseppe CAVALLARO * It inits the DMA invoking the specific MAC/GMAC callback. 154932ceabcaSGiuseppe CAVALLARO * Some DMA parameters can be passed from the platform; 155032ceabcaSGiuseppe CAVALLARO * in case of these are not passed a default is kept for the MAC or GMAC. 155132ceabcaSGiuseppe CAVALLARO */ 15520f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv) 15530f1f88a8SGiuseppe CAVALLARO { 15540f1f88a8SGiuseppe CAVALLARO int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; 1555b9cde0a8SGiuseppe CAVALLARO int mixed_burst = 0; 1556c24602efSGiuseppe CAVALLARO int atds = 0; 15570f1f88a8SGiuseppe CAVALLARO 15580f1f88a8SGiuseppe CAVALLARO if (priv->plat->dma_cfg) { 15590f1f88a8SGiuseppe CAVALLARO pbl = priv->plat->dma_cfg->pbl; 15600f1f88a8SGiuseppe CAVALLARO fixed_burst = priv->plat->dma_cfg->fixed_burst; 1561b9cde0a8SGiuseppe CAVALLARO mixed_burst = priv->plat->dma_cfg->mixed_burst; 15620f1f88a8SGiuseppe CAVALLARO burst_len = priv->plat->dma_cfg->burst_len; 15630f1f88a8SGiuseppe CAVALLARO } 15640f1f88a8SGiuseppe CAVALLARO 1565c24602efSGiuseppe CAVALLARO if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE)) 1566c24602efSGiuseppe CAVALLARO atds = 1; 1567c24602efSGiuseppe CAVALLARO 1568b9cde0a8SGiuseppe CAVALLARO return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, 15690f1f88a8SGiuseppe CAVALLARO burst_len, priv->dma_tx_phy, 1570c24602efSGiuseppe CAVALLARO priv->dma_rx_phy, atds); 15710f1f88a8SGiuseppe CAVALLARO } 15720f1f88a8SGiuseppe CAVALLARO 1573bfab27a1SGiuseppe CAVALLARO /** 157432ceabcaSGiuseppe CAVALLARO * stmmac_tx_timer: mitigation sw timer for tx. 15759125cdd1SGiuseppe CAVALLARO * @data: data pointer 15769125cdd1SGiuseppe CAVALLARO * Description: 15779125cdd1SGiuseppe CAVALLARO * This is the timer handler to directly invoke the stmmac_tx_clean. 15789125cdd1SGiuseppe CAVALLARO */ 15799125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data) 15809125cdd1SGiuseppe CAVALLARO { 15819125cdd1SGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)data; 15829125cdd1SGiuseppe CAVALLARO 15839125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 15849125cdd1SGiuseppe CAVALLARO } 15859125cdd1SGiuseppe CAVALLARO 15869125cdd1SGiuseppe CAVALLARO /** 158732ceabcaSGiuseppe CAVALLARO * stmmac_init_tx_coalesce: init tx mitigation options. 158832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 15899125cdd1SGiuseppe CAVALLARO * Description: 15909125cdd1SGiuseppe CAVALLARO * This inits the transmit coalesce parameters: i.e. timer rate, 15919125cdd1SGiuseppe CAVALLARO * timer handler and default threshold used for enabling the 15929125cdd1SGiuseppe CAVALLARO * interrupt on completion bit. 15939125cdd1SGiuseppe CAVALLARO */ 15949125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) 15959125cdd1SGiuseppe CAVALLARO { 15969125cdd1SGiuseppe CAVALLARO priv->tx_coal_frames = STMMAC_TX_FRAMES; 15979125cdd1SGiuseppe CAVALLARO priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; 15989125cdd1SGiuseppe CAVALLARO init_timer(&priv->txtimer); 15999125cdd1SGiuseppe CAVALLARO priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); 16009125cdd1SGiuseppe CAVALLARO priv->txtimer.data = (unsigned long)priv; 16019125cdd1SGiuseppe CAVALLARO priv->txtimer.function = stmmac_tx_timer; 16029125cdd1SGiuseppe CAVALLARO add_timer(&priv->txtimer); 16039125cdd1SGiuseppe CAVALLARO } 16049125cdd1SGiuseppe CAVALLARO 16059125cdd1SGiuseppe CAVALLARO /** 1606523f11b5SSrinivas Kandagatla * stmmac_hw_setup: setup mac in a usable state. 1607523f11b5SSrinivas Kandagatla * @dev : pointer to the device structure. 1608523f11b5SSrinivas Kandagatla * Description: 1609523f11b5SSrinivas Kandagatla * This function sets up the ip in a usable state. 1610523f11b5SSrinivas Kandagatla * Return value: 1611523f11b5SSrinivas Kandagatla * 0 on success and an appropriate (-)ve integer as defined in errno.h 1612523f11b5SSrinivas Kandagatla * file on failure. 1613523f11b5SSrinivas Kandagatla */ 1614523f11b5SSrinivas Kandagatla static int stmmac_hw_setup(struct net_device *dev) 1615523f11b5SSrinivas Kandagatla { 1616523f11b5SSrinivas Kandagatla struct stmmac_priv *priv = netdev_priv(dev); 1617523f11b5SSrinivas Kandagatla int ret; 1618523f11b5SSrinivas Kandagatla 1619523f11b5SSrinivas Kandagatla ret = init_dma_desc_rings(dev); 1620523f11b5SSrinivas Kandagatla if (ret < 0) { 1621523f11b5SSrinivas Kandagatla pr_err("%s: DMA descriptors initialization failed\n", __func__); 1622523f11b5SSrinivas Kandagatla return ret; 1623523f11b5SSrinivas Kandagatla } 1624523f11b5SSrinivas Kandagatla /* DMA initialization and SW reset */ 1625523f11b5SSrinivas Kandagatla ret = stmmac_init_dma_engine(priv); 1626523f11b5SSrinivas Kandagatla if (ret < 0) { 1627523f11b5SSrinivas Kandagatla pr_err("%s: DMA engine initialization failed\n", __func__); 1628523f11b5SSrinivas Kandagatla return ret; 1629523f11b5SSrinivas Kandagatla } 1630523f11b5SSrinivas Kandagatla 1631523f11b5SSrinivas Kandagatla /* Copy the MAC addr into the HW */ 1632523f11b5SSrinivas Kandagatla priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); 1633523f11b5SSrinivas Kandagatla 1634523f11b5SSrinivas Kandagatla /* If required, perform hw setup of the bus. */ 1635523f11b5SSrinivas Kandagatla if (priv->plat->bus_setup) 1636523f11b5SSrinivas Kandagatla priv->plat->bus_setup(priv->ioaddr); 1637523f11b5SSrinivas Kandagatla 1638523f11b5SSrinivas Kandagatla /* Initialize the MAC Core */ 16392618abb7SVince Bridgers priv->hw->mac->core_init(priv->ioaddr, dev->mtu); 1640523f11b5SSrinivas Kandagatla 1641523f11b5SSrinivas Kandagatla /* Enable the MAC Rx/Tx */ 1642523f11b5SSrinivas Kandagatla stmmac_set_mac(priv->ioaddr, true); 1643523f11b5SSrinivas Kandagatla 1644523f11b5SSrinivas Kandagatla /* Set the HW DMA mode and the COE */ 1645523f11b5SSrinivas Kandagatla stmmac_dma_operation_mode(priv); 1646523f11b5SSrinivas Kandagatla 1647523f11b5SSrinivas Kandagatla stmmac_mmc_setup(priv); 1648523f11b5SSrinivas Kandagatla 1649523f11b5SSrinivas Kandagatla ret = stmmac_init_ptp(priv); 16507509edd6SHans de Goede if (ret && ret != -EOPNOTSUPP) 1651523f11b5SSrinivas Kandagatla pr_warn("%s: failed PTP initialisation\n", __func__); 1652523f11b5SSrinivas Kandagatla 1653523f11b5SSrinivas Kandagatla #ifdef CONFIG_STMMAC_DEBUG_FS 1654523f11b5SSrinivas Kandagatla ret = stmmac_init_fs(dev); 1655523f11b5SSrinivas Kandagatla if (ret < 0) 1656523f11b5SSrinivas Kandagatla pr_warn("%s: failed debugFS registration\n", __func__); 1657523f11b5SSrinivas Kandagatla #endif 1658523f11b5SSrinivas Kandagatla /* Start the ball rolling... */ 1659523f11b5SSrinivas Kandagatla pr_debug("%s: DMA RX/TX processes started...\n", dev->name); 1660523f11b5SSrinivas Kandagatla priv->hw->dma->start_tx(priv->ioaddr); 1661523f11b5SSrinivas Kandagatla priv->hw->dma->start_rx(priv->ioaddr); 1662523f11b5SSrinivas Kandagatla 1663523f11b5SSrinivas Kandagatla /* Dump DMA/MAC registers */ 1664523f11b5SSrinivas Kandagatla if (netif_msg_hw(priv)) { 1665523f11b5SSrinivas Kandagatla priv->hw->mac->dump_regs(priv->ioaddr); 1666523f11b5SSrinivas Kandagatla priv->hw->dma->dump_regs(priv->ioaddr); 1667523f11b5SSrinivas Kandagatla } 1668523f11b5SSrinivas Kandagatla priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; 1669523f11b5SSrinivas Kandagatla 1670523f11b5SSrinivas Kandagatla priv->eee_enabled = stmmac_eee_init(priv); 1671523f11b5SSrinivas Kandagatla 1672523f11b5SSrinivas Kandagatla stmmac_init_tx_coalesce(priv); 1673523f11b5SSrinivas Kandagatla 1674523f11b5SSrinivas Kandagatla if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { 1675523f11b5SSrinivas Kandagatla priv->rx_riwt = MAX_DMA_RIWT; 1676523f11b5SSrinivas Kandagatla priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); 1677523f11b5SSrinivas Kandagatla } 1678523f11b5SSrinivas Kandagatla 1679523f11b5SSrinivas Kandagatla if (priv->pcs && priv->hw->mac->ctrl_ane) 1680523f11b5SSrinivas Kandagatla priv->hw->mac->ctrl_ane(priv->ioaddr, 0); 1681523f11b5SSrinivas Kandagatla 1682523f11b5SSrinivas Kandagatla return 0; 1683523f11b5SSrinivas Kandagatla } 1684523f11b5SSrinivas Kandagatla 1685523f11b5SSrinivas Kandagatla /** 16867ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 16877ac6653aSJeff Kirsher * @dev : pointer to the device structure. 16887ac6653aSJeff Kirsher * Description: 16897ac6653aSJeff Kirsher * This function is the open entry point of the driver. 16907ac6653aSJeff Kirsher * Return value: 16917ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 16927ac6653aSJeff Kirsher * file on failure. 16937ac6653aSJeff Kirsher */ 16947ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 16957ac6653aSJeff Kirsher { 16967ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16977ac6653aSJeff Kirsher int ret; 16987ac6653aSJeff Kirsher 16994bfcbd7aSFrancesco Virlinzi stmmac_check_ether_addr(priv); 17004bfcbd7aSFrancesco Virlinzi 17014d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 17024d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 17037ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 1704e58bb43fSGiuseppe CAVALLARO if (ret) { 1705e58bb43fSGiuseppe CAVALLARO pr_err("%s: Cannot attach to PHY (error: %d)\n", 1706e58bb43fSGiuseppe CAVALLARO __func__, ret); 170789df20d9SHans de Goede return ret; 17087ac6653aSJeff Kirsher } 1709e58bb43fSGiuseppe CAVALLARO } 17107ac6653aSJeff Kirsher 1711523f11b5SSrinivas Kandagatla /* Extra statistics */ 1712523f11b5SSrinivas Kandagatla memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 1713523f11b5SSrinivas Kandagatla priv->xstats.threshold = tc; 1714523f11b5SSrinivas Kandagatla 17157ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 17167ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 17177ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 17187ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 171956329137SBartlomiej Zolnierkiewicz 17207262b7b2STobias Klauser ret = alloc_dma_desc_resources(priv); 172109f8d696SSrinivas Kandagatla if (ret < 0) { 172209f8d696SSrinivas Kandagatla pr_err("%s: DMA descriptors allocation failed\n", __func__); 172309f8d696SSrinivas Kandagatla goto dma_desc_error; 172409f8d696SSrinivas Kandagatla } 172509f8d696SSrinivas Kandagatla 1726523f11b5SSrinivas Kandagatla ret = stmmac_hw_setup(dev); 172756329137SBartlomiej Zolnierkiewicz if (ret < 0) { 1728523f11b5SSrinivas Kandagatla pr_err("%s: Hw setup failed\n", __func__); 1729c9324d18SGiuseppe CAVALLARO goto init_error; 17307ac6653aSJeff Kirsher } 17317ac6653aSJeff Kirsher 1732523f11b5SSrinivas Kandagatla if (priv->phydev) 1733523f11b5SSrinivas Kandagatla phy_start(priv->phydev); 17347ac6653aSJeff Kirsher 17357ac6653aSJeff Kirsher /* Request the IRQ lines */ 17367ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 17377ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 17387ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 17397ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 17407ac6653aSJeff Kirsher __func__, dev->irq, ret); 1741c9324d18SGiuseppe CAVALLARO goto init_error; 17427ac6653aSJeff Kirsher } 17437ac6653aSJeff Kirsher 17447a13f8f5SFrancesco Virlinzi /* Request the Wake IRQ in case of another line is used for WoL */ 17457a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) { 17467a13f8f5SFrancesco Virlinzi ret = request_irq(priv->wol_irq, stmmac_interrupt, 17477a13f8f5SFrancesco Virlinzi IRQF_SHARED, dev->name, dev); 17487a13f8f5SFrancesco Virlinzi if (unlikely(ret < 0)) { 1749ceb69499SGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the WoL IRQ %d (%d)\n", 1750ceb69499SGiuseppe CAVALLARO __func__, priv->wol_irq, ret); 1751c9324d18SGiuseppe CAVALLARO goto wolirq_error; 17527a13f8f5SFrancesco Virlinzi } 17537a13f8f5SFrancesco Virlinzi } 17547a13f8f5SFrancesco Virlinzi 1755d765955dSGiuseppe CAVALLARO /* Request the IRQ lines */ 1756d7ec8584SChen-Yu Tsai if (priv->lpi_irq > 0) { 1757d765955dSGiuseppe CAVALLARO ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, 1758d765955dSGiuseppe CAVALLARO dev->name, dev); 1759d765955dSGiuseppe CAVALLARO if (unlikely(ret < 0)) { 1760d765955dSGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", 1761d765955dSGiuseppe CAVALLARO __func__, priv->lpi_irq, ret); 1762c9324d18SGiuseppe CAVALLARO goto lpiirq_error; 1763d765955dSGiuseppe CAVALLARO } 1764d765955dSGiuseppe CAVALLARO } 1765d765955dSGiuseppe CAVALLARO 17667ac6653aSJeff Kirsher napi_enable(&priv->napi); 17677ac6653aSJeff Kirsher netif_start_queue(dev); 17687ac6653aSJeff Kirsher 17697ac6653aSJeff Kirsher return 0; 17707ac6653aSJeff Kirsher 1771c9324d18SGiuseppe CAVALLARO lpiirq_error: 1772d765955dSGiuseppe CAVALLARO if (priv->wol_irq != dev->irq) 1773d765955dSGiuseppe CAVALLARO free_irq(priv->wol_irq, dev); 1774c9324d18SGiuseppe CAVALLARO wolirq_error: 17757a13f8f5SFrancesco Virlinzi free_irq(dev->irq, dev); 17767a13f8f5SFrancesco Virlinzi 1777c9324d18SGiuseppe CAVALLARO init_error: 1778c9324d18SGiuseppe CAVALLARO free_dma_desc_resources(priv); 177956329137SBartlomiej Zolnierkiewicz dma_desc_error: 17807ac6653aSJeff Kirsher if (priv->phydev) 17817ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 17824bfcbd7aSFrancesco Virlinzi 17837ac6653aSJeff Kirsher return ret; 17847ac6653aSJeff Kirsher } 17857ac6653aSJeff Kirsher 17867ac6653aSJeff Kirsher /** 17877ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 17887ac6653aSJeff Kirsher * @dev : device pointer. 17897ac6653aSJeff Kirsher * Description: 17907ac6653aSJeff Kirsher * This is the stop entry point of the driver. 17917ac6653aSJeff Kirsher */ 17927ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 17937ac6653aSJeff Kirsher { 17947ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 17957ac6653aSJeff Kirsher 1796d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 1797d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 1798d765955dSGiuseppe CAVALLARO 17997ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 18007ac6653aSJeff Kirsher if (priv->phydev) { 18017ac6653aSJeff Kirsher phy_stop(priv->phydev); 18027ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 18037ac6653aSJeff Kirsher priv->phydev = NULL; 18047ac6653aSJeff Kirsher } 18057ac6653aSJeff Kirsher 18067ac6653aSJeff Kirsher netif_stop_queue(dev); 18077ac6653aSJeff Kirsher 18087ac6653aSJeff Kirsher napi_disable(&priv->napi); 18097ac6653aSJeff Kirsher 18109125cdd1SGiuseppe CAVALLARO del_timer_sync(&priv->txtimer); 18119125cdd1SGiuseppe CAVALLARO 18127ac6653aSJeff Kirsher /* Free the IRQ lines */ 18137ac6653aSJeff Kirsher free_irq(dev->irq, dev); 18147a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) 18157a13f8f5SFrancesco Virlinzi free_irq(priv->wol_irq, dev); 1816d7ec8584SChen-Yu Tsai if (priv->lpi_irq > 0) 1817d765955dSGiuseppe CAVALLARO free_irq(priv->lpi_irq, dev); 18187ac6653aSJeff Kirsher 18197ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 18207ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18217ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18227ac6653aSJeff Kirsher 18237ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 18247ac6653aSJeff Kirsher free_dma_desc_resources(priv); 18257ac6653aSJeff Kirsher 18267ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1827bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 18287ac6653aSJeff Kirsher 18297ac6653aSJeff Kirsher netif_carrier_off(dev); 18307ac6653aSJeff Kirsher 1831bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1832bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1833bfab27a1SGiuseppe CAVALLARO #endif 1834bfab27a1SGiuseppe CAVALLARO 183592ba6888SRayagond Kokatanur stmmac_release_ptp(priv); 183692ba6888SRayagond Kokatanur 18377ac6653aSJeff Kirsher return 0; 18387ac6653aSJeff Kirsher } 18397ac6653aSJeff Kirsher 18407ac6653aSJeff Kirsher /** 184132ceabcaSGiuseppe CAVALLARO * stmmac_xmit: Tx entry point of the driver 18427ac6653aSJeff Kirsher * @skb : the socket buffer 18437ac6653aSJeff Kirsher * @dev : device pointer 184432ceabcaSGiuseppe CAVALLARO * Description : this is the tx entry point of the driver. 184532ceabcaSGiuseppe CAVALLARO * It programs the chain or the ring and supports oversized frames 184632ceabcaSGiuseppe CAVALLARO * and SG feature. 18477ac6653aSJeff Kirsher */ 18487ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 18497ac6653aSJeff Kirsher { 18507ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 18517ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 18527ac6653aSJeff Kirsher unsigned int entry; 18534a7d666aSGiuseppe CAVALLARO int i, csum_insertion = 0, is_jumbo = 0; 18547ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 18557ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1856286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 185729896a67SGiuseppe CAVALLARO unsigned int enh_desc = priv->plat->enh_desc; 18587ac6653aSJeff Kirsher 18597ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 18607ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 18617ac6653aSJeff Kirsher netif_stop_queue(dev); 18627ac6653aSJeff Kirsher /* This is a hard error, log it. */ 1863ceb69499SGiuseppe CAVALLARO pr_err("%s: Tx Ring full when queue awake\n", __func__); 18647ac6653aSJeff Kirsher } 18657ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 18667ac6653aSJeff Kirsher } 18677ac6653aSJeff Kirsher 1868a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1869a9097a96SGiuseppe CAVALLARO 1870d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1871d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1872d765955dSGiuseppe CAVALLARO 18737ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 18747ac6653aSJeff Kirsher 18757ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 18767ac6653aSJeff Kirsher 1877c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1878c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1879c24602efSGiuseppe CAVALLARO else 18807ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 1881c24602efSGiuseppe CAVALLARO 18827ac6653aSJeff Kirsher first = desc; 18837ac6653aSJeff Kirsher 18844a7d666aSGiuseppe CAVALLARO /* To program the descriptors according to the size of the frame */ 188529896a67SGiuseppe CAVALLARO if (enh_desc) 188629896a67SGiuseppe CAVALLARO is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc); 188729896a67SGiuseppe CAVALLARO 18884a7d666aSGiuseppe CAVALLARO if (likely(!is_jumbo)) { 18897ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 18907ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 1891cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = desc->des2; 18927ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 18934a7d666aSGiuseppe CAVALLARO csum_insertion, priv->mode); 189429896a67SGiuseppe CAVALLARO } else { 1895c24602efSGiuseppe CAVALLARO desc = first; 189629896a67SGiuseppe CAVALLARO entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); 189729896a67SGiuseppe CAVALLARO } 18987ac6653aSJeff Kirsher 18997ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 19009e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 19019e903e08SEric Dumazet int len = skb_frag_size(frag); 19027ac6653aSJeff Kirsher 190375e4364fSdamuzi000 priv->tx_skbuff[entry] = NULL; 19047ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 1905c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1906c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1907c24602efSGiuseppe CAVALLARO else 19087ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 19097ac6653aSJeff Kirsher 1910f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1911f722380dSIan Campbell DMA_TO_DEVICE); 1912cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = desc->des2; 19134a7d666aSGiuseppe CAVALLARO priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, 19144a7d666aSGiuseppe CAVALLARO priv->mode); 19157ac6653aSJeff Kirsher wmb(); 19167ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 19178e839891SDeepak Sikri wmb(); 19187ac6653aSJeff Kirsher } 19197ac6653aSJeff Kirsher 192075e4364fSdamuzi000 priv->tx_skbuff[entry] = skb; 192175e4364fSdamuzi000 19229125cdd1SGiuseppe CAVALLARO /* Finalize the latest segment. */ 19237ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 19247ac6653aSJeff Kirsher 19257ac6653aSJeff Kirsher wmb(); 19269125cdd1SGiuseppe CAVALLARO /* According to the coalesce parameter the IC bit for the latest 19279125cdd1SGiuseppe CAVALLARO * segment could be reset and the timer re-started to invoke the 19289125cdd1SGiuseppe CAVALLARO * stmmac_tx function. This approach takes care about the fragments. 19299125cdd1SGiuseppe CAVALLARO */ 19309125cdd1SGiuseppe CAVALLARO priv->tx_count_frames += nfrags + 1; 19319125cdd1SGiuseppe CAVALLARO if (priv->tx_coal_frames > priv->tx_count_frames) { 19329125cdd1SGiuseppe CAVALLARO priv->hw->desc->clear_tx_ic(desc); 19339125cdd1SGiuseppe CAVALLARO priv->xstats.tx_reset_ic_bit++; 19349125cdd1SGiuseppe CAVALLARO mod_timer(&priv->txtimer, 19359125cdd1SGiuseppe CAVALLARO STMMAC_COAL_TIMER(priv->tx_coal_timer)); 19369125cdd1SGiuseppe CAVALLARO } else 19379125cdd1SGiuseppe CAVALLARO priv->tx_count_frames = 0; 19387ac6653aSJeff Kirsher 19397ac6653aSJeff Kirsher /* To avoid raise condition */ 19407ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 19418e839891SDeepak Sikri wmb(); 19427ac6653aSJeff Kirsher 19437ac6653aSJeff Kirsher priv->cur_tx++; 19447ac6653aSJeff Kirsher 19457ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 194683d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", 1947ceb69499SGiuseppe CAVALLARO __func__, (priv->cur_tx % txsize), 1948ceb69499SGiuseppe CAVALLARO (priv->dirty_tx % txsize), entry, first, nfrags); 194983d7af64SGiuseppe CAVALLARO 1950c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1951c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 1952c24602efSGiuseppe CAVALLARO else 1953c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 1954c24602efSGiuseppe CAVALLARO 195583d7af64SGiuseppe CAVALLARO pr_debug(">>> frame to be transmitted: "); 19567ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 19577ac6653aSJeff Kirsher } 19587ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 195983d7af64SGiuseppe CAVALLARO if (netif_msg_hw(priv)) 196083d7af64SGiuseppe CAVALLARO pr_debug("%s: stop transmitted packets\n", __func__); 19617ac6653aSJeff Kirsher netif_stop_queue(dev); 19627ac6653aSJeff Kirsher } 19637ac6653aSJeff Kirsher 19647ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 19657ac6653aSJeff Kirsher 1966891434b1SRayagond Kokatanur if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && 1967891434b1SRayagond Kokatanur priv->hwts_tx_en)) { 1968891434b1SRayagond Kokatanur /* declare that device is doing timestamping */ 1969891434b1SRayagond Kokatanur skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 1970891434b1SRayagond Kokatanur priv->hw->desc->enable_tx_timestamp(first); 1971891434b1SRayagond Kokatanur } 1972891434b1SRayagond Kokatanur 1973891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 19747ac6653aSJeff Kirsher skb_tx_timestamp(skb); 19757ac6653aSJeff Kirsher 19767ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 19777ac6653aSJeff Kirsher 1978a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 1979a9097a96SGiuseppe CAVALLARO 19807ac6653aSJeff Kirsher return NETDEV_TX_OK; 19817ac6653aSJeff Kirsher } 19827ac6653aSJeff Kirsher 1983b9381985SVince Bridgers static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) 1984b9381985SVince Bridgers { 1985b9381985SVince Bridgers struct ethhdr *ehdr; 1986b9381985SVince Bridgers u16 vlanid; 1987b9381985SVince Bridgers 1988b9381985SVince Bridgers if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) == 1989b9381985SVince Bridgers NETIF_F_HW_VLAN_CTAG_RX && 1990b9381985SVince Bridgers !__vlan_get_tag(skb, &vlanid)) { 1991b9381985SVince Bridgers /* pop the vlan tag */ 1992b9381985SVince Bridgers ehdr = (struct ethhdr *)skb->data; 1993b9381985SVince Bridgers memmove(skb->data + VLAN_HLEN, ehdr, ETH_ALEN * 2); 1994b9381985SVince Bridgers skb_pull(skb, VLAN_HLEN); 1995b9381985SVince Bridgers __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlanid); 1996b9381985SVince Bridgers } 1997b9381985SVince Bridgers } 1998b9381985SVince Bridgers 1999b9381985SVince Bridgers 200032ceabcaSGiuseppe CAVALLARO /** 200132ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 200232ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 200332ceabcaSGiuseppe CAVALLARO * Description : this is to reallocate the skb for the reception process 200432ceabcaSGiuseppe CAVALLARO * that is based on zero-copy. 200532ceabcaSGiuseppe CAVALLARO */ 20067ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 20077ac6653aSJeff Kirsher { 20087ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20097ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 20107ac6653aSJeff Kirsher 20117ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 20127ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 2013c24602efSGiuseppe CAVALLARO struct dma_desc *p; 2014c24602efSGiuseppe CAVALLARO 2015c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2016c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2017c24602efSGiuseppe CAVALLARO else 2018c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2019c24602efSGiuseppe CAVALLARO 20207ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 20217ac6653aSJeff Kirsher struct sk_buff *skb; 20227ac6653aSJeff Kirsher 2023acb600deSEric Dumazet skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); 20247ac6653aSJeff Kirsher 20257ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 20267ac6653aSJeff Kirsher break; 20277ac6653aSJeff Kirsher 20287ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 20297ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 20307ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 20317ac6653aSJeff Kirsher DMA_FROM_DEVICE); 20327ac6653aSJeff Kirsher 2033c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[entry]; 2034286a8372SGiuseppe CAVALLARO 203529896a67SGiuseppe CAVALLARO priv->hw->mode->refill_desc3(priv, p); 2036286a8372SGiuseppe CAVALLARO 203783d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) 203883d7af64SGiuseppe CAVALLARO pr_debug("\trefill entry #%d\n", entry); 20397ac6653aSJeff Kirsher } 20407ac6653aSJeff Kirsher wmb(); 2041c24602efSGiuseppe CAVALLARO priv->hw->desc->set_rx_owner(p); 20428e839891SDeepak Sikri wmb(); 20437ac6653aSJeff Kirsher } 20447ac6653aSJeff Kirsher } 20457ac6653aSJeff Kirsher 204632ceabcaSGiuseppe CAVALLARO /** 204732ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 204832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 204932ceabcaSGiuseppe CAVALLARO * @limit: napi bugget. 205032ceabcaSGiuseppe CAVALLARO * Description : this the function called by the napi poll method. 205132ceabcaSGiuseppe CAVALLARO * It gets all the frames inside the ring. 205232ceabcaSGiuseppe CAVALLARO */ 20537ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 20547ac6653aSJeff Kirsher { 20557ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20567ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 20577ac6653aSJeff Kirsher unsigned int next_entry; 20587ac6653aSJeff Kirsher unsigned int count = 0; 2059ceb69499SGiuseppe CAVALLARO int coe = priv->plat->rx_coe; 20607ac6653aSJeff Kirsher 206183d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 206283d7af64SGiuseppe CAVALLARO pr_debug("%s: descriptor ring:\n", __func__); 2063c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2064c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 2065c24602efSGiuseppe CAVALLARO else 2066c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 20677ac6653aSJeff Kirsher } 2068c24602efSGiuseppe CAVALLARO while (count < limit) { 20697ac6653aSJeff Kirsher int status; 20709401bb5cSGiuseppe CAVALLARO struct dma_desc *p; 20717ac6653aSJeff Kirsher 2072c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2073c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2074c24602efSGiuseppe CAVALLARO else 2075c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2076c24602efSGiuseppe CAVALLARO 2077c24602efSGiuseppe CAVALLARO if (priv->hw->desc->get_rx_owner(p)) 20787ac6653aSJeff Kirsher break; 20797ac6653aSJeff Kirsher 20807ac6653aSJeff Kirsher count++; 20817ac6653aSJeff Kirsher 20827ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 2083c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 20849401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_erx + next_entry); 2085c24602efSGiuseppe CAVALLARO else 20869401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_rx + next_entry); 20877ac6653aSJeff Kirsher 20887ac6653aSJeff Kirsher /* read the status of the incoming frame */ 2089c24602efSGiuseppe CAVALLARO status = priv->hw->desc->rx_status(&priv->dev->stats, 2090c24602efSGiuseppe CAVALLARO &priv->xstats, p); 2091c24602efSGiuseppe CAVALLARO if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status)) 2092c24602efSGiuseppe CAVALLARO priv->hw->desc->rx_extended_status(&priv->dev->stats, 2093c24602efSGiuseppe CAVALLARO &priv->xstats, 2094c24602efSGiuseppe CAVALLARO priv->dma_erx + 2095c24602efSGiuseppe CAVALLARO entry); 2096891434b1SRayagond Kokatanur if (unlikely(status == discard_frame)) { 20977ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 2098891434b1SRayagond Kokatanur if (priv->hwts_rx_en && !priv->extend_desc) { 2099891434b1SRayagond Kokatanur /* DESC2 & DESC3 will be overwitten by device 2100891434b1SRayagond Kokatanur * with timestamp value, hence reinitialize 2101891434b1SRayagond Kokatanur * them in stmmac_rx_refill() function so that 2102891434b1SRayagond Kokatanur * device can reuse it. 2103891434b1SRayagond Kokatanur */ 2104891434b1SRayagond Kokatanur priv->rx_skbuff[entry] = NULL; 2105891434b1SRayagond Kokatanur dma_unmap_single(priv->device, 2106891434b1SRayagond Kokatanur priv->rx_skbuff_dma[entry], 2107ceb69499SGiuseppe CAVALLARO priv->dma_buf_sz, 2108ceb69499SGiuseppe CAVALLARO DMA_FROM_DEVICE); 2109891434b1SRayagond Kokatanur } 2110891434b1SRayagond Kokatanur } else { 21117ac6653aSJeff Kirsher struct sk_buff *skb; 21127ac6653aSJeff Kirsher int frame_len; 21137ac6653aSJeff Kirsher 2114ceb69499SGiuseppe CAVALLARO frame_len = priv->hw->desc->get_rx_frame_len(p, coe); 2115ceb69499SGiuseppe CAVALLARO 21167ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 2117ceb69499SGiuseppe CAVALLARO * Type frames (LLC/LLC-SNAP) 2118ceb69499SGiuseppe CAVALLARO */ 21197ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 21207ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 21217ac6653aSJeff Kirsher 212283d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 21237ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 21247ac6653aSJeff Kirsher p, entry, p->des2); 212583d7af64SGiuseppe CAVALLARO if (frame_len > ETH_FRAME_LEN) 212683d7af64SGiuseppe CAVALLARO pr_debug("\tframe size %d, COE: %d\n", 212783d7af64SGiuseppe CAVALLARO frame_len, status); 212883d7af64SGiuseppe CAVALLARO } 21297ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 21307ac6653aSJeff Kirsher if (unlikely(!skb)) { 21317ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 21327ac6653aSJeff Kirsher priv->dev->name); 21337ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 21347ac6653aSJeff Kirsher break; 21357ac6653aSJeff Kirsher } 21367ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 21377ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 21387ac6653aSJeff Kirsher 2139891434b1SRayagond Kokatanur stmmac_get_rx_hwtstamp(priv, entry, skb); 2140891434b1SRayagond Kokatanur 21417ac6653aSJeff Kirsher skb_put(skb, frame_len); 21427ac6653aSJeff Kirsher dma_unmap_single(priv->device, 21437ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 21447ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 214583d7af64SGiuseppe CAVALLARO 21467ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 214783d7af64SGiuseppe CAVALLARO pr_debug("frame received (%dbytes)", frame_len); 21487ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 21497ac6653aSJeff Kirsher } 215083d7af64SGiuseppe CAVALLARO 2151b9381985SVince Bridgers stmmac_rx_vlan(priv->dev, skb); 2152b9381985SVince Bridgers 21537ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 21547ac6653aSJeff Kirsher 2155ceb69499SGiuseppe CAVALLARO if (unlikely(!coe)) 21567ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 215762a2ab93SGiuseppe CAVALLARO else 21587ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 215962a2ab93SGiuseppe CAVALLARO 21607ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 21617ac6653aSJeff Kirsher 21627ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 21637ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 21647ac6653aSJeff Kirsher } 21657ac6653aSJeff Kirsher entry = next_entry; 21667ac6653aSJeff Kirsher } 21677ac6653aSJeff Kirsher 21687ac6653aSJeff Kirsher stmmac_rx_refill(priv); 21697ac6653aSJeff Kirsher 21707ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 21717ac6653aSJeff Kirsher 21727ac6653aSJeff Kirsher return count; 21737ac6653aSJeff Kirsher } 21747ac6653aSJeff Kirsher 21757ac6653aSJeff Kirsher /** 21767ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 21777ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 21787ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 21797ac6653aSJeff Kirsher * all interfaces. 21807ac6653aSJeff Kirsher * Description : 21819125cdd1SGiuseppe CAVALLARO * To look at the incoming frames and clear the tx resources. 21827ac6653aSJeff Kirsher */ 21837ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 21847ac6653aSJeff Kirsher { 21857ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 21867ac6653aSJeff Kirsher int work_done = 0; 21877ac6653aSJeff Kirsher 21889125cdd1SGiuseppe CAVALLARO priv->xstats.napi_poll++; 21899125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 21907ac6653aSJeff Kirsher 21919125cdd1SGiuseppe CAVALLARO work_done = stmmac_rx(priv, budget); 21927ac6653aSJeff Kirsher if (work_done < budget) { 21937ac6653aSJeff Kirsher napi_complete(napi); 21949125cdd1SGiuseppe CAVALLARO stmmac_enable_dma_irq(priv); 21957ac6653aSJeff Kirsher } 21967ac6653aSJeff Kirsher return work_done; 21977ac6653aSJeff Kirsher } 21987ac6653aSJeff Kirsher 21997ac6653aSJeff Kirsher /** 22007ac6653aSJeff Kirsher * stmmac_tx_timeout 22017ac6653aSJeff Kirsher * @dev : Pointer to net device structure 22027ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 22037284a3f1SGiuseppe CAVALLARO * complete within a reasonable time. The driver will mark the error in the 22047ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 22057ac6653aSJeff Kirsher * in order to transmit a new packet. 22067ac6653aSJeff Kirsher */ 22077ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 22087ac6653aSJeff Kirsher { 22097ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22107ac6653aSJeff Kirsher 22117ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 22127ac6653aSJeff Kirsher stmmac_tx_err(priv); 22137ac6653aSJeff Kirsher } 22147ac6653aSJeff Kirsher 22157ac6653aSJeff Kirsher /** 221601789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 22177ac6653aSJeff Kirsher * @dev : pointer to the device structure 22187ac6653aSJeff Kirsher * Description: 22197ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 22207ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 22217ac6653aSJeff Kirsher * Return value: 22227ac6653aSJeff Kirsher * void. 22237ac6653aSJeff Kirsher */ 222401789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 22257ac6653aSJeff Kirsher { 22267ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22277ac6653aSJeff Kirsher 22287ac6653aSJeff Kirsher spin_lock(&priv->lock); 2229cffb13f4SGiuseppe CAVALLARO priv->hw->mac->set_filter(dev, priv->synopsys_id); 22307ac6653aSJeff Kirsher spin_unlock(&priv->lock); 22317ac6653aSJeff Kirsher } 22327ac6653aSJeff Kirsher 22337ac6653aSJeff Kirsher /** 22347ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 22357ac6653aSJeff Kirsher * @dev : device pointer. 22367ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 22377ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 22387ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 22397ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 22407ac6653aSJeff Kirsher * Return value: 22417ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 22427ac6653aSJeff Kirsher * file on failure. 22437ac6653aSJeff Kirsher */ 22447ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 22457ac6653aSJeff Kirsher { 22467ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22477ac6653aSJeff Kirsher int max_mtu; 22487ac6653aSJeff Kirsher 22497ac6653aSJeff Kirsher if (netif_running(dev)) { 22507ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 22517ac6653aSJeff Kirsher return -EBUSY; 22527ac6653aSJeff Kirsher } 22537ac6653aSJeff Kirsher 225448febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 22557ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 22567ac6653aSJeff Kirsher else 225745db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 22587ac6653aSJeff Kirsher 22592618abb7SVince Bridgers if (priv->plat->maxmtu < max_mtu) 22602618abb7SVince Bridgers max_mtu = priv->plat->maxmtu; 22612618abb7SVince Bridgers 22627ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 22637ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 22647ac6653aSJeff Kirsher return -EINVAL; 22657ac6653aSJeff Kirsher } 22667ac6653aSJeff Kirsher 22677ac6653aSJeff Kirsher dev->mtu = new_mtu; 22687ac6653aSJeff Kirsher netdev_update_features(dev); 22697ac6653aSJeff Kirsher 22707ac6653aSJeff Kirsher return 0; 22717ac6653aSJeff Kirsher } 22727ac6653aSJeff Kirsher 2273c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 2274c8f44affSMichał Mirosław netdev_features_t features) 22757ac6653aSJeff Kirsher { 22767ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22777ac6653aSJeff Kirsher 227838912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 22797ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 228038912bdbSDeepak SIKRI else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) 228138912bdbSDeepak SIKRI features &= ~NETIF_F_IPV6_CSUM; 22827ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 22837ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 22847ac6653aSJeff Kirsher 22857ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 22867ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 22877ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 2288ceb69499SGiuseppe CAVALLARO * the TX csum insertionin the TDES and not use SF. 2289ceb69499SGiuseppe CAVALLARO */ 22907ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 22917ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 22927ac6653aSJeff Kirsher 22937ac6653aSJeff Kirsher return features; 22947ac6653aSJeff Kirsher } 22957ac6653aSJeff Kirsher 229632ceabcaSGiuseppe CAVALLARO /** 229732ceabcaSGiuseppe CAVALLARO * stmmac_interrupt - main ISR 229832ceabcaSGiuseppe CAVALLARO * @irq: interrupt number. 229932ceabcaSGiuseppe CAVALLARO * @dev_id: to pass the net device pointer. 230032ceabcaSGiuseppe CAVALLARO * Description: this is the main driver interrupt service routine. 230132ceabcaSGiuseppe CAVALLARO * It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI 230232ceabcaSGiuseppe CAVALLARO * interrupts. 230332ceabcaSGiuseppe CAVALLARO */ 23047ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 23057ac6653aSJeff Kirsher { 23067ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 23077ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23087ac6653aSJeff Kirsher 230989f7f2cfSSrinivas Kandagatla if (priv->irq_wake) 231089f7f2cfSSrinivas Kandagatla pm_wakeup_event(priv->device, 0); 231189f7f2cfSSrinivas Kandagatla 23127ac6653aSJeff Kirsher if (unlikely(!dev)) { 23137ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 23147ac6653aSJeff Kirsher return IRQ_NONE; 23157ac6653aSJeff Kirsher } 23167ac6653aSJeff Kirsher 23177ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 2318d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 2319d765955dSGiuseppe CAVALLARO int status = priv->hw->mac->host_irq_status((void __iomem *) 23200982a0f6SGiuseppe CAVALLARO dev->base_addr, 23210982a0f6SGiuseppe CAVALLARO &priv->xstats); 2322d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 2323d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 23240982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) 2325d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 23260982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) 2327d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 2328d765955dSGiuseppe CAVALLARO } 2329d765955dSGiuseppe CAVALLARO } 2330d765955dSGiuseppe CAVALLARO 2331d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 23327ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 23337ac6653aSJeff Kirsher 23347ac6653aSJeff Kirsher return IRQ_HANDLED; 23357ac6653aSJeff Kirsher } 23367ac6653aSJeff Kirsher 23377ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 23387ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 2339ceb69499SGiuseppe CAVALLARO * to allow network I/O with interrupts disabled. 2340ceb69499SGiuseppe CAVALLARO */ 23417ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 23427ac6653aSJeff Kirsher { 23437ac6653aSJeff Kirsher disable_irq(dev->irq); 23447ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 23457ac6653aSJeff Kirsher enable_irq(dev->irq); 23467ac6653aSJeff Kirsher } 23477ac6653aSJeff Kirsher #endif 23487ac6653aSJeff Kirsher 23497ac6653aSJeff Kirsher /** 23507ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 23517ac6653aSJeff Kirsher * @dev: Device pointer. 23527ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 23537ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 23547ac6653aSJeff Kirsher * @cmd: IOCTL command 23557ac6653aSJeff Kirsher * Description: 235632ceabcaSGiuseppe CAVALLARO * Currently it supports the phy_mii_ioctl(...) and HW time stamping. 23577ac6653aSJeff Kirsher */ 23587ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 23597ac6653aSJeff Kirsher { 23607ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2361891434b1SRayagond Kokatanur int ret = -EOPNOTSUPP; 23627ac6653aSJeff Kirsher 23637ac6653aSJeff Kirsher if (!netif_running(dev)) 23647ac6653aSJeff Kirsher return -EINVAL; 23657ac6653aSJeff Kirsher 2366891434b1SRayagond Kokatanur switch (cmd) { 2367891434b1SRayagond Kokatanur case SIOCGMIIPHY: 2368891434b1SRayagond Kokatanur case SIOCGMIIREG: 2369891434b1SRayagond Kokatanur case SIOCSMIIREG: 23707ac6653aSJeff Kirsher if (!priv->phydev) 23717ac6653aSJeff Kirsher return -EINVAL; 23727ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 2373891434b1SRayagond Kokatanur break; 2374891434b1SRayagond Kokatanur case SIOCSHWTSTAMP: 2375891434b1SRayagond Kokatanur ret = stmmac_hwtstamp_ioctl(dev, rq); 2376891434b1SRayagond Kokatanur break; 2377891434b1SRayagond Kokatanur default: 2378891434b1SRayagond Kokatanur break; 2379891434b1SRayagond Kokatanur } 23807ac6653aSJeff Kirsher 23817ac6653aSJeff Kirsher return ret; 23827ac6653aSJeff Kirsher } 23837ac6653aSJeff Kirsher 23847ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 23857ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 23867ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 2387e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 23887ac29055SGiuseppe CAVALLARO 2389c24602efSGiuseppe CAVALLARO static void sysfs_display_ring(void *head, int size, int extend_desc, 2390c24602efSGiuseppe CAVALLARO struct seq_file *seq) 23917ac29055SGiuseppe CAVALLARO { 23927ac29055SGiuseppe CAVALLARO int i; 2393c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 2394c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 23957ac29055SGiuseppe CAVALLARO 2396c24602efSGiuseppe CAVALLARO for (i = 0; i < size; i++) { 2397c24602efSGiuseppe CAVALLARO u64 x; 2398c24602efSGiuseppe CAVALLARO if (extend_desc) { 2399c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 2400c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2401c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2402c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2403c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 2404c24602efSGiuseppe CAVALLARO ep++; 2405c24602efSGiuseppe CAVALLARO } else { 2406c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 2407c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2408c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2409c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2410c24602efSGiuseppe CAVALLARO p->des2, p->des3); 2411c24602efSGiuseppe CAVALLARO p++; 2412c24602efSGiuseppe CAVALLARO } 24137ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 24147ac29055SGiuseppe CAVALLARO } 2415c24602efSGiuseppe CAVALLARO } 24167ac29055SGiuseppe CAVALLARO 2417c24602efSGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 2418c24602efSGiuseppe CAVALLARO { 2419c24602efSGiuseppe CAVALLARO struct net_device *dev = seq->private; 2420c24602efSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2421c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 2422c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 24237ac29055SGiuseppe CAVALLARO 2424c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 2425c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended RX descriptor ring:\n"); 2426c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_erx, rxsize, 1, seq); 2427c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended TX descriptor ring:\n"); 2428c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_etx, txsize, 1, seq); 2429c24602efSGiuseppe CAVALLARO } else { 2430c24602efSGiuseppe CAVALLARO seq_printf(seq, "RX descriptor ring:\n"); 2431c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_rx, rxsize, 0, seq); 2432c24602efSGiuseppe CAVALLARO seq_printf(seq, "TX descriptor ring:\n"); 2433c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_tx, txsize, 0, seq); 24347ac29055SGiuseppe CAVALLARO } 24357ac29055SGiuseppe CAVALLARO 24367ac29055SGiuseppe CAVALLARO return 0; 24377ac29055SGiuseppe CAVALLARO } 24387ac29055SGiuseppe CAVALLARO 24397ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 24407ac29055SGiuseppe CAVALLARO { 24417ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 24427ac29055SGiuseppe CAVALLARO } 24437ac29055SGiuseppe CAVALLARO 24447ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 24457ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 24467ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 24477ac29055SGiuseppe CAVALLARO .read = seq_read, 24487ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 244974863948SDjalal Harouni .release = single_release, 24507ac29055SGiuseppe CAVALLARO }; 24517ac29055SGiuseppe CAVALLARO 2452e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 2453e7434821SGiuseppe CAVALLARO { 2454e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 2455e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2456e7434821SGiuseppe CAVALLARO 245719e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 2458e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 2459e7434821SGiuseppe CAVALLARO return 0; 2460e7434821SGiuseppe CAVALLARO } 2461e7434821SGiuseppe CAVALLARO 2462e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2463e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 2464e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2465e7434821SGiuseppe CAVALLARO 2466e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 2467e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 2468e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 2469e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 2470e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 2471e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 2472e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 2473e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 2474e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 2475e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 2476e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 2477e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 2478e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 2479e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 2480e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 2481e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 2482e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 2483e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 2484e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 2485e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 2486e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 2487e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 2488e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 2489e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 2490e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 2491e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 2492e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 2493e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 2494e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 2495e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 2496e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 2497e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 2498e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 2499e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 2500e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 2501e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 2502e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 2503e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 2504e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 2505e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 2506e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 2507e7434821SGiuseppe CAVALLARO 2508e7434821SGiuseppe CAVALLARO return 0; 2509e7434821SGiuseppe CAVALLARO } 2510e7434821SGiuseppe CAVALLARO 2511e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 2512e7434821SGiuseppe CAVALLARO { 2513e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 2514e7434821SGiuseppe CAVALLARO } 2515e7434821SGiuseppe CAVALLARO 2516e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 2517e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 2518e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 2519e7434821SGiuseppe CAVALLARO .read = seq_read, 2520e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 252174863948SDjalal Harouni .release = single_release, 2522e7434821SGiuseppe CAVALLARO }; 2523e7434821SGiuseppe CAVALLARO 25247ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 25257ac29055SGiuseppe CAVALLARO { 25267ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 25277ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 25287ac29055SGiuseppe CAVALLARO 25297ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 25307ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 25317ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 25327ac29055SGiuseppe CAVALLARO 25337ac29055SGiuseppe CAVALLARO return -ENOMEM; 25347ac29055SGiuseppe CAVALLARO } 25357ac29055SGiuseppe CAVALLARO 25367ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 25377ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 25387ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 25397ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 25407ac29055SGiuseppe CAVALLARO 25417ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 25427ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 25437ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 25447ac29055SGiuseppe CAVALLARO 25457ac29055SGiuseppe CAVALLARO return -ENOMEM; 25467ac29055SGiuseppe CAVALLARO } 25477ac29055SGiuseppe CAVALLARO 2548e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 2549e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 2550e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 2551e7434821SGiuseppe CAVALLARO 2552e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 2553e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 2554e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2555e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 2556e7434821SGiuseppe CAVALLARO 2557e7434821SGiuseppe CAVALLARO return -ENOMEM; 2558e7434821SGiuseppe CAVALLARO } 2559e7434821SGiuseppe CAVALLARO 25607ac29055SGiuseppe CAVALLARO return 0; 25617ac29055SGiuseppe CAVALLARO } 25627ac29055SGiuseppe CAVALLARO 25637ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 25647ac29055SGiuseppe CAVALLARO { 25657ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2566e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 25677ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 25687ac29055SGiuseppe CAVALLARO } 25697ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 25707ac29055SGiuseppe CAVALLARO 25717ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 25727ac6653aSJeff Kirsher .ndo_open = stmmac_open, 25737ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 25747ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 25757ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 25767ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 257701789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 25787ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 25797ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 25807ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 25817ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 25827ac6653aSJeff Kirsher #endif 25837ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 25847ac6653aSJeff Kirsher }; 25857ac6653aSJeff Kirsher 25867ac6653aSJeff Kirsher /** 2587cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 258832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 2589cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 2590cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 2591cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 2592cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 2593cf3f047bSGiuseppe CAVALLARO * descriptor structure). 2594cf3f047bSGiuseppe CAVALLARO */ 2595cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 2596cf3f047bSGiuseppe CAVALLARO { 2597c24602efSGiuseppe CAVALLARO int ret; 2598cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 2599cf3f047bSGiuseppe CAVALLARO 2600cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 260103f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 260203f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 2603cf3f047bSGiuseppe CAVALLARO mac = dwmac1000_setup(priv->ioaddr); 260403f2eecdSMarc Kleine-Budde } else { 2605cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 260603f2eecdSMarc Kleine-Budde } 2607cf3f047bSGiuseppe CAVALLARO if (!mac) 2608cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 2609cf3f047bSGiuseppe CAVALLARO 2610cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 2611cf3f047bSGiuseppe CAVALLARO 2612cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 2613cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 2614cf3f047bSGiuseppe CAVALLARO 26154a7d666aSGiuseppe CAVALLARO /* To use the chained or ring mode */ 26164a7d666aSGiuseppe CAVALLARO if (chain_mode) { 261729896a67SGiuseppe CAVALLARO priv->hw->mode = &chain_mode_ops; 26184a7d666aSGiuseppe CAVALLARO pr_info(" Chain mode enabled\n"); 26194a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_CHAIN_MODE; 26204a7d666aSGiuseppe CAVALLARO } else { 262129896a67SGiuseppe CAVALLARO priv->hw->mode = &ring_mode_ops; 26224a7d666aSGiuseppe CAVALLARO pr_info(" Ring mode enabled\n"); 26234a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_RING_MODE; 26244a7d666aSGiuseppe CAVALLARO } 26254a7d666aSGiuseppe CAVALLARO 2626cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 2627cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 2628cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 2629cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 2630cf3f047bSGiuseppe CAVALLARO 2631cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 2632cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 2633cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 2634cf3f047bSGiuseppe CAVALLARO * register (if supported). 2635cf3f047bSGiuseppe CAVALLARO */ 2636cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 2637cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 263838912bdbSDeepak SIKRI 263938912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 264038912bdbSDeepak SIKRI 264138912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 264238912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 264338912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 264438912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 264538912bdbSDeepak SIKRI 2646cf3f047bSGiuseppe CAVALLARO } else 2647cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 2648cf3f047bSGiuseppe CAVALLARO 264961369d02SByungho An /* To use alternate (extended) or normal descriptor structures */ 265061369d02SByungho An stmmac_selec_desc_mode(priv); 265161369d02SByungho An 265238912bdbSDeepak SIKRI ret = priv->hw->mac->rx_ipc(priv->ioaddr); 265338912bdbSDeepak SIKRI if (!ret) { 2654ceb69499SGiuseppe CAVALLARO pr_warn(" RX IPC Checksum Offload not configured.\n"); 265538912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_NONE; 265638912bdbSDeepak SIKRI } 265738912bdbSDeepak SIKRI 265838912bdbSDeepak SIKRI if (priv->plat->rx_coe) 265938912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 266038912bdbSDeepak SIKRI priv->plat->rx_coe); 2661cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 2662cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 2663cf3f047bSGiuseppe CAVALLARO 2664cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 2665cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 2666cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 2667cf3f047bSGiuseppe CAVALLARO } 2668cf3f047bSGiuseppe CAVALLARO 2669c24602efSGiuseppe CAVALLARO return 0; 2670cf3f047bSGiuseppe CAVALLARO } 2671cf3f047bSGiuseppe CAVALLARO 2672cf3f047bSGiuseppe CAVALLARO /** 2673bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 2674bfab27a1SGiuseppe CAVALLARO * @device: device pointer 2675ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 2676ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 2677bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 2678bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 26797ac6653aSJeff Kirsher */ 2680bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 2681cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 2682cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 26837ac6653aSJeff Kirsher { 26847ac6653aSJeff Kirsher int ret = 0; 2685bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 2686bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 26877ac6653aSJeff Kirsher 2688bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 268941de8d4cSJoe Perches if (!ndev) 2690bfab27a1SGiuseppe CAVALLARO return NULL; 26917ac6653aSJeff Kirsher 2692bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 26937ac6653aSJeff Kirsher 2694bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 2695bfab27a1SGiuseppe CAVALLARO priv->device = device; 2696bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 2697bfab27a1SGiuseppe CAVALLARO 2698bfab27a1SGiuseppe CAVALLARO ether_setup(ndev); 2699bfab27a1SGiuseppe CAVALLARO 2700bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 2701cf3f047bSGiuseppe CAVALLARO priv->pause = pause; 2702cf3f047bSGiuseppe CAVALLARO priv->plat = plat_dat; 2703cf3f047bSGiuseppe CAVALLARO priv->ioaddr = addr; 2704cf3f047bSGiuseppe CAVALLARO priv->dev->base_addr = (unsigned long)addr; 2705bfab27a1SGiuseppe CAVALLARO 2706cf3f047bSGiuseppe CAVALLARO /* Verify driver arguments */ 2707cf3f047bSGiuseppe CAVALLARO stmmac_verify_args(); 2708cf3f047bSGiuseppe CAVALLARO 2709cf3f047bSGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 2710ceb69499SGiuseppe CAVALLARO * this needs to have multiple instances 2711ceb69499SGiuseppe CAVALLARO */ 2712cf3f047bSGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 2713cf3f047bSGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 2714cf3f047bSGiuseppe CAVALLARO 271562866e98SChen-Yu Tsai priv->stmmac_clk = devm_clk_get(priv->device, STMMAC_RESOURCE_NAME); 271662866e98SChen-Yu Tsai if (IS_ERR(priv->stmmac_clk)) { 271762866e98SChen-Yu Tsai dev_warn(priv->device, "%s: warning: cannot get CSR clock\n", 271862866e98SChen-Yu Tsai __func__); 2719c5e4ddbdSChen-Yu Tsai ret = PTR_ERR(priv->stmmac_clk); 272062866e98SChen-Yu Tsai goto error_clk_get; 272162866e98SChen-Yu Tsai } 272262866e98SChen-Yu Tsai clk_prepare_enable(priv->stmmac_clk); 272362866e98SChen-Yu Tsai 2724c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = devm_reset_control_get(priv->device, 2725c5e4ddbdSChen-Yu Tsai STMMAC_RESOURCE_NAME); 2726c5e4ddbdSChen-Yu Tsai if (IS_ERR(priv->stmmac_rst)) { 2727c5e4ddbdSChen-Yu Tsai if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) { 2728c5e4ddbdSChen-Yu Tsai ret = -EPROBE_DEFER; 2729c5e4ddbdSChen-Yu Tsai goto error_hw_init; 2730c5e4ddbdSChen-Yu Tsai } 2731c5e4ddbdSChen-Yu Tsai dev_info(priv->device, "no reset control found\n"); 2732c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = NULL; 2733c5e4ddbdSChen-Yu Tsai } 2734c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2735c5e4ddbdSChen-Yu Tsai reset_control_deassert(priv->stmmac_rst); 2736c5e4ddbdSChen-Yu Tsai 2737cf3f047bSGiuseppe CAVALLARO /* Init MAC and get the capabilities */ 2738c24602efSGiuseppe CAVALLARO ret = stmmac_hw_init(priv); 2739c24602efSGiuseppe CAVALLARO if (ret) 274062866e98SChen-Yu Tsai goto error_hw_init; 2741cf3f047bSGiuseppe CAVALLARO 2742cf3f047bSGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 2743cf3f047bSGiuseppe CAVALLARO 2744cf3f047bSGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 2745cf3f047bSGiuseppe CAVALLARO NETIF_F_RXCSUM; 2746bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 2747bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 27487ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 27497ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 2750f646968fSPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; 27517ac6653aSJeff Kirsher #endif 27527ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 27537ac6653aSJeff Kirsher 27547ac6653aSJeff Kirsher if (flow_ctrl) 27557ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 27567ac6653aSJeff Kirsher 275762a2ab93SGiuseppe CAVALLARO /* Rx Watchdog is available in the COREs newer than the 3.40. 275862a2ab93SGiuseppe CAVALLARO * In some case, for example on bugged HW this feature 275962a2ab93SGiuseppe CAVALLARO * has to be disable and this can be done by passing the 276062a2ab93SGiuseppe CAVALLARO * riwt_off field from the platform. 276162a2ab93SGiuseppe CAVALLARO */ 276262a2ab93SGiuseppe CAVALLARO if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { 276362a2ab93SGiuseppe CAVALLARO priv->use_riwt = 1; 276462a2ab93SGiuseppe CAVALLARO pr_info(" Enable RX Mitigation via HW Watchdog Timer\n"); 276562a2ab93SGiuseppe CAVALLARO } 276662a2ab93SGiuseppe CAVALLARO 2767bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 27687ac6653aSJeff Kirsher 27697ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 2770a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 27717ac6653aSJeff Kirsher 2772bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 27737ac6653aSJeff Kirsher if (ret) { 2774cf3f047bSGiuseppe CAVALLARO pr_err("%s: ERROR %i registering the device\n", __func__, ret); 27756a81c26fSViresh Kumar goto error_netdev_register; 27767ac6653aSJeff Kirsher } 27777ac6653aSJeff Kirsher 2778cd7201f4SGiuseppe CAVALLARO /* If a specific clk_csr value is passed from the platform 2779cd7201f4SGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 2780cd7201f4SGiuseppe CAVALLARO * changed at run-time and it is fixed. Viceversa the driver'll try to 2781cd7201f4SGiuseppe CAVALLARO * set the MDC clock dynamically according to the csr actual 2782cd7201f4SGiuseppe CAVALLARO * clock input. 2783cd7201f4SGiuseppe CAVALLARO */ 2784cd7201f4SGiuseppe CAVALLARO if (!priv->plat->clk_csr) 2785cd7201f4SGiuseppe CAVALLARO stmmac_clk_csr_set(priv); 2786cd7201f4SGiuseppe CAVALLARO else 2787cd7201f4SGiuseppe CAVALLARO priv->clk_csr = priv->plat->clk_csr; 2788cd7201f4SGiuseppe CAVALLARO 2789e58bb43fSGiuseppe CAVALLARO stmmac_check_pcs_mode(priv); 2790e58bb43fSGiuseppe CAVALLARO 27914d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 27924d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 27934bfcbd7aSFrancesco Virlinzi /* MDIO bus Registration */ 27944bfcbd7aSFrancesco Virlinzi ret = stmmac_mdio_register(ndev); 27954bfcbd7aSFrancesco Virlinzi if (ret < 0) { 27964bfcbd7aSFrancesco Virlinzi pr_debug("%s: MDIO bus (id: %d) registration failed", 27974bfcbd7aSFrancesco Virlinzi __func__, priv->plat->bus_id); 27986a81c26fSViresh Kumar goto error_mdio_register; 27994bfcbd7aSFrancesco Virlinzi } 2800e58bb43fSGiuseppe CAVALLARO } 28014bfcbd7aSFrancesco Virlinzi 2802bfab27a1SGiuseppe CAVALLARO return priv; 28037ac6653aSJeff Kirsher 28046a81c26fSViresh Kumar error_mdio_register: 28057ac6653aSJeff Kirsher unregister_netdev(ndev); 28066a81c26fSViresh Kumar error_netdev_register: 28076a81c26fSViresh Kumar netif_napi_del(&priv->napi); 280862866e98SChen-Yu Tsai error_hw_init: 280962866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 281062866e98SChen-Yu Tsai error_clk_get: 28117ac6653aSJeff Kirsher free_netdev(ndev); 28127ac6653aSJeff Kirsher 2813c5e4ddbdSChen-Yu Tsai return ERR_PTR(ret); 28147ac6653aSJeff Kirsher } 28157ac6653aSJeff Kirsher 28167ac6653aSJeff Kirsher /** 28177ac6653aSJeff Kirsher * stmmac_dvr_remove 2818bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 28197ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 2820bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 28217ac6653aSJeff Kirsher */ 2822bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 28237ac6653aSJeff Kirsher { 28247ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 28257ac6653aSJeff Kirsher 28267ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 28277ac6653aSJeff Kirsher 28287ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 28297ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 28307ac6653aSJeff Kirsher 2831bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 28324d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 28334d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) 28344bfcbd7aSFrancesco Virlinzi stmmac_mdio_unregister(ndev); 28357ac6653aSJeff Kirsher netif_carrier_off(ndev); 28367ac6653aSJeff Kirsher unregister_netdev(ndev); 2837c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2838c5e4ddbdSChen-Yu Tsai reset_control_assert(priv->stmmac_rst); 283962866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 28407ac6653aSJeff Kirsher free_netdev(ndev); 28417ac6653aSJeff Kirsher 28427ac6653aSJeff Kirsher return 0; 28437ac6653aSJeff Kirsher } 28447ac6653aSJeff Kirsher 28457ac6653aSJeff Kirsher #ifdef CONFIG_PM 2846bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 28477ac6653aSJeff Kirsher { 28487ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2849f8c5a875SGiuseppe CAVALLARO unsigned long flags; 28507ac6653aSJeff Kirsher 28517ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 28527ac6653aSJeff Kirsher return 0; 28537ac6653aSJeff Kirsher 2854102463b1SFrancesco Virlinzi if (priv->phydev) 2855102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 2856102463b1SFrancesco Virlinzi 2857f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 28587ac6653aSJeff Kirsher 28597ac6653aSJeff Kirsher netif_device_detach(ndev); 28607ac6653aSJeff Kirsher netif_stop_queue(ndev); 28617ac6653aSJeff Kirsher 28627ac6653aSJeff Kirsher napi_disable(&priv->napi); 28637ac6653aSJeff Kirsher 28647ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 28657ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 28667ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 2867c24602efSGiuseppe CAVALLARO 2868c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 28697ac6653aSJeff Kirsher 28707ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 287189f7f2cfSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 28727ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 287389f7f2cfSSrinivas Kandagatla priv->irq_wake = 1; 287489f7f2cfSSrinivas Kandagatla } else { 2875bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 2876db88f10aSSrinivas Kandagatla pinctrl_pm_select_sleep_state(priv->device); 2877ba1377ffSGiuseppe CAVALLARO /* Disable clock in case of PWM is off */ 2878a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 2879ba1377ffSGiuseppe CAVALLARO } 2880f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 28812d871aa0SVince Bridgers 28822d871aa0SVince Bridgers priv->oldlink = 0; 28832d871aa0SVince Bridgers priv->speed = 0; 28842d871aa0SVince Bridgers priv->oldduplex = -1; 28857ac6653aSJeff Kirsher return 0; 28867ac6653aSJeff Kirsher } 28877ac6653aSJeff Kirsher 2888bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 28897ac6653aSJeff Kirsher { 28907ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2891f8c5a875SGiuseppe CAVALLARO unsigned long flags; 28927ac6653aSJeff Kirsher 28937ac6653aSJeff Kirsher if (!netif_running(ndev)) 28947ac6653aSJeff Kirsher return 0; 28957ac6653aSJeff Kirsher 2896f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 28977ac6653aSJeff Kirsher 28987ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 28997ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 29007ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 29017ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 2902ceb69499SGiuseppe CAVALLARO * from another devices (e.g. serial console). 2903ceb69499SGiuseppe CAVALLARO */ 2904623997fbSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 29057ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, 0); 290689f7f2cfSSrinivas Kandagatla priv->irq_wake = 0; 2907623997fbSSrinivas Kandagatla } else { 2908db88f10aSSrinivas Kandagatla pinctrl_pm_select_default_state(priv->device); 2909ba1377ffSGiuseppe CAVALLARO /* enable the clk prevously disabled */ 2910a630844dSStefan Roese clk_prepare_enable(priv->stmmac_clk); 2911623997fbSSrinivas Kandagatla /* reset the phy so that it's ready */ 2912623997fbSSrinivas Kandagatla if (priv->mii) 2913623997fbSSrinivas Kandagatla stmmac_mdio_reset(priv->mii); 2914623997fbSSrinivas Kandagatla } 29157ac6653aSJeff Kirsher 29167ac6653aSJeff Kirsher netif_device_attach(ndev); 29177ac6653aSJeff Kirsher 2918623997fbSSrinivas Kandagatla stmmac_hw_setup(ndev); 29197ac6653aSJeff Kirsher 29207ac6653aSJeff Kirsher napi_enable(&priv->napi); 29217ac6653aSJeff Kirsher 29227ac6653aSJeff Kirsher netif_start_queue(ndev); 29237ac6653aSJeff Kirsher 2924f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 2925102463b1SFrancesco Virlinzi 2926102463b1SFrancesco Virlinzi if (priv->phydev) 2927102463b1SFrancesco Virlinzi phy_start(priv->phydev); 2928102463b1SFrancesco Virlinzi 29297ac6653aSJeff Kirsher return 0; 29307ac6653aSJeff Kirsher } 29317ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 29327ac6653aSJeff Kirsher 293333d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers 293433d5e332SGiuseppe CAVALLARO * depending on the configuration selected. 293533d5e332SGiuseppe CAVALLARO */ 2936ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void) 2937ba27ec66SGiuseppe CAVALLARO { 2938493682b8SKonstantin Khlebnikov int ret; 2939ba27ec66SGiuseppe CAVALLARO 2940493682b8SKonstantin Khlebnikov ret = stmmac_register_platform(); 2941493682b8SKonstantin Khlebnikov if (ret) 2942493682b8SKonstantin Khlebnikov goto err; 2943493682b8SKonstantin Khlebnikov ret = stmmac_register_pci(); 2944493682b8SKonstantin Khlebnikov if (ret) 2945493682b8SKonstantin Khlebnikov goto err_pci; 294633d5e332SGiuseppe CAVALLARO return 0; 2947493682b8SKonstantin Khlebnikov err_pci: 2948493682b8SKonstantin Khlebnikov stmmac_unregister_platform(); 2949493682b8SKonstantin Khlebnikov err: 2950493682b8SKonstantin Khlebnikov pr_err("stmmac: driver registration failed\n"); 2951493682b8SKonstantin Khlebnikov return ret; 2952ba27ec66SGiuseppe CAVALLARO } 2953ba27ec66SGiuseppe CAVALLARO 2954ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void) 2955ba27ec66SGiuseppe CAVALLARO { 295633d5e332SGiuseppe CAVALLARO stmmac_unregister_platform(); 295733d5e332SGiuseppe CAVALLARO stmmac_unregister_pci(); 2958ba27ec66SGiuseppe CAVALLARO } 2959ba27ec66SGiuseppe CAVALLARO 2960ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init); 2961ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit); 2962ba27ec66SGiuseppe CAVALLARO 29637ac6653aSJeff Kirsher #ifndef MODULE 29647ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 29657ac6653aSJeff Kirsher { 29667ac6653aSJeff Kirsher char *opt; 29677ac6653aSJeff Kirsher 29687ac6653aSJeff Kirsher if (!str || !*str) 29697ac6653aSJeff Kirsher return -EINVAL; 29707ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 29717ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 2972ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &debug)) 29737ac6653aSJeff Kirsher goto err; 29747ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 2975ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 8, 0, &phyaddr)) 29767ac6653aSJeff Kirsher goto err; 29777ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 2978ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_txsize)) 29797ac6653aSJeff Kirsher goto err; 29807ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 2981ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_rxsize)) 29827ac6653aSJeff Kirsher goto err; 29837ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 2984ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &buf_sz)) 29857ac6653aSJeff Kirsher goto err; 29867ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 2987ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 3, 0, &tc)) 29887ac6653aSJeff Kirsher goto err; 29897ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 2990ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 9, 0, &watchdog)) 29917ac6653aSJeff Kirsher goto err; 29927ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 2993ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &flow_ctrl)) 29947ac6653aSJeff Kirsher goto err; 29957ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 2996ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &pause)) 29977ac6653aSJeff Kirsher goto err; 2998506f669cSGiuseppe CAVALLARO } else if (!strncmp(opt, "eee_timer:", 10)) { 2999d765955dSGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &eee_timer)) 3000d765955dSGiuseppe CAVALLARO goto err; 30014a7d666aSGiuseppe CAVALLARO } else if (!strncmp(opt, "chain_mode:", 11)) { 30024a7d666aSGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &chain_mode)) 30034a7d666aSGiuseppe CAVALLARO goto err; 30047ac6653aSJeff Kirsher } 30057ac6653aSJeff Kirsher } 30067ac6653aSJeff Kirsher return 0; 30077ac6653aSJeff Kirsher 30087ac6653aSJeff Kirsher err: 30097ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 30107ac6653aSJeff Kirsher return -EINVAL; 30117ac6653aSJeff Kirsher } 30127ac6653aSJeff Kirsher 30137ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 3014ceb69499SGiuseppe CAVALLARO #endif /* MODULE */ 30156fc0d0f2SGiuseppe Cavallaro 30166fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 30176fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 30186fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 3019