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