17ac6653aSJeff Kirsher /******************************************************************************* 27ac6653aSJeff Kirsher This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers. 37ac6653aSJeff Kirsher ST Ethernet IPs are built around a Synopsys IP Core. 47ac6653aSJeff Kirsher 5286a8372SGiuseppe CAVALLARO Copyright(C) 2007-2011 STMicroelectronics Ltd 67ac6653aSJeff Kirsher 77ac6653aSJeff Kirsher This program is free software; you can redistribute it and/or modify it 87ac6653aSJeff Kirsher under the terms and conditions of the GNU General Public License, 97ac6653aSJeff Kirsher version 2, as published by the Free Software Foundation. 107ac6653aSJeff Kirsher 117ac6653aSJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 127ac6653aSJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137ac6653aSJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 147ac6653aSJeff Kirsher more details. 157ac6653aSJeff Kirsher 167ac6653aSJeff Kirsher You should have received a copy of the GNU General Public License along with 177ac6653aSJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 187ac6653aSJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 197ac6653aSJeff Kirsher 207ac6653aSJeff Kirsher The full GNU General Public License is included in this distribution in 217ac6653aSJeff Kirsher the file called "COPYING". 227ac6653aSJeff Kirsher 237ac6653aSJeff Kirsher Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 247ac6653aSJeff Kirsher 257ac6653aSJeff Kirsher Documentation available at: 267ac6653aSJeff Kirsher http://www.stlinux.com 277ac6653aSJeff Kirsher Support available at: 287ac6653aSJeff Kirsher https://bugzilla.stlinux.com/ 297ac6653aSJeff Kirsher *******************************************************************************/ 307ac6653aSJeff Kirsher 316a81c26fSViresh Kumar #include <linux/clk.h> 327ac6653aSJeff Kirsher #include <linux/kernel.h> 337ac6653aSJeff Kirsher #include <linux/interrupt.h> 347ac6653aSJeff Kirsher #include <linux/ip.h> 357ac6653aSJeff Kirsher #include <linux/tcp.h> 367ac6653aSJeff Kirsher #include <linux/skbuff.h> 377ac6653aSJeff Kirsher #include <linux/ethtool.h> 387ac6653aSJeff Kirsher #include <linux/if_ether.h> 397ac6653aSJeff Kirsher #include <linux/crc32.h> 407ac6653aSJeff Kirsher #include <linux/mii.h> 4101789349SJiri Pirko #include <linux/if.h> 427ac6653aSJeff Kirsher #include <linux/if_vlan.h> 437ac6653aSJeff Kirsher #include <linux/dma-mapping.h> 447ac6653aSJeff Kirsher #include <linux/slab.h> 457ac6653aSJeff Kirsher #include <linux/prefetch.h> 46db88f10aSSrinivas Kandagatla #include <linux/pinctrl/consumer.h> 477ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 487ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h> 497ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h> 50ceb69499SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 51891434b1SRayagond Kokatanur #include <linux/net_tstamp.h> 52891434b1SRayagond Kokatanur #include "stmmac_ptp.h" 53286a8372SGiuseppe CAVALLARO #include "stmmac.h" 54c5e4ddbdSChen-Yu Tsai #include <linux/reset.h> 557ac6653aSJeff Kirsher 567ac6653aSJeff Kirsher #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) 577ac6653aSJeff Kirsher 587ac6653aSJeff Kirsher /* Module parameters */ 5932ceabcaSGiuseppe CAVALLARO #define TX_TIMEO 5000 607ac6653aSJeff Kirsher static int watchdog = TX_TIMEO; 617ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR); 6232ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds (default 5s)"); 637ac6653aSJeff Kirsher 6432ceabcaSGiuseppe CAVALLARO static int debug = -1; 657ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR); 6632ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); 677ac6653aSJeff Kirsher 6847d1f71fSstephen hemminger static int phyaddr = -1; 697ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO); 707ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address"); 717ac6653aSJeff Kirsher 727ac6653aSJeff Kirsher #define DMA_TX_SIZE 256 737ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE; 747ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR); 757ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list"); 767ac6653aSJeff Kirsher 777ac6653aSJeff Kirsher #define DMA_RX_SIZE 256 787ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE; 797ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR); 807ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list"); 817ac6653aSJeff Kirsher 827ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF; 837ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); 847ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); 857ac6653aSJeff Kirsher 867ac6653aSJeff Kirsher static int pause = PAUSE_TIME; 877ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR); 887ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time"); 897ac6653aSJeff Kirsher 907ac6653aSJeff Kirsher #define TC_DEFAULT 64 917ac6653aSJeff Kirsher static int tc = TC_DEFAULT; 927ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR); 937ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value"); 947ac6653aSJeff Kirsher 95d916701cSGiuseppe CAVALLARO #define DEFAULT_BUFSIZE 1536 96d916701cSGiuseppe CAVALLARO static int buf_sz = DEFAULT_BUFSIZE; 977ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 987ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 997ac6653aSJeff Kirsher 1007ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1017ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1027ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1037ac6653aSJeff Kirsher 104d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER 1000 105d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; 106d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR); 107d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); 108f5351ef7SGiuseppe CAVALLARO #define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x)) 109d765955dSGiuseppe CAVALLARO 1104a7d666aSGiuseppe CAVALLARO /* By default the driver will use the ring mode to manage tx and rx descriptors 1114a7d666aSGiuseppe CAVALLARO * but passing this value so user can force to use the chain instead of the ring 1124a7d666aSGiuseppe CAVALLARO */ 1134a7d666aSGiuseppe CAVALLARO static unsigned int chain_mode; 1144a7d666aSGiuseppe CAVALLARO module_param(chain_mode, int, S_IRUGO); 1154a7d666aSGiuseppe CAVALLARO MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode"); 1164a7d666aSGiuseppe CAVALLARO 1177ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1187ac6653aSJeff Kirsher 119bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 120bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev); 121bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void); 122bfab27a1SGiuseppe CAVALLARO #endif 123bfab27a1SGiuseppe CAVALLARO 1249125cdd1SGiuseppe CAVALLARO #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) 1259125cdd1SGiuseppe CAVALLARO 1267ac6653aSJeff Kirsher /** 1277ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1287ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1297ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1307ac6653aSJeff Kirsher */ 1317ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1327ac6653aSJeff Kirsher { 1337ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1347ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1357ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1367ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1377ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1387ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 139d916701cSGiuseppe CAVALLARO if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB))) 140d916701cSGiuseppe CAVALLARO buf_sz = DEFAULT_BUFSIZE; 1417ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1427ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1437ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1447ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1457ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1467ac6653aSJeff Kirsher pause = PAUSE_TIME; 147d765955dSGiuseppe CAVALLARO if (eee_timer < 0) 148d765955dSGiuseppe CAVALLARO eee_timer = STMMAC_DEFAULT_LPI_TIMER; 1497ac6653aSJeff Kirsher } 1507ac6653aSJeff Kirsher 15132ceabcaSGiuseppe CAVALLARO /** 15232ceabcaSGiuseppe CAVALLARO * stmmac_clk_csr_set - dynamically set the MDC clock 15332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 15432ceabcaSGiuseppe CAVALLARO * Description: this is to dynamically set the MDC clock according to the csr 15532ceabcaSGiuseppe CAVALLARO * clock input. 15632ceabcaSGiuseppe CAVALLARO * Note: 15732ceabcaSGiuseppe CAVALLARO * If a specific clk_csr value is passed from the platform 15832ceabcaSGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 15932ceabcaSGiuseppe CAVALLARO * changed at run-time and it is fixed (as reported in the driver 16032ceabcaSGiuseppe CAVALLARO * documentation). Viceversa the driver will try to set the MDC 16132ceabcaSGiuseppe CAVALLARO * clock dynamically according to the actual clock input. 16232ceabcaSGiuseppe CAVALLARO */ 163cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv) 164cd7201f4SGiuseppe CAVALLARO { 165cd7201f4SGiuseppe CAVALLARO u32 clk_rate; 166cd7201f4SGiuseppe CAVALLARO 167cd7201f4SGiuseppe CAVALLARO clk_rate = clk_get_rate(priv->stmmac_clk); 168cd7201f4SGiuseppe CAVALLARO 169cd7201f4SGiuseppe CAVALLARO /* Platform provided default clk_csr would be assumed valid 170ceb69499SGiuseppe CAVALLARO * for all other cases except for the below mentioned ones. 171ceb69499SGiuseppe CAVALLARO * For values higher than the IEEE 802.3 specified frequency 172ceb69499SGiuseppe CAVALLARO * we can not estimate the proper divider as it is not known 173ceb69499SGiuseppe CAVALLARO * the frequency of clk_csr_i. So we do not change the default 174ceb69499SGiuseppe CAVALLARO * divider. 175ceb69499SGiuseppe CAVALLARO */ 176cd7201f4SGiuseppe CAVALLARO if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) { 177cd7201f4SGiuseppe CAVALLARO if (clk_rate < CSR_F_35M) 178cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_20_35M; 179cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M)) 180cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_35_60M; 181cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M)) 182cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_60_100M; 183cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M)) 184cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_100_150M; 185cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) 186cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_150_250M; 187cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) 188cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_250_300M; 189ceb69499SGiuseppe CAVALLARO } 190cd7201f4SGiuseppe CAVALLARO } 191cd7201f4SGiuseppe CAVALLARO 1927ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1937ac6653aSJeff Kirsher { 1947ac6653aSJeff Kirsher int j; 19583d7af64SGiuseppe CAVALLARO pr_debug("len = %d byte, buf addr: 0x%p", len, buf); 1967ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 1977ac6653aSJeff Kirsher if ((j % 16) == 0) 19883d7af64SGiuseppe CAVALLARO pr_debug("\n %03x:", j); 19983d7af64SGiuseppe CAVALLARO pr_debug(" %02x", buf[j]); 2007ac6653aSJeff Kirsher } 20183d7af64SGiuseppe CAVALLARO pr_debug("\n"); 2027ac6653aSJeff Kirsher } 2037ac6653aSJeff Kirsher 2047ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 2057ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 2067ac6653aSJeff Kirsher 2077ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 2087ac6653aSJeff Kirsher { 2097ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 2107ac6653aSJeff Kirsher } 2117ac6653aSJeff Kirsher 21232ceabcaSGiuseppe CAVALLARO /** 21332ceabcaSGiuseppe CAVALLARO * stmmac_hw_fix_mac_speed: callback for speed selection 21432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 21532ceabcaSGiuseppe CAVALLARO * Description: on some platforms (e.g. ST), some HW system configuraton 21632ceabcaSGiuseppe CAVALLARO * registers have to be set according to the link speed negotiated. 2177ac6653aSJeff Kirsher */ 2187ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 2197ac6653aSJeff Kirsher { 2207ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2217ac6653aSJeff Kirsher 2227ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 223ceb69499SGiuseppe CAVALLARO priv->plat->fix_mac_speed(priv->plat->bsp_priv, phydev->speed); 2247ac6653aSJeff Kirsher } 2257ac6653aSJeff Kirsher 22632ceabcaSGiuseppe CAVALLARO /** 22732ceabcaSGiuseppe CAVALLARO * stmmac_enable_eee_mode: Check and enter in LPI mode 22832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 22932ceabcaSGiuseppe CAVALLARO * Description: this function is to verify and enter in LPI mode for EEE. 23032ceabcaSGiuseppe CAVALLARO */ 231d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv) 232d765955dSGiuseppe CAVALLARO { 233d765955dSGiuseppe CAVALLARO /* Check and enter in LPI mode */ 234d765955dSGiuseppe CAVALLARO if ((priv->dirty_tx == priv->cur_tx) && 235d765955dSGiuseppe CAVALLARO (priv->tx_path_in_lpi_mode == false)) 2367ed24bbeSVince Bridgers priv->hw->mac->set_eee_mode(priv->hw); 237d765955dSGiuseppe CAVALLARO } 238d765955dSGiuseppe CAVALLARO 23932ceabcaSGiuseppe CAVALLARO /** 24032ceabcaSGiuseppe CAVALLARO * stmmac_disable_eee_mode: disable/exit from EEE 24132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 24232ceabcaSGiuseppe CAVALLARO * Description: this function is to exit and disable EEE in case of 24332ceabcaSGiuseppe CAVALLARO * LPI state is true. This is called by the xmit. 24432ceabcaSGiuseppe CAVALLARO */ 245d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv) 246d765955dSGiuseppe CAVALLARO { 2477ed24bbeSVince Bridgers priv->hw->mac->reset_eee_mode(priv->hw); 248d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 249d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 250d765955dSGiuseppe CAVALLARO } 251d765955dSGiuseppe CAVALLARO 252d765955dSGiuseppe CAVALLARO /** 25332ceabcaSGiuseppe CAVALLARO * stmmac_eee_ctrl_timer: EEE TX SW timer. 254d765955dSGiuseppe CAVALLARO * @arg : data hook 255d765955dSGiuseppe CAVALLARO * Description: 25632ceabcaSGiuseppe CAVALLARO * if there is no data transfer and if we are not in LPI state, 257d765955dSGiuseppe CAVALLARO * then MAC Transmitter can be moved to LPI state. 258d765955dSGiuseppe CAVALLARO */ 259d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg) 260d765955dSGiuseppe CAVALLARO { 261d765955dSGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)arg; 262d765955dSGiuseppe CAVALLARO 263d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 264f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 265d765955dSGiuseppe CAVALLARO } 266d765955dSGiuseppe CAVALLARO 267d765955dSGiuseppe CAVALLARO /** 26832ceabcaSGiuseppe CAVALLARO * stmmac_eee_init: init EEE 26932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 270d765955dSGiuseppe CAVALLARO * Description: 271d765955dSGiuseppe CAVALLARO * If the EEE support has been enabled while configuring the driver, 272d765955dSGiuseppe CAVALLARO * if the GMAC actually supports the EEE (from the HW cap reg) and the 273d765955dSGiuseppe CAVALLARO * phy can also manage EEE, so enable the LPI state and start the timer 274d765955dSGiuseppe CAVALLARO * to verify if the tx path can enter in LPI state. 275d765955dSGiuseppe CAVALLARO */ 276d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv) 277d765955dSGiuseppe CAVALLARO { 278d765955dSGiuseppe CAVALLARO bool ret = false; 279d765955dSGiuseppe CAVALLARO 280f5351ef7SGiuseppe CAVALLARO /* Using PCS we cannot dial with the phy registers at this stage 281f5351ef7SGiuseppe CAVALLARO * so we do not support extra feature like EEE. 282f5351ef7SGiuseppe CAVALLARO */ 283f5351ef7SGiuseppe CAVALLARO if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) || 284f5351ef7SGiuseppe CAVALLARO (priv->pcs == STMMAC_PCS_RTBI)) 285f5351ef7SGiuseppe CAVALLARO goto out; 286f5351ef7SGiuseppe CAVALLARO 287d765955dSGiuseppe CAVALLARO /* MAC core supports the EEE feature. */ 288d765955dSGiuseppe CAVALLARO if (priv->dma_cap.eee) { 28983bf79b6SGiuseppe CAVALLARO int tx_lpi_timer = priv->tx_lpi_timer; 290d765955dSGiuseppe CAVALLARO 29183bf79b6SGiuseppe CAVALLARO /* Check if the PHY supports EEE */ 29283bf79b6SGiuseppe CAVALLARO if (phy_init_eee(priv->phydev, 1)) { 29383bf79b6SGiuseppe CAVALLARO /* To manage at run-time if the EEE cannot be supported 29483bf79b6SGiuseppe CAVALLARO * anymore (for example because the lp caps have been 29583bf79b6SGiuseppe CAVALLARO * changed). 29683bf79b6SGiuseppe CAVALLARO * In that case the driver disable own timers. 29783bf79b6SGiuseppe CAVALLARO */ 29883bf79b6SGiuseppe CAVALLARO if (priv->eee_active) { 29983bf79b6SGiuseppe CAVALLARO pr_debug("stmmac: disable EEE\n"); 30083bf79b6SGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 3017ed24bbeSVince Bridgers priv->hw->mac->set_eee_timer(priv->hw, 0, 30283bf79b6SGiuseppe CAVALLARO tx_lpi_timer); 30383bf79b6SGiuseppe CAVALLARO } 30483bf79b6SGiuseppe CAVALLARO priv->eee_active = 0; 30583bf79b6SGiuseppe CAVALLARO goto out; 30683bf79b6SGiuseppe CAVALLARO } 30783bf79b6SGiuseppe CAVALLARO /* Activate the EEE and start timers */ 308f5351ef7SGiuseppe CAVALLARO if (!priv->eee_active) { 309d765955dSGiuseppe CAVALLARO priv->eee_active = 1; 310d765955dSGiuseppe CAVALLARO init_timer(&priv->eee_ctrl_timer); 311d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; 312d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.data = (unsigned long)priv; 313f5351ef7SGiuseppe CAVALLARO priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer); 314d765955dSGiuseppe CAVALLARO add_timer(&priv->eee_ctrl_timer); 315d765955dSGiuseppe CAVALLARO 3167ed24bbeSVince Bridgers priv->hw->mac->set_eee_timer(priv->hw, 317f5351ef7SGiuseppe CAVALLARO STMMAC_DEFAULT_LIT_LS, 31883bf79b6SGiuseppe CAVALLARO tx_lpi_timer); 319f5351ef7SGiuseppe CAVALLARO } else 320f5351ef7SGiuseppe CAVALLARO /* Set HW EEE according to the speed */ 3217ed24bbeSVince Bridgers priv->hw->mac->set_eee_pls(priv->hw, 322f5351ef7SGiuseppe CAVALLARO priv->phydev->link); 323d765955dSGiuseppe CAVALLARO 32483bf79b6SGiuseppe CAVALLARO pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); 325d765955dSGiuseppe CAVALLARO 326d765955dSGiuseppe CAVALLARO ret = true; 327d765955dSGiuseppe CAVALLARO } 328d765955dSGiuseppe CAVALLARO out: 329d765955dSGiuseppe CAVALLARO return ret; 330d765955dSGiuseppe CAVALLARO } 331d765955dSGiuseppe CAVALLARO 33232ceabcaSGiuseppe CAVALLARO /* stmmac_get_tx_hwtstamp: get HW TX timestamps 33332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 334891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 335891434b1SRayagond Kokatanur * @skb : the socket buffer 336891434b1SRayagond Kokatanur * Description : 337891434b1SRayagond Kokatanur * This function will read timestamp from the descriptor & pass it to stack. 338891434b1SRayagond Kokatanur * and also perform some sanity checks. 339891434b1SRayagond Kokatanur */ 340891434b1SRayagond Kokatanur static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, 341ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 342891434b1SRayagond Kokatanur { 343891434b1SRayagond Kokatanur struct skb_shared_hwtstamps shhwtstamp; 344891434b1SRayagond Kokatanur u64 ns; 345891434b1SRayagond Kokatanur void *desc = NULL; 346891434b1SRayagond Kokatanur 347891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 348891434b1SRayagond Kokatanur return; 349891434b1SRayagond Kokatanur 350ceb69499SGiuseppe CAVALLARO /* exit if skb doesn't support hw tstamp */ 35175e4364fSdamuzi000 if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))) 352891434b1SRayagond Kokatanur return; 353891434b1SRayagond Kokatanur 354891434b1SRayagond Kokatanur if (priv->adv_ts) 355891434b1SRayagond Kokatanur desc = (priv->dma_etx + entry); 356891434b1SRayagond Kokatanur else 357891434b1SRayagond Kokatanur desc = (priv->dma_tx + entry); 358891434b1SRayagond Kokatanur 359891434b1SRayagond Kokatanur /* check tx tstamp status */ 360891434b1SRayagond Kokatanur if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc)) 361891434b1SRayagond Kokatanur return; 362891434b1SRayagond Kokatanur 363891434b1SRayagond Kokatanur /* get the valid tstamp */ 364891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 365891434b1SRayagond Kokatanur 366891434b1SRayagond Kokatanur memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 367891434b1SRayagond Kokatanur shhwtstamp.hwtstamp = ns_to_ktime(ns); 368891434b1SRayagond Kokatanur /* pass tstamp to stack */ 369891434b1SRayagond Kokatanur skb_tstamp_tx(skb, &shhwtstamp); 370891434b1SRayagond Kokatanur 371891434b1SRayagond Kokatanur return; 372891434b1SRayagond Kokatanur } 373891434b1SRayagond Kokatanur 37432ceabcaSGiuseppe CAVALLARO /* stmmac_get_rx_hwtstamp: get HW RX timestamps 37532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 376891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 377891434b1SRayagond Kokatanur * @skb : the socket buffer 378891434b1SRayagond Kokatanur * Description : 379891434b1SRayagond Kokatanur * This function will read received packet's timestamp from the descriptor 380891434b1SRayagond Kokatanur * and pass it to stack. It also perform some sanity checks. 381891434b1SRayagond Kokatanur */ 382891434b1SRayagond Kokatanur static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, 383ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 384891434b1SRayagond Kokatanur { 385891434b1SRayagond Kokatanur struct skb_shared_hwtstamps *shhwtstamp = NULL; 386891434b1SRayagond Kokatanur u64 ns; 387891434b1SRayagond Kokatanur void *desc = NULL; 388891434b1SRayagond Kokatanur 389891434b1SRayagond Kokatanur if (!priv->hwts_rx_en) 390891434b1SRayagond Kokatanur return; 391891434b1SRayagond Kokatanur 392891434b1SRayagond Kokatanur if (priv->adv_ts) 393891434b1SRayagond Kokatanur desc = (priv->dma_erx + entry); 394891434b1SRayagond Kokatanur else 395891434b1SRayagond Kokatanur desc = (priv->dma_rx + entry); 396891434b1SRayagond Kokatanur 397ceb69499SGiuseppe CAVALLARO /* exit if rx tstamp is not valid */ 398891434b1SRayagond Kokatanur if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) 399891434b1SRayagond Kokatanur return; 400891434b1SRayagond Kokatanur 401891434b1SRayagond Kokatanur /* get valid tstamp */ 402891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 403891434b1SRayagond Kokatanur shhwtstamp = skb_hwtstamps(skb); 404891434b1SRayagond Kokatanur memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 405891434b1SRayagond Kokatanur shhwtstamp->hwtstamp = ns_to_ktime(ns); 406891434b1SRayagond Kokatanur } 407891434b1SRayagond Kokatanur 408891434b1SRayagond Kokatanur /** 409891434b1SRayagond Kokatanur * stmmac_hwtstamp_ioctl - control hardware timestamping. 410891434b1SRayagond Kokatanur * @dev: device pointer. 411891434b1SRayagond Kokatanur * @ifr: An IOCTL specefic structure, that can contain a pointer to 412891434b1SRayagond Kokatanur * a proprietary structure used to pass information to the driver. 413891434b1SRayagond Kokatanur * Description: 414891434b1SRayagond Kokatanur * This function configures the MAC to enable/disable both outgoing(TX) 415891434b1SRayagond Kokatanur * and incoming(RX) packets time stamping based on user input. 416891434b1SRayagond Kokatanur * Return Value: 417891434b1SRayagond Kokatanur * 0 on success and an appropriate -ve integer on failure. 418891434b1SRayagond Kokatanur */ 419891434b1SRayagond Kokatanur static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) 420891434b1SRayagond Kokatanur { 421891434b1SRayagond Kokatanur struct stmmac_priv *priv = netdev_priv(dev); 422891434b1SRayagond Kokatanur struct hwtstamp_config config; 423891434b1SRayagond Kokatanur struct timespec now; 424891434b1SRayagond Kokatanur u64 temp = 0; 425891434b1SRayagond Kokatanur u32 ptp_v2 = 0; 426891434b1SRayagond Kokatanur u32 tstamp_all = 0; 427891434b1SRayagond Kokatanur u32 ptp_over_ipv4_udp = 0; 428891434b1SRayagond Kokatanur u32 ptp_over_ipv6_udp = 0; 429891434b1SRayagond Kokatanur u32 ptp_over_ethernet = 0; 430891434b1SRayagond Kokatanur u32 snap_type_sel = 0; 431891434b1SRayagond Kokatanur u32 ts_master_en = 0; 432891434b1SRayagond Kokatanur u32 ts_event_en = 0; 433891434b1SRayagond Kokatanur u32 value = 0; 434891434b1SRayagond Kokatanur 435891434b1SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { 436891434b1SRayagond Kokatanur netdev_alert(priv->dev, "No support for HW time stamping\n"); 437891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 438891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 439891434b1SRayagond Kokatanur 440891434b1SRayagond Kokatanur return -EOPNOTSUPP; 441891434b1SRayagond Kokatanur } 442891434b1SRayagond Kokatanur 443891434b1SRayagond Kokatanur if (copy_from_user(&config, ifr->ifr_data, 444891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config))) 445891434b1SRayagond Kokatanur return -EFAULT; 446891434b1SRayagond Kokatanur 447891434b1SRayagond Kokatanur pr_debug("%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n", 448891434b1SRayagond Kokatanur __func__, config.flags, config.tx_type, config.rx_filter); 449891434b1SRayagond Kokatanur 450891434b1SRayagond Kokatanur /* reserved for future extensions */ 451891434b1SRayagond Kokatanur if (config.flags) 452891434b1SRayagond Kokatanur return -EINVAL; 453891434b1SRayagond Kokatanur 4545f3da328SBen Hutchings if (config.tx_type != HWTSTAMP_TX_OFF && 4555f3da328SBen Hutchings config.tx_type != HWTSTAMP_TX_ON) 456891434b1SRayagond Kokatanur return -ERANGE; 457891434b1SRayagond Kokatanur 458891434b1SRayagond Kokatanur if (priv->adv_ts) { 459891434b1SRayagond Kokatanur switch (config.rx_filter) { 460891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 461ceb69499SGiuseppe CAVALLARO /* time stamp no incoming packet at all */ 462891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 463891434b1SRayagond Kokatanur break; 464891434b1SRayagond Kokatanur 465891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 466ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, any kind of event packet */ 467891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 468891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 469891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 470891434b1SRayagond Kokatanur 471891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 472891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 473891434b1SRayagond Kokatanur break; 474891434b1SRayagond Kokatanur 475891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 476ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Sync packet */ 477891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; 478891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 479891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 480891434b1SRayagond Kokatanur 481891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 482891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 483891434b1SRayagond Kokatanur break; 484891434b1SRayagond Kokatanur 485891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 486ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Delay_req packet */ 487891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; 488891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 489891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 490891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 491891434b1SRayagond Kokatanur 492891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 493891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 494891434b1SRayagond Kokatanur break; 495891434b1SRayagond Kokatanur 496891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 497ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, any kind of event packet */ 498891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 499891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 500891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 501891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 502891434b1SRayagond Kokatanur 503891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 504891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 505891434b1SRayagond Kokatanur break; 506891434b1SRayagond Kokatanur 507891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 508ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Sync packet */ 509891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; 510891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 511891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 512891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 513891434b1SRayagond Kokatanur 514891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 515891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 516891434b1SRayagond Kokatanur break; 517891434b1SRayagond Kokatanur 518891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 519ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Delay_req packet */ 520891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; 521891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 522891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 523891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 524891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 525891434b1SRayagond Kokatanur 526891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 527891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 528891434b1SRayagond Kokatanur break; 529891434b1SRayagond Kokatanur 530891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_EVENT: 531ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1 any layer, any kind of event packet */ 532891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 533891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 534891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 535891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 536891434b1SRayagond Kokatanur 537891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 538891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 539891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 540891434b1SRayagond Kokatanur break; 541891434b1SRayagond Kokatanur 542891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_SYNC: 543ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Sync packet */ 544891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 545891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 546891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 547891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 548891434b1SRayagond Kokatanur 549891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 550891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 551891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 552891434b1SRayagond Kokatanur break; 553891434b1SRayagond Kokatanur 554891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 555ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Delay_req packet */ 556891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 557891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 558891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 559891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 560891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 561891434b1SRayagond Kokatanur 562891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 563891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 564891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 565891434b1SRayagond Kokatanur break; 566891434b1SRayagond Kokatanur 567891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_ALL: 568ceb69499SGiuseppe CAVALLARO /* time stamp any incoming packet */ 569891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_ALL; 570891434b1SRayagond Kokatanur tstamp_all = PTP_TCR_TSENALL; 571891434b1SRayagond Kokatanur break; 572891434b1SRayagond Kokatanur 573891434b1SRayagond Kokatanur default: 574891434b1SRayagond Kokatanur return -ERANGE; 575891434b1SRayagond Kokatanur } 576891434b1SRayagond Kokatanur } else { 577891434b1SRayagond Kokatanur switch (config.rx_filter) { 578891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 579891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 580891434b1SRayagond Kokatanur break; 581891434b1SRayagond Kokatanur default: 582891434b1SRayagond Kokatanur /* PTP v1, UDP, any kind of event packet */ 583891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 584891434b1SRayagond Kokatanur break; 585891434b1SRayagond Kokatanur } 586891434b1SRayagond Kokatanur } 587891434b1SRayagond Kokatanur priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1); 5885f3da328SBen Hutchings priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; 589891434b1SRayagond Kokatanur 590891434b1SRayagond Kokatanur if (!priv->hwts_tx_en && !priv->hwts_rx_en) 591891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0); 592891434b1SRayagond Kokatanur else { 593891434b1SRayagond Kokatanur value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR | 594891434b1SRayagond Kokatanur tstamp_all | ptp_v2 | ptp_over_ethernet | 595891434b1SRayagond Kokatanur ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en | 596891434b1SRayagond Kokatanur ts_master_en | snap_type_sel); 597891434b1SRayagond Kokatanur 598891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value); 599891434b1SRayagond Kokatanur 600891434b1SRayagond Kokatanur /* program Sub Second Increment reg */ 601891434b1SRayagond Kokatanur priv->hw->ptp->config_sub_second_increment(priv->ioaddr); 602891434b1SRayagond Kokatanur 603891434b1SRayagond Kokatanur /* calculate default added value: 604891434b1SRayagond Kokatanur * formula is : 605891434b1SRayagond Kokatanur * addend = (2^32)/freq_div_ratio; 6065566401fSGiuseppe CAVALLARO * where, freq_div_ratio = clk_ptp_ref_i/50MHz 6075566401fSGiuseppe CAVALLARO * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i; 6085566401fSGiuseppe CAVALLARO * NOTE: clk_ptp_ref_i should be >= 50MHz to 609891434b1SRayagond Kokatanur * achive 20ns accuracy. 610891434b1SRayagond Kokatanur * 611891434b1SRayagond Kokatanur * 2^x * y == (y << x), hence 612891434b1SRayagond Kokatanur * 2^32 * 50000000 ==> (50000000 << 32) 613891434b1SRayagond Kokatanur */ 614891434b1SRayagond Kokatanur temp = (u64) (50000000ULL << 32); 6155566401fSGiuseppe CAVALLARO priv->default_addend = div_u64(temp, priv->clk_ptp_rate); 616891434b1SRayagond Kokatanur priv->hw->ptp->config_addend(priv->ioaddr, 617891434b1SRayagond Kokatanur priv->default_addend); 618891434b1SRayagond Kokatanur 619891434b1SRayagond Kokatanur /* initialize system time */ 620891434b1SRayagond Kokatanur getnstimeofday(&now); 621891434b1SRayagond Kokatanur priv->hw->ptp->init_systime(priv->ioaddr, now.tv_sec, 622891434b1SRayagond Kokatanur now.tv_nsec); 623891434b1SRayagond Kokatanur } 624891434b1SRayagond Kokatanur 625891434b1SRayagond Kokatanur return copy_to_user(ifr->ifr_data, &config, 626891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config)) ? -EFAULT : 0; 627891434b1SRayagond Kokatanur } 628891434b1SRayagond Kokatanur 62932ceabcaSGiuseppe CAVALLARO /** 63032ceabcaSGiuseppe CAVALLARO * stmmac_init_ptp: init PTP 63132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 63232ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PTPv1 or v2. 63332ceabcaSGiuseppe CAVALLARO * This is done by looking at the HW cap. register. 63432ceabcaSGiuseppe CAVALLARO * Also it registers the ptp driver. 63532ceabcaSGiuseppe CAVALLARO */ 63692ba6888SRayagond Kokatanur static int stmmac_init_ptp(struct stmmac_priv *priv) 637891434b1SRayagond Kokatanur { 63892ba6888SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) 63992ba6888SRayagond Kokatanur return -EOPNOTSUPP; 64092ba6888SRayagond Kokatanur 6415566401fSGiuseppe CAVALLARO /* Fall-back to main clock in case of no PTP ref is passed */ 6425566401fSGiuseppe CAVALLARO priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref"); 6435566401fSGiuseppe CAVALLARO if (IS_ERR(priv->clk_ptp_ref)) { 6445566401fSGiuseppe CAVALLARO priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk); 6455566401fSGiuseppe CAVALLARO priv->clk_ptp_ref = NULL; 6465566401fSGiuseppe CAVALLARO } else { 6475566401fSGiuseppe CAVALLARO clk_prepare_enable(priv->clk_ptp_ref); 6485566401fSGiuseppe CAVALLARO priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref); 6495566401fSGiuseppe CAVALLARO } 6505566401fSGiuseppe CAVALLARO 651891434b1SRayagond Kokatanur priv->adv_ts = 0; 6527cd01399SVince Bridgers if (priv->dma_cap.atime_stamp && priv->extend_desc) 653891434b1SRayagond Kokatanur priv->adv_ts = 1; 6547cd01399SVince Bridgers 6557cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->dma_cap.time_stamp) 6567cd01399SVince Bridgers pr_debug("IEEE 1588-2002 Time Stamp supported\n"); 6577cd01399SVince Bridgers 6587cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->adv_ts) 6597cd01399SVince Bridgers pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); 660891434b1SRayagond Kokatanur 661891434b1SRayagond Kokatanur priv->hw->ptp = &stmmac_ptp; 662891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 663891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 66492ba6888SRayagond Kokatanur 66592ba6888SRayagond Kokatanur return stmmac_ptp_register(priv); 66692ba6888SRayagond Kokatanur } 66792ba6888SRayagond Kokatanur 66892ba6888SRayagond Kokatanur static void stmmac_release_ptp(struct stmmac_priv *priv) 66992ba6888SRayagond Kokatanur { 6705566401fSGiuseppe CAVALLARO if (priv->clk_ptp_ref) 6715566401fSGiuseppe CAVALLARO clk_disable_unprepare(priv->clk_ptp_ref); 67292ba6888SRayagond Kokatanur stmmac_ptp_unregister(priv); 673891434b1SRayagond Kokatanur } 674891434b1SRayagond Kokatanur 6757ac6653aSJeff Kirsher /** 6767ac6653aSJeff Kirsher * stmmac_adjust_link 6777ac6653aSJeff Kirsher * @dev: net device structure 6787ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 6797ac6653aSJeff Kirsher */ 6807ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 6817ac6653aSJeff Kirsher { 6827ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 6837ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 6847ac6653aSJeff Kirsher unsigned long flags; 6857ac6653aSJeff Kirsher int new_state = 0; 6867ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 6877ac6653aSJeff Kirsher 6887ac6653aSJeff Kirsher if (phydev == NULL) 6897ac6653aSJeff Kirsher return; 6907ac6653aSJeff Kirsher 6917ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 692d765955dSGiuseppe CAVALLARO 6937ac6653aSJeff Kirsher if (phydev->link) { 6947ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 6957ac6653aSJeff Kirsher 6967ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 6977ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 6987ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 6997ac6653aSJeff Kirsher new_state = 1; 7007ac6653aSJeff Kirsher if (!(phydev->duplex)) 7017ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 7027ac6653aSJeff Kirsher else 7037ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 7047ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 7057ac6653aSJeff Kirsher } 7067ac6653aSJeff Kirsher /* Flow Control operation */ 7077ac6653aSJeff Kirsher if (phydev->pause) 7087ed24bbeSVince Bridgers priv->hw->mac->flow_ctrl(priv->hw, phydev->duplex, 7097ac6653aSJeff Kirsher fc, pause_time); 7107ac6653aSJeff Kirsher 7117ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 7127ac6653aSJeff Kirsher new_state = 1; 7137ac6653aSJeff Kirsher switch (phydev->speed) { 7147ac6653aSJeff Kirsher case 1000: 7157ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 7167ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7177ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7187ac6653aSJeff Kirsher break; 7197ac6653aSJeff Kirsher case 100: 7207ac6653aSJeff Kirsher case 10: 7217ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 7227ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 7237ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 7247ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 7257ac6653aSJeff Kirsher } else { 7267ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 7277ac6653aSJeff Kirsher } 7287ac6653aSJeff Kirsher } else { 7297ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7307ac6653aSJeff Kirsher } 7317ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7327ac6653aSJeff Kirsher break; 7337ac6653aSJeff Kirsher default: 7347ac6653aSJeff Kirsher if (netif_msg_link(priv)) 735ceb69499SGiuseppe CAVALLARO pr_warn("%s: Speed (%d) not 10/100\n", 736ceb69499SGiuseppe CAVALLARO dev->name, phydev->speed); 7377ac6653aSJeff Kirsher break; 7387ac6653aSJeff Kirsher } 7397ac6653aSJeff Kirsher 7407ac6653aSJeff Kirsher priv->speed = phydev->speed; 7417ac6653aSJeff Kirsher } 7427ac6653aSJeff Kirsher 7437ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 7447ac6653aSJeff Kirsher 7457ac6653aSJeff Kirsher if (!priv->oldlink) { 7467ac6653aSJeff Kirsher new_state = 1; 7477ac6653aSJeff Kirsher priv->oldlink = 1; 7487ac6653aSJeff Kirsher } 7497ac6653aSJeff Kirsher } else if (priv->oldlink) { 7507ac6653aSJeff Kirsher new_state = 1; 7517ac6653aSJeff Kirsher priv->oldlink = 0; 7527ac6653aSJeff Kirsher priv->speed = 0; 7537ac6653aSJeff Kirsher priv->oldduplex = -1; 7547ac6653aSJeff Kirsher } 7557ac6653aSJeff Kirsher 7567ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 7577ac6653aSJeff Kirsher phy_print_status(phydev); 7587ac6653aSJeff Kirsher 759f5351ef7SGiuseppe CAVALLARO /* At this stage, it could be needed to setup the EEE or adjust some 760f5351ef7SGiuseppe CAVALLARO * MAC related HW registers. 761f5351ef7SGiuseppe CAVALLARO */ 762f5351ef7SGiuseppe CAVALLARO priv->eee_enabled = stmmac_eee_init(priv); 763d765955dSGiuseppe CAVALLARO 7647ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 7657ac6653aSJeff Kirsher } 7667ac6653aSJeff Kirsher 76732ceabcaSGiuseppe CAVALLARO /** 76832ceabcaSGiuseppe CAVALLARO * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported 76932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 77032ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PCS. 77132ceabcaSGiuseppe CAVALLARO * Physical Coding Sublayer (PCS) interface that can be used when the MAC is 77232ceabcaSGiuseppe CAVALLARO * configured for the TBI, RTBI, or SGMII PHY interface. 77332ceabcaSGiuseppe CAVALLARO */ 774e58bb43fSGiuseppe CAVALLARO static void stmmac_check_pcs_mode(struct stmmac_priv *priv) 775e58bb43fSGiuseppe CAVALLARO { 776e58bb43fSGiuseppe CAVALLARO int interface = priv->plat->interface; 777e58bb43fSGiuseppe CAVALLARO 778e58bb43fSGiuseppe CAVALLARO if (priv->dma_cap.pcs) { 7790d909dcdSByungho An if ((interface == PHY_INTERFACE_MODE_RGMII) || 7800d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_ID) || 7810d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_RXID) || 7820d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_TXID)) { 783e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS RGMII support enable\n"); 784e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_RGMII; 7850d909dcdSByungho An } else if (interface == PHY_INTERFACE_MODE_SGMII) { 786e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS SGMII support enable\n"); 787e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_SGMII; 788e58bb43fSGiuseppe CAVALLARO } 789e58bb43fSGiuseppe CAVALLARO } 790e58bb43fSGiuseppe CAVALLARO } 791e58bb43fSGiuseppe CAVALLARO 7927ac6653aSJeff Kirsher /** 7937ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 7947ac6653aSJeff Kirsher * @dev: net device structure 7957ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 7967ac6653aSJeff Kirsher * to the mac driver. 7977ac6653aSJeff Kirsher * Return value: 7987ac6653aSJeff Kirsher * 0 on success 7997ac6653aSJeff Kirsher */ 8007ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 8017ac6653aSJeff Kirsher { 8027ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 8037ac6653aSJeff Kirsher struct phy_device *phydev; 804d765955dSGiuseppe CAVALLARO char phy_id_fmt[MII_BUS_ID_SIZE + 3]; 8057ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 80679ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 8079cbadf09SSrinivas Kandagatla int max_speed = priv->plat->max_speed; 8087ac6653aSJeff Kirsher priv->oldlink = 0; 8097ac6653aSJeff Kirsher priv->speed = 0; 8107ac6653aSJeff Kirsher priv->oldduplex = -1; 8117ac6653aSJeff Kirsher 812f142af2eSSrinivas Kandagatla if (priv->plat->phy_bus_name) 813f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", 814f142af2eSSrinivas Kandagatla priv->plat->phy_bus_name, priv->plat->bus_id); 815f142af2eSSrinivas Kandagatla else 816f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", 817f142af2eSSrinivas Kandagatla priv->plat->bus_id); 818f142af2eSSrinivas Kandagatla 819d765955dSGiuseppe CAVALLARO snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 8207ac6653aSJeff Kirsher priv->plat->phy_addr); 821d765955dSGiuseppe CAVALLARO pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 8227ac6653aSJeff Kirsher 823f9a8f83bSFlorian Fainelli phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface); 8247ac6653aSJeff Kirsher 8257ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 8267ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 8277ac6653aSJeff Kirsher return PTR_ERR(phydev); 8287ac6653aSJeff Kirsher } 8297ac6653aSJeff Kirsher 83079ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 831c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 8329cbadf09SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII) || 8339cbadf09SSrinivas Kandagatla (max_speed < 1000 && max_speed > 0)) 834c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 835c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 83679ee1dc3SSrinivas Kandagatla 8377ac6653aSJeff Kirsher /* 8387ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 8397ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 8407ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 8417ac6653aSJeff Kirsher * device as well. 8427ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 8437ac6653aSJeff Kirsher */ 8447ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 8457ac6653aSJeff Kirsher phy_disconnect(phydev); 8467ac6653aSJeff Kirsher return -ENODEV; 8477ac6653aSJeff Kirsher } 8487ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 8497ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 8507ac6653aSJeff Kirsher 8517ac6653aSJeff Kirsher priv->phydev = phydev; 8527ac6653aSJeff Kirsher 8537ac6653aSJeff Kirsher return 0; 8547ac6653aSJeff Kirsher } 8557ac6653aSJeff Kirsher 8567ac6653aSJeff Kirsher /** 85732ceabcaSGiuseppe CAVALLARO * stmmac_display_ring: display ring 85832ceabcaSGiuseppe CAVALLARO * @head: pointer to the head of the ring passed. 8597ac6653aSJeff Kirsher * @size: size of the ring. 86032ceabcaSGiuseppe CAVALLARO * @extend_desc: to verify if extended descriptors are used. 861c24602efSGiuseppe CAVALLARO * Description: display the control/status and buffer descriptors. 8627ac6653aSJeff Kirsher */ 863c24602efSGiuseppe CAVALLARO static void stmmac_display_ring(void *head, int size, int extend_desc) 8647ac6653aSJeff Kirsher { 8657ac6653aSJeff Kirsher int i; 866c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 867c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 868c24602efSGiuseppe CAVALLARO 8697ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 870c24602efSGiuseppe CAVALLARO u64 x; 871c24602efSGiuseppe CAVALLARO if (extend_desc) { 872c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 873c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 874c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 875c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 876c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 877c24602efSGiuseppe CAVALLARO ep++; 878c24602efSGiuseppe CAVALLARO } else { 879c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 880c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", 881c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(p), 882c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 883c24602efSGiuseppe CAVALLARO p->des2, p->des3); 884c24602efSGiuseppe CAVALLARO p++; 885c24602efSGiuseppe CAVALLARO } 8867ac6653aSJeff Kirsher pr_info("\n"); 8877ac6653aSJeff Kirsher } 8887ac6653aSJeff Kirsher } 8897ac6653aSJeff Kirsher 890c24602efSGiuseppe CAVALLARO static void stmmac_display_rings(struct stmmac_priv *priv) 891c24602efSGiuseppe CAVALLARO { 892c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 893c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 894c24602efSGiuseppe CAVALLARO 895c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 896c24602efSGiuseppe CAVALLARO pr_info("Extended RX descriptor ring:\n"); 897c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 898c24602efSGiuseppe CAVALLARO pr_info("Extended TX descriptor ring:\n"); 899c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 900c24602efSGiuseppe CAVALLARO } else { 901c24602efSGiuseppe CAVALLARO pr_info("RX descriptor ring:\n"); 902c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 903c24602efSGiuseppe CAVALLARO pr_info("TX descriptor ring:\n"); 904c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 905c24602efSGiuseppe CAVALLARO } 906c24602efSGiuseppe CAVALLARO } 907c24602efSGiuseppe CAVALLARO 908286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 909286a8372SGiuseppe CAVALLARO { 910286a8372SGiuseppe CAVALLARO int ret = bufsize; 911286a8372SGiuseppe CAVALLARO 912286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 913286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 914286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 915286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 916d916701cSGiuseppe CAVALLARO else if (mtu > DEFAULT_BUFSIZE) 917286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 918286a8372SGiuseppe CAVALLARO else 919d916701cSGiuseppe CAVALLARO ret = DEFAULT_BUFSIZE; 920286a8372SGiuseppe CAVALLARO 921286a8372SGiuseppe CAVALLARO return ret; 922286a8372SGiuseppe CAVALLARO } 923286a8372SGiuseppe CAVALLARO 92432ceabcaSGiuseppe CAVALLARO /** 92532ceabcaSGiuseppe CAVALLARO * stmmac_clear_descriptors: clear descriptors 92632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 92732ceabcaSGiuseppe CAVALLARO * Description: this function is called to clear the tx and rx descriptors 92832ceabcaSGiuseppe CAVALLARO * in case of both basic and extended descriptors are used. 92932ceabcaSGiuseppe CAVALLARO */ 930c24602efSGiuseppe CAVALLARO static void stmmac_clear_descriptors(struct stmmac_priv *priv) 931c24602efSGiuseppe CAVALLARO { 932c24602efSGiuseppe CAVALLARO int i; 933c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 934c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 935c24602efSGiuseppe CAVALLARO 936c24602efSGiuseppe CAVALLARO /* Clear the Rx/Tx descriptors */ 937c24602efSGiuseppe CAVALLARO for (i = 0; i < rxsize; i++) 938c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 939c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_erx[i].basic, 940c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 941c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 942c24602efSGiuseppe CAVALLARO else 943c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_rx[i], 944c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 945c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 946c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 947c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 948c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 949c24602efSGiuseppe CAVALLARO priv->mode, 950c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 951c24602efSGiuseppe CAVALLARO else 952c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 953c24602efSGiuseppe CAVALLARO priv->mode, 954c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 955c24602efSGiuseppe CAVALLARO } 956c24602efSGiuseppe CAVALLARO 957c24602efSGiuseppe CAVALLARO static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, 958c24602efSGiuseppe CAVALLARO int i) 959c24602efSGiuseppe CAVALLARO { 960c24602efSGiuseppe CAVALLARO struct sk_buff *skb; 961c24602efSGiuseppe CAVALLARO 962c24602efSGiuseppe CAVALLARO skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, 963c24602efSGiuseppe CAVALLARO GFP_KERNEL); 96456329137SBartlomiej Zolnierkiewicz if (!skb) { 965c24602efSGiuseppe CAVALLARO pr_err("%s: Rx init fails; skb is NULL\n", __func__); 96656329137SBartlomiej Zolnierkiewicz return -ENOMEM; 967c24602efSGiuseppe CAVALLARO } 968c24602efSGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 969c24602efSGiuseppe CAVALLARO priv->rx_skbuff[i] = skb; 970c24602efSGiuseppe CAVALLARO priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 971c24602efSGiuseppe CAVALLARO priv->dma_buf_sz, 972c24602efSGiuseppe CAVALLARO DMA_FROM_DEVICE); 97356329137SBartlomiej Zolnierkiewicz if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) { 97456329137SBartlomiej Zolnierkiewicz pr_err("%s: DMA mapping error\n", __func__); 97556329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(skb); 97656329137SBartlomiej Zolnierkiewicz return -EINVAL; 97756329137SBartlomiej Zolnierkiewicz } 978c24602efSGiuseppe CAVALLARO 979c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[i]; 980c24602efSGiuseppe CAVALLARO 98129896a67SGiuseppe CAVALLARO if ((priv->hw->mode->init_desc3) && 982c24602efSGiuseppe CAVALLARO (priv->dma_buf_sz == BUF_SIZE_16KiB)) 98329896a67SGiuseppe CAVALLARO priv->hw->mode->init_desc3(p); 984c24602efSGiuseppe CAVALLARO 985c24602efSGiuseppe CAVALLARO return 0; 986c24602efSGiuseppe CAVALLARO } 987c24602efSGiuseppe CAVALLARO 98856329137SBartlomiej Zolnierkiewicz static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) 98956329137SBartlomiej Zolnierkiewicz { 99056329137SBartlomiej Zolnierkiewicz if (priv->rx_skbuff[i]) { 99156329137SBartlomiej Zolnierkiewicz dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 99256329137SBartlomiej Zolnierkiewicz priv->dma_buf_sz, DMA_FROM_DEVICE); 99356329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(priv->rx_skbuff[i]); 99456329137SBartlomiej Zolnierkiewicz } 99556329137SBartlomiej Zolnierkiewicz priv->rx_skbuff[i] = NULL; 99656329137SBartlomiej Zolnierkiewicz } 99756329137SBartlomiej Zolnierkiewicz 9987ac6653aSJeff Kirsher /** 9997ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 10007ac6653aSJeff Kirsher * @dev: net device structure 10017ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 1002286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 1003286a8372SGiuseppe CAVALLARO * modes. 10047ac6653aSJeff Kirsher */ 100556329137SBartlomiej Zolnierkiewicz static int init_dma_desc_rings(struct net_device *dev) 10067ac6653aSJeff Kirsher { 10077ac6653aSJeff Kirsher int i; 10087ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 10097ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 10107ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 10114a7d666aSGiuseppe CAVALLARO unsigned int bfsize = 0; 101256329137SBartlomiej Zolnierkiewicz int ret = -ENOMEM; 10137ac6653aSJeff Kirsher 101429896a67SGiuseppe CAVALLARO if (priv->hw->mode->set_16kib_bfsize) 101529896a67SGiuseppe CAVALLARO bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu); 1016286a8372SGiuseppe CAVALLARO 10174a7d666aSGiuseppe CAVALLARO if (bfsize < BUF_SIZE_16KiB) 1018286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 10197ac6653aSJeff Kirsher 10202618abb7SVince Bridgers priv->dma_buf_sz = bfsize; 10212618abb7SVince Bridgers 102283d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 102383d7af64SGiuseppe CAVALLARO pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__, 10247ac6653aSJeff Kirsher txsize, rxsize, bfsize); 10257ac6653aSJeff Kirsher 102683d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) { 1027c24602efSGiuseppe CAVALLARO pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__, 1028c24602efSGiuseppe CAVALLARO (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy); 10297ac6653aSJeff Kirsher 10307ac6653aSJeff Kirsher /* RX INITIALIZATION */ 103183d7af64SGiuseppe CAVALLARO pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n"); 103283d7af64SGiuseppe CAVALLARO } 10337ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 1034c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1035c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1036c24602efSGiuseppe CAVALLARO p = &((priv->dma_erx + i)->basic); 1037c24602efSGiuseppe CAVALLARO else 1038c24602efSGiuseppe CAVALLARO p = priv->dma_rx + i; 10397ac6653aSJeff Kirsher 104056329137SBartlomiej Zolnierkiewicz ret = stmmac_init_rx_buffers(priv, p, i); 104156329137SBartlomiej Zolnierkiewicz if (ret) 104256329137SBartlomiej Zolnierkiewicz goto err_init_rx_buffers; 1043286a8372SGiuseppe CAVALLARO 104483d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 104583d7af64SGiuseppe CAVALLARO pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 104683d7af64SGiuseppe CAVALLARO priv->rx_skbuff[i]->data, 104783d7af64SGiuseppe CAVALLARO (unsigned int)priv->rx_skbuff_dma[i]); 10487ac6653aSJeff Kirsher } 10497ac6653aSJeff Kirsher priv->cur_rx = 0; 10507ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 10517ac6653aSJeff Kirsher buf_sz = bfsize; 10527ac6653aSJeff Kirsher 1053c24602efSGiuseppe CAVALLARO /* Setup the chained descriptor addresses */ 1054c24602efSGiuseppe CAVALLARO if (priv->mode == STMMAC_CHAIN_MODE) { 1055c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 105629896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_erx, priv->dma_rx_phy, 1057c24602efSGiuseppe CAVALLARO rxsize, 1); 105829896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_etx, priv->dma_tx_phy, 1059c24602efSGiuseppe CAVALLARO txsize, 1); 1060c24602efSGiuseppe CAVALLARO } else { 106129896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_rx, priv->dma_rx_phy, 1062c24602efSGiuseppe CAVALLARO rxsize, 0); 106329896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_tx, priv->dma_tx_phy, 1064c24602efSGiuseppe CAVALLARO txsize, 0); 1065c24602efSGiuseppe CAVALLARO } 10667ac6653aSJeff Kirsher } 1067286a8372SGiuseppe CAVALLARO 1068c24602efSGiuseppe CAVALLARO /* TX INITIALIZATION */ 1069c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) { 1070c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1071c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1072c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1073c24602efSGiuseppe CAVALLARO else 1074c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1075c24602efSGiuseppe CAVALLARO p->des2 = 0; 1076cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[i] = 0; 1077c24602efSGiuseppe CAVALLARO priv->tx_skbuff[i] = NULL; 10784a7d666aSGiuseppe CAVALLARO } 1079c24602efSGiuseppe CAVALLARO 10807ac6653aSJeff Kirsher priv->dirty_tx = 0; 10817ac6653aSJeff Kirsher priv->cur_tx = 0; 10827ac6653aSJeff Kirsher 1083c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 10847ac6653aSJeff Kirsher 1085c24602efSGiuseppe CAVALLARO if (netif_msg_hw(priv)) 1086c24602efSGiuseppe CAVALLARO stmmac_display_rings(priv); 108756329137SBartlomiej Zolnierkiewicz 108856329137SBartlomiej Zolnierkiewicz return 0; 108956329137SBartlomiej Zolnierkiewicz err_init_rx_buffers: 109056329137SBartlomiej Zolnierkiewicz while (--i >= 0) 109156329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 109256329137SBartlomiej Zolnierkiewicz return ret; 10937ac6653aSJeff Kirsher } 10947ac6653aSJeff Kirsher 10957ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 10967ac6653aSJeff Kirsher { 10977ac6653aSJeff Kirsher int i; 10987ac6653aSJeff Kirsher 109956329137SBartlomiej Zolnierkiewicz for (i = 0; i < priv->dma_rx_size; i++) 110056329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 11017ac6653aSJeff Kirsher } 11027ac6653aSJeff Kirsher 11037ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 11047ac6653aSJeff Kirsher { 11057ac6653aSJeff Kirsher int i; 11067ac6653aSJeff Kirsher 11077ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 1108c24602efSGiuseppe CAVALLARO struct dma_desc *p; 110975e4364fSdamuzi000 1110c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1111c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1112c24602efSGiuseppe CAVALLARO else 1113c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1114c24602efSGiuseppe CAVALLARO 111575e4364fSdamuzi000 if (priv->tx_skbuff_dma[i]) { 1116cf32deecSRayagond Kokatanur dma_unmap_single(priv->device, 1117cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[i], 11187ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 11197ac6653aSJeff Kirsher DMA_TO_DEVICE); 112075e4364fSdamuzi000 priv->tx_skbuff_dma[i] = 0; 112175e4364fSdamuzi000 } 112275e4364fSdamuzi000 112375e4364fSdamuzi000 if (priv->tx_skbuff[i] != NULL) { 11247ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 11257ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 11267ac6653aSJeff Kirsher } 11277ac6653aSJeff Kirsher } 11287ac6653aSJeff Kirsher } 11297ac6653aSJeff Kirsher 113009f8d696SSrinivas Kandagatla static int alloc_dma_desc_resources(struct stmmac_priv *priv) 113109f8d696SSrinivas Kandagatla { 113209f8d696SSrinivas Kandagatla unsigned int txsize = priv->dma_tx_size; 113309f8d696SSrinivas Kandagatla unsigned int rxsize = priv->dma_rx_size; 113409f8d696SSrinivas Kandagatla int ret = -ENOMEM; 113509f8d696SSrinivas Kandagatla 113609f8d696SSrinivas Kandagatla priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t), 113709f8d696SSrinivas Kandagatla GFP_KERNEL); 113809f8d696SSrinivas Kandagatla if (!priv->rx_skbuff_dma) 113909f8d696SSrinivas Kandagatla return -ENOMEM; 114009f8d696SSrinivas Kandagatla 114109f8d696SSrinivas Kandagatla priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), 114209f8d696SSrinivas Kandagatla GFP_KERNEL); 114309f8d696SSrinivas Kandagatla if (!priv->rx_skbuff) 114409f8d696SSrinivas Kandagatla goto err_rx_skbuff; 114509f8d696SSrinivas Kandagatla 114609f8d696SSrinivas Kandagatla priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t), 114709f8d696SSrinivas Kandagatla GFP_KERNEL); 114809f8d696SSrinivas Kandagatla if (!priv->tx_skbuff_dma) 114909f8d696SSrinivas Kandagatla goto err_tx_skbuff_dma; 115009f8d696SSrinivas Kandagatla 115109f8d696SSrinivas Kandagatla priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), 115209f8d696SSrinivas Kandagatla GFP_KERNEL); 115309f8d696SSrinivas Kandagatla if (!priv->tx_skbuff) 115409f8d696SSrinivas Kandagatla goto err_tx_skbuff; 115509f8d696SSrinivas Kandagatla 115609f8d696SSrinivas Kandagatla if (priv->extend_desc) { 115709f8d696SSrinivas Kandagatla priv->dma_erx = dma_alloc_coherent(priv->device, rxsize * 115809f8d696SSrinivas Kandagatla sizeof(struct 115909f8d696SSrinivas Kandagatla dma_extended_desc), 116009f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 116109f8d696SSrinivas Kandagatla GFP_KERNEL); 116209f8d696SSrinivas Kandagatla if (!priv->dma_erx) 116309f8d696SSrinivas Kandagatla goto err_dma; 116409f8d696SSrinivas Kandagatla 116509f8d696SSrinivas Kandagatla priv->dma_etx = dma_alloc_coherent(priv->device, txsize * 116609f8d696SSrinivas Kandagatla sizeof(struct 116709f8d696SSrinivas Kandagatla dma_extended_desc), 116809f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 116909f8d696SSrinivas Kandagatla GFP_KERNEL); 117009f8d696SSrinivas Kandagatla if (!priv->dma_etx) { 117109f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 117209f8d696SSrinivas Kandagatla sizeof(struct dma_extended_desc), 117309f8d696SSrinivas Kandagatla priv->dma_erx, priv->dma_rx_phy); 117409f8d696SSrinivas Kandagatla goto err_dma; 117509f8d696SSrinivas Kandagatla } 117609f8d696SSrinivas Kandagatla } else { 117709f8d696SSrinivas Kandagatla priv->dma_rx = dma_alloc_coherent(priv->device, rxsize * 117809f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 117909f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 118009f8d696SSrinivas Kandagatla GFP_KERNEL); 118109f8d696SSrinivas Kandagatla if (!priv->dma_rx) 118209f8d696SSrinivas Kandagatla goto err_dma; 118309f8d696SSrinivas Kandagatla 118409f8d696SSrinivas Kandagatla priv->dma_tx = dma_alloc_coherent(priv->device, txsize * 118509f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 118609f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 118709f8d696SSrinivas Kandagatla GFP_KERNEL); 118809f8d696SSrinivas Kandagatla if (!priv->dma_tx) { 118909f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 119009f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 119109f8d696SSrinivas Kandagatla priv->dma_rx, priv->dma_rx_phy); 119209f8d696SSrinivas Kandagatla goto err_dma; 119309f8d696SSrinivas Kandagatla } 119409f8d696SSrinivas Kandagatla } 119509f8d696SSrinivas Kandagatla 119609f8d696SSrinivas Kandagatla return 0; 119709f8d696SSrinivas Kandagatla 119809f8d696SSrinivas Kandagatla err_dma: 119909f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff); 120009f8d696SSrinivas Kandagatla err_tx_skbuff: 120109f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff_dma); 120209f8d696SSrinivas Kandagatla err_tx_skbuff_dma: 120309f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff); 120409f8d696SSrinivas Kandagatla err_rx_skbuff: 120509f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff_dma); 120609f8d696SSrinivas Kandagatla return ret; 120709f8d696SSrinivas Kandagatla } 120809f8d696SSrinivas Kandagatla 12097ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 12107ac6653aSJeff Kirsher { 12117ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 12127ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 12137ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 12147ac6653aSJeff Kirsher 1215ceb69499SGiuseppe CAVALLARO /* Free DMA regions of consistent memory previously allocated */ 1216c24602efSGiuseppe CAVALLARO if (!priv->extend_desc) { 12177ac6653aSJeff Kirsher dma_free_coherent(priv->device, 12187ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 12197ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 12207ac6653aSJeff Kirsher dma_free_coherent(priv->device, 12217ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 12227ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 1223c24602efSGiuseppe CAVALLARO } else { 1224c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_tx_size * 1225c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1226c24602efSGiuseppe CAVALLARO priv->dma_etx, priv->dma_tx_phy); 1227c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_rx_size * 1228c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1229c24602efSGiuseppe CAVALLARO priv->dma_erx, priv->dma_rx_phy); 1230c24602efSGiuseppe CAVALLARO } 12317ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 12327ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 1233cf32deecSRayagond Kokatanur kfree(priv->tx_skbuff_dma); 12347ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 12357ac6653aSJeff Kirsher } 12367ac6653aSJeff Kirsher 12377ac6653aSJeff Kirsher /** 12387ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 123932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12407ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 12417ac6653aSJeff Kirsher * or Store-And-Forward capability. 12427ac6653aSJeff Kirsher */ 12437ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 12447ac6653aSJeff Kirsher { 1245e2a240c7SSonic Zhang if (priv->plat->force_thresh_dma_mode) 1246e2a240c7SSonic Zhang priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); 1247e2a240c7SSonic Zhang else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { 12487ac6653aSJeff Kirsher /* 12497ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 12507ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 12517ac6653aSJeff Kirsher * 1) TX COE if actually supported 12527ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 12537ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 12547ac6653aSJeff Kirsher */ 1255ceb69499SGiuseppe CAVALLARO priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); 12567ac6653aSJeff Kirsher tc = SF_DMA_MODE; 12577ac6653aSJeff Kirsher } else 12587ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 12597ac6653aSJeff Kirsher } 12607ac6653aSJeff Kirsher 12617ac6653aSJeff Kirsher /** 12629125cdd1SGiuseppe CAVALLARO * stmmac_tx_clean: 126332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12647ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 12657ac6653aSJeff Kirsher */ 12669125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv) 12677ac6653aSJeff Kirsher { 12687ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 12697ac6653aSJeff Kirsher 1270a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1271a9097a96SGiuseppe CAVALLARO 12729125cdd1SGiuseppe CAVALLARO priv->xstats.tx_clean++; 12739125cdd1SGiuseppe CAVALLARO 12747ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 12757ac6653aSJeff Kirsher int last; 12767ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 12777ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 1278c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1279c24602efSGiuseppe CAVALLARO 1280c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1281c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_etx + entry); 1282c24602efSGiuseppe CAVALLARO else 1283c24602efSGiuseppe CAVALLARO p = priv->dma_tx + entry; 12847ac6653aSJeff Kirsher 12857ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 12867ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 12877ac6653aSJeff Kirsher break; 12887ac6653aSJeff Kirsher 1289c24602efSGiuseppe CAVALLARO /* Verify tx error by looking at the last segment. */ 12907ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 12917ac6653aSJeff Kirsher if (likely(last)) { 12927ac6653aSJeff Kirsher int tx_error = 12937ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 12947ac6653aSJeff Kirsher &priv->xstats, p, 12957ac6653aSJeff Kirsher priv->ioaddr); 12967ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 12977ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 12987ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 12997ac6653aSJeff Kirsher } else 13007ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 1301891434b1SRayagond Kokatanur 1302891434b1SRayagond Kokatanur stmmac_get_tx_hwtstamp(priv, entry, skb); 13037ac6653aSJeff Kirsher } 130483d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 130583d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d, dirty %d\n", __func__, 13067ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 13077ac6653aSJeff Kirsher 1308cf32deecSRayagond Kokatanur if (likely(priv->tx_skbuff_dma[entry])) { 1309cf32deecSRayagond Kokatanur dma_unmap_single(priv->device, 1310cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry], 13117ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 13127ac6653aSJeff Kirsher DMA_TO_DEVICE); 1313cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = 0; 1314cf32deecSRayagond Kokatanur } 131529896a67SGiuseppe CAVALLARO priv->hw->mode->clean_desc3(priv, p); 13167ac6653aSJeff Kirsher 13177ac6653aSJeff Kirsher if (likely(skb != NULL)) { 13187c565c33SEric W. Biederman dev_consume_skb_any(skb); 13197ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 13207ac6653aSJeff Kirsher } 13217ac6653aSJeff Kirsher 13224a7d666aSGiuseppe CAVALLARO priv->hw->desc->release_tx_desc(p, priv->mode); 13237ac6653aSJeff Kirsher 132413497f58SGiuseppe CAVALLARO priv->dirty_tx++; 13257ac6653aSJeff Kirsher } 13267ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 13277ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 13287ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 13297ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 13307ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 133183d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 133283d7af64SGiuseppe CAVALLARO pr_debug("%s: restart transmit\n", __func__); 13337ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13347ac6653aSJeff Kirsher } 13357ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 13367ac6653aSJeff Kirsher } 1337d765955dSGiuseppe CAVALLARO 1338d765955dSGiuseppe CAVALLARO if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { 1339d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 1340f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 1341d765955dSGiuseppe CAVALLARO } 1342a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 13437ac6653aSJeff Kirsher } 13447ac6653aSJeff Kirsher 13459125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv) 13467ac6653aSJeff Kirsher { 13477ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 13487ac6653aSJeff Kirsher } 13497ac6653aSJeff Kirsher 13509125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv) 13517ac6653aSJeff Kirsher { 13527ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 13537ac6653aSJeff Kirsher } 13547ac6653aSJeff Kirsher 13557ac6653aSJeff Kirsher /** 135632ceabcaSGiuseppe CAVALLARO * stmmac_tx_err: irq tx error mng function 135732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 13587ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 13597ac6653aSJeff Kirsher * in case of errors. 13607ac6653aSJeff Kirsher */ 13617ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 13627ac6653aSJeff Kirsher { 1363c24602efSGiuseppe CAVALLARO int i; 1364c24602efSGiuseppe CAVALLARO int txsize = priv->dma_tx_size; 13657ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 13667ac6653aSJeff Kirsher 13677ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 13687ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 1369c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 1370c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1371c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 1372c24602efSGiuseppe CAVALLARO priv->mode, 1373c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 1374c24602efSGiuseppe CAVALLARO else 1375c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 1376c24602efSGiuseppe CAVALLARO priv->mode, 1377c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 13787ac6653aSJeff Kirsher priv->dirty_tx = 0; 13797ac6653aSJeff Kirsher priv->cur_tx = 0; 13807ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 13817ac6653aSJeff Kirsher 13827ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 13837ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13847ac6653aSJeff Kirsher } 13857ac6653aSJeff Kirsher 138632ceabcaSGiuseppe CAVALLARO /** 138732ceabcaSGiuseppe CAVALLARO * stmmac_dma_interrupt: DMA ISR 138832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 138932ceabcaSGiuseppe CAVALLARO * Description: this is the DMA ISR. It is called by the main ISR. 139032ceabcaSGiuseppe CAVALLARO * It calls the dwmac dma routine to understand which type of interrupt 139132ceabcaSGiuseppe CAVALLARO * happened. In case of there is a Normal interrupt and either TX or RX 139232ceabcaSGiuseppe CAVALLARO * interrupt happened so the NAPI is scheduled. 139332ceabcaSGiuseppe CAVALLARO */ 13947ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 13957ac6653aSJeff Kirsher { 13967ac6653aSJeff Kirsher int status; 13977ac6653aSJeff Kirsher 13987ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 13999125cdd1SGiuseppe CAVALLARO if (likely((status & handle_rx)) || (status & handle_tx)) { 14009125cdd1SGiuseppe CAVALLARO if (likely(napi_schedule_prep(&priv->napi))) { 14019125cdd1SGiuseppe CAVALLARO stmmac_disable_dma_irq(priv); 14029125cdd1SGiuseppe CAVALLARO __napi_schedule(&priv->napi); 14039125cdd1SGiuseppe CAVALLARO } 14049125cdd1SGiuseppe CAVALLARO } 14059125cdd1SGiuseppe CAVALLARO if (unlikely(status & tx_hard_error_bump_tc)) { 14067ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 14077ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 14087ac6653aSJeff Kirsher tc += 64; 14097ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 14107ac6653aSJeff Kirsher priv->xstats.threshold = tc; 14117ac6653aSJeff Kirsher } 14127ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 14137ac6653aSJeff Kirsher stmmac_tx_err(priv); 14147ac6653aSJeff Kirsher } 14157ac6653aSJeff Kirsher 141632ceabcaSGiuseppe CAVALLARO /** 141732ceabcaSGiuseppe CAVALLARO * stmmac_mmc_setup: setup the Mac Management Counters (MMC) 141832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 141932ceabcaSGiuseppe CAVALLARO * Description: this masks the MMC irq, in fact, the counters are managed in SW. 142032ceabcaSGiuseppe CAVALLARO */ 14211c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 14221c901a46SGiuseppe CAVALLARO { 14231c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 14241c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 14251c901a46SGiuseppe CAVALLARO 14261c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 14274f795b25SGiuseppe CAVALLARO 14284f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 14291c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 14301c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 14314f795b25SGiuseppe CAVALLARO } else 1432aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 14331c901a46SGiuseppe CAVALLARO } 14341c901a46SGiuseppe CAVALLARO 1435f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 1436f0b9d786SGiuseppe CAVALLARO { 1437f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 1438f0b9d786SGiuseppe CAVALLARO 1439ceb69499SGiuseppe CAVALLARO /* Check Synopsys Id (not available on old chips) */ 1440f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 1441f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 1442f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 1443f0b9d786SGiuseppe CAVALLARO 1444cf3f047bSGiuseppe CAVALLARO pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", 1445f0b9d786SGiuseppe CAVALLARO uid, synid); 1446f0b9d786SGiuseppe CAVALLARO 1447f0b9d786SGiuseppe CAVALLARO return synid; 1448f0b9d786SGiuseppe CAVALLARO } 1449f0b9d786SGiuseppe CAVALLARO return 0; 1450f0b9d786SGiuseppe CAVALLARO } 1451e7434821SGiuseppe CAVALLARO 145219e30c14SGiuseppe CAVALLARO /** 145332ceabcaSGiuseppe CAVALLARO * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors 145432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 145532ceabcaSGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors. 145632ceabcaSGiuseppe CAVALLARO * In case of Enhanced/Alternate, it looks at the extended descriptors are 145732ceabcaSGiuseppe CAVALLARO * supported by the HW cap. register. 1458ff3dd78cSGiuseppe CAVALLARO */ 145919e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 146019e30c14SGiuseppe CAVALLARO { 146119e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 146219e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 1463c24602efSGiuseppe CAVALLARO 1464c24602efSGiuseppe CAVALLARO /* GMAC older than 3.50 has no extended descriptors */ 1465c24602efSGiuseppe CAVALLARO if (priv->synopsys_id >= DWMAC_CORE_3_50) { 1466c24602efSGiuseppe CAVALLARO pr_info("\tEnabled extended descriptors\n"); 1467c24602efSGiuseppe CAVALLARO priv->extend_desc = 1; 1468c24602efSGiuseppe CAVALLARO } else 1469c24602efSGiuseppe CAVALLARO pr_warn("Extended descriptors not supported\n"); 1470c24602efSGiuseppe CAVALLARO 147119e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 147219e30c14SGiuseppe CAVALLARO } else { 147319e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 147419e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 147519e30c14SGiuseppe CAVALLARO } 147619e30c14SGiuseppe CAVALLARO } 147719e30c14SGiuseppe CAVALLARO 147819e30c14SGiuseppe CAVALLARO /** 147932ceabcaSGiuseppe CAVALLARO * stmmac_get_hw_features: get MAC capabilities from the HW cap. register. 148032ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 148119e30c14SGiuseppe CAVALLARO * Description: 148219e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 1483e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 148419e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 148519e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 1486e7434821SGiuseppe CAVALLARO */ 1487e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 1488e7434821SGiuseppe CAVALLARO { 14895e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 14903c20f72fSGiuseppe CAVALLARO 14915e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 14925e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 1493e7434821SGiuseppe CAVALLARO 14941db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 14951db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 14961db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 14971db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 1498ceb69499SGiuseppe CAVALLARO priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; 14991db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 15001db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 15011db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 15021db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 15031db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 15041db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 15051db123fbSRayagond Kokatanur /* MMC */ 15061db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 1507e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002 */ 15081db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 15091db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 1510e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008 */ 15111db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 15121db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 1513e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 15141db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 15151db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 1516e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 15171db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 15181db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 15191db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 15201db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 15211db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 15221db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 15231db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 1524e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 15251db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 15261db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 15271db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 15281db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 1529e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode */ 1530ceb69499SGiuseppe CAVALLARO priv->dma_cap.enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 153119e30c14SGiuseppe CAVALLARO } 1532e7434821SGiuseppe CAVALLARO 1533e7434821SGiuseppe CAVALLARO return hw_cap; 1534e7434821SGiuseppe CAVALLARO } 1535e7434821SGiuseppe CAVALLARO 153632ceabcaSGiuseppe CAVALLARO /** 153732ceabcaSGiuseppe CAVALLARO * stmmac_check_ether_addr: check if the MAC addr is valid 153832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 153932ceabcaSGiuseppe CAVALLARO * Description: 154032ceabcaSGiuseppe CAVALLARO * it is to verify if the MAC address is valid, in case of failures it 154132ceabcaSGiuseppe CAVALLARO * generates a random MAC address 154232ceabcaSGiuseppe CAVALLARO */ 1543bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 1544bfab27a1SGiuseppe CAVALLARO { 1545bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 15467ed24bbeSVince Bridgers priv->hw->mac->get_umac_addr(priv->hw, 1547bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 1548bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 1549f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 1550c88460b7SHans de Goede pr_info("%s: device MAC address %pM\n", priv->dev->name, 1551bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 1552bfab27a1SGiuseppe CAVALLARO } 1553c88460b7SHans de Goede } 1554bfab27a1SGiuseppe CAVALLARO 155532ceabcaSGiuseppe CAVALLARO /** 155632ceabcaSGiuseppe CAVALLARO * stmmac_init_dma_engine: DMA init. 155732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 155832ceabcaSGiuseppe CAVALLARO * Description: 155932ceabcaSGiuseppe CAVALLARO * It inits the DMA invoking the specific MAC/GMAC callback. 156032ceabcaSGiuseppe CAVALLARO * Some DMA parameters can be passed from the platform; 156132ceabcaSGiuseppe CAVALLARO * in case of these are not passed a default is kept for the MAC or GMAC. 156232ceabcaSGiuseppe CAVALLARO */ 15630f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv) 15640f1f88a8SGiuseppe CAVALLARO { 15650f1f88a8SGiuseppe CAVALLARO int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; 1566b9cde0a8SGiuseppe CAVALLARO int mixed_burst = 0; 1567c24602efSGiuseppe CAVALLARO int atds = 0; 15680f1f88a8SGiuseppe CAVALLARO 15690f1f88a8SGiuseppe CAVALLARO if (priv->plat->dma_cfg) { 15700f1f88a8SGiuseppe CAVALLARO pbl = priv->plat->dma_cfg->pbl; 15710f1f88a8SGiuseppe CAVALLARO fixed_burst = priv->plat->dma_cfg->fixed_burst; 1572b9cde0a8SGiuseppe CAVALLARO mixed_burst = priv->plat->dma_cfg->mixed_burst; 15730f1f88a8SGiuseppe CAVALLARO burst_len = priv->plat->dma_cfg->burst_len; 15740f1f88a8SGiuseppe CAVALLARO } 15750f1f88a8SGiuseppe CAVALLARO 1576c24602efSGiuseppe CAVALLARO if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE)) 1577c24602efSGiuseppe CAVALLARO atds = 1; 1578c24602efSGiuseppe CAVALLARO 1579b9cde0a8SGiuseppe CAVALLARO return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, 15800f1f88a8SGiuseppe CAVALLARO burst_len, priv->dma_tx_phy, 1581c24602efSGiuseppe CAVALLARO priv->dma_rx_phy, atds); 15820f1f88a8SGiuseppe CAVALLARO } 15830f1f88a8SGiuseppe CAVALLARO 1584bfab27a1SGiuseppe CAVALLARO /** 158532ceabcaSGiuseppe CAVALLARO * stmmac_tx_timer: mitigation sw timer for tx. 15869125cdd1SGiuseppe CAVALLARO * @data: data pointer 15879125cdd1SGiuseppe CAVALLARO * Description: 15889125cdd1SGiuseppe CAVALLARO * This is the timer handler to directly invoke the stmmac_tx_clean. 15899125cdd1SGiuseppe CAVALLARO */ 15909125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data) 15919125cdd1SGiuseppe CAVALLARO { 15929125cdd1SGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)data; 15939125cdd1SGiuseppe CAVALLARO 15949125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 15959125cdd1SGiuseppe CAVALLARO } 15969125cdd1SGiuseppe CAVALLARO 15979125cdd1SGiuseppe CAVALLARO /** 159832ceabcaSGiuseppe CAVALLARO * stmmac_init_tx_coalesce: init tx mitigation options. 159932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 16009125cdd1SGiuseppe CAVALLARO * Description: 16019125cdd1SGiuseppe CAVALLARO * This inits the transmit coalesce parameters: i.e. timer rate, 16029125cdd1SGiuseppe CAVALLARO * timer handler and default threshold used for enabling the 16039125cdd1SGiuseppe CAVALLARO * interrupt on completion bit. 16049125cdd1SGiuseppe CAVALLARO */ 16059125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) 16069125cdd1SGiuseppe CAVALLARO { 16079125cdd1SGiuseppe CAVALLARO priv->tx_coal_frames = STMMAC_TX_FRAMES; 16089125cdd1SGiuseppe CAVALLARO priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; 16099125cdd1SGiuseppe CAVALLARO init_timer(&priv->txtimer); 16109125cdd1SGiuseppe CAVALLARO priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); 16119125cdd1SGiuseppe CAVALLARO priv->txtimer.data = (unsigned long)priv; 16129125cdd1SGiuseppe CAVALLARO priv->txtimer.function = stmmac_tx_timer; 16139125cdd1SGiuseppe CAVALLARO add_timer(&priv->txtimer); 16149125cdd1SGiuseppe CAVALLARO } 16159125cdd1SGiuseppe CAVALLARO 16169125cdd1SGiuseppe CAVALLARO /** 1617523f11b5SSrinivas Kandagatla * stmmac_hw_setup: setup mac in a usable state. 1618523f11b5SSrinivas Kandagatla * @dev : pointer to the device structure. 1619523f11b5SSrinivas Kandagatla * Description: 1620523f11b5SSrinivas Kandagatla * This function sets up the ip in a usable state. 1621523f11b5SSrinivas Kandagatla * Return value: 1622523f11b5SSrinivas Kandagatla * 0 on success and an appropriate (-)ve integer as defined in errno.h 1623523f11b5SSrinivas Kandagatla * file on failure. 1624523f11b5SSrinivas Kandagatla */ 1625523f11b5SSrinivas Kandagatla static int stmmac_hw_setup(struct net_device *dev) 1626523f11b5SSrinivas Kandagatla { 1627523f11b5SSrinivas Kandagatla struct stmmac_priv *priv = netdev_priv(dev); 1628523f11b5SSrinivas Kandagatla int ret; 1629523f11b5SSrinivas Kandagatla 1630523f11b5SSrinivas Kandagatla ret = init_dma_desc_rings(dev); 1631523f11b5SSrinivas Kandagatla if (ret < 0) { 1632523f11b5SSrinivas Kandagatla pr_err("%s: DMA descriptors initialization failed\n", __func__); 1633523f11b5SSrinivas Kandagatla return ret; 1634523f11b5SSrinivas Kandagatla } 1635523f11b5SSrinivas Kandagatla /* DMA initialization and SW reset */ 1636523f11b5SSrinivas Kandagatla ret = stmmac_init_dma_engine(priv); 1637523f11b5SSrinivas Kandagatla if (ret < 0) { 1638523f11b5SSrinivas Kandagatla pr_err("%s: DMA engine initialization failed\n", __func__); 1639523f11b5SSrinivas Kandagatla return ret; 1640523f11b5SSrinivas Kandagatla } 1641523f11b5SSrinivas Kandagatla 1642523f11b5SSrinivas Kandagatla /* Copy the MAC addr into the HW */ 16437ed24bbeSVince Bridgers priv->hw->mac->set_umac_addr(priv->hw, dev->dev_addr, 0); 1644523f11b5SSrinivas Kandagatla 1645523f11b5SSrinivas Kandagatla /* If required, perform hw setup of the bus. */ 1646523f11b5SSrinivas Kandagatla if (priv->plat->bus_setup) 1647523f11b5SSrinivas Kandagatla priv->plat->bus_setup(priv->ioaddr); 1648523f11b5SSrinivas Kandagatla 1649523f11b5SSrinivas Kandagatla /* Initialize the MAC Core */ 16507ed24bbeSVince Bridgers priv->hw->mac->core_init(priv->hw, dev->mtu); 1651523f11b5SSrinivas Kandagatla 1652978aded4SGiuseppe CAVALLARO ret = priv->hw->mac->rx_ipc(priv->hw); 1653978aded4SGiuseppe CAVALLARO if (!ret) { 1654978aded4SGiuseppe CAVALLARO pr_warn(" RX IPC Checksum Offload disabled\n"); 1655978aded4SGiuseppe CAVALLARO priv->plat->rx_coe = STMMAC_RX_COE_NONE; 1656978aded4SGiuseppe CAVALLARO } 1657978aded4SGiuseppe CAVALLARO 1658523f11b5SSrinivas Kandagatla /* Enable the MAC Rx/Tx */ 1659523f11b5SSrinivas Kandagatla stmmac_set_mac(priv->ioaddr, true); 1660523f11b5SSrinivas Kandagatla 1661523f11b5SSrinivas Kandagatla /* Set the HW DMA mode and the COE */ 1662523f11b5SSrinivas Kandagatla stmmac_dma_operation_mode(priv); 1663523f11b5SSrinivas Kandagatla 1664523f11b5SSrinivas Kandagatla stmmac_mmc_setup(priv); 1665523f11b5SSrinivas Kandagatla 1666523f11b5SSrinivas Kandagatla ret = stmmac_init_ptp(priv); 16677509edd6SHans de Goede if (ret && ret != -EOPNOTSUPP) 1668523f11b5SSrinivas Kandagatla pr_warn("%s: failed PTP initialisation\n", __func__); 1669523f11b5SSrinivas Kandagatla 1670523f11b5SSrinivas Kandagatla #ifdef CONFIG_STMMAC_DEBUG_FS 1671523f11b5SSrinivas Kandagatla ret = stmmac_init_fs(dev); 1672523f11b5SSrinivas Kandagatla if (ret < 0) 1673523f11b5SSrinivas Kandagatla pr_warn("%s: failed debugFS registration\n", __func__); 1674523f11b5SSrinivas Kandagatla #endif 1675523f11b5SSrinivas Kandagatla /* Start the ball rolling... */ 1676523f11b5SSrinivas Kandagatla pr_debug("%s: DMA RX/TX processes started...\n", dev->name); 1677523f11b5SSrinivas Kandagatla priv->hw->dma->start_tx(priv->ioaddr); 1678523f11b5SSrinivas Kandagatla priv->hw->dma->start_rx(priv->ioaddr); 1679523f11b5SSrinivas Kandagatla 1680523f11b5SSrinivas Kandagatla /* Dump DMA/MAC registers */ 1681523f11b5SSrinivas Kandagatla if (netif_msg_hw(priv)) { 16827ed24bbeSVince Bridgers priv->hw->mac->dump_regs(priv->hw); 1683523f11b5SSrinivas Kandagatla priv->hw->dma->dump_regs(priv->ioaddr); 1684523f11b5SSrinivas Kandagatla } 1685523f11b5SSrinivas Kandagatla priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; 1686523f11b5SSrinivas Kandagatla 1687523f11b5SSrinivas Kandagatla priv->eee_enabled = stmmac_eee_init(priv); 1688523f11b5SSrinivas Kandagatla 1689523f11b5SSrinivas Kandagatla stmmac_init_tx_coalesce(priv); 1690523f11b5SSrinivas Kandagatla 1691523f11b5SSrinivas Kandagatla if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { 1692523f11b5SSrinivas Kandagatla priv->rx_riwt = MAX_DMA_RIWT; 1693523f11b5SSrinivas Kandagatla priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); 1694523f11b5SSrinivas Kandagatla } 1695523f11b5SSrinivas Kandagatla 1696523f11b5SSrinivas Kandagatla if (priv->pcs && priv->hw->mac->ctrl_ane) 16977ed24bbeSVince Bridgers priv->hw->mac->ctrl_ane(priv->hw, 0); 1698523f11b5SSrinivas Kandagatla 1699523f11b5SSrinivas Kandagatla return 0; 1700523f11b5SSrinivas Kandagatla } 1701523f11b5SSrinivas Kandagatla 1702523f11b5SSrinivas Kandagatla /** 17037ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 17047ac6653aSJeff Kirsher * @dev : pointer to the device structure. 17057ac6653aSJeff Kirsher * Description: 17067ac6653aSJeff Kirsher * This function is the open entry point of the driver. 17077ac6653aSJeff Kirsher * Return value: 17087ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 17097ac6653aSJeff Kirsher * file on failure. 17107ac6653aSJeff Kirsher */ 17117ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 17127ac6653aSJeff Kirsher { 17137ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 17147ac6653aSJeff Kirsher int ret; 17157ac6653aSJeff Kirsher 17164bfcbd7aSFrancesco Virlinzi stmmac_check_ether_addr(priv); 17174bfcbd7aSFrancesco Virlinzi 17184d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 17194d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 17207ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 1721e58bb43fSGiuseppe CAVALLARO if (ret) { 1722e58bb43fSGiuseppe CAVALLARO pr_err("%s: Cannot attach to PHY (error: %d)\n", 1723e58bb43fSGiuseppe CAVALLARO __func__, ret); 172489df20d9SHans de Goede return ret; 17257ac6653aSJeff Kirsher } 1726e58bb43fSGiuseppe CAVALLARO } 17277ac6653aSJeff Kirsher 1728523f11b5SSrinivas Kandagatla /* Extra statistics */ 1729523f11b5SSrinivas Kandagatla memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 1730523f11b5SSrinivas Kandagatla priv->xstats.threshold = tc; 1731523f11b5SSrinivas Kandagatla 17327ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 17337ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 17347ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 17357ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 173656329137SBartlomiej Zolnierkiewicz 17377262b7b2STobias Klauser ret = alloc_dma_desc_resources(priv); 173809f8d696SSrinivas Kandagatla if (ret < 0) { 173909f8d696SSrinivas Kandagatla pr_err("%s: DMA descriptors allocation failed\n", __func__); 174009f8d696SSrinivas Kandagatla goto dma_desc_error; 174109f8d696SSrinivas Kandagatla } 174209f8d696SSrinivas Kandagatla 1743523f11b5SSrinivas Kandagatla ret = stmmac_hw_setup(dev); 174456329137SBartlomiej Zolnierkiewicz if (ret < 0) { 1745523f11b5SSrinivas Kandagatla pr_err("%s: Hw setup failed\n", __func__); 1746c9324d18SGiuseppe CAVALLARO goto init_error; 17477ac6653aSJeff Kirsher } 17487ac6653aSJeff Kirsher 1749523f11b5SSrinivas Kandagatla if (priv->phydev) 1750523f11b5SSrinivas Kandagatla phy_start(priv->phydev); 17517ac6653aSJeff Kirsher 17527ac6653aSJeff Kirsher /* Request the IRQ lines */ 17537ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 17547ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 17557ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 17567ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 17577ac6653aSJeff Kirsher __func__, dev->irq, ret); 1758c9324d18SGiuseppe CAVALLARO goto init_error; 17597ac6653aSJeff Kirsher } 17607ac6653aSJeff Kirsher 17617a13f8f5SFrancesco Virlinzi /* Request the Wake IRQ in case of another line is used for WoL */ 17627a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) { 17637a13f8f5SFrancesco Virlinzi ret = request_irq(priv->wol_irq, stmmac_interrupt, 17647a13f8f5SFrancesco Virlinzi IRQF_SHARED, dev->name, dev); 17657a13f8f5SFrancesco Virlinzi if (unlikely(ret < 0)) { 1766ceb69499SGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the WoL IRQ %d (%d)\n", 1767ceb69499SGiuseppe CAVALLARO __func__, priv->wol_irq, ret); 1768c9324d18SGiuseppe CAVALLARO goto wolirq_error; 17697a13f8f5SFrancesco Virlinzi } 17707a13f8f5SFrancesco Virlinzi } 17717a13f8f5SFrancesco Virlinzi 1772d765955dSGiuseppe CAVALLARO /* Request the IRQ lines */ 1773d7ec8584SChen-Yu Tsai if (priv->lpi_irq > 0) { 1774d765955dSGiuseppe CAVALLARO ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, 1775d765955dSGiuseppe CAVALLARO dev->name, dev); 1776d765955dSGiuseppe CAVALLARO if (unlikely(ret < 0)) { 1777d765955dSGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", 1778d765955dSGiuseppe CAVALLARO __func__, priv->lpi_irq, ret); 1779c9324d18SGiuseppe CAVALLARO goto lpiirq_error; 1780d765955dSGiuseppe CAVALLARO } 1781d765955dSGiuseppe CAVALLARO } 1782d765955dSGiuseppe CAVALLARO 17837ac6653aSJeff Kirsher napi_enable(&priv->napi); 17847ac6653aSJeff Kirsher netif_start_queue(dev); 17857ac6653aSJeff Kirsher 17867ac6653aSJeff Kirsher return 0; 17877ac6653aSJeff Kirsher 1788c9324d18SGiuseppe CAVALLARO lpiirq_error: 1789d765955dSGiuseppe CAVALLARO if (priv->wol_irq != dev->irq) 1790d765955dSGiuseppe CAVALLARO free_irq(priv->wol_irq, dev); 1791c9324d18SGiuseppe CAVALLARO wolirq_error: 17927a13f8f5SFrancesco Virlinzi free_irq(dev->irq, dev); 17937a13f8f5SFrancesco Virlinzi 1794c9324d18SGiuseppe CAVALLARO init_error: 1795c9324d18SGiuseppe CAVALLARO free_dma_desc_resources(priv); 179656329137SBartlomiej Zolnierkiewicz dma_desc_error: 17977ac6653aSJeff Kirsher if (priv->phydev) 17987ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 17994bfcbd7aSFrancesco Virlinzi 18007ac6653aSJeff Kirsher return ret; 18017ac6653aSJeff Kirsher } 18027ac6653aSJeff Kirsher 18037ac6653aSJeff Kirsher /** 18047ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 18057ac6653aSJeff Kirsher * @dev : device pointer. 18067ac6653aSJeff Kirsher * Description: 18077ac6653aSJeff Kirsher * This is the stop entry point of the driver. 18087ac6653aSJeff Kirsher */ 18097ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 18107ac6653aSJeff Kirsher { 18117ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 18127ac6653aSJeff Kirsher 1813d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 1814d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 1815d765955dSGiuseppe CAVALLARO 18167ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 18177ac6653aSJeff Kirsher if (priv->phydev) { 18187ac6653aSJeff Kirsher phy_stop(priv->phydev); 18197ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 18207ac6653aSJeff Kirsher priv->phydev = NULL; 18217ac6653aSJeff Kirsher } 18227ac6653aSJeff Kirsher 18237ac6653aSJeff Kirsher netif_stop_queue(dev); 18247ac6653aSJeff Kirsher 18257ac6653aSJeff Kirsher napi_disable(&priv->napi); 18267ac6653aSJeff Kirsher 18279125cdd1SGiuseppe CAVALLARO del_timer_sync(&priv->txtimer); 18289125cdd1SGiuseppe CAVALLARO 18297ac6653aSJeff Kirsher /* Free the IRQ lines */ 18307ac6653aSJeff Kirsher free_irq(dev->irq, dev); 18317a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) 18327a13f8f5SFrancesco Virlinzi free_irq(priv->wol_irq, dev); 1833d7ec8584SChen-Yu Tsai if (priv->lpi_irq > 0) 1834d765955dSGiuseppe CAVALLARO free_irq(priv->lpi_irq, dev); 18357ac6653aSJeff Kirsher 18367ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 18377ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18387ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18397ac6653aSJeff Kirsher 18407ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 18417ac6653aSJeff Kirsher free_dma_desc_resources(priv); 18427ac6653aSJeff Kirsher 18437ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1844bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 18457ac6653aSJeff Kirsher 18467ac6653aSJeff Kirsher netif_carrier_off(dev); 18477ac6653aSJeff Kirsher 1848bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1849bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1850bfab27a1SGiuseppe CAVALLARO #endif 1851bfab27a1SGiuseppe CAVALLARO 185292ba6888SRayagond Kokatanur stmmac_release_ptp(priv); 185392ba6888SRayagond Kokatanur 18547ac6653aSJeff Kirsher return 0; 18557ac6653aSJeff Kirsher } 18567ac6653aSJeff Kirsher 18577ac6653aSJeff Kirsher /** 185832ceabcaSGiuseppe CAVALLARO * stmmac_xmit: Tx entry point of the driver 18597ac6653aSJeff Kirsher * @skb : the socket buffer 18607ac6653aSJeff Kirsher * @dev : device pointer 186132ceabcaSGiuseppe CAVALLARO * Description : this is the tx entry point of the driver. 186232ceabcaSGiuseppe CAVALLARO * It programs the chain or the ring and supports oversized frames 186332ceabcaSGiuseppe CAVALLARO * and SG feature. 18647ac6653aSJeff Kirsher */ 18657ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 18667ac6653aSJeff Kirsher { 18677ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 18687ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 18697ac6653aSJeff Kirsher unsigned int entry; 18704a7d666aSGiuseppe CAVALLARO int i, csum_insertion = 0, is_jumbo = 0; 18717ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 18727ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1873286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 187429896a67SGiuseppe CAVALLARO unsigned int enh_desc = priv->plat->enh_desc; 18757ac6653aSJeff Kirsher 18767ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 18777ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 18787ac6653aSJeff Kirsher netif_stop_queue(dev); 18797ac6653aSJeff Kirsher /* This is a hard error, log it. */ 1880ceb69499SGiuseppe CAVALLARO pr_err("%s: Tx Ring full when queue awake\n", __func__); 18817ac6653aSJeff Kirsher } 18827ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 18837ac6653aSJeff Kirsher } 18847ac6653aSJeff Kirsher 1885a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1886a9097a96SGiuseppe CAVALLARO 1887d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1888d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1889d765955dSGiuseppe CAVALLARO 18907ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 18917ac6653aSJeff Kirsher 18927ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 18937ac6653aSJeff Kirsher 1894c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1895c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1896c24602efSGiuseppe CAVALLARO else 18977ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 1898c24602efSGiuseppe CAVALLARO 18997ac6653aSJeff Kirsher first = desc; 19007ac6653aSJeff Kirsher 19014a7d666aSGiuseppe CAVALLARO /* To program the descriptors according to the size of the frame */ 190229896a67SGiuseppe CAVALLARO if (enh_desc) 190329896a67SGiuseppe CAVALLARO is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc); 190429896a67SGiuseppe CAVALLARO 19054a7d666aSGiuseppe CAVALLARO if (likely(!is_jumbo)) { 19067ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 19077ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 1908cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = desc->des2; 19097ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 19104a7d666aSGiuseppe CAVALLARO csum_insertion, priv->mode); 191129896a67SGiuseppe CAVALLARO } else { 1912c24602efSGiuseppe CAVALLARO desc = first; 191329896a67SGiuseppe CAVALLARO entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); 191429896a67SGiuseppe CAVALLARO } 19157ac6653aSJeff Kirsher 19167ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 19179e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 19189e903e08SEric Dumazet int len = skb_frag_size(frag); 19197ac6653aSJeff Kirsher 192075e4364fSdamuzi000 priv->tx_skbuff[entry] = NULL; 19217ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 1922c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1923c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1924c24602efSGiuseppe CAVALLARO else 19257ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 19267ac6653aSJeff Kirsher 1927f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1928f722380dSIan Campbell DMA_TO_DEVICE); 1929cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = desc->des2; 19304a7d666aSGiuseppe CAVALLARO priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, 19314a7d666aSGiuseppe CAVALLARO priv->mode); 19327ac6653aSJeff Kirsher wmb(); 19337ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 19348e839891SDeepak Sikri wmb(); 19357ac6653aSJeff Kirsher } 19367ac6653aSJeff Kirsher 193775e4364fSdamuzi000 priv->tx_skbuff[entry] = skb; 193875e4364fSdamuzi000 19399125cdd1SGiuseppe CAVALLARO /* Finalize the latest segment. */ 19407ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 19417ac6653aSJeff Kirsher 19427ac6653aSJeff Kirsher wmb(); 19439125cdd1SGiuseppe CAVALLARO /* According to the coalesce parameter the IC bit for the latest 19449125cdd1SGiuseppe CAVALLARO * segment could be reset and the timer re-started to invoke the 19459125cdd1SGiuseppe CAVALLARO * stmmac_tx function. This approach takes care about the fragments. 19469125cdd1SGiuseppe CAVALLARO */ 19479125cdd1SGiuseppe CAVALLARO priv->tx_count_frames += nfrags + 1; 19489125cdd1SGiuseppe CAVALLARO if (priv->tx_coal_frames > priv->tx_count_frames) { 19499125cdd1SGiuseppe CAVALLARO priv->hw->desc->clear_tx_ic(desc); 19509125cdd1SGiuseppe CAVALLARO priv->xstats.tx_reset_ic_bit++; 19519125cdd1SGiuseppe CAVALLARO mod_timer(&priv->txtimer, 19529125cdd1SGiuseppe CAVALLARO STMMAC_COAL_TIMER(priv->tx_coal_timer)); 19539125cdd1SGiuseppe CAVALLARO } else 19549125cdd1SGiuseppe CAVALLARO priv->tx_count_frames = 0; 19557ac6653aSJeff Kirsher 19567ac6653aSJeff Kirsher /* To avoid raise condition */ 19577ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 19588e839891SDeepak Sikri wmb(); 19597ac6653aSJeff Kirsher 19607ac6653aSJeff Kirsher priv->cur_tx++; 19617ac6653aSJeff Kirsher 19627ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 196383d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", 1964ceb69499SGiuseppe CAVALLARO __func__, (priv->cur_tx % txsize), 1965ceb69499SGiuseppe CAVALLARO (priv->dirty_tx % txsize), entry, first, nfrags); 196683d7af64SGiuseppe CAVALLARO 1967c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1968c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 1969c24602efSGiuseppe CAVALLARO else 1970c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 1971c24602efSGiuseppe CAVALLARO 197283d7af64SGiuseppe CAVALLARO pr_debug(">>> frame to be transmitted: "); 19737ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 19747ac6653aSJeff Kirsher } 19757ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 197683d7af64SGiuseppe CAVALLARO if (netif_msg_hw(priv)) 197783d7af64SGiuseppe CAVALLARO pr_debug("%s: stop transmitted packets\n", __func__); 19787ac6653aSJeff Kirsher netif_stop_queue(dev); 19797ac6653aSJeff Kirsher } 19807ac6653aSJeff Kirsher 19817ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 19827ac6653aSJeff Kirsher 1983891434b1SRayagond Kokatanur if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && 1984891434b1SRayagond Kokatanur priv->hwts_tx_en)) { 1985891434b1SRayagond Kokatanur /* declare that device is doing timestamping */ 1986891434b1SRayagond Kokatanur skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 1987891434b1SRayagond Kokatanur priv->hw->desc->enable_tx_timestamp(first); 1988891434b1SRayagond Kokatanur } 1989891434b1SRayagond Kokatanur 1990891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 19917ac6653aSJeff Kirsher skb_tx_timestamp(skb); 19927ac6653aSJeff Kirsher 19937ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 19947ac6653aSJeff Kirsher 1995a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 1996a9097a96SGiuseppe CAVALLARO 19977ac6653aSJeff Kirsher return NETDEV_TX_OK; 19987ac6653aSJeff Kirsher } 19997ac6653aSJeff Kirsher 2000b9381985SVince Bridgers static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) 2001b9381985SVince Bridgers { 2002b9381985SVince Bridgers struct ethhdr *ehdr; 2003b9381985SVince Bridgers u16 vlanid; 2004b9381985SVince Bridgers 2005b9381985SVince Bridgers if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) == 2006b9381985SVince Bridgers NETIF_F_HW_VLAN_CTAG_RX && 2007b9381985SVince Bridgers !__vlan_get_tag(skb, &vlanid)) { 2008b9381985SVince Bridgers /* pop the vlan tag */ 2009b9381985SVince Bridgers ehdr = (struct ethhdr *)skb->data; 2010b9381985SVince Bridgers memmove(skb->data + VLAN_HLEN, ehdr, ETH_ALEN * 2); 2011b9381985SVince Bridgers skb_pull(skb, VLAN_HLEN); 2012b9381985SVince Bridgers __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlanid); 2013b9381985SVince Bridgers } 2014b9381985SVince Bridgers } 2015b9381985SVince Bridgers 2016b9381985SVince Bridgers 201732ceabcaSGiuseppe CAVALLARO /** 201832ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 201932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 202032ceabcaSGiuseppe CAVALLARO * Description : this is to reallocate the skb for the reception process 202132ceabcaSGiuseppe CAVALLARO * that is based on zero-copy. 202232ceabcaSGiuseppe CAVALLARO */ 20237ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 20247ac6653aSJeff Kirsher { 20257ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20267ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 20277ac6653aSJeff Kirsher 20287ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 20297ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 2030c24602efSGiuseppe CAVALLARO struct dma_desc *p; 2031c24602efSGiuseppe CAVALLARO 2032c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2033c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2034c24602efSGiuseppe CAVALLARO else 2035c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2036c24602efSGiuseppe CAVALLARO 20377ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 20387ac6653aSJeff Kirsher struct sk_buff *skb; 20397ac6653aSJeff Kirsher 2040acb600deSEric Dumazet skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); 20417ac6653aSJeff Kirsher 20427ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 20437ac6653aSJeff Kirsher break; 20447ac6653aSJeff Kirsher 20457ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 20467ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 20477ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 20487ac6653aSJeff Kirsher DMA_FROM_DEVICE); 20497ac6653aSJeff Kirsher 2050c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[entry]; 2051286a8372SGiuseppe CAVALLARO 205229896a67SGiuseppe CAVALLARO priv->hw->mode->refill_desc3(priv, p); 2053286a8372SGiuseppe CAVALLARO 205483d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) 205583d7af64SGiuseppe CAVALLARO pr_debug("\trefill entry #%d\n", entry); 20567ac6653aSJeff Kirsher } 20577ac6653aSJeff Kirsher wmb(); 2058c24602efSGiuseppe CAVALLARO priv->hw->desc->set_rx_owner(p); 20598e839891SDeepak Sikri wmb(); 20607ac6653aSJeff Kirsher } 20617ac6653aSJeff Kirsher } 20627ac6653aSJeff Kirsher 206332ceabcaSGiuseppe CAVALLARO /** 206432ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 206532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 206632ceabcaSGiuseppe CAVALLARO * @limit: napi bugget. 206732ceabcaSGiuseppe CAVALLARO * Description : this the function called by the napi poll method. 206832ceabcaSGiuseppe CAVALLARO * It gets all the frames inside the ring. 206932ceabcaSGiuseppe CAVALLARO */ 20707ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 20717ac6653aSJeff Kirsher { 20727ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20737ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 20747ac6653aSJeff Kirsher unsigned int next_entry; 20757ac6653aSJeff Kirsher unsigned int count = 0; 2076ceb69499SGiuseppe CAVALLARO int coe = priv->plat->rx_coe; 20777ac6653aSJeff Kirsher 207883d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 207983d7af64SGiuseppe CAVALLARO pr_debug("%s: descriptor ring:\n", __func__); 2080c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2081c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 2082c24602efSGiuseppe CAVALLARO else 2083c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 20847ac6653aSJeff Kirsher } 2085c24602efSGiuseppe CAVALLARO while (count < limit) { 20867ac6653aSJeff Kirsher int status; 20879401bb5cSGiuseppe CAVALLARO struct dma_desc *p; 20887ac6653aSJeff Kirsher 2089c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2090c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2091c24602efSGiuseppe CAVALLARO else 2092c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2093c24602efSGiuseppe CAVALLARO 2094c24602efSGiuseppe CAVALLARO if (priv->hw->desc->get_rx_owner(p)) 20957ac6653aSJeff Kirsher break; 20967ac6653aSJeff Kirsher 20977ac6653aSJeff Kirsher count++; 20987ac6653aSJeff Kirsher 20997ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 2100c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 21019401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_erx + next_entry); 2102c24602efSGiuseppe CAVALLARO else 21039401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_rx + next_entry); 21047ac6653aSJeff Kirsher 21057ac6653aSJeff Kirsher /* read the status of the incoming frame */ 2106c24602efSGiuseppe CAVALLARO status = priv->hw->desc->rx_status(&priv->dev->stats, 2107c24602efSGiuseppe CAVALLARO &priv->xstats, p); 2108c24602efSGiuseppe CAVALLARO if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status)) 2109c24602efSGiuseppe CAVALLARO priv->hw->desc->rx_extended_status(&priv->dev->stats, 2110c24602efSGiuseppe CAVALLARO &priv->xstats, 2111c24602efSGiuseppe CAVALLARO priv->dma_erx + 2112c24602efSGiuseppe CAVALLARO entry); 2113891434b1SRayagond Kokatanur if (unlikely(status == discard_frame)) { 21147ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 2115891434b1SRayagond Kokatanur if (priv->hwts_rx_en && !priv->extend_desc) { 2116891434b1SRayagond Kokatanur /* DESC2 & DESC3 will be overwitten by device 2117891434b1SRayagond Kokatanur * with timestamp value, hence reinitialize 2118891434b1SRayagond Kokatanur * them in stmmac_rx_refill() function so that 2119891434b1SRayagond Kokatanur * device can reuse it. 2120891434b1SRayagond Kokatanur */ 2121891434b1SRayagond Kokatanur priv->rx_skbuff[entry] = NULL; 2122891434b1SRayagond Kokatanur dma_unmap_single(priv->device, 2123891434b1SRayagond Kokatanur priv->rx_skbuff_dma[entry], 2124ceb69499SGiuseppe CAVALLARO priv->dma_buf_sz, 2125ceb69499SGiuseppe CAVALLARO DMA_FROM_DEVICE); 2126891434b1SRayagond Kokatanur } 2127891434b1SRayagond Kokatanur } else { 21287ac6653aSJeff Kirsher struct sk_buff *skb; 21297ac6653aSJeff Kirsher int frame_len; 21307ac6653aSJeff Kirsher 2131ceb69499SGiuseppe CAVALLARO frame_len = priv->hw->desc->get_rx_frame_len(p, coe); 2132ceb69499SGiuseppe CAVALLARO 21337ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 2134ceb69499SGiuseppe CAVALLARO * Type frames (LLC/LLC-SNAP) 2135ceb69499SGiuseppe CAVALLARO */ 21367ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 21377ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 21387ac6653aSJeff Kirsher 213983d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 21407ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 21417ac6653aSJeff Kirsher p, entry, p->des2); 214283d7af64SGiuseppe CAVALLARO if (frame_len > ETH_FRAME_LEN) 214383d7af64SGiuseppe CAVALLARO pr_debug("\tframe size %d, COE: %d\n", 214483d7af64SGiuseppe CAVALLARO frame_len, status); 214583d7af64SGiuseppe CAVALLARO } 21467ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 21477ac6653aSJeff Kirsher if (unlikely(!skb)) { 21487ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 21497ac6653aSJeff Kirsher priv->dev->name); 21507ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 21517ac6653aSJeff Kirsher break; 21527ac6653aSJeff Kirsher } 21537ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 21547ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 21557ac6653aSJeff Kirsher 2156891434b1SRayagond Kokatanur stmmac_get_rx_hwtstamp(priv, entry, skb); 2157891434b1SRayagond Kokatanur 21587ac6653aSJeff Kirsher skb_put(skb, frame_len); 21597ac6653aSJeff Kirsher dma_unmap_single(priv->device, 21607ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 21617ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 216283d7af64SGiuseppe CAVALLARO 21637ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 216483d7af64SGiuseppe CAVALLARO pr_debug("frame received (%dbytes)", frame_len); 21657ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 21667ac6653aSJeff Kirsher } 216783d7af64SGiuseppe CAVALLARO 2168b9381985SVince Bridgers stmmac_rx_vlan(priv->dev, skb); 2169b9381985SVince Bridgers 21707ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 21717ac6653aSJeff Kirsher 2172ceb69499SGiuseppe CAVALLARO if (unlikely(!coe)) 21737ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 217462a2ab93SGiuseppe CAVALLARO else 21757ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 217662a2ab93SGiuseppe CAVALLARO 21777ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 21787ac6653aSJeff Kirsher 21797ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 21807ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 21817ac6653aSJeff Kirsher } 21827ac6653aSJeff Kirsher entry = next_entry; 21837ac6653aSJeff Kirsher } 21847ac6653aSJeff Kirsher 21857ac6653aSJeff Kirsher stmmac_rx_refill(priv); 21867ac6653aSJeff Kirsher 21877ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 21887ac6653aSJeff Kirsher 21897ac6653aSJeff Kirsher return count; 21907ac6653aSJeff Kirsher } 21917ac6653aSJeff Kirsher 21927ac6653aSJeff Kirsher /** 21937ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 21947ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 21957ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 21967ac6653aSJeff Kirsher * all interfaces. 21977ac6653aSJeff Kirsher * Description : 21989125cdd1SGiuseppe CAVALLARO * To look at the incoming frames and clear the tx resources. 21997ac6653aSJeff Kirsher */ 22007ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 22017ac6653aSJeff Kirsher { 22027ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 22037ac6653aSJeff Kirsher int work_done = 0; 22047ac6653aSJeff Kirsher 22059125cdd1SGiuseppe CAVALLARO priv->xstats.napi_poll++; 22069125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 22077ac6653aSJeff Kirsher 22089125cdd1SGiuseppe CAVALLARO work_done = stmmac_rx(priv, budget); 22097ac6653aSJeff Kirsher if (work_done < budget) { 22107ac6653aSJeff Kirsher napi_complete(napi); 22119125cdd1SGiuseppe CAVALLARO stmmac_enable_dma_irq(priv); 22127ac6653aSJeff Kirsher } 22137ac6653aSJeff Kirsher return work_done; 22147ac6653aSJeff Kirsher } 22157ac6653aSJeff Kirsher 22167ac6653aSJeff Kirsher /** 22177ac6653aSJeff Kirsher * stmmac_tx_timeout 22187ac6653aSJeff Kirsher * @dev : Pointer to net device structure 22197ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 22207284a3f1SGiuseppe CAVALLARO * complete within a reasonable time. The driver will mark the error in the 22217ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 22227ac6653aSJeff Kirsher * in order to transmit a new packet. 22237ac6653aSJeff Kirsher */ 22247ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 22257ac6653aSJeff Kirsher { 22267ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22277ac6653aSJeff Kirsher 22287ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 22297ac6653aSJeff Kirsher stmmac_tx_err(priv); 22307ac6653aSJeff Kirsher } 22317ac6653aSJeff Kirsher 22327ac6653aSJeff Kirsher /** 223301789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 22347ac6653aSJeff Kirsher * @dev : pointer to the device structure 22357ac6653aSJeff Kirsher * Description: 22367ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 22377ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 22387ac6653aSJeff Kirsher * Return value: 22397ac6653aSJeff Kirsher * void. 22407ac6653aSJeff Kirsher */ 224101789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 22427ac6653aSJeff Kirsher { 22437ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22447ac6653aSJeff Kirsher 22457ac6653aSJeff Kirsher spin_lock(&priv->lock); 22463b57de95SVince Bridgers priv->hw->mac->set_filter(priv->hw, dev); 22477ac6653aSJeff Kirsher spin_unlock(&priv->lock); 22487ac6653aSJeff Kirsher } 22497ac6653aSJeff Kirsher 22507ac6653aSJeff Kirsher /** 22517ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 22527ac6653aSJeff Kirsher * @dev : device pointer. 22537ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 22547ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 22557ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 22567ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 22577ac6653aSJeff Kirsher * Return value: 22587ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 22597ac6653aSJeff Kirsher * file on failure. 22607ac6653aSJeff Kirsher */ 22617ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 22627ac6653aSJeff Kirsher { 22637ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22647ac6653aSJeff Kirsher int max_mtu; 22657ac6653aSJeff Kirsher 22667ac6653aSJeff Kirsher if (netif_running(dev)) { 22677ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 22687ac6653aSJeff Kirsher return -EBUSY; 22697ac6653aSJeff Kirsher } 22707ac6653aSJeff Kirsher 227148febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 22727ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 22737ac6653aSJeff Kirsher else 227445db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 22757ac6653aSJeff Kirsher 22762618abb7SVince Bridgers if (priv->plat->maxmtu < max_mtu) 22772618abb7SVince Bridgers max_mtu = priv->plat->maxmtu; 22782618abb7SVince Bridgers 22797ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 22807ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 22817ac6653aSJeff Kirsher return -EINVAL; 22827ac6653aSJeff Kirsher } 22837ac6653aSJeff Kirsher 22847ac6653aSJeff Kirsher dev->mtu = new_mtu; 22857ac6653aSJeff Kirsher netdev_update_features(dev); 22867ac6653aSJeff Kirsher 22877ac6653aSJeff Kirsher return 0; 22887ac6653aSJeff Kirsher } 22897ac6653aSJeff Kirsher 2290c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 2291c8f44affSMichał Mirosław netdev_features_t features) 22927ac6653aSJeff Kirsher { 22937ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22947ac6653aSJeff Kirsher 229538912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 22967ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 229738912bdbSDeepak SIKRI else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) 229838912bdbSDeepak SIKRI features &= ~NETIF_F_IPV6_CSUM; 22997ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 23007ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23017ac6653aSJeff Kirsher 23027ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 23037ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 23047ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 2305ceb69499SGiuseppe CAVALLARO * the TX csum insertionin the TDES and not use SF. 2306ceb69499SGiuseppe CAVALLARO */ 23077ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 23087ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23097ac6653aSJeff Kirsher 23107ac6653aSJeff Kirsher return features; 23117ac6653aSJeff Kirsher } 23127ac6653aSJeff Kirsher 231332ceabcaSGiuseppe CAVALLARO /** 231432ceabcaSGiuseppe CAVALLARO * stmmac_interrupt - main ISR 231532ceabcaSGiuseppe CAVALLARO * @irq: interrupt number. 231632ceabcaSGiuseppe CAVALLARO * @dev_id: to pass the net device pointer. 231732ceabcaSGiuseppe CAVALLARO * Description: this is the main driver interrupt service routine. 231832ceabcaSGiuseppe CAVALLARO * It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI 231932ceabcaSGiuseppe CAVALLARO * interrupts. 232032ceabcaSGiuseppe CAVALLARO */ 23217ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 23227ac6653aSJeff Kirsher { 23237ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 23247ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23257ac6653aSJeff Kirsher 232689f7f2cfSSrinivas Kandagatla if (priv->irq_wake) 232789f7f2cfSSrinivas Kandagatla pm_wakeup_event(priv->device, 0); 232889f7f2cfSSrinivas Kandagatla 23297ac6653aSJeff Kirsher if (unlikely(!dev)) { 23307ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 23317ac6653aSJeff Kirsher return IRQ_NONE; 23327ac6653aSJeff Kirsher } 23337ac6653aSJeff Kirsher 23347ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 2335d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 23367ed24bbeSVince Bridgers int status = priv->hw->mac->host_irq_status(priv->hw, 23370982a0f6SGiuseppe CAVALLARO &priv->xstats); 2338d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 2339d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 23400982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) 2341d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 23420982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) 2343d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 2344d765955dSGiuseppe CAVALLARO } 2345d765955dSGiuseppe CAVALLARO } 2346d765955dSGiuseppe CAVALLARO 2347d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 23487ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 23497ac6653aSJeff Kirsher 23507ac6653aSJeff Kirsher return IRQ_HANDLED; 23517ac6653aSJeff Kirsher } 23527ac6653aSJeff Kirsher 23537ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 23547ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 2355ceb69499SGiuseppe CAVALLARO * to allow network I/O with interrupts disabled. 2356ceb69499SGiuseppe CAVALLARO */ 23577ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 23587ac6653aSJeff Kirsher { 23597ac6653aSJeff Kirsher disable_irq(dev->irq); 23607ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 23617ac6653aSJeff Kirsher enable_irq(dev->irq); 23627ac6653aSJeff Kirsher } 23637ac6653aSJeff Kirsher #endif 23647ac6653aSJeff Kirsher 23657ac6653aSJeff Kirsher /** 23667ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 23677ac6653aSJeff Kirsher * @dev: Device pointer. 23687ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 23697ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 23707ac6653aSJeff Kirsher * @cmd: IOCTL command 23717ac6653aSJeff Kirsher * Description: 237232ceabcaSGiuseppe CAVALLARO * Currently it supports the phy_mii_ioctl(...) and HW time stamping. 23737ac6653aSJeff Kirsher */ 23747ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 23757ac6653aSJeff Kirsher { 23767ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2377891434b1SRayagond Kokatanur int ret = -EOPNOTSUPP; 23787ac6653aSJeff Kirsher 23797ac6653aSJeff Kirsher if (!netif_running(dev)) 23807ac6653aSJeff Kirsher return -EINVAL; 23817ac6653aSJeff Kirsher 2382891434b1SRayagond Kokatanur switch (cmd) { 2383891434b1SRayagond Kokatanur case SIOCGMIIPHY: 2384891434b1SRayagond Kokatanur case SIOCGMIIREG: 2385891434b1SRayagond Kokatanur case SIOCSMIIREG: 23867ac6653aSJeff Kirsher if (!priv->phydev) 23877ac6653aSJeff Kirsher return -EINVAL; 23887ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 2389891434b1SRayagond Kokatanur break; 2390891434b1SRayagond Kokatanur case SIOCSHWTSTAMP: 2391891434b1SRayagond Kokatanur ret = stmmac_hwtstamp_ioctl(dev, rq); 2392891434b1SRayagond Kokatanur break; 2393891434b1SRayagond Kokatanur default: 2394891434b1SRayagond Kokatanur break; 2395891434b1SRayagond Kokatanur } 23967ac6653aSJeff Kirsher 23977ac6653aSJeff Kirsher return ret; 23987ac6653aSJeff Kirsher } 23997ac6653aSJeff Kirsher 24007ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 24017ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 24027ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 2403e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 24047ac29055SGiuseppe CAVALLARO 2405c24602efSGiuseppe CAVALLARO static void sysfs_display_ring(void *head, int size, int extend_desc, 2406c24602efSGiuseppe CAVALLARO struct seq_file *seq) 24077ac29055SGiuseppe CAVALLARO { 24087ac29055SGiuseppe CAVALLARO int i; 2409c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 2410c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 24117ac29055SGiuseppe CAVALLARO 2412c24602efSGiuseppe CAVALLARO for (i = 0; i < size; i++) { 2413c24602efSGiuseppe CAVALLARO u64 x; 2414c24602efSGiuseppe CAVALLARO if (extend_desc) { 2415c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 2416c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2417c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2418c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2419c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 2420c24602efSGiuseppe CAVALLARO ep++; 2421c24602efSGiuseppe CAVALLARO } else { 2422c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 2423c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2424c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2425c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2426c24602efSGiuseppe CAVALLARO p->des2, p->des3); 2427c24602efSGiuseppe CAVALLARO p++; 2428c24602efSGiuseppe CAVALLARO } 24297ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 24307ac29055SGiuseppe CAVALLARO } 2431c24602efSGiuseppe CAVALLARO } 24327ac29055SGiuseppe CAVALLARO 2433c24602efSGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 2434c24602efSGiuseppe CAVALLARO { 2435c24602efSGiuseppe CAVALLARO struct net_device *dev = seq->private; 2436c24602efSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2437c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 2438c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 24397ac29055SGiuseppe CAVALLARO 2440c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 2441c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended RX descriptor ring:\n"); 2442c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_erx, rxsize, 1, seq); 2443c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended TX descriptor ring:\n"); 2444c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_etx, txsize, 1, seq); 2445c24602efSGiuseppe CAVALLARO } else { 2446c24602efSGiuseppe CAVALLARO seq_printf(seq, "RX descriptor ring:\n"); 2447c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_rx, rxsize, 0, seq); 2448c24602efSGiuseppe CAVALLARO seq_printf(seq, "TX descriptor ring:\n"); 2449c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_tx, txsize, 0, seq); 24507ac29055SGiuseppe CAVALLARO } 24517ac29055SGiuseppe CAVALLARO 24527ac29055SGiuseppe CAVALLARO return 0; 24537ac29055SGiuseppe CAVALLARO } 24547ac29055SGiuseppe CAVALLARO 24557ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 24567ac29055SGiuseppe CAVALLARO { 24577ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 24587ac29055SGiuseppe CAVALLARO } 24597ac29055SGiuseppe CAVALLARO 24607ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 24617ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 24627ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 24637ac29055SGiuseppe CAVALLARO .read = seq_read, 24647ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 246574863948SDjalal Harouni .release = single_release, 24667ac29055SGiuseppe CAVALLARO }; 24677ac29055SGiuseppe CAVALLARO 2468e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 2469e7434821SGiuseppe CAVALLARO { 2470e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 2471e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2472e7434821SGiuseppe CAVALLARO 247319e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 2474e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 2475e7434821SGiuseppe CAVALLARO return 0; 2476e7434821SGiuseppe CAVALLARO } 2477e7434821SGiuseppe CAVALLARO 2478e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2479e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 2480e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2481e7434821SGiuseppe CAVALLARO 2482e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 2483e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 2484e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 2485e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 2486e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 2487e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 2488e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 2489e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 2490e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 2491e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 2492e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 2493e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 2494e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 2495e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 2496e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 2497e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 2498e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 2499e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 2500e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 2501e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 2502e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 2503e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 2504e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 2505e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 2506e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 2507e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 2508e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 2509e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 2510e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 2511e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 2512e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 2513e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 2514e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 2515e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 2516e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 2517e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 2518e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 2519e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 2520e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 2521e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 2522e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 2523e7434821SGiuseppe CAVALLARO 2524e7434821SGiuseppe CAVALLARO return 0; 2525e7434821SGiuseppe CAVALLARO } 2526e7434821SGiuseppe CAVALLARO 2527e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 2528e7434821SGiuseppe CAVALLARO { 2529e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 2530e7434821SGiuseppe CAVALLARO } 2531e7434821SGiuseppe CAVALLARO 2532e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 2533e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 2534e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 2535e7434821SGiuseppe CAVALLARO .read = seq_read, 2536e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 253774863948SDjalal Harouni .release = single_release, 2538e7434821SGiuseppe CAVALLARO }; 2539e7434821SGiuseppe CAVALLARO 25407ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 25417ac29055SGiuseppe CAVALLARO { 25427ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 25437ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 25447ac29055SGiuseppe CAVALLARO 25457ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 25467ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 25477ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 25487ac29055SGiuseppe CAVALLARO 25497ac29055SGiuseppe CAVALLARO return -ENOMEM; 25507ac29055SGiuseppe CAVALLARO } 25517ac29055SGiuseppe CAVALLARO 25527ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 25537ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 25547ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 25557ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 25567ac29055SGiuseppe CAVALLARO 25577ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 25587ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 25597ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 25607ac29055SGiuseppe CAVALLARO 25617ac29055SGiuseppe CAVALLARO return -ENOMEM; 25627ac29055SGiuseppe CAVALLARO } 25637ac29055SGiuseppe CAVALLARO 2564e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 2565e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 2566e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 2567e7434821SGiuseppe CAVALLARO 2568e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 2569e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 2570e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2571e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 2572e7434821SGiuseppe CAVALLARO 2573e7434821SGiuseppe CAVALLARO return -ENOMEM; 2574e7434821SGiuseppe CAVALLARO } 2575e7434821SGiuseppe CAVALLARO 25767ac29055SGiuseppe CAVALLARO return 0; 25777ac29055SGiuseppe CAVALLARO } 25787ac29055SGiuseppe CAVALLARO 25797ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 25807ac29055SGiuseppe CAVALLARO { 25817ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2582e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 25837ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 25847ac29055SGiuseppe CAVALLARO } 25857ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 25867ac29055SGiuseppe CAVALLARO 25877ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 25887ac6653aSJeff Kirsher .ndo_open = stmmac_open, 25897ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 25907ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 25917ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 25927ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 259301789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 25947ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 25957ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 25967ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 25977ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 25987ac6653aSJeff Kirsher #endif 25997ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 26007ac6653aSJeff Kirsher }; 26017ac6653aSJeff Kirsher 26027ac6653aSJeff Kirsher /** 2603cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 260432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 2605cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 2606cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 2607cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 2608cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 2609cf3f047bSGiuseppe CAVALLARO * descriptor structure). 2610cf3f047bSGiuseppe CAVALLARO */ 2611cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 2612cf3f047bSGiuseppe CAVALLARO { 2613cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 2614cf3f047bSGiuseppe CAVALLARO 2615cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 261603f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 261703f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 26183b57de95SVince Bridgers mac = dwmac1000_setup(priv->ioaddr, 26193b57de95SVince Bridgers priv->plat->multicast_filter_bins, 26203b57de95SVince Bridgers priv->plat->unicast_filter_entries); 262103f2eecdSMarc Kleine-Budde } else { 2622cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 262303f2eecdSMarc Kleine-Budde } 2624cf3f047bSGiuseppe CAVALLARO if (!mac) 2625cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 2626cf3f047bSGiuseppe CAVALLARO 2627cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 2628cf3f047bSGiuseppe CAVALLARO 2629cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 2630cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 2631cf3f047bSGiuseppe CAVALLARO 26324a7d666aSGiuseppe CAVALLARO /* To use the chained or ring mode */ 26334a7d666aSGiuseppe CAVALLARO if (chain_mode) { 263429896a67SGiuseppe CAVALLARO priv->hw->mode = &chain_mode_ops; 26354a7d666aSGiuseppe CAVALLARO pr_info(" Chain mode enabled\n"); 26364a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_CHAIN_MODE; 26374a7d666aSGiuseppe CAVALLARO } else { 263829896a67SGiuseppe CAVALLARO priv->hw->mode = &ring_mode_ops; 26394a7d666aSGiuseppe CAVALLARO pr_info(" Ring mode enabled\n"); 26404a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_RING_MODE; 26414a7d666aSGiuseppe CAVALLARO } 26424a7d666aSGiuseppe CAVALLARO 2643cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 2644cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 2645cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 2646cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 2647cf3f047bSGiuseppe CAVALLARO 2648cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 2649cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 2650cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 2651cf3f047bSGiuseppe CAVALLARO * register (if supported). 2652cf3f047bSGiuseppe CAVALLARO */ 2653cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 2654cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 265538912bdbSDeepak SIKRI 265638912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 265738912bdbSDeepak SIKRI 265838912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 265938912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 266038912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 266138912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 266238912bdbSDeepak SIKRI 2663cf3f047bSGiuseppe CAVALLARO } else 2664cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 2665cf3f047bSGiuseppe CAVALLARO 266661369d02SByungho An /* To use alternate (extended) or normal descriptor structures */ 266761369d02SByungho An stmmac_selec_desc_mode(priv); 266861369d02SByungho An 266938912bdbSDeepak SIKRI if (priv->plat->rx_coe) 267038912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 267138912bdbSDeepak SIKRI priv->plat->rx_coe); 2672cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 2673cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 2674cf3f047bSGiuseppe CAVALLARO 2675cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 2676cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 2677cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 2678cf3f047bSGiuseppe CAVALLARO } 2679cf3f047bSGiuseppe CAVALLARO 2680c24602efSGiuseppe CAVALLARO return 0; 2681cf3f047bSGiuseppe CAVALLARO } 2682cf3f047bSGiuseppe CAVALLARO 2683cf3f047bSGiuseppe CAVALLARO /** 2684bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 2685bfab27a1SGiuseppe CAVALLARO * @device: device pointer 2686ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 2687ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 2688bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 2689bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 26907ac6653aSJeff Kirsher */ 2691bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 2692cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 2693cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 26947ac6653aSJeff Kirsher { 26957ac6653aSJeff Kirsher int ret = 0; 2696bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 2697bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 26987ac6653aSJeff Kirsher 2699bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 270041de8d4cSJoe Perches if (!ndev) 2701bfab27a1SGiuseppe CAVALLARO return NULL; 27027ac6653aSJeff Kirsher 2703bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 27047ac6653aSJeff Kirsher 2705bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 2706bfab27a1SGiuseppe CAVALLARO priv->device = device; 2707bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 2708bfab27a1SGiuseppe CAVALLARO 2709bfab27a1SGiuseppe CAVALLARO ether_setup(ndev); 2710bfab27a1SGiuseppe CAVALLARO 2711bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 2712cf3f047bSGiuseppe CAVALLARO priv->pause = pause; 2713cf3f047bSGiuseppe CAVALLARO priv->plat = plat_dat; 2714cf3f047bSGiuseppe CAVALLARO priv->ioaddr = addr; 2715cf3f047bSGiuseppe CAVALLARO priv->dev->base_addr = (unsigned long)addr; 2716bfab27a1SGiuseppe CAVALLARO 2717cf3f047bSGiuseppe CAVALLARO /* Verify driver arguments */ 2718cf3f047bSGiuseppe CAVALLARO stmmac_verify_args(); 2719cf3f047bSGiuseppe CAVALLARO 2720cf3f047bSGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 2721ceb69499SGiuseppe CAVALLARO * this needs to have multiple instances 2722ceb69499SGiuseppe CAVALLARO */ 2723cf3f047bSGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 2724cf3f047bSGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 2725cf3f047bSGiuseppe CAVALLARO 272662866e98SChen-Yu Tsai priv->stmmac_clk = devm_clk_get(priv->device, STMMAC_RESOURCE_NAME); 272762866e98SChen-Yu Tsai if (IS_ERR(priv->stmmac_clk)) { 272862866e98SChen-Yu Tsai dev_warn(priv->device, "%s: warning: cannot get CSR clock\n", 272962866e98SChen-Yu Tsai __func__); 2730c5e4ddbdSChen-Yu Tsai ret = PTR_ERR(priv->stmmac_clk); 273162866e98SChen-Yu Tsai goto error_clk_get; 273262866e98SChen-Yu Tsai } 273362866e98SChen-Yu Tsai clk_prepare_enable(priv->stmmac_clk); 273462866e98SChen-Yu Tsai 2735c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = devm_reset_control_get(priv->device, 2736c5e4ddbdSChen-Yu Tsai STMMAC_RESOURCE_NAME); 2737c5e4ddbdSChen-Yu Tsai if (IS_ERR(priv->stmmac_rst)) { 2738c5e4ddbdSChen-Yu Tsai if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) { 2739c5e4ddbdSChen-Yu Tsai ret = -EPROBE_DEFER; 2740c5e4ddbdSChen-Yu Tsai goto error_hw_init; 2741c5e4ddbdSChen-Yu Tsai } 2742c5e4ddbdSChen-Yu Tsai dev_info(priv->device, "no reset control found\n"); 2743c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = NULL; 2744c5e4ddbdSChen-Yu Tsai } 2745c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2746c5e4ddbdSChen-Yu Tsai reset_control_deassert(priv->stmmac_rst); 2747c5e4ddbdSChen-Yu Tsai 2748cf3f047bSGiuseppe CAVALLARO /* Init MAC and get the capabilities */ 2749c24602efSGiuseppe CAVALLARO ret = stmmac_hw_init(priv); 2750c24602efSGiuseppe CAVALLARO if (ret) 275162866e98SChen-Yu Tsai goto error_hw_init; 2752cf3f047bSGiuseppe CAVALLARO 2753cf3f047bSGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 2754cf3f047bSGiuseppe CAVALLARO 2755cf3f047bSGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 2756cf3f047bSGiuseppe CAVALLARO NETIF_F_RXCSUM; 2757bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 2758bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 27597ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 27607ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 2761f646968fSPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; 27627ac6653aSJeff Kirsher #endif 27637ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 27647ac6653aSJeff Kirsher 27657ac6653aSJeff Kirsher if (flow_ctrl) 27667ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 27677ac6653aSJeff Kirsher 276862a2ab93SGiuseppe CAVALLARO /* Rx Watchdog is available in the COREs newer than the 3.40. 276962a2ab93SGiuseppe CAVALLARO * In some case, for example on bugged HW this feature 277062a2ab93SGiuseppe CAVALLARO * has to be disable and this can be done by passing the 277162a2ab93SGiuseppe CAVALLARO * riwt_off field from the platform. 277262a2ab93SGiuseppe CAVALLARO */ 277362a2ab93SGiuseppe CAVALLARO if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { 277462a2ab93SGiuseppe CAVALLARO priv->use_riwt = 1; 277562a2ab93SGiuseppe CAVALLARO pr_info(" Enable RX Mitigation via HW Watchdog Timer\n"); 277662a2ab93SGiuseppe CAVALLARO } 277762a2ab93SGiuseppe CAVALLARO 2778bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 27797ac6653aSJeff Kirsher 27807ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 2781a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 27827ac6653aSJeff Kirsher 2783bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 27847ac6653aSJeff Kirsher if (ret) { 2785cf3f047bSGiuseppe CAVALLARO pr_err("%s: ERROR %i registering the device\n", __func__, ret); 27866a81c26fSViresh Kumar goto error_netdev_register; 27877ac6653aSJeff Kirsher } 27887ac6653aSJeff Kirsher 2789cd7201f4SGiuseppe CAVALLARO /* If a specific clk_csr value is passed from the platform 2790cd7201f4SGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 2791cd7201f4SGiuseppe CAVALLARO * changed at run-time and it is fixed. Viceversa the driver'll try to 2792cd7201f4SGiuseppe CAVALLARO * set the MDC clock dynamically according to the csr actual 2793cd7201f4SGiuseppe CAVALLARO * clock input. 2794cd7201f4SGiuseppe CAVALLARO */ 2795cd7201f4SGiuseppe CAVALLARO if (!priv->plat->clk_csr) 2796cd7201f4SGiuseppe CAVALLARO stmmac_clk_csr_set(priv); 2797cd7201f4SGiuseppe CAVALLARO else 2798cd7201f4SGiuseppe CAVALLARO priv->clk_csr = priv->plat->clk_csr; 2799cd7201f4SGiuseppe CAVALLARO 2800e58bb43fSGiuseppe CAVALLARO stmmac_check_pcs_mode(priv); 2801e58bb43fSGiuseppe CAVALLARO 28024d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 28034d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 28044bfcbd7aSFrancesco Virlinzi /* MDIO bus Registration */ 28054bfcbd7aSFrancesco Virlinzi ret = stmmac_mdio_register(ndev); 28064bfcbd7aSFrancesco Virlinzi if (ret < 0) { 28074bfcbd7aSFrancesco Virlinzi pr_debug("%s: MDIO bus (id: %d) registration failed", 28084bfcbd7aSFrancesco Virlinzi __func__, priv->plat->bus_id); 28096a81c26fSViresh Kumar goto error_mdio_register; 28104bfcbd7aSFrancesco Virlinzi } 2811e58bb43fSGiuseppe CAVALLARO } 28124bfcbd7aSFrancesco Virlinzi 2813bfab27a1SGiuseppe CAVALLARO return priv; 28147ac6653aSJeff Kirsher 28156a81c26fSViresh Kumar error_mdio_register: 28167ac6653aSJeff Kirsher unregister_netdev(ndev); 28176a81c26fSViresh Kumar error_netdev_register: 28186a81c26fSViresh Kumar netif_napi_del(&priv->napi); 281962866e98SChen-Yu Tsai error_hw_init: 282062866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 282162866e98SChen-Yu Tsai error_clk_get: 28227ac6653aSJeff Kirsher free_netdev(ndev); 28237ac6653aSJeff Kirsher 2824c5e4ddbdSChen-Yu Tsai return ERR_PTR(ret); 28257ac6653aSJeff Kirsher } 28267ac6653aSJeff Kirsher 28277ac6653aSJeff Kirsher /** 28287ac6653aSJeff Kirsher * stmmac_dvr_remove 2829bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 28307ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 2831bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 28327ac6653aSJeff Kirsher */ 2833bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 28347ac6653aSJeff Kirsher { 28357ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 28367ac6653aSJeff Kirsher 28377ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 28387ac6653aSJeff Kirsher 28397ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 28407ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 28417ac6653aSJeff Kirsher 2842bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 28434d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 28444d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) 28454bfcbd7aSFrancesco Virlinzi stmmac_mdio_unregister(ndev); 28467ac6653aSJeff Kirsher netif_carrier_off(ndev); 28477ac6653aSJeff Kirsher unregister_netdev(ndev); 2848c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2849c5e4ddbdSChen-Yu Tsai reset_control_assert(priv->stmmac_rst); 285062866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 28517ac6653aSJeff Kirsher free_netdev(ndev); 28527ac6653aSJeff Kirsher 28537ac6653aSJeff Kirsher return 0; 28547ac6653aSJeff Kirsher } 28557ac6653aSJeff Kirsher 28567ac6653aSJeff Kirsher #ifdef CONFIG_PM 2857bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 28587ac6653aSJeff Kirsher { 28597ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2860f8c5a875SGiuseppe CAVALLARO unsigned long flags; 28617ac6653aSJeff Kirsher 28627ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 28637ac6653aSJeff Kirsher return 0; 28647ac6653aSJeff Kirsher 2865102463b1SFrancesco Virlinzi if (priv->phydev) 2866102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 2867102463b1SFrancesco Virlinzi 2868f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 28697ac6653aSJeff Kirsher 28707ac6653aSJeff Kirsher netif_device_detach(ndev); 28717ac6653aSJeff Kirsher netif_stop_queue(ndev); 28727ac6653aSJeff Kirsher 28737ac6653aSJeff Kirsher napi_disable(&priv->napi); 28747ac6653aSJeff Kirsher 28757ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 28767ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 28777ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 2878c24602efSGiuseppe CAVALLARO 2879c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 28807ac6653aSJeff Kirsher 28817ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 288289f7f2cfSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 28837ed24bbeSVince Bridgers priv->hw->mac->pmt(priv->hw, priv->wolopts); 288489f7f2cfSSrinivas Kandagatla priv->irq_wake = 1; 288589f7f2cfSSrinivas Kandagatla } else { 2886bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 2887db88f10aSSrinivas Kandagatla pinctrl_pm_select_sleep_state(priv->device); 2888ba1377ffSGiuseppe CAVALLARO /* Disable clock in case of PWM is off */ 2889a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 2890ba1377ffSGiuseppe CAVALLARO } 2891f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 28922d871aa0SVince Bridgers 28932d871aa0SVince Bridgers priv->oldlink = 0; 28942d871aa0SVince Bridgers priv->speed = 0; 28952d871aa0SVince Bridgers priv->oldduplex = -1; 28967ac6653aSJeff Kirsher return 0; 28977ac6653aSJeff Kirsher } 28987ac6653aSJeff Kirsher 2899bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 29007ac6653aSJeff Kirsher { 29017ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2902f8c5a875SGiuseppe CAVALLARO unsigned long flags; 29037ac6653aSJeff Kirsher 29047ac6653aSJeff Kirsher if (!netif_running(ndev)) 29057ac6653aSJeff Kirsher return 0; 29067ac6653aSJeff Kirsher 2907f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 29087ac6653aSJeff Kirsher 29097ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 29107ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 29117ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 29127ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 2913ceb69499SGiuseppe CAVALLARO * from another devices (e.g. serial console). 2914ceb69499SGiuseppe CAVALLARO */ 2915623997fbSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 29167ed24bbeSVince Bridgers priv->hw->mac->pmt(priv->hw, 0); 291789f7f2cfSSrinivas Kandagatla priv->irq_wake = 0; 2918623997fbSSrinivas Kandagatla } else { 2919db88f10aSSrinivas Kandagatla pinctrl_pm_select_default_state(priv->device); 2920ba1377ffSGiuseppe CAVALLARO /* enable the clk prevously disabled */ 2921a630844dSStefan Roese clk_prepare_enable(priv->stmmac_clk); 2922623997fbSSrinivas Kandagatla /* reset the phy so that it's ready */ 2923623997fbSSrinivas Kandagatla if (priv->mii) 2924623997fbSSrinivas Kandagatla stmmac_mdio_reset(priv->mii); 2925623997fbSSrinivas Kandagatla } 29267ac6653aSJeff Kirsher 29277ac6653aSJeff Kirsher netif_device_attach(ndev); 29287ac6653aSJeff Kirsher 2929623997fbSSrinivas Kandagatla stmmac_hw_setup(ndev); 29307ac6653aSJeff Kirsher 29317ac6653aSJeff Kirsher napi_enable(&priv->napi); 29327ac6653aSJeff Kirsher 29337ac6653aSJeff Kirsher netif_start_queue(ndev); 29347ac6653aSJeff Kirsher 2935f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 2936102463b1SFrancesco Virlinzi 2937102463b1SFrancesco Virlinzi if (priv->phydev) 2938102463b1SFrancesco Virlinzi phy_start(priv->phydev); 2939102463b1SFrancesco Virlinzi 29407ac6653aSJeff Kirsher return 0; 29417ac6653aSJeff Kirsher } 29427ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 29437ac6653aSJeff Kirsher 294433d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers 294533d5e332SGiuseppe CAVALLARO * depending on the configuration selected. 294633d5e332SGiuseppe CAVALLARO */ 2947ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void) 2948ba27ec66SGiuseppe CAVALLARO { 2949493682b8SKonstantin Khlebnikov int ret; 2950ba27ec66SGiuseppe CAVALLARO 2951493682b8SKonstantin Khlebnikov ret = stmmac_register_platform(); 2952493682b8SKonstantin Khlebnikov if (ret) 2953493682b8SKonstantin Khlebnikov goto err; 2954493682b8SKonstantin Khlebnikov ret = stmmac_register_pci(); 2955493682b8SKonstantin Khlebnikov if (ret) 2956493682b8SKonstantin Khlebnikov goto err_pci; 295733d5e332SGiuseppe CAVALLARO return 0; 2958493682b8SKonstantin Khlebnikov err_pci: 2959493682b8SKonstantin Khlebnikov stmmac_unregister_platform(); 2960493682b8SKonstantin Khlebnikov err: 2961493682b8SKonstantin Khlebnikov pr_err("stmmac: driver registration failed\n"); 2962493682b8SKonstantin Khlebnikov return ret; 2963ba27ec66SGiuseppe CAVALLARO } 2964ba27ec66SGiuseppe CAVALLARO 2965ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void) 2966ba27ec66SGiuseppe CAVALLARO { 296733d5e332SGiuseppe CAVALLARO stmmac_unregister_platform(); 296833d5e332SGiuseppe CAVALLARO stmmac_unregister_pci(); 2969ba27ec66SGiuseppe CAVALLARO } 2970ba27ec66SGiuseppe CAVALLARO 2971ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init); 2972ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit); 2973ba27ec66SGiuseppe CAVALLARO 29747ac6653aSJeff Kirsher #ifndef MODULE 29757ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 29767ac6653aSJeff Kirsher { 29777ac6653aSJeff Kirsher char *opt; 29787ac6653aSJeff Kirsher 29797ac6653aSJeff Kirsher if (!str || !*str) 29807ac6653aSJeff Kirsher return -EINVAL; 29817ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 29827ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 2983ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &debug)) 29847ac6653aSJeff Kirsher goto err; 29857ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 2986ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 8, 0, &phyaddr)) 29877ac6653aSJeff Kirsher goto err; 29887ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 2989ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_txsize)) 29907ac6653aSJeff Kirsher goto err; 29917ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 2992ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_rxsize)) 29937ac6653aSJeff Kirsher goto err; 29947ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 2995ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &buf_sz)) 29967ac6653aSJeff Kirsher goto err; 29977ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 2998ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 3, 0, &tc)) 29997ac6653aSJeff Kirsher goto err; 30007ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 3001ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 9, 0, &watchdog)) 30027ac6653aSJeff Kirsher goto err; 30037ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 3004ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &flow_ctrl)) 30057ac6653aSJeff Kirsher goto err; 30067ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 3007ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &pause)) 30087ac6653aSJeff Kirsher goto err; 3009506f669cSGiuseppe CAVALLARO } else if (!strncmp(opt, "eee_timer:", 10)) { 3010d765955dSGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &eee_timer)) 3011d765955dSGiuseppe CAVALLARO goto err; 30124a7d666aSGiuseppe CAVALLARO } else if (!strncmp(opt, "chain_mode:", 11)) { 30134a7d666aSGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &chain_mode)) 30144a7d666aSGiuseppe CAVALLARO goto err; 30157ac6653aSJeff Kirsher } 30167ac6653aSJeff Kirsher } 30177ac6653aSJeff Kirsher return 0; 30187ac6653aSJeff Kirsher 30197ac6653aSJeff Kirsher err: 30207ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 30217ac6653aSJeff Kirsher return -EINVAL; 30227ac6653aSJeff Kirsher } 30237ac6653aSJeff Kirsher 30247ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 3025ceb69499SGiuseppe CAVALLARO #endif /* MODULE */ 30266fc0d0f2SGiuseppe Cavallaro 30276fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 30286fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 30296fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 3030