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 952618abb7SVince Bridgers #define DMA_BUFFER_SIZE BUF_SIZE_4KiB 967ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE; 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; 1397ac6653aSJeff Kirsher if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) 1407ac6653aSJeff Kirsher buf_sz = DMA_BUFFER_SIZE; 1417ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1427ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1437ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1447ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1457ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1467ac6653aSJeff Kirsher pause = PAUSE_TIME; 147d765955dSGiuseppe CAVALLARO if (eee_timer < 0) 148d765955dSGiuseppe CAVALLARO eee_timer = STMMAC_DEFAULT_LPI_TIMER; 1497ac6653aSJeff Kirsher } 1507ac6653aSJeff Kirsher 15132ceabcaSGiuseppe CAVALLARO /** 15232ceabcaSGiuseppe CAVALLARO * stmmac_clk_csr_set - dynamically set the MDC clock 15332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 15432ceabcaSGiuseppe CAVALLARO * Description: this is to dynamically set the MDC clock according to the csr 15532ceabcaSGiuseppe CAVALLARO * clock input. 15632ceabcaSGiuseppe CAVALLARO * Note: 15732ceabcaSGiuseppe CAVALLARO * If a specific clk_csr value is passed from the platform 15832ceabcaSGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 15932ceabcaSGiuseppe CAVALLARO * changed at run-time and it is fixed (as reported in the driver 16032ceabcaSGiuseppe CAVALLARO * documentation). Viceversa the driver will try to set the MDC 16132ceabcaSGiuseppe CAVALLARO * clock dynamically according to the actual clock input. 16232ceabcaSGiuseppe CAVALLARO */ 163cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv) 164cd7201f4SGiuseppe CAVALLARO { 165cd7201f4SGiuseppe CAVALLARO u32 clk_rate; 166cd7201f4SGiuseppe CAVALLARO 167cd7201f4SGiuseppe CAVALLARO clk_rate = clk_get_rate(priv->stmmac_clk); 168cd7201f4SGiuseppe CAVALLARO 169cd7201f4SGiuseppe CAVALLARO /* Platform provided default clk_csr would be assumed valid 170ceb69499SGiuseppe CAVALLARO * for all other cases except for the below mentioned ones. 171ceb69499SGiuseppe CAVALLARO * For values higher than the IEEE 802.3 specified frequency 172ceb69499SGiuseppe CAVALLARO * we can not estimate the proper divider as it is not known 173ceb69499SGiuseppe CAVALLARO * the frequency of clk_csr_i. So we do not change the default 174ceb69499SGiuseppe CAVALLARO * divider. 175ceb69499SGiuseppe CAVALLARO */ 176cd7201f4SGiuseppe CAVALLARO if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) { 177cd7201f4SGiuseppe CAVALLARO if (clk_rate < CSR_F_35M) 178cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_20_35M; 179cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M)) 180cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_35_60M; 181cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M)) 182cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_60_100M; 183cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M)) 184cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_100_150M; 185cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) 186cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_150_250M; 187cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) 188cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_250_300M; 189ceb69499SGiuseppe CAVALLARO } 190cd7201f4SGiuseppe CAVALLARO } 191cd7201f4SGiuseppe CAVALLARO 1927ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1937ac6653aSJeff Kirsher { 1947ac6653aSJeff Kirsher int j; 19583d7af64SGiuseppe CAVALLARO pr_debug("len = %d byte, buf addr: 0x%p", len, buf); 1967ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 1977ac6653aSJeff Kirsher if ((j % 16) == 0) 19883d7af64SGiuseppe CAVALLARO pr_debug("\n %03x:", j); 19983d7af64SGiuseppe CAVALLARO pr_debug(" %02x", buf[j]); 2007ac6653aSJeff Kirsher } 20183d7af64SGiuseppe CAVALLARO pr_debug("\n"); 2027ac6653aSJeff Kirsher } 2037ac6653aSJeff Kirsher 2047ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 2057ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 2067ac6653aSJeff Kirsher 2077ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 2087ac6653aSJeff Kirsher { 2097ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 2107ac6653aSJeff Kirsher } 2117ac6653aSJeff Kirsher 21232ceabcaSGiuseppe CAVALLARO /** 21332ceabcaSGiuseppe CAVALLARO * stmmac_hw_fix_mac_speed: callback for speed selection 21432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 21532ceabcaSGiuseppe CAVALLARO * Description: on some platforms (e.g. ST), some HW system configuraton 21632ceabcaSGiuseppe CAVALLARO * registers have to be set according to the link speed negotiated. 2177ac6653aSJeff Kirsher */ 2187ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 2197ac6653aSJeff Kirsher { 2207ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2217ac6653aSJeff Kirsher 2227ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 223ceb69499SGiuseppe CAVALLARO priv->plat->fix_mac_speed(priv->plat->bsp_priv, phydev->speed); 2247ac6653aSJeff Kirsher } 2257ac6653aSJeff Kirsher 22632ceabcaSGiuseppe CAVALLARO /** 22732ceabcaSGiuseppe CAVALLARO * stmmac_enable_eee_mode: Check and enter in LPI mode 22832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 22932ceabcaSGiuseppe CAVALLARO * Description: this function is to verify and enter in LPI mode for EEE. 23032ceabcaSGiuseppe CAVALLARO */ 231d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv) 232d765955dSGiuseppe CAVALLARO { 233d765955dSGiuseppe CAVALLARO /* Check and enter in LPI mode */ 234d765955dSGiuseppe CAVALLARO if ((priv->dirty_tx == priv->cur_tx) && 235d765955dSGiuseppe CAVALLARO (priv->tx_path_in_lpi_mode == false)) 236d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_mode(priv->ioaddr); 237d765955dSGiuseppe CAVALLARO } 238d765955dSGiuseppe CAVALLARO 23932ceabcaSGiuseppe CAVALLARO /** 24032ceabcaSGiuseppe CAVALLARO * stmmac_disable_eee_mode: disable/exit from EEE 24132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 24232ceabcaSGiuseppe CAVALLARO * Description: this function is to exit and disable EEE in case of 24332ceabcaSGiuseppe CAVALLARO * LPI state is true. This is called by the xmit. 24432ceabcaSGiuseppe CAVALLARO */ 245d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv) 246d765955dSGiuseppe CAVALLARO { 247d765955dSGiuseppe CAVALLARO priv->hw->mac->reset_eee_mode(priv->ioaddr); 248d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 249d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 250d765955dSGiuseppe CAVALLARO } 251d765955dSGiuseppe CAVALLARO 252d765955dSGiuseppe CAVALLARO /** 25332ceabcaSGiuseppe CAVALLARO * stmmac_eee_ctrl_timer: EEE TX SW timer. 254d765955dSGiuseppe CAVALLARO * @arg : data hook 255d765955dSGiuseppe CAVALLARO * Description: 25632ceabcaSGiuseppe CAVALLARO * if there is no data transfer and if we are not in LPI state, 257d765955dSGiuseppe CAVALLARO * then MAC Transmitter can be moved to LPI state. 258d765955dSGiuseppe CAVALLARO */ 259d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg) 260d765955dSGiuseppe CAVALLARO { 261d765955dSGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)arg; 262d765955dSGiuseppe CAVALLARO 263d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 264f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 265d765955dSGiuseppe CAVALLARO } 266d765955dSGiuseppe CAVALLARO 267d765955dSGiuseppe CAVALLARO /** 26832ceabcaSGiuseppe CAVALLARO * stmmac_eee_init: init EEE 26932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 270d765955dSGiuseppe CAVALLARO * Description: 271d765955dSGiuseppe CAVALLARO * If the EEE support has been enabled while configuring the driver, 272d765955dSGiuseppe CAVALLARO * if the GMAC actually supports the EEE (from the HW cap reg) and the 273d765955dSGiuseppe CAVALLARO * phy can also manage EEE, so enable the LPI state and start the timer 274d765955dSGiuseppe CAVALLARO * to verify if the tx path can enter in LPI state. 275d765955dSGiuseppe CAVALLARO */ 276d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv) 277d765955dSGiuseppe CAVALLARO { 278d765955dSGiuseppe CAVALLARO bool ret = false; 279d765955dSGiuseppe CAVALLARO 280f5351ef7SGiuseppe CAVALLARO /* Using PCS we cannot dial with the phy registers at this stage 281f5351ef7SGiuseppe CAVALLARO * so we do not support extra feature like EEE. 282f5351ef7SGiuseppe CAVALLARO */ 283f5351ef7SGiuseppe CAVALLARO if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) || 284f5351ef7SGiuseppe CAVALLARO (priv->pcs == STMMAC_PCS_RTBI)) 285f5351ef7SGiuseppe CAVALLARO goto out; 286f5351ef7SGiuseppe CAVALLARO 287d765955dSGiuseppe CAVALLARO /* MAC core supports the EEE feature. */ 288d765955dSGiuseppe CAVALLARO if (priv->dma_cap.eee) { 289d765955dSGiuseppe CAVALLARO /* Check if the PHY supports EEE */ 290d765955dSGiuseppe CAVALLARO if (phy_init_eee(priv->phydev, 1)) 291d765955dSGiuseppe CAVALLARO goto out; 292d765955dSGiuseppe CAVALLARO 293f5351ef7SGiuseppe CAVALLARO if (!priv->eee_active) { 294d765955dSGiuseppe CAVALLARO priv->eee_active = 1; 295d765955dSGiuseppe CAVALLARO init_timer(&priv->eee_ctrl_timer); 296d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; 297d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.data = (unsigned long)priv; 298f5351ef7SGiuseppe CAVALLARO priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer); 299d765955dSGiuseppe CAVALLARO add_timer(&priv->eee_ctrl_timer); 300d765955dSGiuseppe CAVALLARO 301d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_timer(priv->ioaddr, 302f5351ef7SGiuseppe CAVALLARO STMMAC_DEFAULT_LIT_LS, 303d765955dSGiuseppe CAVALLARO priv->tx_lpi_timer); 304f5351ef7SGiuseppe CAVALLARO } else 305f5351ef7SGiuseppe CAVALLARO /* Set HW EEE according to the speed */ 306f5351ef7SGiuseppe CAVALLARO priv->hw->mac->set_eee_pls(priv->ioaddr, 307f5351ef7SGiuseppe CAVALLARO priv->phydev->link); 308d765955dSGiuseppe CAVALLARO 309d765955dSGiuseppe CAVALLARO pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); 310d765955dSGiuseppe CAVALLARO 311d765955dSGiuseppe CAVALLARO ret = true; 312d765955dSGiuseppe CAVALLARO } 313d765955dSGiuseppe CAVALLARO out: 314d765955dSGiuseppe CAVALLARO return ret; 315d765955dSGiuseppe CAVALLARO } 316d765955dSGiuseppe CAVALLARO 31732ceabcaSGiuseppe CAVALLARO /* stmmac_get_tx_hwtstamp: get HW TX timestamps 31832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 319891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 320891434b1SRayagond Kokatanur * @skb : the socket buffer 321891434b1SRayagond Kokatanur * Description : 322891434b1SRayagond Kokatanur * This function will read timestamp from the descriptor & pass it to stack. 323891434b1SRayagond Kokatanur * and also perform some sanity checks. 324891434b1SRayagond Kokatanur */ 325891434b1SRayagond Kokatanur static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, 326ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 327891434b1SRayagond Kokatanur { 328891434b1SRayagond Kokatanur struct skb_shared_hwtstamps shhwtstamp; 329891434b1SRayagond Kokatanur u64 ns; 330891434b1SRayagond Kokatanur void *desc = NULL; 331891434b1SRayagond Kokatanur 332891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 333891434b1SRayagond Kokatanur return; 334891434b1SRayagond Kokatanur 335ceb69499SGiuseppe CAVALLARO /* exit if skb doesn't support hw tstamp */ 33675e4364fSdamuzi000 if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))) 337891434b1SRayagond Kokatanur return; 338891434b1SRayagond Kokatanur 339891434b1SRayagond Kokatanur if (priv->adv_ts) 340891434b1SRayagond Kokatanur desc = (priv->dma_etx + entry); 341891434b1SRayagond Kokatanur else 342891434b1SRayagond Kokatanur desc = (priv->dma_tx + entry); 343891434b1SRayagond Kokatanur 344891434b1SRayagond Kokatanur /* check tx tstamp status */ 345891434b1SRayagond Kokatanur if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc)) 346891434b1SRayagond Kokatanur return; 347891434b1SRayagond Kokatanur 348891434b1SRayagond Kokatanur /* get the valid tstamp */ 349891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 350891434b1SRayagond Kokatanur 351891434b1SRayagond Kokatanur memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 352891434b1SRayagond Kokatanur shhwtstamp.hwtstamp = ns_to_ktime(ns); 353891434b1SRayagond Kokatanur /* pass tstamp to stack */ 354891434b1SRayagond Kokatanur skb_tstamp_tx(skb, &shhwtstamp); 355891434b1SRayagond Kokatanur 356891434b1SRayagond Kokatanur return; 357891434b1SRayagond Kokatanur } 358891434b1SRayagond Kokatanur 35932ceabcaSGiuseppe CAVALLARO /* stmmac_get_rx_hwtstamp: get HW RX timestamps 36032ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 361891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 362891434b1SRayagond Kokatanur * @skb : the socket buffer 363891434b1SRayagond Kokatanur * Description : 364891434b1SRayagond Kokatanur * This function will read received packet's timestamp from the descriptor 365891434b1SRayagond Kokatanur * and pass it to stack. It also perform some sanity checks. 366891434b1SRayagond Kokatanur */ 367891434b1SRayagond Kokatanur static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, 368ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 369891434b1SRayagond Kokatanur { 370891434b1SRayagond Kokatanur struct skb_shared_hwtstamps *shhwtstamp = NULL; 371891434b1SRayagond Kokatanur u64 ns; 372891434b1SRayagond Kokatanur void *desc = NULL; 373891434b1SRayagond Kokatanur 374891434b1SRayagond Kokatanur if (!priv->hwts_rx_en) 375891434b1SRayagond Kokatanur return; 376891434b1SRayagond Kokatanur 377891434b1SRayagond Kokatanur if (priv->adv_ts) 378891434b1SRayagond Kokatanur desc = (priv->dma_erx + entry); 379891434b1SRayagond Kokatanur else 380891434b1SRayagond Kokatanur desc = (priv->dma_rx + entry); 381891434b1SRayagond Kokatanur 382ceb69499SGiuseppe CAVALLARO /* exit if rx tstamp is not valid */ 383891434b1SRayagond Kokatanur if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) 384891434b1SRayagond Kokatanur return; 385891434b1SRayagond Kokatanur 386891434b1SRayagond Kokatanur /* get valid tstamp */ 387891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 388891434b1SRayagond Kokatanur shhwtstamp = skb_hwtstamps(skb); 389891434b1SRayagond Kokatanur memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 390891434b1SRayagond Kokatanur shhwtstamp->hwtstamp = ns_to_ktime(ns); 391891434b1SRayagond Kokatanur } 392891434b1SRayagond Kokatanur 393891434b1SRayagond Kokatanur /** 394891434b1SRayagond Kokatanur * stmmac_hwtstamp_ioctl - control hardware timestamping. 395891434b1SRayagond Kokatanur * @dev: device pointer. 396891434b1SRayagond Kokatanur * @ifr: An IOCTL specefic structure, that can contain a pointer to 397891434b1SRayagond Kokatanur * a proprietary structure used to pass information to the driver. 398891434b1SRayagond Kokatanur * Description: 399891434b1SRayagond Kokatanur * This function configures the MAC to enable/disable both outgoing(TX) 400891434b1SRayagond Kokatanur * and incoming(RX) packets time stamping based on user input. 401891434b1SRayagond Kokatanur * Return Value: 402891434b1SRayagond Kokatanur * 0 on success and an appropriate -ve integer on failure. 403891434b1SRayagond Kokatanur */ 404891434b1SRayagond Kokatanur static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) 405891434b1SRayagond Kokatanur { 406891434b1SRayagond Kokatanur struct stmmac_priv *priv = netdev_priv(dev); 407891434b1SRayagond Kokatanur struct hwtstamp_config config; 408891434b1SRayagond Kokatanur struct timespec now; 409891434b1SRayagond Kokatanur u64 temp = 0; 410891434b1SRayagond Kokatanur u32 ptp_v2 = 0; 411891434b1SRayagond Kokatanur u32 tstamp_all = 0; 412891434b1SRayagond Kokatanur u32 ptp_over_ipv4_udp = 0; 413891434b1SRayagond Kokatanur u32 ptp_over_ipv6_udp = 0; 414891434b1SRayagond Kokatanur u32 ptp_over_ethernet = 0; 415891434b1SRayagond Kokatanur u32 snap_type_sel = 0; 416891434b1SRayagond Kokatanur u32 ts_master_en = 0; 417891434b1SRayagond Kokatanur u32 ts_event_en = 0; 418891434b1SRayagond Kokatanur u32 value = 0; 419891434b1SRayagond Kokatanur 420891434b1SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { 421891434b1SRayagond Kokatanur netdev_alert(priv->dev, "No support for HW time stamping\n"); 422891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 423891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 424891434b1SRayagond Kokatanur 425891434b1SRayagond Kokatanur return -EOPNOTSUPP; 426891434b1SRayagond Kokatanur } 427891434b1SRayagond Kokatanur 428891434b1SRayagond Kokatanur if (copy_from_user(&config, ifr->ifr_data, 429891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config))) 430891434b1SRayagond Kokatanur return -EFAULT; 431891434b1SRayagond Kokatanur 432891434b1SRayagond Kokatanur pr_debug("%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n", 433891434b1SRayagond Kokatanur __func__, config.flags, config.tx_type, config.rx_filter); 434891434b1SRayagond Kokatanur 435891434b1SRayagond Kokatanur /* reserved for future extensions */ 436891434b1SRayagond Kokatanur if (config.flags) 437891434b1SRayagond Kokatanur return -EINVAL; 438891434b1SRayagond Kokatanur 4395f3da328SBen Hutchings if (config.tx_type != HWTSTAMP_TX_OFF && 4405f3da328SBen Hutchings config.tx_type != HWTSTAMP_TX_ON) 441891434b1SRayagond Kokatanur return -ERANGE; 442891434b1SRayagond Kokatanur 443891434b1SRayagond Kokatanur if (priv->adv_ts) { 444891434b1SRayagond Kokatanur switch (config.rx_filter) { 445891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 446ceb69499SGiuseppe CAVALLARO /* time stamp no incoming packet at all */ 447891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 448891434b1SRayagond Kokatanur break; 449891434b1SRayagond Kokatanur 450891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 451ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, any kind of event packet */ 452891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 453891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 454891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 455891434b1SRayagond Kokatanur 456891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 457891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 458891434b1SRayagond Kokatanur break; 459891434b1SRayagond Kokatanur 460891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 461ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Sync packet */ 462891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; 463891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 464891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 465891434b1SRayagond Kokatanur 466891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 467891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 468891434b1SRayagond Kokatanur break; 469891434b1SRayagond Kokatanur 470891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 471ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Delay_req packet */ 472891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; 473891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 474891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 475891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 476891434b1SRayagond Kokatanur 477891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 478891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 479891434b1SRayagond Kokatanur break; 480891434b1SRayagond Kokatanur 481891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 482ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, any kind of event packet */ 483891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 484891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 485891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 486891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 487891434b1SRayagond Kokatanur 488891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 489891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 490891434b1SRayagond Kokatanur break; 491891434b1SRayagond Kokatanur 492891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 493ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Sync packet */ 494891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; 495891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 496891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 497891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 498891434b1SRayagond Kokatanur 499891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 500891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 501891434b1SRayagond Kokatanur break; 502891434b1SRayagond Kokatanur 503891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 504ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Delay_req packet */ 505891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; 506891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 507891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 508891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 509891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 510891434b1SRayagond Kokatanur 511891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 512891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 513891434b1SRayagond Kokatanur break; 514891434b1SRayagond Kokatanur 515891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_EVENT: 516ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1 any layer, any kind of event packet */ 517891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 518891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 519891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 520891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 521891434b1SRayagond Kokatanur 522891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 523891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 524891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 525891434b1SRayagond Kokatanur break; 526891434b1SRayagond Kokatanur 527891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_SYNC: 528ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Sync packet */ 529891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 530891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 531891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 532891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 533891434b1SRayagond Kokatanur 534891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 535891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 536891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 537891434b1SRayagond Kokatanur break; 538891434b1SRayagond Kokatanur 539891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 540ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Delay_req packet */ 541891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 542891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 543891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 544891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 545891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 546891434b1SRayagond Kokatanur 547891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 548891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 549891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 550891434b1SRayagond Kokatanur break; 551891434b1SRayagond Kokatanur 552891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_ALL: 553ceb69499SGiuseppe CAVALLARO /* time stamp any incoming packet */ 554891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_ALL; 555891434b1SRayagond Kokatanur tstamp_all = PTP_TCR_TSENALL; 556891434b1SRayagond Kokatanur break; 557891434b1SRayagond Kokatanur 558891434b1SRayagond Kokatanur default: 559891434b1SRayagond Kokatanur return -ERANGE; 560891434b1SRayagond Kokatanur } 561891434b1SRayagond Kokatanur } else { 562891434b1SRayagond Kokatanur switch (config.rx_filter) { 563891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 564891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 565891434b1SRayagond Kokatanur break; 566891434b1SRayagond Kokatanur default: 567891434b1SRayagond Kokatanur /* PTP v1, UDP, any kind of event packet */ 568891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 569891434b1SRayagond Kokatanur break; 570891434b1SRayagond Kokatanur } 571891434b1SRayagond Kokatanur } 572891434b1SRayagond Kokatanur priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1); 5735f3da328SBen Hutchings priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; 574891434b1SRayagond Kokatanur 575891434b1SRayagond Kokatanur if (!priv->hwts_tx_en && !priv->hwts_rx_en) 576891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0); 577891434b1SRayagond Kokatanur else { 578891434b1SRayagond Kokatanur value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR | 579891434b1SRayagond Kokatanur tstamp_all | ptp_v2 | ptp_over_ethernet | 580891434b1SRayagond Kokatanur ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en | 581891434b1SRayagond Kokatanur ts_master_en | snap_type_sel); 582891434b1SRayagond Kokatanur 583891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value); 584891434b1SRayagond Kokatanur 585891434b1SRayagond Kokatanur /* program Sub Second Increment reg */ 586891434b1SRayagond Kokatanur priv->hw->ptp->config_sub_second_increment(priv->ioaddr); 587891434b1SRayagond Kokatanur 588891434b1SRayagond Kokatanur /* calculate default added value: 589891434b1SRayagond Kokatanur * formula is : 590891434b1SRayagond Kokatanur * addend = (2^32)/freq_div_ratio; 591891434b1SRayagond Kokatanur * where, freq_div_ratio = STMMAC_SYSCLOCK/50MHz 592891434b1SRayagond Kokatanur * hence, addend = ((2^32) * 50MHz)/STMMAC_SYSCLOCK; 593891434b1SRayagond Kokatanur * NOTE: STMMAC_SYSCLOCK should be >= 50MHz to 594891434b1SRayagond Kokatanur * achive 20ns accuracy. 595891434b1SRayagond Kokatanur * 596891434b1SRayagond Kokatanur * 2^x * y == (y << x), hence 597891434b1SRayagond Kokatanur * 2^32 * 50000000 ==> (50000000 << 32) 598891434b1SRayagond Kokatanur */ 599891434b1SRayagond Kokatanur temp = (u64) (50000000ULL << 32); 600891434b1SRayagond Kokatanur priv->default_addend = div_u64(temp, STMMAC_SYSCLOCK); 601891434b1SRayagond Kokatanur priv->hw->ptp->config_addend(priv->ioaddr, 602891434b1SRayagond Kokatanur priv->default_addend); 603891434b1SRayagond Kokatanur 604891434b1SRayagond Kokatanur /* initialize system time */ 605891434b1SRayagond Kokatanur getnstimeofday(&now); 606891434b1SRayagond Kokatanur priv->hw->ptp->init_systime(priv->ioaddr, now.tv_sec, 607891434b1SRayagond Kokatanur now.tv_nsec); 608891434b1SRayagond Kokatanur } 609891434b1SRayagond Kokatanur 610891434b1SRayagond Kokatanur return copy_to_user(ifr->ifr_data, &config, 611891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config)) ? -EFAULT : 0; 612891434b1SRayagond Kokatanur } 613891434b1SRayagond Kokatanur 61432ceabcaSGiuseppe CAVALLARO /** 61532ceabcaSGiuseppe CAVALLARO * stmmac_init_ptp: init PTP 61632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 61732ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PTPv1 or v2. 61832ceabcaSGiuseppe CAVALLARO * This is done by looking at the HW cap. register. 61932ceabcaSGiuseppe CAVALLARO * Also it registers the ptp driver. 62032ceabcaSGiuseppe CAVALLARO */ 62192ba6888SRayagond Kokatanur static int stmmac_init_ptp(struct stmmac_priv *priv) 622891434b1SRayagond Kokatanur { 62392ba6888SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) 62492ba6888SRayagond Kokatanur return -EOPNOTSUPP; 62592ba6888SRayagond Kokatanur 626891434b1SRayagond Kokatanur priv->adv_ts = 0; 6277cd01399SVince Bridgers if (priv->dma_cap.atime_stamp && priv->extend_desc) 628891434b1SRayagond Kokatanur priv->adv_ts = 1; 6297cd01399SVince Bridgers 6307cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->dma_cap.time_stamp) 6317cd01399SVince Bridgers pr_debug("IEEE 1588-2002 Time Stamp supported\n"); 6327cd01399SVince Bridgers 6337cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->adv_ts) 6347cd01399SVince Bridgers pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); 635891434b1SRayagond Kokatanur 636891434b1SRayagond Kokatanur priv->hw->ptp = &stmmac_ptp; 637891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 638891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 63992ba6888SRayagond Kokatanur 64092ba6888SRayagond Kokatanur return stmmac_ptp_register(priv); 64192ba6888SRayagond Kokatanur } 64292ba6888SRayagond Kokatanur 64392ba6888SRayagond Kokatanur static void stmmac_release_ptp(struct stmmac_priv *priv) 64492ba6888SRayagond Kokatanur { 64592ba6888SRayagond Kokatanur stmmac_ptp_unregister(priv); 646891434b1SRayagond Kokatanur } 647891434b1SRayagond Kokatanur 6487ac6653aSJeff Kirsher /** 6497ac6653aSJeff Kirsher * stmmac_adjust_link 6507ac6653aSJeff Kirsher * @dev: net device structure 6517ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 6527ac6653aSJeff Kirsher */ 6537ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 6547ac6653aSJeff Kirsher { 6557ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 6567ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 6577ac6653aSJeff Kirsher unsigned long flags; 6587ac6653aSJeff Kirsher int new_state = 0; 6597ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 6607ac6653aSJeff Kirsher 6617ac6653aSJeff Kirsher if (phydev == NULL) 6627ac6653aSJeff Kirsher return; 6637ac6653aSJeff Kirsher 6647ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 665d765955dSGiuseppe CAVALLARO 6667ac6653aSJeff Kirsher if (phydev->link) { 6677ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 6687ac6653aSJeff Kirsher 6697ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 6707ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 6717ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 6727ac6653aSJeff Kirsher new_state = 1; 6737ac6653aSJeff Kirsher if (!(phydev->duplex)) 6747ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 6757ac6653aSJeff Kirsher else 6767ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 6777ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 6787ac6653aSJeff Kirsher } 6797ac6653aSJeff Kirsher /* Flow Control operation */ 6807ac6653aSJeff Kirsher if (phydev->pause) 6817ac6653aSJeff Kirsher priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, 6827ac6653aSJeff Kirsher fc, pause_time); 6837ac6653aSJeff Kirsher 6847ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 6857ac6653aSJeff Kirsher new_state = 1; 6867ac6653aSJeff Kirsher switch (phydev->speed) { 6877ac6653aSJeff Kirsher case 1000: 6887ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 6897ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 6907ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 6917ac6653aSJeff Kirsher break; 6927ac6653aSJeff Kirsher case 100: 6937ac6653aSJeff Kirsher case 10: 6947ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 6957ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 6967ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 6977ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 6987ac6653aSJeff Kirsher } else { 6997ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 7007ac6653aSJeff Kirsher } 7017ac6653aSJeff Kirsher } else { 7027ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7037ac6653aSJeff Kirsher } 7047ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7057ac6653aSJeff Kirsher break; 7067ac6653aSJeff Kirsher default: 7077ac6653aSJeff Kirsher if (netif_msg_link(priv)) 708ceb69499SGiuseppe CAVALLARO pr_warn("%s: Speed (%d) not 10/100\n", 709ceb69499SGiuseppe CAVALLARO dev->name, phydev->speed); 7107ac6653aSJeff Kirsher break; 7117ac6653aSJeff Kirsher } 7127ac6653aSJeff Kirsher 7137ac6653aSJeff Kirsher priv->speed = phydev->speed; 7147ac6653aSJeff Kirsher } 7157ac6653aSJeff Kirsher 7167ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 7177ac6653aSJeff Kirsher 7187ac6653aSJeff Kirsher if (!priv->oldlink) { 7197ac6653aSJeff Kirsher new_state = 1; 7207ac6653aSJeff Kirsher priv->oldlink = 1; 7217ac6653aSJeff Kirsher } 7227ac6653aSJeff Kirsher } else if (priv->oldlink) { 7237ac6653aSJeff Kirsher new_state = 1; 7247ac6653aSJeff Kirsher priv->oldlink = 0; 7257ac6653aSJeff Kirsher priv->speed = 0; 7267ac6653aSJeff Kirsher priv->oldduplex = -1; 7277ac6653aSJeff Kirsher } 7287ac6653aSJeff Kirsher 7297ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 7307ac6653aSJeff Kirsher phy_print_status(phydev); 7317ac6653aSJeff Kirsher 732f5351ef7SGiuseppe CAVALLARO /* At this stage, it could be needed to setup the EEE or adjust some 733f5351ef7SGiuseppe CAVALLARO * MAC related HW registers. 734f5351ef7SGiuseppe CAVALLARO */ 735f5351ef7SGiuseppe CAVALLARO priv->eee_enabled = stmmac_eee_init(priv); 736d765955dSGiuseppe CAVALLARO 7377ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 7387ac6653aSJeff Kirsher } 7397ac6653aSJeff Kirsher 74032ceabcaSGiuseppe CAVALLARO /** 74132ceabcaSGiuseppe CAVALLARO * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported 74232ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 74332ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PCS. 74432ceabcaSGiuseppe CAVALLARO * Physical Coding Sublayer (PCS) interface that can be used when the MAC is 74532ceabcaSGiuseppe CAVALLARO * configured for the TBI, RTBI, or SGMII PHY interface. 74632ceabcaSGiuseppe CAVALLARO */ 747e58bb43fSGiuseppe CAVALLARO static void stmmac_check_pcs_mode(struct stmmac_priv *priv) 748e58bb43fSGiuseppe CAVALLARO { 749e58bb43fSGiuseppe CAVALLARO int interface = priv->plat->interface; 750e58bb43fSGiuseppe CAVALLARO 751e58bb43fSGiuseppe CAVALLARO if (priv->dma_cap.pcs) { 7520d909dcdSByungho An if ((interface == PHY_INTERFACE_MODE_RGMII) || 7530d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_ID) || 7540d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_RXID) || 7550d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_TXID)) { 756e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS RGMII support enable\n"); 757e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_RGMII; 7580d909dcdSByungho An } else if (interface == PHY_INTERFACE_MODE_SGMII) { 759e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS SGMII support enable\n"); 760e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_SGMII; 761e58bb43fSGiuseppe CAVALLARO } 762e58bb43fSGiuseppe CAVALLARO } 763e58bb43fSGiuseppe CAVALLARO } 764e58bb43fSGiuseppe CAVALLARO 7657ac6653aSJeff Kirsher /** 7667ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 7677ac6653aSJeff Kirsher * @dev: net device structure 7687ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 7697ac6653aSJeff Kirsher * to the mac driver. 7707ac6653aSJeff Kirsher * Return value: 7717ac6653aSJeff Kirsher * 0 on success 7727ac6653aSJeff Kirsher */ 7737ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 7747ac6653aSJeff Kirsher { 7757ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 7767ac6653aSJeff Kirsher struct phy_device *phydev; 777d765955dSGiuseppe CAVALLARO char phy_id_fmt[MII_BUS_ID_SIZE + 3]; 7787ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 77979ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 7809cbadf09SSrinivas Kandagatla int max_speed = priv->plat->max_speed; 7817ac6653aSJeff Kirsher priv->oldlink = 0; 7827ac6653aSJeff Kirsher priv->speed = 0; 7837ac6653aSJeff Kirsher priv->oldduplex = -1; 7847ac6653aSJeff Kirsher 785f142af2eSSrinivas Kandagatla if (priv->plat->phy_bus_name) 786f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", 787f142af2eSSrinivas Kandagatla priv->plat->phy_bus_name, priv->plat->bus_id); 788f142af2eSSrinivas Kandagatla else 789f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", 790f142af2eSSrinivas Kandagatla priv->plat->bus_id); 791f142af2eSSrinivas Kandagatla 792d765955dSGiuseppe CAVALLARO snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 7937ac6653aSJeff Kirsher priv->plat->phy_addr); 794d765955dSGiuseppe CAVALLARO pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 7957ac6653aSJeff Kirsher 796f9a8f83bSFlorian Fainelli phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface); 7977ac6653aSJeff Kirsher 7987ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 7997ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 8007ac6653aSJeff Kirsher return PTR_ERR(phydev); 8017ac6653aSJeff Kirsher } 8027ac6653aSJeff Kirsher 80379ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 804c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 8059cbadf09SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII) || 8069cbadf09SSrinivas Kandagatla (max_speed < 1000 && max_speed > 0)) 807c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 808c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 80979ee1dc3SSrinivas Kandagatla 8107ac6653aSJeff Kirsher /* 8117ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 8127ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 8137ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 8147ac6653aSJeff Kirsher * device as well. 8157ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 8167ac6653aSJeff Kirsher */ 8177ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 8187ac6653aSJeff Kirsher phy_disconnect(phydev); 8197ac6653aSJeff Kirsher return -ENODEV; 8207ac6653aSJeff Kirsher } 8217ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 8227ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 8237ac6653aSJeff Kirsher 8247ac6653aSJeff Kirsher priv->phydev = phydev; 8257ac6653aSJeff Kirsher 8267ac6653aSJeff Kirsher return 0; 8277ac6653aSJeff Kirsher } 8287ac6653aSJeff Kirsher 8297ac6653aSJeff Kirsher /** 83032ceabcaSGiuseppe CAVALLARO * stmmac_display_ring: display ring 83132ceabcaSGiuseppe CAVALLARO * @head: pointer to the head of the ring passed. 8327ac6653aSJeff Kirsher * @size: size of the ring. 83332ceabcaSGiuseppe CAVALLARO * @extend_desc: to verify if extended descriptors are used. 834c24602efSGiuseppe CAVALLARO * Description: display the control/status and buffer descriptors. 8357ac6653aSJeff Kirsher */ 836c24602efSGiuseppe CAVALLARO static void stmmac_display_ring(void *head, int size, int extend_desc) 8377ac6653aSJeff Kirsher { 8387ac6653aSJeff Kirsher int i; 839c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 840c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 841c24602efSGiuseppe CAVALLARO 8427ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 843c24602efSGiuseppe CAVALLARO u64 x; 844c24602efSGiuseppe CAVALLARO if (extend_desc) { 845c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 846c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 847c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 848c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 849c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 850c24602efSGiuseppe CAVALLARO ep++; 851c24602efSGiuseppe CAVALLARO } else { 852c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 853c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", 854c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(p), 855c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 856c24602efSGiuseppe CAVALLARO p->des2, p->des3); 857c24602efSGiuseppe CAVALLARO p++; 858c24602efSGiuseppe CAVALLARO } 8597ac6653aSJeff Kirsher pr_info("\n"); 8607ac6653aSJeff Kirsher } 8617ac6653aSJeff Kirsher } 8627ac6653aSJeff Kirsher 863c24602efSGiuseppe CAVALLARO static void stmmac_display_rings(struct stmmac_priv *priv) 864c24602efSGiuseppe CAVALLARO { 865c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 866c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 867c24602efSGiuseppe CAVALLARO 868c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 869c24602efSGiuseppe CAVALLARO pr_info("Extended RX descriptor ring:\n"); 870c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 871c24602efSGiuseppe CAVALLARO pr_info("Extended TX descriptor ring:\n"); 872c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 873c24602efSGiuseppe CAVALLARO } else { 874c24602efSGiuseppe CAVALLARO pr_info("RX descriptor ring:\n"); 875c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 876c24602efSGiuseppe CAVALLARO pr_info("TX descriptor ring:\n"); 877c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 878c24602efSGiuseppe CAVALLARO } 879c24602efSGiuseppe CAVALLARO } 880c24602efSGiuseppe CAVALLARO 881286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 882286a8372SGiuseppe CAVALLARO { 883286a8372SGiuseppe CAVALLARO int ret = bufsize; 884286a8372SGiuseppe CAVALLARO 885286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 886286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 887286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 888286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 889286a8372SGiuseppe CAVALLARO else if (mtu >= DMA_BUFFER_SIZE) 890286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 891286a8372SGiuseppe CAVALLARO else 892286a8372SGiuseppe CAVALLARO ret = DMA_BUFFER_SIZE; 893286a8372SGiuseppe CAVALLARO 894286a8372SGiuseppe CAVALLARO return ret; 895286a8372SGiuseppe CAVALLARO } 896286a8372SGiuseppe CAVALLARO 89732ceabcaSGiuseppe CAVALLARO /** 89832ceabcaSGiuseppe CAVALLARO * stmmac_clear_descriptors: clear descriptors 89932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 90032ceabcaSGiuseppe CAVALLARO * Description: this function is called to clear the tx and rx descriptors 90132ceabcaSGiuseppe CAVALLARO * in case of both basic and extended descriptors are used. 90232ceabcaSGiuseppe CAVALLARO */ 903c24602efSGiuseppe CAVALLARO static void stmmac_clear_descriptors(struct stmmac_priv *priv) 904c24602efSGiuseppe CAVALLARO { 905c24602efSGiuseppe CAVALLARO int i; 906c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 907c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 908c24602efSGiuseppe CAVALLARO 909c24602efSGiuseppe CAVALLARO /* Clear the Rx/Tx descriptors */ 910c24602efSGiuseppe CAVALLARO for (i = 0; i < rxsize; i++) 911c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 912c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_erx[i].basic, 913c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 914c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 915c24602efSGiuseppe CAVALLARO else 916c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_rx[i], 917c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 918c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 919c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 920c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 921c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 922c24602efSGiuseppe CAVALLARO priv->mode, 923c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 924c24602efSGiuseppe CAVALLARO else 925c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 926c24602efSGiuseppe CAVALLARO priv->mode, 927c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 928c24602efSGiuseppe CAVALLARO } 929c24602efSGiuseppe CAVALLARO 930c24602efSGiuseppe CAVALLARO static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, 931c24602efSGiuseppe CAVALLARO int i) 932c24602efSGiuseppe CAVALLARO { 933c24602efSGiuseppe CAVALLARO struct sk_buff *skb; 934c24602efSGiuseppe CAVALLARO 935c24602efSGiuseppe CAVALLARO skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, 936c24602efSGiuseppe CAVALLARO GFP_KERNEL); 93756329137SBartlomiej Zolnierkiewicz if (!skb) { 938c24602efSGiuseppe CAVALLARO pr_err("%s: Rx init fails; skb is NULL\n", __func__); 93956329137SBartlomiej Zolnierkiewicz return -ENOMEM; 940c24602efSGiuseppe CAVALLARO } 941c24602efSGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 942c24602efSGiuseppe CAVALLARO priv->rx_skbuff[i] = skb; 943c24602efSGiuseppe CAVALLARO priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 944c24602efSGiuseppe CAVALLARO priv->dma_buf_sz, 945c24602efSGiuseppe CAVALLARO DMA_FROM_DEVICE); 94656329137SBartlomiej Zolnierkiewicz if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) { 94756329137SBartlomiej Zolnierkiewicz pr_err("%s: DMA mapping error\n", __func__); 94856329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(skb); 94956329137SBartlomiej Zolnierkiewicz return -EINVAL; 95056329137SBartlomiej Zolnierkiewicz } 951c24602efSGiuseppe CAVALLARO 952c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[i]; 953c24602efSGiuseppe CAVALLARO 954c24602efSGiuseppe CAVALLARO if ((priv->mode == STMMAC_RING_MODE) && 955c24602efSGiuseppe CAVALLARO (priv->dma_buf_sz == BUF_SIZE_16KiB)) 956c24602efSGiuseppe CAVALLARO priv->hw->ring->init_desc3(p); 957c24602efSGiuseppe CAVALLARO 958c24602efSGiuseppe CAVALLARO return 0; 959c24602efSGiuseppe CAVALLARO } 960c24602efSGiuseppe CAVALLARO 96156329137SBartlomiej Zolnierkiewicz static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) 96256329137SBartlomiej Zolnierkiewicz { 96356329137SBartlomiej Zolnierkiewicz if (priv->rx_skbuff[i]) { 96456329137SBartlomiej Zolnierkiewicz dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 96556329137SBartlomiej Zolnierkiewicz priv->dma_buf_sz, DMA_FROM_DEVICE); 96656329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(priv->rx_skbuff[i]); 96756329137SBartlomiej Zolnierkiewicz } 96856329137SBartlomiej Zolnierkiewicz priv->rx_skbuff[i] = NULL; 96956329137SBartlomiej Zolnierkiewicz } 97056329137SBartlomiej Zolnierkiewicz 9717ac6653aSJeff Kirsher /** 9727ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 9737ac6653aSJeff Kirsher * @dev: net device structure 9747ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 975286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 976286a8372SGiuseppe CAVALLARO * modes. 9777ac6653aSJeff Kirsher */ 97856329137SBartlomiej Zolnierkiewicz static int init_dma_desc_rings(struct net_device *dev) 9797ac6653aSJeff Kirsher { 9807ac6653aSJeff Kirsher int i; 9817ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 9827ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 9837ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 9844a7d666aSGiuseppe CAVALLARO unsigned int bfsize = 0; 98556329137SBartlomiej Zolnierkiewicz int ret = -ENOMEM; 9867ac6653aSJeff Kirsher 987286a8372SGiuseppe CAVALLARO /* Set the max buffer size according to the DESC mode 988ceb69499SGiuseppe CAVALLARO * and the MTU. Note that RING mode allows 16KiB bsize. 989ceb69499SGiuseppe CAVALLARO */ 9904a7d666aSGiuseppe CAVALLARO if (priv->mode == STMMAC_RING_MODE) 991286a8372SGiuseppe CAVALLARO bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu); 992286a8372SGiuseppe CAVALLARO 9934a7d666aSGiuseppe CAVALLARO if (bfsize < BUF_SIZE_16KiB) 994286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 9957ac6653aSJeff Kirsher 9962618abb7SVince Bridgers priv->dma_buf_sz = bfsize; 9972618abb7SVince Bridgers 99883d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 99983d7af64SGiuseppe CAVALLARO pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__, 10007ac6653aSJeff Kirsher txsize, rxsize, bfsize); 10017ac6653aSJeff Kirsher 100283d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) { 1003c24602efSGiuseppe CAVALLARO pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__, 1004c24602efSGiuseppe CAVALLARO (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy); 10057ac6653aSJeff Kirsher 10067ac6653aSJeff Kirsher /* RX INITIALIZATION */ 100783d7af64SGiuseppe CAVALLARO pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n"); 100883d7af64SGiuseppe CAVALLARO } 10097ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 1010c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1011c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1012c24602efSGiuseppe CAVALLARO p = &((priv->dma_erx + i)->basic); 1013c24602efSGiuseppe CAVALLARO else 1014c24602efSGiuseppe CAVALLARO p = priv->dma_rx + i; 10157ac6653aSJeff Kirsher 101656329137SBartlomiej Zolnierkiewicz ret = stmmac_init_rx_buffers(priv, p, i); 101756329137SBartlomiej Zolnierkiewicz if (ret) 101856329137SBartlomiej Zolnierkiewicz goto err_init_rx_buffers; 1019286a8372SGiuseppe CAVALLARO 102083d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 102183d7af64SGiuseppe CAVALLARO pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 102283d7af64SGiuseppe CAVALLARO priv->rx_skbuff[i]->data, 102383d7af64SGiuseppe CAVALLARO (unsigned int)priv->rx_skbuff_dma[i]); 10247ac6653aSJeff Kirsher } 10257ac6653aSJeff Kirsher priv->cur_rx = 0; 10267ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 10277ac6653aSJeff Kirsher buf_sz = bfsize; 10287ac6653aSJeff Kirsher 1029c24602efSGiuseppe CAVALLARO /* Setup the chained descriptor addresses */ 1030c24602efSGiuseppe CAVALLARO if (priv->mode == STMMAC_CHAIN_MODE) { 1031c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 1032c24602efSGiuseppe CAVALLARO priv->hw->chain->init(priv->dma_erx, priv->dma_rx_phy, 1033c24602efSGiuseppe CAVALLARO rxsize, 1); 1034c24602efSGiuseppe CAVALLARO priv->hw->chain->init(priv->dma_etx, priv->dma_tx_phy, 1035c24602efSGiuseppe CAVALLARO txsize, 1); 1036c24602efSGiuseppe CAVALLARO } else { 1037c24602efSGiuseppe CAVALLARO priv->hw->chain->init(priv->dma_rx, priv->dma_rx_phy, 1038c24602efSGiuseppe CAVALLARO rxsize, 0); 1039c24602efSGiuseppe CAVALLARO priv->hw->chain->init(priv->dma_tx, priv->dma_tx_phy, 1040c24602efSGiuseppe CAVALLARO txsize, 0); 1041c24602efSGiuseppe CAVALLARO } 10427ac6653aSJeff Kirsher } 1043286a8372SGiuseppe CAVALLARO 1044c24602efSGiuseppe CAVALLARO /* TX INITIALIZATION */ 1045c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) { 1046c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1047c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1048c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1049c24602efSGiuseppe CAVALLARO else 1050c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1051c24602efSGiuseppe CAVALLARO p->des2 = 0; 1052cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[i] = 0; 1053c24602efSGiuseppe CAVALLARO priv->tx_skbuff[i] = NULL; 10544a7d666aSGiuseppe CAVALLARO } 1055c24602efSGiuseppe CAVALLARO 10567ac6653aSJeff Kirsher priv->dirty_tx = 0; 10577ac6653aSJeff Kirsher priv->cur_tx = 0; 10587ac6653aSJeff Kirsher 1059c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 10607ac6653aSJeff Kirsher 1061c24602efSGiuseppe CAVALLARO if (netif_msg_hw(priv)) 1062c24602efSGiuseppe CAVALLARO stmmac_display_rings(priv); 106356329137SBartlomiej Zolnierkiewicz 106456329137SBartlomiej Zolnierkiewicz return 0; 106556329137SBartlomiej Zolnierkiewicz err_init_rx_buffers: 106656329137SBartlomiej Zolnierkiewicz while (--i >= 0) 106756329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 106856329137SBartlomiej Zolnierkiewicz return ret; 10697ac6653aSJeff Kirsher } 10707ac6653aSJeff Kirsher 10717ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 10727ac6653aSJeff Kirsher { 10737ac6653aSJeff Kirsher int i; 10747ac6653aSJeff Kirsher 107556329137SBartlomiej Zolnierkiewicz for (i = 0; i < priv->dma_rx_size; i++) 107656329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 10777ac6653aSJeff Kirsher } 10787ac6653aSJeff Kirsher 10797ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 10807ac6653aSJeff Kirsher { 10817ac6653aSJeff Kirsher int i; 10827ac6653aSJeff Kirsher 10837ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 1084c24602efSGiuseppe CAVALLARO struct dma_desc *p; 108575e4364fSdamuzi000 1086c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1087c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1088c24602efSGiuseppe CAVALLARO else 1089c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1090c24602efSGiuseppe CAVALLARO 109175e4364fSdamuzi000 if (priv->tx_skbuff_dma[i]) { 1092cf32deecSRayagond Kokatanur dma_unmap_single(priv->device, 1093cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[i], 10947ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 10957ac6653aSJeff Kirsher DMA_TO_DEVICE); 109675e4364fSdamuzi000 priv->tx_skbuff_dma[i] = 0; 109775e4364fSdamuzi000 } 109875e4364fSdamuzi000 109975e4364fSdamuzi000 if (priv->tx_skbuff[i] != NULL) { 11007ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 11017ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 11027ac6653aSJeff Kirsher } 11037ac6653aSJeff Kirsher } 11047ac6653aSJeff Kirsher } 11057ac6653aSJeff Kirsher 110609f8d696SSrinivas Kandagatla static int alloc_dma_desc_resources(struct stmmac_priv *priv) 110709f8d696SSrinivas Kandagatla { 110809f8d696SSrinivas Kandagatla unsigned int txsize = priv->dma_tx_size; 110909f8d696SSrinivas Kandagatla unsigned int rxsize = priv->dma_rx_size; 111009f8d696SSrinivas Kandagatla int ret = -ENOMEM; 111109f8d696SSrinivas Kandagatla 111209f8d696SSrinivas Kandagatla priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t), 111309f8d696SSrinivas Kandagatla GFP_KERNEL); 111409f8d696SSrinivas Kandagatla if (!priv->rx_skbuff_dma) 111509f8d696SSrinivas Kandagatla return -ENOMEM; 111609f8d696SSrinivas Kandagatla 111709f8d696SSrinivas Kandagatla priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), 111809f8d696SSrinivas Kandagatla GFP_KERNEL); 111909f8d696SSrinivas Kandagatla if (!priv->rx_skbuff) 112009f8d696SSrinivas Kandagatla goto err_rx_skbuff; 112109f8d696SSrinivas Kandagatla 112209f8d696SSrinivas Kandagatla priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t), 112309f8d696SSrinivas Kandagatla GFP_KERNEL); 112409f8d696SSrinivas Kandagatla if (!priv->tx_skbuff_dma) 112509f8d696SSrinivas Kandagatla goto err_tx_skbuff_dma; 112609f8d696SSrinivas Kandagatla 112709f8d696SSrinivas Kandagatla priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), 112809f8d696SSrinivas Kandagatla GFP_KERNEL); 112909f8d696SSrinivas Kandagatla if (!priv->tx_skbuff) 113009f8d696SSrinivas Kandagatla goto err_tx_skbuff; 113109f8d696SSrinivas Kandagatla 113209f8d696SSrinivas Kandagatla if (priv->extend_desc) { 113309f8d696SSrinivas Kandagatla priv->dma_erx = dma_alloc_coherent(priv->device, rxsize * 113409f8d696SSrinivas Kandagatla sizeof(struct 113509f8d696SSrinivas Kandagatla dma_extended_desc), 113609f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 113709f8d696SSrinivas Kandagatla GFP_KERNEL); 113809f8d696SSrinivas Kandagatla if (!priv->dma_erx) 113909f8d696SSrinivas Kandagatla goto err_dma; 114009f8d696SSrinivas Kandagatla 114109f8d696SSrinivas Kandagatla priv->dma_etx = dma_alloc_coherent(priv->device, txsize * 114209f8d696SSrinivas Kandagatla sizeof(struct 114309f8d696SSrinivas Kandagatla dma_extended_desc), 114409f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 114509f8d696SSrinivas Kandagatla GFP_KERNEL); 114609f8d696SSrinivas Kandagatla if (!priv->dma_etx) { 114709f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 114809f8d696SSrinivas Kandagatla sizeof(struct dma_extended_desc), 114909f8d696SSrinivas Kandagatla priv->dma_erx, priv->dma_rx_phy); 115009f8d696SSrinivas Kandagatla goto err_dma; 115109f8d696SSrinivas Kandagatla } 115209f8d696SSrinivas Kandagatla } else { 115309f8d696SSrinivas Kandagatla priv->dma_rx = dma_alloc_coherent(priv->device, rxsize * 115409f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 115509f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 115609f8d696SSrinivas Kandagatla GFP_KERNEL); 115709f8d696SSrinivas Kandagatla if (!priv->dma_rx) 115809f8d696SSrinivas Kandagatla goto err_dma; 115909f8d696SSrinivas Kandagatla 116009f8d696SSrinivas Kandagatla priv->dma_tx = dma_alloc_coherent(priv->device, txsize * 116109f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 116209f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 116309f8d696SSrinivas Kandagatla GFP_KERNEL); 116409f8d696SSrinivas Kandagatla if (!priv->dma_tx) { 116509f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 116609f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 116709f8d696SSrinivas Kandagatla priv->dma_rx, priv->dma_rx_phy); 116809f8d696SSrinivas Kandagatla goto err_dma; 116909f8d696SSrinivas Kandagatla } 117009f8d696SSrinivas Kandagatla } 117109f8d696SSrinivas Kandagatla 117209f8d696SSrinivas Kandagatla return 0; 117309f8d696SSrinivas Kandagatla 117409f8d696SSrinivas Kandagatla err_dma: 117509f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff); 117609f8d696SSrinivas Kandagatla err_tx_skbuff: 117709f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff_dma); 117809f8d696SSrinivas Kandagatla err_tx_skbuff_dma: 117909f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff); 118009f8d696SSrinivas Kandagatla err_rx_skbuff: 118109f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff_dma); 118209f8d696SSrinivas Kandagatla return ret; 118309f8d696SSrinivas Kandagatla } 118409f8d696SSrinivas Kandagatla 11857ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 11867ac6653aSJeff Kirsher { 11877ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 11887ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 11897ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 11907ac6653aSJeff Kirsher 1191ceb69499SGiuseppe CAVALLARO /* Free DMA regions of consistent memory previously allocated */ 1192c24602efSGiuseppe CAVALLARO if (!priv->extend_desc) { 11937ac6653aSJeff Kirsher dma_free_coherent(priv->device, 11947ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 11957ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 11967ac6653aSJeff Kirsher dma_free_coherent(priv->device, 11977ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 11987ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 1199c24602efSGiuseppe CAVALLARO } else { 1200c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_tx_size * 1201c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1202c24602efSGiuseppe CAVALLARO priv->dma_etx, priv->dma_tx_phy); 1203c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_rx_size * 1204c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1205c24602efSGiuseppe CAVALLARO priv->dma_erx, priv->dma_rx_phy); 1206c24602efSGiuseppe CAVALLARO } 12077ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 12087ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 1209cf32deecSRayagond Kokatanur kfree(priv->tx_skbuff_dma); 12107ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 12117ac6653aSJeff Kirsher } 12127ac6653aSJeff Kirsher 12137ac6653aSJeff Kirsher /** 12147ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 121532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12167ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 12177ac6653aSJeff Kirsher * or Store-And-Forward capability. 12187ac6653aSJeff Kirsher */ 12197ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 12207ac6653aSJeff Kirsher { 1221e2a240c7SSonic Zhang if (priv->plat->force_thresh_dma_mode) 1222e2a240c7SSonic Zhang priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); 1223e2a240c7SSonic Zhang else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { 12247ac6653aSJeff Kirsher /* 12257ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 12267ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 12277ac6653aSJeff Kirsher * 1) TX COE if actually supported 12287ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 12297ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 12307ac6653aSJeff Kirsher */ 1231ceb69499SGiuseppe CAVALLARO priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); 12327ac6653aSJeff Kirsher tc = SF_DMA_MODE; 12337ac6653aSJeff Kirsher } else 12347ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 12357ac6653aSJeff Kirsher } 12367ac6653aSJeff Kirsher 12377ac6653aSJeff Kirsher /** 12389125cdd1SGiuseppe CAVALLARO * stmmac_tx_clean: 123932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12407ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 12417ac6653aSJeff Kirsher */ 12429125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv) 12437ac6653aSJeff Kirsher { 12447ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 12457ac6653aSJeff Kirsher 1246a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1247a9097a96SGiuseppe CAVALLARO 12489125cdd1SGiuseppe CAVALLARO priv->xstats.tx_clean++; 12499125cdd1SGiuseppe CAVALLARO 12507ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 12517ac6653aSJeff Kirsher int last; 12527ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 12537ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 1254c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1255c24602efSGiuseppe CAVALLARO 1256c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1257c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_etx + entry); 1258c24602efSGiuseppe CAVALLARO else 1259c24602efSGiuseppe CAVALLARO p = priv->dma_tx + entry; 12607ac6653aSJeff Kirsher 12617ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 12627ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 12637ac6653aSJeff Kirsher break; 12647ac6653aSJeff Kirsher 1265c24602efSGiuseppe CAVALLARO /* Verify tx error by looking at the last segment. */ 12667ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 12677ac6653aSJeff Kirsher if (likely(last)) { 12687ac6653aSJeff Kirsher int tx_error = 12697ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 12707ac6653aSJeff Kirsher &priv->xstats, p, 12717ac6653aSJeff Kirsher priv->ioaddr); 12727ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 12737ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 12747ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 12757ac6653aSJeff Kirsher } else 12767ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 1277891434b1SRayagond Kokatanur 1278891434b1SRayagond Kokatanur stmmac_get_tx_hwtstamp(priv, entry, skb); 12797ac6653aSJeff Kirsher } 128083d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 128183d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d, dirty %d\n", __func__, 12827ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 12837ac6653aSJeff Kirsher 1284cf32deecSRayagond Kokatanur if (likely(priv->tx_skbuff_dma[entry])) { 1285cf32deecSRayagond Kokatanur dma_unmap_single(priv->device, 1286cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry], 12877ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 12887ac6653aSJeff Kirsher DMA_TO_DEVICE); 1289cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = 0; 1290cf32deecSRayagond Kokatanur } 1291891434b1SRayagond Kokatanur priv->hw->ring->clean_desc3(priv, p); 12927ac6653aSJeff Kirsher 12937ac6653aSJeff Kirsher if (likely(skb != NULL)) { 12947ac6653aSJeff Kirsher dev_kfree_skb(skb); 12957ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 12967ac6653aSJeff Kirsher } 12977ac6653aSJeff Kirsher 12984a7d666aSGiuseppe CAVALLARO priv->hw->desc->release_tx_desc(p, priv->mode); 12997ac6653aSJeff Kirsher 130013497f58SGiuseppe CAVALLARO priv->dirty_tx++; 13017ac6653aSJeff Kirsher } 13027ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 13037ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 13047ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 13057ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 13067ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 130783d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 130883d7af64SGiuseppe CAVALLARO pr_debug("%s: restart transmit\n", __func__); 13097ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13107ac6653aSJeff Kirsher } 13117ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 13127ac6653aSJeff Kirsher } 1313d765955dSGiuseppe CAVALLARO 1314d765955dSGiuseppe CAVALLARO if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { 1315d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 1316f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 1317d765955dSGiuseppe CAVALLARO } 1318a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 13197ac6653aSJeff Kirsher } 13207ac6653aSJeff Kirsher 13219125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv) 13227ac6653aSJeff Kirsher { 13237ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 13247ac6653aSJeff Kirsher } 13257ac6653aSJeff Kirsher 13269125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv) 13277ac6653aSJeff Kirsher { 13287ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 13297ac6653aSJeff Kirsher } 13307ac6653aSJeff Kirsher 13317ac6653aSJeff Kirsher /** 133232ceabcaSGiuseppe CAVALLARO * stmmac_tx_err: irq tx error mng function 133332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 13347ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 13357ac6653aSJeff Kirsher * in case of errors. 13367ac6653aSJeff Kirsher */ 13377ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 13387ac6653aSJeff Kirsher { 1339c24602efSGiuseppe CAVALLARO int i; 1340c24602efSGiuseppe CAVALLARO int txsize = priv->dma_tx_size; 13417ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 13427ac6653aSJeff Kirsher 13437ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 13447ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 1345c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 1346c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1347c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 1348c24602efSGiuseppe CAVALLARO priv->mode, 1349c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 1350c24602efSGiuseppe CAVALLARO else 1351c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 1352c24602efSGiuseppe CAVALLARO priv->mode, 1353c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 13547ac6653aSJeff Kirsher priv->dirty_tx = 0; 13557ac6653aSJeff Kirsher priv->cur_tx = 0; 13567ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 13577ac6653aSJeff Kirsher 13587ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 13597ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13607ac6653aSJeff Kirsher } 13617ac6653aSJeff Kirsher 136232ceabcaSGiuseppe CAVALLARO /** 136332ceabcaSGiuseppe CAVALLARO * stmmac_dma_interrupt: DMA ISR 136432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 136532ceabcaSGiuseppe CAVALLARO * Description: this is the DMA ISR. It is called by the main ISR. 136632ceabcaSGiuseppe CAVALLARO * It calls the dwmac dma routine to understand which type of interrupt 136732ceabcaSGiuseppe CAVALLARO * happened. In case of there is a Normal interrupt and either TX or RX 136832ceabcaSGiuseppe CAVALLARO * interrupt happened so the NAPI is scheduled. 136932ceabcaSGiuseppe CAVALLARO */ 13707ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 13717ac6653aSJeff Kirsher { 13727ac6653aSJeff Kirsher int status; 13737ac6653aSJeff Kirsher 13747ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 13759125cdd1SGiuseppe CAVALLARO if (likely((status & handle_rx)) || (status & handle_tx)) { 13769125cdd1SGiuseppe CAVALLARO if (likely(napi_schedule_prep(&priv->napi))) { 13779125cdd1SGiuseppe CAVALLARO stmmac_disable_dma_irq(priv); 13789125cdd1SGiuseppe CAVALLARO __napi_schedule(&priv->napi); 13799125cdd1SGiuseppe CAVALLARO } 13809125cdd1SGiuseppe CAVALLARO } 13819125cdd1SGiuseppe CAVALLARO if (unlikely(status & tx_hard_error_bump_tc)) { 13827ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 13837ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 13847ac6653aSJeff Kirsher tc += 64; 13857ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 13867ac6653aSJeff Kirsher priv->xstats.threshold = tc; 13877ac6653aSJeff Kirsher } 13887ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 13897ac6653aSJeff Kirsher stmmac_tx_err(priv); 13907ac6653aSJeff Kirsher } 13917ac6653aSJeff Kirsher 139232ceabcaSGiuseppe CAVALLARO /** 139332ceabcaSGiuseppe CAVALLARO * stmmac_mmc_setup: setup the Mac Management Counters (MMC) 139432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 139532ceabcaSGiuseppe CAVALLARO * Description: this masks the MMC irq, in fact, the counters are managed in SW. 139632ceabcaSGiuseppe CAVALLARO */ 13971c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 13981c901a46SGiuseppe CAVALLARO { 13991c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 14001c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 14011c901a46SGiuseppe CAVALLARO 14021c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 14034f795b25SGiuseppe CAVALLARO 14044f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 14051c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 14061c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 14074f795b25SGiuseppe CAVALLARO } else 1408aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 14091c901a46SGiuseppe CAVALLARO } 14101c901a46SGiuseppe CAVALLARO 1411f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 1412f0b9d786SGiuseppe CAVALLARO { 1413f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 1414f0b9d786SGiuseppe CAVALLARO 1415ceb69499SGiuseppe CAVALLARO /* Check Synopsys Id (not available on old chips) */ 1416f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 1417f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 1418f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 1419f0b9d786SGiuseppe CAVALLARO 1420cf3f047bSGiuseppe CAVALLARO pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", 1421f0b9d786SGiuseppe CAVALLARO uid, synid); 1422f0b9d786SGiuseppe CAVALLARO 1423f0b9d786SGiuseppe CAVALLARO return synid; 1424f0b9d786SGiuseppe CAVALLARO } 1425f0b9d786SGiuseppe CAVALLARO return 0; 1426f0b9d786SGiuseppe CAVALLARO } 1427e7434821SGiuseppe CAVALLARO 142819e30c14SGiuseppe CAVALLARO /** 142932ceabcaSGiuseppe CAVALLARO * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors 143032ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 143132ceabcaSGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors. 143232ceabcaSGiuseppe CAVALLARO * In case of Enhanced/Alternate, it looks at the extended descriptors are 143332ceabcaSGiuseppe CAVALLARO * supported by the HW cap. register. 1434ff3dd78cSGiuseppe CAVALLARO */ 143519e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 143619e30c14SGiuseppe CAVALLARO { 143719e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 143819e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 1439c24602efSGiuseppe CAVALLARO 1440c24602efSGiuseppe CAVALLARO /* GMAC older than 3.50 has no extended descriptors */ 1441c24602efSGiuseppe CAVALLARO if (priv->synopsys_id >= DWMAC_CORE_3_50) { 1442c24602efSGiuseppe CAVALLARO pr_info("\tEnabled extended descriptors\n"); 1443c24602efSGiuseppe CAVALLARO priv->extend_desc = 1; 1444c24602efSGiuseppe CAVALLARO } else 1445c24602efSGiuseppe CAVALLARO pr_warn("Extended descriptors not supported\n"); 1446c24602efSGiuseppe CAVALLARO 144719e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 144819e30c14SGiuseppe CAVALLARO } else { 144919e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 145019e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 145119e30c14SGiuseppe CAVALLARO } 145219e30c14SGiuseppe CAVALLARO } 145319e30c14SGiuseppe CAVALLARO 145419e30c14SGiuseppe CAVALLARO /** 145532ceabcaSGiuseppe CAVALLARO * stmmac_get_hw_features: get MAC capabilities from the HW cap. register. 145632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 145719e30c14SGiuseppe CAVALLARO * Description: 145819e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 1459e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 146019e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 146119e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 1462e7434821SGiuseppe CAVALLARO */ 1463e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 1464e7434821SGiuseppe CAVALLARO { 14655e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 14663c20f72fSGiuseppe CAVALLARO 14675e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 14685e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 1469e7434821SGiuseppe CAVALLARO 14701db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 14711db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 14721db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 14731db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 1474ceb69499SGiuseppe CAVALLARO priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; 14751db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 14761db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 14771db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 14781db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 14791db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 14801db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 14811db123fbSRayagond Kokatanur /* MMC */ 14821db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 1483e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002 */ 14841db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 14851db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 1486e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008 */ 14871db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 14881db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 1489e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 14901db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 14911db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 1492e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 14931db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 14941db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 14951db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 14961db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 14971db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 14981db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 14991db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 1500e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 15011db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 15021db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 15031db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 15041db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 1505e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode */ 1506ceb69499SGiuseppe CAVALLARO priv->dma_cap.enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 150719e30c14SGiuseppe CAVALLARO } 1508e7434821SGiuseppe CAVALLARO 1509e7434821SGiuseppe CAVALLARO return hw_cap; 1510e7434821SGiuseppe CAVALLARO } 1511e7434821SGiuseppe CAVALLARO 151232ceabcaSGiuseppe CAVALLARO /** 151332ceabcaSGiuseppe CAVALLARO * stmmac_check_ether_addr: check if the MAC addr is valid 151432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 151532ceabcaSGiuseppe CAVALLARO * Description: 151632ceabcaSGiuseppe CAVALLARO * it is to verify if the MAC address is valid, in case of failures it 151732ceabcaSGiuseppe CAVALLARO * generates a random MAC address 151832ceabcaSGiuseppe CAVALLARO */ 1519bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 1520bfab27a1SGiuseppe CAVALLARO { 1521bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 1522bfab27a1SGiuseppe CAVALLARO priv->hw->mac->get_umac_addr((void __iomem *) 1523bfab27a1SGiuseppe CAVALLARO priv->dev->base_addr, 1524bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 1525bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 1526f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 1527c88460b7SHans de Goede pr_info("%s: device MAC address %pM\n", priv->dev->name, 1528bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 1529bfab27a1SGiuseppe CAVALLARO } 1530c88460b7SHans de Goede } 1531bfab27a1SGiuseppe CAVALLARO 153232ceabcaSGiuseppe CAVALLARO /** 153332ceabcaSGiuseppe CAVALLARO * stmmac_init_dma_engine: DMA init. 153432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 153532ceabcaSGiuseppe CAVALLARO * Description: 153632ceabcaSGiuseppe CAVALLARO * It inits the DMA invoking the specific MAC/GMAC callback. 153732ceabcaSGiuseppe CAVALLARO * Some DMA parameters can be passed from the platform; 153832ceabcaSGiuseppe CAVALLARO * in case of these are not passed a default is kept for the MAC or GMAC. 153932ceabcaSGiuseppe CAVALLARO */ 15400f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv) 15410f1f88a8SGiuseppe CAVALLARO { 15420f1f88a8SGiuseppe CAVALLARO int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; 1543b9cde0a8SGiuseppe CAVALLARO int mixed_burst = 0; 1544c24602efSGiuseppe CAVALLARO int atds = 0; 15450f1f88a8SGiuseppe CAVALLARO 15460f1f88a8SGiuseppe CAVALLARO if (priv->plat->dma_cfg) { 15470f1f88a8SGiuseppe CAVALLARO pbl = priv->plat->dma_cfg->pbl; 15480f1f88a8SGiuseppe CAVALLARO fixed_burst = priv->plat->dma_cfg->fixed_burst; 1549b9cde0a8SGiuseppe CAVALLARO mixed_burst = priv->plat->dma_cfg->mixed_burst; 15500f1f88a8SGiuseppe CAVALLARO burst_len = priv->plat->dma_cfg->burst_len; 15510f1f88a8SGiuseppe CAVALLARO } 15520f1f88a8SGiuseppe CAVALLARO 1553c24602efSGiuseppe CAVALLARO if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE)) 1554c24602efSGiuseppe CAVALLARO atds = 1; 1555c24602efSGiuseppe CAVALLARO 1556b9cde0a8SGiuseppe CAVALLARO return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, 15570f1f88a8SGiuseppe CAVALLARO burst_len, priv->dma_tx_phy, 1558c24602efSGiuseppe CAVALLARO priv->dma_rx_phy, atds); 15590f1f88a8SGiuseppe CAVALLARO } 15600f1f88a8SGiuseppe CAVALLARO 1561bfab27a1SGiuseppe CAVALLARO /** 156232ceabcaSGiuseppe CAVALLARO * stmmac_tx_timer: mitigation sw timer for tx. 15639125cdd1SGiuseppe CAVALLARO * @data: data pointer 15649125cdd1SGiuseppe CAVALLARO * Description: 15659125cdd1SGiuseppe CAVALLARO * This is the timer handler to directly invoke the stmmac_tx_clean. 15669125cdd1SGiuseppe CAVALLARO */ 15679125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data) 15689125cdd1SGiuseppe CAVALLARO { 15699125cdd1SGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)data; 15709125cdd1SGiuseppe CAVALLARO 15719125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 15729125cdd1SGiuseppe CAVALLARO } 15739125cdd1SGiuseppe CAVALLARO 15749125cdd1SGiuseppe CAVALLARO /** 157532ceabcaSGiuseppe CAVALLARO * stmmac_init_tx_coalesce: init tx mitigation options. 157632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 15779125cdd1SGiuseppe CAVALLARO * Description: 15789125cdd1SGiuseppe CAVALLARO * This inits the transmit coalesce parameters: i.e. timer rate, 15799125cdd1SGiuseppe CAVALLARO * timer handler and default threshold used for enabling the 15809125cdd1SGiuseppe CAVALLARO * interrupt on completion bit. 15819125cdd1SGiuseppe CAVALLARO */ 15829125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) 15839125cdd1SGiuseppe CAVALLARO { 15849125cdd1SGiuseppe CAVALLARO priv->tx_coal_frames = STMMAC_TX_FRAMES; 15859125cdd1SGiuseppe CAVALLARO priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; 15869125cdd1SGiuseppe CAVALLARO init_timer(&priv->txtimer); 15879125cdd1SGiuseppe CAVALLARO priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); 15889125cdd1SGiuseppe CAVALLARO priv->txtimer.data = (unsigned long)priv; 15899125cdd1SGiuseppe CAVALLARO priv->txtimer.function = stmmac_tx_timer; 15909125cdd1SGiuseppe CAVALLARO add_timer(&priv->txtimer); 15919125cdd1SGiuseppe CAVALLARO } 15929125cdd1SGiuseppe CAVALLARO 15939125cdd1SGiuseppe CAVALLARO /** 1594523f11b5SSrinivas Kandagatla * stmmac_hw_setup: setup mac in a usable state. 1595523f11b5SSrinivas Kandagatla * @dev : pointer to the device structure. 1596523f11b5SSrinivas Kandagatla * Description: 1597523f11b5SSrinivas Kandagatla * This function sets up the ip in a usable state. 1598523f11b5SSrinivas Kandagatla * Return value: 1599523f11b5SSrinivas Kandagatla * 0 on success and an appropriate (-)ve integer as defined in errno.h 1600523f11b5SSrinivas Kandagatla * file on failure. 1601523f11b5SSrinivas Kandagatla */ 1602523f11b5SSrinivas Kandagatla static int stmmac_hw_setup(struct net_device *dev) 1603523f11b5SSrinivas Kandagatla { 1604523f11b5SSrinivas Kandagatla struct stmmac_priv *priv = netdev_priv(dev); 1605523f11b5SSrinivas Kandagatla int ret; 1606523f11b5SSrinivas Kandagatla 1607523f11b5SSrinivas Kandagatla ret = init_dma_desc_rings(dev); 1608523f11b5SSrinivas Kandagatla if (ret < 0) { 1609523f11b5SSrinivas Kandagatla pr_err("%s: DMA descriptors initialization failed\n", __func__); 1610523f11b5SSrinivas Kandagatla return ret; 1611523f11b5SSrinivas Kandagatla } 1612523f11b5SSrinivas Kandagatla /* DMA initialization and SW reset */ 1613523f11b5SSrinivas Kandagatla ret = stmmac_init_dma_engine(priv); 1614523f11b5SSrinivas Kandagatla if (ret < 0) { 1615523f11b5SSrinivas Kandagatla pr_err("%s: DMA engine initialization failed\n", __func__); 1616523f11b5SSrinivas Kandagatla return ret; 1617523f11b5SSrinivas Kandagatla } 1618523f11b5SSrinivas Kandagatla 1619523f11b5SSrinivas Kandagatla /* Copy the MAC addr into the HW */ 1620523f11b5SSrinivas Kandagatla priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); 1621523f11b5SSrinivas Kandagatla 1622523f11b5SSrinivas Kandagatla /* If required, perform hw setup of the bus. */ 1623523f11b5SSrinivas Kandagatla if (priv->plat->bus_setup) 1624523f11b5SSrinivas Kandagatla priv->plat->bus_setup(priv->ioaddr); 1625523f11b5SSrinivas Kandagatla 1626523f11b5SSrinivas Kandagatla /* Initialize the MAC Core */ 16272618abb7SVince Bridgers priv->hw->mac->core_init(priv->ioaddr, dev->mtu); 1628523f11b5SSrinivas Kandagatla 1629523f11b5SSrinivas Kandagatla /* Enable the MAC Rx/Tx */ 1630523f11b5SSrinivas Kandagatla stmmac_set_mac(priv->ioaddr, true); 1631523f11b5SSrinivas Kandagatla 1632523f11b5SSrinivas Kandagatla /* Set the HW DMA mode and the COE */ 1633523f11b5SSrinivas Kandagatla stmmac_dma_operation_mode(priv); 1634523f11b5SSrinivas Kandagatla 1635523f11b5SSrinivas Kandagatla stmmac_mmc_setup(priv); 1636523f11b5SSrinivas Kandagatla 1637523f11b5SSrinivas Kandagatla ret = stmmac_init_ptp(priv); 16387509edd6SHans de Goede if (ret && ret != -EOPNOTSUPP) 1639523f11b5SSrinivas Kandagatla pr_warn("%s: failed PTP initialisation\n", __func__); 1640523f11b5SSrinivas Kandagatla 1641523f11b5SSrinivas Kandagatla #ifdef CONFIG_STMMAC_DEBUG_FS 1642523f11b5SSrinivas Kandagatla ret = stmmac_init_fs(dev); 1643523f11b5SSrinivas Kandagatla if (ret < 0) 1644523f11b5SSrinivas Kandagatla pr_warn("%s: failed debugFS registration\n", __func__); 1645523f11b5SSrinivas Kandagatla #endif 1646523f11b5SSrinivas Kandagatla /* Start the ball rolling... */ 1647523f11b5SSrinivas Kandagatla pr_debug("%s: DMA RX/TX processes started...\n", dev->name); 1648523f11b5SSrinivas Kandagatla priv->hw->dma->start_tx(priv->ioaddr); 1649523f11b5SSrinivas Kandagatla priv->hw->dma->start_rx(priv->ioaddr); 1650523f11b5SSrinivas Kandagatla 1651523f11b5SSrinivas Kandagatla /* Dump DMA/MAC registers */ 1652523f11b5SSrinivas Kandagatla if (netif_msg_hw(priv)) { 1653523f11b5SSrinivas Kandagatla priv->hw->mac->dump_regs(priv->ioaddr); 1654523f11b5SSrinivas Kandagatla priv->hw->dma->dump_regs(priv->ioaddr); 1655523f11b5SSrinivas Kandagatla } 1656523f11b5SSrinivas Kandagatla priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; 1657523f11b5SSrinivas Kandagatla 1658523f11b5SSrinivas Kandagatla priv->eee_enabled = stmmac_eee_init(priv); 1659523f11b5SSrinivas Kandagatla 1660523f11b5SSrinivas Kandagatla stmmac_init_tx_coalesce(priv); 1661523f11b5SSrinivas Kandagatla 1662523f11b5SSrinivas Kandagatla if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { 1663523f11b5SSrinivas Kandagatla priv->rx_riwt = MAX_DMA_RIWT; 1664523f11b5SSrinivas Kandagatla priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); 1665523f11b5SSrinivas Kandagatla } 1666523f11b5SSrinivas Kandagatla 1667523f11b5SSrinivas Kandagatla if (priv->pcs && priv->hw->mac->ctrl_ane) 1668523f11b5SSrinivas Kandagatla priv->hw->mac->ctrl_ane(priv->ioaddr, 0); 1669523f11b5SSrinivas Kandagatla 1670523f11b5SSrinivas Kandagatla return 0; 1671523f11b5SSrinivas Kandagatla } 1672523f11b5SSrinivas Kandagatla 1673523f11b5SSrinivas Kandagatla /** 16747ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 16757ac6653aSJeff Kirsher * @dev : pointer to the device structure. 16767ac6653aSJeff Kirsher * Description: 16777ac6653aSJeff Kirsher * This function is the open entry point of the driver. 16787ac6653aSJeff Kirsher * Return value: 16797ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 16807ac6653aSJeff Kirsher * file on failure. 16817ac6653aSJeff Kirsher */ 16827ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 16837ac6653aSJeff Kirsher { 16847ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16857ac6653aSJeff Kirsher int ret; 16867ac6653aSJeff Kirsher 16874bfcbd7aSFrancesco Virlinzi stmmac_check_ether_addr(priv); 16884bfcbd7aSFrancesco Virlinzi 16894d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 16904d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 16917ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 1692e58bb43fSGiuseppe CAVALLARO if (ret) { 1693e58bb43fSGiuseppe CAVALLARO pr_err("%s: Cannot attach to PHY (error: %d)\n", 1694e58bb43fSGiuseppe CAVALLARO __func__, ret); 1695c9324d18SGiuseppe CAVALLARO goto phy_error; 16967ac6653aSJeff Kirsher } 1697e58bb43fSGiuseppe CAVALLARO } 16987ac6653aSJeff Kirsher 1699523f11b5SSrinivas Kandagatla /* Extra statistics */ 1700523f11b5SSrinivas Kandagatla memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 1701523f11b5SSrinivas Kandagatla priv->xstats.threshold = tc; 1702523f11b5SSrinivas Kandagatla 17037ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 17047ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 17057ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 17067ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 170756329137SBartlomiej Zolnierkiewicz 17087262b7b2STobias Klauser ret = alloc_dma_desc_resources(priv); 170909f8d696SSrinivas Kandagatla if (ret < 0) { 171009f8d696SSrinivas Kandagatla pr_err("%s: DMA descriptors allocation failed\n", __func__); 171109f8d696SSrinivas Kandagatla goto dma_desc_error; 171209f8d696SSrinivas Kandagatla } 171309f8d696SSrinivas Kandagatla 1714523f11b5SSrinivas Kandagatla ret = stmmac_hw_setup(dev); 171556329137SBartlomiej Zolnierkiewicz if (ret < 0) { 1716523f11b5SSrinivas Kandagatla pr_err("%s: Hw setup failed\n", __func__); 1717c9324d18SGiuseppe CAVALLARO goto init_error; 17187ac6653aSJeff Kirsher } 17197ac6653aSJeff Kirsher 1720523f11b5SSrinivas Kandagatla if (priv->phydev) 1721523f11b5SSrinivas Kandagatla phy_start(priv->phydev); 17227ac6653aSJeff Kirsher 17237ac6653aSJeff Kirsher /* Request the IRQ lines */ 17247ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 17257ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 17267ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 17277ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 17287ac6653aSJeff Kirsher __func__, dev->irq, ret); 1729c9324d18SGiuseppe CAVALLARO goto init_error; 17307ac6653aSJeff Kirsher } 17317ac6653aSJeff Kirsher 17327a13f8f5SFrancesco Virlinzi /* Request the Wake IRQ in case of another line is used for WoL */ 17337a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) { 17347a13f8f5SFrancesco Virlinzi ret = request_irq(priv->wol_irq, stmmac_interrupt, 17357a13f8f5SFrancesco Virlinzi IRQF_SHARED, dev->name, dev); 17367a13f8f5SFrancesco Virlinzi if (unlikely(ret < 0)) { 1737ceb69499SGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the WoL IRQ %d (%d)\n", 1738ceb69499SGiuseppe CAVALLARO __func__, priv->wol_irq, ret); 1739c9324d18SGiuseppe CAVALLARO goto wolirq_error; 17407a13f8f5SFrancesco Virlinzi } 17417a13f8f5SFrancesco Virlinzi } 17427a13f8f5SFrancesco Virlinzi 1743d765955dSGiuseppe CAVALLARO /* Request the IRQ lines */ 1744d765955dSGiuseppe CAVALLARO if (priv->lpi_irq != -ENXIO) { 1745d765955dSGiuseppe CAVALLARO ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, 1746d765955dSGiuseppe CAVALLARO dev->name, dev); 1747d765955dSGiuseppe CAVALLARO if (unlikely(ret < 0)) { 1748d765955dSGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", 1749d765955dSGiuseppe CAVALLARO __func__, priv->lpi_irq, ret); 1750c9324d18SGiuseppe CAVALLARO goto lpiirq_error; 1751d765955dSGiuseppe CAVALLARO } 1752d765955dSGiuseppe CAVALLARO } 1753d765955dSGiuseppe CAVALLARO 17547ac6653aSJeff Kirsher napi_enable(&priv->napi); 17557ac6653aSJeff Kirsher netif_start_queue(dev); 17567ac6653aSJeff Kirsher 17577ac6653aSJeff Kirsher return 0; 17587ac6653aSJeff Kirsher 1759c9324d18SGiuseppe CAVALLARO lpiirq_error: 1760d765955dSGiuseppe CAVALLARO if (priv->wol_irq != dev->irq) 1761d765955dSGiuseppe CAVALLARO free_irq(priv->wol_irq, dev); 1762c9324d18SGiuseppe CAVALLARO wolirq_error: 17637a13f8f5SFrancesco Virlinzi free_irq(dev->irq, dev); 17647a13f8f5SFrancesco Virlinzi 1765c9324d18SGiuseppe CAVALLARO init_error: 1766c9324d18SGiuseppe CAVALLARO free_dma_desc_resources(priv); 176756329137SBartlomiej Zolnierkiewicz dma_desc_error: 17687ac6653aSJeff Kirsher if (priv->phydev) 17697ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 1770c9324d18SGiuseppe CAVALLARO phy_error: 1771a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 17724bfcbd7aSFrancesco Virlinzi 17737ac6653aSJeff Kirsher return ret; 17747ac6653aSJeff Kirsher } 17757ac6653aSJeff Kirsher 17767ac6653aSJeff Kirsher /** 17777ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 17787ac6653aSJeff Kirsher * @dev : device pointer. 17797ac6653aSJeff Kirsher * Description: 17807ac6653aSJeff Kirsher * This is the stop entry point of the driver. 17817ac6653aSJeff Kirsher */ 17827ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 17837ac6653aSJeff Kirsher { 17847ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 17857ac6653aSJeff Kirsher 1786d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 1787d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 1788d765955dSGiuseppe CAVALLARO 17897ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 17907ac6653aSJeff Kirsher if (priv->phydev) { 17917ac6653aSJeff Kirsher phy_stop(priv->phydev); 17927ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 17937ac6653aSJeff Kirsher priv->phydev = NULL; 17947ac6653aSJeff Kirsher } 17957ac6653aSJeff Kirsher 17967ac6653aSJeff Kirsher netif_stop_queue(dev); 17977ac6653aSJeff Kirsher 17987ac6653aSJeff Kirsher napi_disable(&priv->napi); 17997ac6653aSJeff Kirsher 18009125cdd1SGiuseppe CAVALLARO del_timer_sync(&priv->txtimer); 18019125cdd1SGiuseppe CAVALLARO 18027ac6653aSJeff Kirsher /* Free the IRQ lines */ 18037ac6653aSJeff Kirsher free_irq(dev->irq, dev); 18047a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) 18057a13f8f5SFrancesco Virlinzi free_irq(priv->wol_irq, dev); 1806d765955dSGiuseppe CAVALLARO if (priv->lpi_irq != -ENXIO) 1807d765955dSGiuseppe CAVALLARO free_irq(priv->lpi_irq, dev); 18087ac6653aSJeff Kirsher 18097ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 18107ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18117ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18127ac6653aSJeff Kirsher 18137ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 18147ac6653aSJeff Kirsher free_dma_desc_resources(priv); 18157ac6653aSJeff Kirsher 18167ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1817bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 18187ac6653aSJeff Kirsher 18197ac6653aSJeff Kirsher netif_carrier_off(dev); 18207ac6653aSJeff Kirsher 1821bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1822bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1823bfab27a1SGiuseppe CAVALLARO #endif 1824bfab27a1SGiuseppe CAVALLARO 182592ba6888SRayagond Kokatanur stmmac_release_ptp(priv); 182692ba6888SRayagond Kokatanur 18277ac6653aSJeff Kirsher return 0; 18287ac6653aSJeff Kirsher } 18297ac6653aSJeff Kirsher 18307ac6653aSJeff Kirsher /** 183132ceabcaSGiuseppe CAVALLARO * stmmac_xmit: Tx entry point of the driver 18327ac6653aSJeff Kirsher * @skb : the socket buffer 18337ac6653aSJeff Kirsher * @dev : device pointer 183432ceabcaSGiuseppe CAVALLARO * Description : this is the tx entry point of the driver. 183532ceabcaSGiuseppe CAVALLARO * It programs the chain or the ring and supports oversized frames 183632ceabcaSGiuseppe CAVALLARO * and SG feature. 18377ac6653aSJeff Kirsher */ 18387ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 18397ac6653aSJeff Kirsher { 18407ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 18417ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 18427ac6653aSJeff Kirsher unsigned int entry; 18434a7d666aSGiuseppe CAVALLARO int i, csum_insertion = 0, is_jumbo = 0; 18447ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 18457ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1846286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 18477ac6653aSJeff Kirsher 18487ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 18497ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 18507ac6653aSJeff Kirsher netif_stop_queue(dev); 18517ac6653aSJeff Kirsher /* This is a hard error, log it. */ 1852ceb69499SGiuseppe CAVALLARO pr_err("%s: Tx Ring full when queue awake\n", __func__); 18537ac6653aSJeff Kirsher } 18547ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 18557ac6653aSJeff Kirsher } 18567ac6653aSJeff Kirsher 1857a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1858a9097a96SGiuseppe CAVALLARO 1859d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1860d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1861d765955dSGiuseppe CAVALLARO 18627ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 18637ac6653aSJeff Kirsher 18647ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 18657ac6653aSJeff Kirsher 1866c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1867c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1868c24602efSGiuseppe CAVALLARO else 18697ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 1870c24602efSGiuseppe CAVALLARO 18717ac6653aSJeff Kirsher first = desc; 18727ac6653aSJeff Kirsher 18734a7d666aSGiuseppe CAVALLARO /* To program the descriptors according to the size of the frame */ 18744a7d666aSGiuseppe CAVALLARO if (priv->mode == STMMAC_RING_MODE) { 18754a7d666aSGiuseppe CAVALLARO is_jumbo = priv->hw->ring->is_jumbo_frm(skb->len, 18764a7d666aSGiuseppe CAVALLARO priv->plat->enh_desc); 18774a7d666aSGiuseppe CAVALLARO if (unlikely(is_jumbo)) 18784a7d666aSGiuseppe CAVALLARO entry = priv->hw->ring->jumbo_frm(priv, skb, 18794a7d666aSGiuseppe CAVALLARO csum_insertion); 18807ac6653aSJeff Kirsher } else { 18814a7d666aSGiuseppe CAVALLARO is_jumbo = priv->hw->chain->is_jumbo_frm(skb->len, 18824a7d666aSGiuseppe CAVALLARO priv->plat->enh_desc); 18834a7d666aSGiuseppe CAVALLARO if (unlikely(is_jumbo)) 18844a7d666aSGiuseppe CAVALLARO entry = priv->hw->chain->jumbo_frm(priv, skb, 18854a7d666aSGiuseppe CAVALLARO csum_insertion); 18864a7d666aSGiuseppe CAVALLARO } 18874a7d666aSGiuseppe CAVALLARO if (likely(!is_jumbo)) { 18887ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 18897ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 1890cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = desc->des2; 18917ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 18924a7d666aSGiuseppe CAVALLARO csum_insertion, priv->mode); 18934a7d666aSGiuseppe CAVALLARO } else 1894c24602efSGiuseppe CAVALLARO desc = first; 18957ac6653aSJeff Kirsher 18967ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 18979e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 18989e903e08SEric Dumazet int len = skb_frag_size(frag); 18997ac6653aSJeff Kirsher 190075e4364fSdamuzi000 priv->tx_skbuff[entry] = NULL; 19017ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 1902c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1903c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1904c24602efSGiuseppe CAVALLARO else 19057ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 19067ac6653aSJeff Kirsher 1907f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1908f722380dSIan Campbell DMA_TO_DEVICE); 1909cf32deecSRayagond Kokatanur priv->tx_skbuff_dma[entry] = desc->des2; 19104a7d666aSGiuseppe CAVALLARO priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, 19114a7d666aSGiuseppe CAVALLARO priv->mode); 19127ac6653aSJeff Kirsher wmb(); 19137ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 19148e839891SDeepak Sikri wmb(); 19157ac6653aSJeff Kirsher } 19167ac6653aSJeff Kirsher 191775e4364fSdamuzi000 priv->tx_skbuff[entry] = skb; 191875e4364fSdamuzi000 19199125cdd1SGiuseppe CAVALLARO /* Finalize the latest segment. */ 19207ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 19217ac6653aSJeff Kirsher 19227ac6653aSJeff Kirsher wmb(); 19239125cdd1SGiuseppe CAVALLARO /* According to the coalesce parameter the IC bit for the latest 19249125cdd1SGiuseppe CAVALLARO * segment could be reset and the timer re-started to invoke the 19259125cdd1SGiuseppe CAVALLARO * stmmac_tx function. This approach takes care about the fragments. 19269125cdd1SGiuseppe CAVALLARO */ 19279125cdd1SGiuseppe CAVALLARO priv->tx_count_frames += nfrags + 1; 19289125cdd1SGiuseppe CAVALLARO if (priv->tx_coal_frames > priv->tx_count_frames) { 19299125cdd1SGiuseppe CAVALLARO priv->hw->desc->clear_tx_ic(desc); 19309125cdd1SGiuseppe CAVALLARO priv->xstats.tx_reset_ic_bit++; 19319125cdd1SGiuseppe CAVALLARO mod_timer(&priv->txtimer, 19329125cdd1SGiuseppe CAVALLARO STMMAC_COAL_TIMER(priv->tx_coal_timer)); 19339125cdd1SGiuseppe CAVALLARO } else 19349125cdd1SGiuseppe CAVALLARO priv->tx_count_frames = 0; 19357ac6653aSJeff Kirsher 19367ac6653aSJeff Kirsher /* To avoid raise condition */ 19377ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 19388e839891SDeepak Sikri wmb(); 19397ac6653aSJeff Kirsher 19407ac6653aSJeff Kirsher priv->cur_tx++; 19417ac6653aSJeff Kirsher 19427ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 194383d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", 1944ceb69499SGiuseppe CAVALLARO __func__, (priv->cur_tx % txsize), 1945ceb69499SGiuseppe CAVALLARO (priv->dirty_tx % txsize), entry, first, nfrags); 194683d7af64SGiuseppe CAVALLARO 1947c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1948c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 1949c24602efSGiuseppe CAVALLARO else 1950c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 1951c24602efSGiuseppe CAVALLARO 195283d7af64SGiuseppe CAVALLARO pr_debug(">>> frame to be transmitted: "); 19537ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 19547ac6653aSJeff Kirsher } 19557ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 195683d7af64SGiuseppe CAVALLARO if (netif_msg_hw(priv)) 195783d7af64SGiuseppe CAVALLARO pr_debug("%s: stop transmitted packets\n", __func__); 19587ac6653aSJeff Kirsher netif_stop_queue(dev); 19597ac6653aSJeff Kirsher } 19607ac6653aSJeff Kirsher 19617ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 19627ac6653aSJeff Kirsher 1963891434b1SRayagond Kokatanur if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && 1964891434b1SRayagond Kokatanur priv->hwts_tx_en)) { 1965891434b1SRayagond Kokatanur /* declare that device is doing timestamping */ 1966891434b1SRayagond Kokatanur skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 1967891434b1SRayagond Kokatanur priv->hw->desc->enable_tx_timestamp(first); 1968891434b1SRayagond Kokatanur } 1969891434b1SRayagond Kokatanur 1970891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 19717ac6653aSJeff Kirsher skb_tx_timestamp(skb); 19727ac6653aSJeff Kirsher 19737ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 19747ac6653aSJeff Kirsher 1975a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 1976a9097a96SGiuseppe CAVALLARO 19777ac6653aSJeff Kirsher return NETDEV_TX_OK; 19787ac6653aSJeff Kirsher } 19797ac6653aSJeff Kirsher 1980b9381985SVince Bridgers static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) 1981b9381985SVince Bridgers { 1982b9381985SVince Bridgers struct ethhdr *ehdr; 1983b9381985SVince Bridgers u16 vlanid; 1984b9381985SVince Bridgers 1985b9381985SVince Bridgers if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) == 1986b9381985SVince Bridgers NETIF_F_HW_VLAN_CTAG_RX && 1987b9381985SVince Bridgers !__vlan_get_tag(skb, &vlanid)) { 1988b9381985SVince Bridgers /* pop the vlan tag */ 1989b9381985SVince Bridgers ehdr = (struct ethhdr *)skb->data; 1990b9381985SVince Bridgers memmove(skb->data + VLAN_HLEN, ehdr, ETH_ALEN * 2); 1991b9381985SVince Bridgers skb_pull(skb, VLAN_HLEN); 1992b9381985SVince Bridgers __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlanid); 1993b9381985SVince Bridgers } 1994b9381985SVince Bridgers } 1995b9381985SVince Bridgers 1996b9381985SVince Bridgers 199732ceabcaSGiuseppe CAVALLARO /** 199832ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 199932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 200032ceabcaSGiuseppe CAVALLARO * Description : this is to reallocate the skb for the reception process 200132ceabcaSGiuseppe CAVALLARO * that is based on zero-copy. 200232ceabcaSGiuseppe CAVALLARO */ 20037ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 20047ac6653aSJeff Kirsher { 20057ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20067ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 20077ac6653aSJeff Kirsher 20087ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 20097ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 2010c24602efSGiuseppe CAVALLARO struct dma_desc *p; 2011c24602efSGiuseppe CAVALLARO 2012c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2013c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2014c24602efSGiuseppe CAVALLARO else 2015c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2016c24602efSGiuseppe CAVALLARO 20177ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 20187ac6653aSJeff Kirsher struct sk_buff *skb; 20197ac6653aSJeff Kirsher 2020acb600deSEric Dumazet skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); 20217ac6653aSJeff Kirsher 20227ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 20237ac6653aSJeff Kirsher break; 20247ac6653aSJeff Kirsher 20257ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 20267ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 20277ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 20287ac6653aSJeff Kirsher DMA_FROM_DEVICE); 20297ac6653aSJeff Kirsher 2030c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[entry]; 2031286a8372SGiuseppe CAVALLARO 2032891434b1SRayagond Kokatanur priv->hw->ring->refill_desc3(priv, p); 2033286a8372SGiuseppe CAVALLARO 203483d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) 203583d7af64SGiuseppe CAVALLARO pr_debug("\trefill entry #%d\n", entry); 20367ac6653aSJeff Kirsher } 20377ac6653aSJeff Kirsher wmb(); 2038c24602efSGiuseppe CAVALLARO priv->hw->desc->set_rx_owner(p); 20398e839891SDeepak Sikri wmb(); 20407ac6653aSJeff Kirsher } 20417ac6653aSJeff Kirsher } 20427ac6653aSJeff Kirsher 204332ceabcaSGiuseppe CAVALLARO /** 204432ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 204532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 204632ceabcaSGiuseppe CAVALLARO * @limit: napi bugget. 204732ceabcaSGiuseppe CAVALLARO * Description : this the function called by the napi poll method. 204832ceabcaSGiuseppe CAVALLARO * It gets all the frames inside the ring. 204932ceabcaSGiuseppe CAVALLARO */ 20507ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 20517ac6653aSJeff Kirsher { 20527ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20537ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 20547ac6653aSJeff Kirsher unsigned int next_entry; 20557ac6653aSJeff Kirsher unsigned int count = 0; 2056ceb69499SGiuseppe CAVALLARO int coe = priv->plat->rx_coe; 20577ac6653aSJeff Kirsher 205883d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 205983d7af64SGiuseppe CAVALLARO pr_debug("%s: descriptor ring:\n", __func__); 2060c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2061c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 2062c24602efSGiuseppe CAVALLARO else 2063c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 20647ac6653aSJeff Kirsher } 2065c24602efSGiuseppe CAVALLARO while (count < limit) { 20667ac6653aSJeff Kirsher int status; 20679401bb5cSGiuseppe CAVALLARO struct dma_desc *p; 20687ac6653aSJeff Kirsher 2069c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2070c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2071c24602efSGiuseppe CAVALLARO else 2072c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2073c24602efSGiuseppe CAVALLARO 2074c24602efSGiuseppe CAVALLARO if (priv->hw->desc->get_rx_owner(p)) 20757ac6653aSJeff Kirsher break; 20767ac6653aSJeff Kirsher 20777ac6653aSJeff Kirsher count++; 20787ac6653aSJeff Kirsher 20797ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 2080c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 20819401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_erx + next_entry); 2082c24602efSGiuseppe CAVALLARO else 20839401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_rx + next_entry); 20847ac6653aSJeff Kirsher 20857ac6653aSJeff Kirsher /* read the status of the incoming frame */ 2086c24602efSGiuseppe CAVALLARO status = priv->hw->desc->rx_status(&priv->dev->stats, 2087c24602efSGiuseppe CAVALLARO &priv->xstats, p); 2088c24602efSGiuseppe CAVALLARO if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status)) 2089c24602efSGiuseppe CAVALLARO priv->hw->desc->rx_extended_status(&priv->dev->stats, 2090c24602efSGiuseppe CAVALLARO &priv->xstats, 2091c24602efSGiuseppe CAVALLARO priv->dma_erx + 2092c24602efSGiuseppe CAVALLARO entry); 2093891434b1SRayagond Kokatanur if (unlikely(status == discard_frame)) { 20947ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 2095891434b1SRayagond Kokatanur if (priv->hwts_rx_en && !priv->extend_desc) { 2096891434b1SRayagond Kokatanur /* DESC2 & DESC3 will be overwitten by device 2097891434b1SRayagond Kokatanur * with timestamp value, hence reinitialize 2098891434b1SRayagond Kokatanur * them in stmmac_rx_refill() function so that 2099891434b1SRayagond Kokatanur * device can reuse it. 2100891434b1SRayagond Kokatanur */ 2101891434b1SRayagond Kokatanur priv->rx_skbuff[entry] = NULL; 2102891434b1SRayagond Kokatanur dma_unmap_single(priv->device, 2103891434b1SRayagond Kokatanur priv->rx_skbuff_dma[entry], 2104ceb69499SGiuseppe CAVALLARO priv->dma_buf_sz, 2105ceb69499SGiuseppe CAVALLARO DMA_FROM_DEVICE); 2106891434b1SRayagond Kokatanur } 2107891434b1SRayagond Kokatanur } else { 21087ac6653aSJeff Kirsher struct sk_buff *skb; 21097ac6653aSJeff Kirsher int frame_len; 21107ac6653aSJeff Kirsher 2111ceb69499SGiuseppe CAVALLARO frame_len = priv->hw->desc->get_rx_frame_len(p, coe); 2112ceb69499SGiuseppe CAVALLARO 21137ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 2114ceb69499SGiuseppe CAVALLARO * Type frames (LLC/LLC-SNAP) 2115ceb69499SGiuseppe CAVALLARO */ 21167ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 21177ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 21187ac6653aSJeff Kirsher 211983d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 21207ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 21217ac6653aSJeff Kirsher p, entry, p->des2); 212283d7af64SGiuseppe CAVALLARO if (frame_len > ETH_FRAME_LEN) 212383d7af64SGiuseppe CAVALLARO pr_debug("\tframe size %d, COE: %d\n", 212483d7af64SGiuseppe CAVALLARO frame_len, status); 212583d7af64SGiuseppe CAVALLARO } 21267ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 21277ac6653aSJeff Kirsher if (unlikely(!skb)) { 21287ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 21297ac6653aSJeff Kirsher priv->dev->name); 21307ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 21317ac6653aSJeff Kirsher break; 21327ac6653aSJeff Kirsher } 21337ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 21347ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 21357ac6653aSJeff Kirsher 2136891434b1SRayagond Kokatanur stmmac_get_rx_hwtstamp(priv, entry, skb); 2137891434b1SRayagond Kokatanur 21387ac6653aSJeff Kirsher skb_put(skb, frame_len); 21397ac6653aSJeff Kirsher dma_unmap_single(priv->device, 21407ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 21417ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 214283d7af64SGiuseppe CAVALLARO 21437ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 214483d7af64SGiuseppe CAVALLARO pr_debug("frame received (%dbytes)", frame_len); 21457ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 21467ac6653aSJeff Kirsher } 214783d7af64SGiuseppe CAVALLARO 2148b9381985SVince Bridgers stmmac_rx_vlan(priv->dev, skb); 2149b9381985SVince Bridgers 21507ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 21517ac6653aSJeff Kirsher 2152ceb69499SGiuseppe CAVALLARO if (unlikely(!coe)) 21537ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 215462a2ab93SGiuseppe CAVALLARO else 21557ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 215662a2ab93SGiuseppe CAVALLARO 21577ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 21587ac6653aSJeff Kirsher 21597ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 21607ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 21617ac6653aSJeff Kirsher } 21627ac6653aSJeff Kirsher entry = next_entry; 21637ac6653aSJeff Kirsher } 21647ac6653aSJeff Kirsher 21657ac6653aSJeff Kirsher stmmac_rx_refill(priv); 21667ac6653aSJeff Kirsher 21677ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 21687ac6653aSJeff Kirsher 21697ac6653aSJeff Kirsher return count; 21707ac6653aSJeff Kirsher } 21717ac6653aSJeff Kirsher 21727ac6653aSJeff Kirsher /** 21737ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 21747ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 21757ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 21767ac6653aSJeff Kirsher * all interfaces. 21777ac6653aSJeff Kirsher * Description : 21789125cdd1SGiuseppe CAVALLARO * To look at the incoming frames and clear the tx resources. 21797ac6653aSJeff Kirsher */ 21807ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 21817ac6653aSJeff Kirsher { 21827ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 21837ac6653aSJeff Kirsher int work_done = 0; 21847ac6653aSJeff Kirsher 21859125cdd1SGiuseppe CAVALLARO priv->xstats.napi_poll++; 21869125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 21877ac6653aSJeff Kirsher 21889125cdd1SGiuseppe CAVALLARO work_done = stmmac_rx(priv, budget); 21897ac6653aSJeff Kirsher if (work_done < budget) { 21907ac6653aSJeff Kirsher napi_complete(napi); 21919125cdd1SGiuseppe CAVALLARO stmmac_enable_dma_irq(priv); 21927ac6653aSJeff Kirsher } 21937ac6653aSJeff Kirsher return work_done; 21947ac6653aSJeff Kirsher } 21957ac6653aSJeff Kirsher 21967ac6653aSJeff Kirsher /** 21977ac6653aSJeff Kirsher * stmmac_tx_timeout 21987ac6653aSJeff Kirsher * @dev : Pointer to net device structure 21997ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 22007284a3f1SGiuseppe CAVALLARO * complete within a reasonable time. The driver will mark the error in the 22017ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 22027ac6653aSJeff Kirsher * in order to transmit a new packet. 22037ac6653aSJeff Kirsher */ 22047ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 22057ac6653aSJeff Kirsher { 22067ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22077ac6653aSJeff Kirsher 22087ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 22097ac6653aSJeff Kirsher stmmac_tx_err(priv); 22107ac6653aSJeff Kirsher } 22117ac6653aSJeff Kirsher 22127ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */ 22137ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map) 22147ac6653aSJeff Kirsher { 22157ac6653aSJeff Kirsher if (dev->flags & IFF_UP) /* can't act on a running interface */ 22167ac6653aSJeff Kirsher return -EBUSY; 22177ac6653aSJeff Kirsher 22187ac6653aSJeff Kirsher /* Don't allow changing the I/O address */ 22197ac6653aSJeff Kirsher if (map->base_addr != dev->base_addr) { 2220ceb69499SGiuseppe CAVALLARO pr_warn("%s: can't change I/O address\n", dev->name); 22217ac6653aSJeff Kirsher return -EOPNOTSUPP; 22227ac6653aSJeff Kirsher } 22237ac6653aSJeff Kirsher 22247ac6653aSJeff Kirsher /* Don't allow changing the IRQ */ 22257ac6653aSJeff Kirsher if (map->irq != dev->irq) { 2226ceb69499SGiuseppe CAVALLARO pr_warn("%s: not change IRQ number %d\n", dev->name, dev->irq); 22277ac6653aSJeff Kirsher return -EOPNOTSUPP; 22287ac6653aSJeff Kirsher } 22297ac6653aSJeff Kirsher 22307ac6653aSJeff Kirsher return 0; 22317ac6653aSJeff Kirsher } 22327ac6653aSJeff Kirsher 22337ac6653aSJeff Kirsher /** 223401789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 22357ac6653aSJeff Kirsher * @dev : pointer to the device structure 22367ac6653aSJeff Kirsher * Description: 22377ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 22387ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 22397ac6653aSJeff Kirsher * Return value: 22407ac6653aSJeff Kirsher * void. 22417ac6653aSJeff Kirsher */ 224201789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 22437ac6653aSJeff Kirsher { 22447ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22457ac6653aSJeff Kirsher 22467ac6653aSJeff Kirsher spin_lock(&priv->lock); 2247cffb13f4SGiuseppe CAVALLARO priv->hw->mac->set_filter(dev, priv->synopsys_id); 22487ac6653aSJeff Kirsher spin_unlock(&priv->lock); 22497ac6653aSJeff Kirsher } 22507ac6653aSJeff Kirsher 22517ac6653aSJeff Kirsher /** 22527ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 22537ac6653aSJeff Kirsher * @dev : device pointer. 22547ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 22557ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 22567ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 22577ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 22587ac6653aSJeff Kirsher * Return value: 22597ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 22607ac6653aSJeff Kirsher * file on failure. 22617ac6653aSJeff Kirsher */ 22627ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 22637ac6653aSJeff Kirsher { 22647ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22657ac6653aSJeff Kirsher int max_mtu; 22667ac6653aSJeff Kirsher 22677ac6653aSJeff Kirsher if (netif_running(dev)) { 22687ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 22697ac6653aSJeff Kirsher return -EBUSY; 22707ac6653aSJeff Kirsher } 22717ac6653aSJeff Kirsher 227248febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 22737ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 22747ac6653aSJeff Kirsher else 227545db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 22767ac6653aSJeff Kirsher 22772618abb7SVince Bridgers if (priv->plat->maxmtu < max_mtu) 22782618abb7SVince Bridgers max_mtu = priv->plat->maxmtu; 22792618abb7SVince Bridgers 22807ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 22817ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 22827ac6653aSJeff Kirsher return -EINVAL; 22837ac6653aSJeff Kirsher } 22847ac6653aSJeff Kirsher 22857ac6653aSJeff Kirsher dev->mtu = new_mtu; 22867ac6653aSJeff Kirsher netdev_update_features(dev); 22877ac6653aSJeff Kirsher 22887ac6653aSJeff Kirsher return 0; 22897ac6653aSJeff Kirsher } 22907ac6653aSJeff Kirsher 2291c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 2292c8f44affSMichał Mirosław netdev_features_t features) 22937ac6653aSJeff Kirsher { 22947ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22957ac6653aSJeff Kirsher 229638912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 22977ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 229838912bdbSDeepak SIKRI else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) 229938912bdbSDeepak SIKRI features &= ~NETIF_F_IPV6_CSUM; 23007ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 23017ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23027ac6653aSJeff Kirsher 23037ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 23047ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 23057ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 2306ceb69499SGiuseppe CAVALLARO * the TX csum insertionin the TDES and not use SF. 2307ceb69499SGiuseppe CAVALLARO */ 23087ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 23097ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23107ac6653aSJeff Kirsher 23117ac6653aSJeff Kirsher return features; 23127ac6653aSJeff Kirsher } 23137ac6653aSJeff Kirsher 231432ceabcaSGiuseppe CAVALLARO /** 231532ceabcaSGiuseppe CAVALLARO * stmmac_interrupt - main ISR 231632ceabcaSGiuseppe CAVALLARO * @irq: interrupt number. 231732ceabcaSGiuseppe CAVALLARO * @dev_id: to pass the net device pointer. 231832ceabcaSGiuseppe CAVALLARO * Description: this is the main driver interrupt service routine. 231932ceabcaSGiuseppe CAVALLARO * It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI 232032ceabcaSGiuseppe CAVALLARO * interrupts. 232132ceabcaSGiuseppe CAVALLARO */ 23227ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 23237ac6653aSJeff Kirsher { 23247ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 23257ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23267ac6653aSJeff Kirsher 232789f7f2cfSSrinivas Kandagatla if (priv->irq_wake) 232889f7f2cfSSrinivas Kandagatla pm_wakeup_event(priv->device, 0); 232989f7f2cfSSrinivas Kandagatla 23307ac6653aSJeff Kirsher if (unlikely(!dev)) { 23317ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 23327ac6653aSJeff Kirsher return IRQ_NONE; 23337ac6653aSJeff Kirsher } 23347ac6653aSJeff Kirsher 23357ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 2336d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 2337d765955dSGiuseppe CAVALLARO int status = priv->hw->mac->host_irq_status((void __iomem *) 23380982a0f6SGiuseppe CAVALLARO dev->base_addr, 23390982a0f6SGiuseppe CAVALLARO &priv->xstats); 2340d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 2341d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 23420982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) 2343d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 23440982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) 2345d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 2346d765955dSGiuseppe CAVALLARO } 2347d765955dSGiuseppe CAVALLARO } 2348d765955dSGiuseppe CAVALLARO 2349d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 23507ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 23517ac6653aSJeff Kirsher 23527ac6653aSJeff Kirsher return IRQ_HANDLED; 23537ac6653aSJeff Kirsher } 23547ac6653aSJeff Kirsher 23557ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 23567ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 2357ceb69499SGiuseppe CAVALLARO * to allow network I/O with interrupts disabled. 2358ceb69499SGiuseppe CAVALLARO */ 23597ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 23607ac6653aSJeff Kirsher { 23617ac6653aSJeff Kirsher disable_irq(dev->irq); 23627ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 23637ac6653aSJeff Kirsher enable_irq(dev->irq); 23647ac6653aSJeff Kirsher } 23657ac6653aSJeff Kirsher #endif 23667ac6653aSJeff Kirsher 23677ac6653aSJeff Kirsher /** 23687ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 23697ac6653aSJeff Kirsher * @dev: Device pointer. 23707ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 23717ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 23727ac6653aSJeff Kirsher * @cmd: IOCTL command 23737ac6653aSJeff Kirsher * Description: 237432ceabcaSGiuseppe CAVALLARO * Currently it supports the phy_mii_ioctl(...) and HW time stamping. 23757ac6653aSJeff Kirsher */ 23767ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 23777ac6653aSJeff Kirsher { 23787ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2379891434b1SRayagond Kokatanur int ret = -EOPNOTSUPP; 23807ac6653aSJeff Kirsher 23817ac6653aSJeff Kirsher if (!netif_running(dev)) 23827ac6653aSJeff Kirsher return -EINVAL; 23837ac6653aSJeff Kirsher 2384891434b1SRayagond Kokatanur switch (cmd) { 2385891434b1SRayagond Kokatanur case SIOCGMIIPHY: 2386891434b1SRayagond Kokatanur case SIOCGMIIREG: 2387891434b1SRayagond Kokatanur case SIOCSMIIREG: 23887ac6653aSJeff Kirsher if (!priv->phydev) 23897ac6653aSJeff Kirsher return -EINVAL; 23907ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 2391891434b1SRayagond Kokatanur break; 2392891434b1SRayagond Kokatanur case SIOCSHWTSTAMP: 2393891434b1SRayagond Kokatanur ret = stmmac_hwtstamp_ioctl(dev, rq); 2394891434b1SRayagond Kokatanur break; 2395891434b1SRayagond Kokatanur default: 2396891434b1SRayagond Kokatanur break; 2397891434b1SRayagond Kokatanur } 23987ac6653aSJeff Kirsher 23997ac6653aSJeff Kirsher return ret; 24007ac6653aSJeff Kirsher } 24017ac6653aSJeff Kirsher 24027ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 24037ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 24047ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 2405e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 24067ac29055SGiuseppe CAVALLARO 2407c24602efSGiuseppe CAVALLARO static void sysfs_display_ring(void *head, int size, int extend_desc, 2408c24602efSGiuseppe CAVALLARO struct seq_file *seq) 24097ac29055SGiuseppe CAVALLARO { 24107ac29055SGiuseppe CAVALLARO int i; 2411c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 2412c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 24137ac29055SGiuseppe CAVALLARO 2414c24602efSGiuseppe CAVALLARO for (i = 0; i < size; i++) { 2415c24602efSGiuseppe CAVALLARO u64 x; 2416c24602efSGiuseppe CAVALLARO if (extend_desc) { 2417c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 2418c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2419c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2420c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2421c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 2422c24602efSGiuseppe CAVALLARO ep++; 2423c24602efSGiuseppe CAVALLARO } else { 2424c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 2425c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2426c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2427c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2428c24602efSGiuseppe CAVALLARO p->des2, p->des3); 2429c24602efSGiuseppe CAVALLARO p++; 2430c24602efSGiuseppe CAVALLARO } 24317ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 24327ac29055SGiuseppe CAVALLARO } 2433c24602efSGiuseppe CAVALLARO } 24347ac29055SGiuseppe CAVALLARO 2435c24602efSGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 2436c24602efSGiuseppe CAVALLARO { 2437c24602efSGiuseppe CAVALLARO struct net_device *dev = seq->private; 2438c24602efSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2439c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 2440c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 24417ac29055SGiuseppe CAVALLARO 2442c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 2443c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended RX descriptor ring:\n"); 2444c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_erx, rxsize, 1, seq); 2445c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended TX descriptor ring:\n"); 2446c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_etx, txsize, 1, seq); 2447c24602efSGiuseppe CAVALLARO } else { 2448c24602efSGiuseppe CAVALLARO seq_printf(seq, "RX descriptor ring:\n"); 2449c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_rx, rxsize, 0, seq); 2450c24602efSGiuseppe CAVALLARO seq_printf(seq, "TX descriptor ring:\n"); 2451c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_tx, txsize, 0, seq); 24527ac29055SGiuseppe CAVALLARO } 24537ac29055SGiuseppe CAVALLARO 24547ac29055SGiuseppe CAVALLARO return 0; 24557ac29055SGiuseppe CAVALLARO } 24567ac29055SGiuseppe CAVALLARO 24577ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 24587ac29055SGiuseppe CAVALLARO { 24597ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 24607ac29055SGiuseppe CAVALLARO } 24617ac29055SGiuseppe CAVALLARO 24627ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 24637ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 24647ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 24657ac29055SGiuseppe CAVALLARO .read = seq_read, 24667ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 246774863948SDjalal Harouni .release = single_release, 24687ac29055SGiuseppe CAVALLARO }; 24697ac29055SGiuseppe CAVALLARO 2470e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 2471e7434821SGiuseppe CAVALLARO { 2472e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 2473e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2474e7434821SGiuseppe CAVALLARO 247519e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 2476e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 2477e7434821SGiuseppe CAVALLARO return 0; 2478e7434821SGiuseppe CAVALLARO } 2479e7434821SGiuseppe CAVALLARO 2480e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2481e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 2482e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2483e7434821SGiuseppe CAVALLARO 2484e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 2485e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 2486e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 2487e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 2488e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 2489e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 2490e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 2491e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 2492e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 2493e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 2494e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 2495e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 2496e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 2497e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 2498e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 2499e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 2500e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 2501e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 2502e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 2503e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 2504e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 2505e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 2506e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 2507e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 2508e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 2509e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 2510e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 2511e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 2512e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 2513e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 2514e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 2515e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 2516e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 2517e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 2518e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 2519e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 2520e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 2521e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 2522e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 2523e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 2524e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 2525e7434821SGiuseppe CAVALLARO 2526e7434821SGiuseppe CAVALLARO return 0; 2527e7434821SGiuseppe CAVALLARO } 2528e7434821SGiuseppe CAVALLARO 2529e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 2530e7434821SGiuseppe CAVALLARO { 2531e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 2532e7434821SGiuseppe CAVALLARO } 2533e7434821SGiuseppe CAVALLARO 2534e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 2535e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 2536e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 2537e7434821SGiuseppe CAVALLARO .read = seq_read, 2538e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 253974863948SDjalal Harouni .release = single_release, 2540e7434821SGiuseppe CAVALLARO }; 2541e7434821SGiuseppe CAVALLARO 25427ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 25437ac29055SGiuseppe CAVALLARO { 25447ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 25457ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 25467ac29055SGiuseppe CAVALLARO 25477ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 25487ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 25497ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 25507ac29055SGiuseppe CAVALLARO 25517ac29055SGiuseppe CAVALLARO return -ENOMEM; 25527ac29055SGiuseppe CAVALLARO } 25537ac29055SGiuseppe CAVALLARO 25547ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 25557ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 25567ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 25577ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 25587ac29055SGiuseppe CAVALLARO 25597ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 25607ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 25617ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 25627ac29055SGiuseppe CAVALLARO 25637ac29055SGiuseppe CAVALLARO return -ENOMEM; 25647ac29055SGiuseppe CAVALLARO } 25657ac29055SGiuseppe CAVALLARO 2566e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 2567e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 2568e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 2569e7434821SGiuseppe CAVALLARO 2570e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 2571e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 2572e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2573e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 2574e7434821SGiuseppe CAVALLARO 2575e7434821SGiuseppe CAVALLARO return -ENOMEM; 2576e7434821SGiuseppe CAVALLARO } 2577e7434821SGiuseppe CAVALLARO 25787ac29055SGiuseppe CAVALLARO return 0; 25797ac29055SGiuseppe CAVALLARO } 25807ac29055SGiuseppe CAVALLARO 25817ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 25827ac29055SGiuseppe CAVALLARO { 25837ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2584e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 25857ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 25867ac29055SGiuseppe CAVALLARO } 25877ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 25887ac29055SGiuseppe CAVALLARO 25897ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 25907ac6653aSJeff Kirsher .ndo_open = stmmac_open, 25917ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 25927ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 25937ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 25947ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 259501789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 25967ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 25977ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 25987ac6653aSJeff Kirsher .ndo_set_config = stmmac_config, 25997ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 26007ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 26017ac6653aSJeff Kirsher #endif 26027ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 26037ac6653aSJeff Kirsher }; 26047ac6653aSJeff Kirsher 26057ac6653aSJeff Kirsher /** 2606cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 260732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 2608cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 2609cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 2610cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 2611cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 2612cf3f047bSGiuseppe CAVALLARO * descriptor structure). 2613cf3f047bSGiuseppe CAVALLARO */ 2614cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 2615cf3f047bSGiuseppe CAVALLARO { 2616c24602efSGiuseppe CAVALLARO int ret; 2617cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 2618cf3f047bSGiuseppe CAVALLARO 2619cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 262003f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 262103f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 2622cf3f047bSGiuseppe CAVALLARO mac = dwmac1000_setup(priv->ioaddr); 262303f2eecdSMarc Kleine-Budde } else { 2624cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 262503f2eecdSMarc Kleine-Budde } 2626cf3f047bSGiuseppe CAVALLARO if (!mac) 2627cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 2628cf3f047bSGiuseppe CAVALLARO 2629cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 2630cf3f047bSGiuseppe CAVALLARO 2631cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 2632cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 2633cf3f047bSGiuseppe CAVALLARO 26344a7d666aSGiuseppe CAVALLARO /* To use the chained or ring mode */ 26354a7d666aSGiuseppe CAVALLARO if (chain_mode) { 26364a7d666aSGiuseppe CAVALLARO priv->hw->chain = &chain_mode_ops; 26374a7d666aSGiuseppe CAVALLARO pr_info(" Chain mode enabled\n"); 26384a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_CHAIN_MODE; 26394a7d666aSGiuseppe CAVALLARO } else { 26404a7d666aSGiuseppe CAVALLARO priv->hw->ring = &ring_mode_ops; 26414a7d666aSGiuseppe CAVALLARO pr_info(" Ring mode enabled\n"); 26424a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_RING_MODE; 26434a7d666aSGiuseppe CAVALLARO } 26444a7d666aSGiuseppe CAVALLARO 2645cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 2646cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 2647cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 2648cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 2649cf3f047bSGiuseppe CAVALLARO 2650cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 2651cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 2652cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 2653cf3f047bSGiuseppe CAVALLARO * register (if supported). 2654cf3f047bSGiuseppe CAVALLARO */ 2655cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 2656cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 265738912bdbSDeepak SIKRI 265838912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 265938912bdbSDeepak SIKRI 266038912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 266138912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 266238912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 266338912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 266438912bdbSDeepak SIKRI 2665cf3f047bSGiuseppe CAVALLARO } else 2666cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 2667cf3f047bSGiuseppe CAVALLARO 266861369d02SByungho An /* To use alternate (extended) or normal descriptor structures */ 266961369d02SByungho An stmmac_selec_desc_mode(priv); 267061369d02SByungho An 267138912bdbSDeepak SIKRI ret = priv->hw->mac->rx_ipc(priv->ioaddr); 267238912bdbSDeepak SIKRI if (!ret) { 2673ceb69499SGiuseppe CAVALLARO pr_warn(" RX IPC Checksum Offload not configured.\n"); 267438912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_NONE; 267538912bdbSDeepak SIKRI } 267638912bdbSDeepak SIKRI 267738912bdbSDeepak SIKRI if (priv->plat->rx_coe) 267838912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 267938912bdbSDeepak SIKRI priv->plat->rx_coe); 2680cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 2681cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 2682cf3f047bSGiuseppe CAVALLARO 2683cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 2684cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 2685cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 2686cf3f047bSGiuseppe CAVALLARO } 2687cf3f047bSGiuseppe CAVALLARO 2688c24602efSGiuseppe CAVALLARO return 0; 2689cf3f047bSGiuseppe CAVALLARO } 2690cf3f047bSGiuseppe CAVALLARO 2691cf3f047bSGiuseppe CAVALLARO /** 2692bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 2693bfab27a1SGiuseppe CAVALLARO * @device: device pointer 2694ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 2695ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 2696bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 2697bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 26987ac6653aSJeff Kirsher */ 2699bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 2700cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 2701cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 27027ac6653aSJeff Kirsher { 27037ac6653aSJeff Kirsher int ret = 0; 2704bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 2705bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 27067ac6653aSJeff Kirsher 2707bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 270841de8d4cSJoe Perches if (!ndev) 2709bfab27a1SGiuseppe CAVALLARO return NULL; 27107ac6653aSJeff Kirsher 2711bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 27127ac6653aSJeff Kirsher 2713bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 2714bfab27a1SGiuseppe CAVALLARO priv->device = device; 2715bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 2716bfab27a1SGiuseppe CAVALLARO 2717bfab27a1SGiuseppe CAVALLARO ether_setup(ndev); 2718bfab27a1SGiuseppe CAVALLARO 2719bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 2720cf3f047bSGiuseppe CAVALLARO priv->pause = pause; 2721cf3f047bSGiuseppe CAVALLARO priv->plat = plat_dat; 2722cf3f047bSGiuseppe CAVALLARO priv->ioaddr = addr; 2723cf3f047bSGiuseppe CAVALLARO priv->dev->base_addr = (unsigned long)addr; 2724bfab27a1SGiuseppe CAVALLARO 2725cf3f047bSGiuseppe CAVALLARO /* Verify driver arguments */ 2726cf3f047bSGiuseppe CAVALLARO stmmac_verify_args(); 2727cf3f047bSGiuseppe CAVALLARO 2728cf3f047bSGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 2729ceb69499SGiuseppe CAVALLARO * this needs to have multiple instances 2730ceb69499SGiuseppe CAVALLARO */ 2731cf3f047bSGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 2732cf3f047bSGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 2733cf3f047bSGiuseppe CAVALLARO 273462866e98SChen-Yu Tsai priv->stmmac_clk = devm_clk_get(priv->device, STMMAC_RESOURCE_NAME); 273562866e98SChen-Yu Tsai if (IS_ERR(priv->stmmac_clk)) { 273662866e98SChen-Yu Tsai dev_warn(priv->device, "%s: warning: cannot get CSR clock\n", 273762866e98SChen-Yu Tsai __func__); 2738c5e4ddbdSChen-Yu Tsai ret = PTR_ERR(priv->stmmac_clk); 273962866e98SChen-Yu Tsai goto error_clk_get; 274062866e98SChen-Yu Tsai } 274162866e98SChen-Yu Tsai clk_prepare_enable(priv->stmmac_clk); 274262866e98SChen-Yu Tsai 2743c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = devm_reset_control_get(priv->device, 2744c5e4ddbdSChen-Yu Tsai STMMAC_RESOURCE_NAME); 2745c5e4ddbdSChen-Yu Tsai if (IS_ERR(priv->stmmac_rst)) { 2746c5e4ddbdSChen-Yu Tsai if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) { 2747c5e4ddbdSChen-Yu Tsai ret = -EPROBE_DEFER; 2748c5e4ddbdSChen-Yu Tsai goto error_hw_init; 2749c5e4ddbdSChen-Yu Tsai } 2750c5e4ddbdSChen-Yu Tsai dev_info(priv->device, "no reset control found\n"); 2751c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = NULL; 2752c5e4ddbdSChen-Yu Tsai } 2753c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2754c5e4ddbdSChen-Yu Tsai reset_control_deassert(priv->stmmac_rst); 2755c5e4ddbdSChen-Yu Tsai 2756cf3f047bSGiuseppe CAVALLARO /* Init MAC and get the capabilities */ 2757c24602efSGiuseppe CAVALLARO ret = stmmac_hw_init(priv); 2758c24602efSGiuseppe CAVALLARO if (ret) 275962866e98SChen-Yu Tsai goto error_hw_init; 2760cf3f047bSGiuseppe CAVALLARO 2761cf3f047bSGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 2762cf3f047bSGiuseppe CAVALLARO 2763cf3f047bSGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 2764cf3f047bSGiuseppe CAVALLARO NETIF_F_RXCSUM; 2765bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 2766bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 27677ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 27687ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 2769f646968fSPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; 27707ac6653aSJeff Kirsher #endif 27717ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 27727ac6653aSJeff Kirsher 27737ac6653aSJeff Kirsher if (flow_ctrl) 27747ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 27757ac6653aSJeff Kirsher 277662a2ab93SGiuseppe CAVALLARO /* Rx Watchdog is available in the COREs newer than the 3.40. 277762a2ab93SGiuseppe CAVALLARO * In some case, for example on bugged HW this feature 277862a2ab93SGiuseppe CAVALLARO * has to be disable and this can be done by passing the 277962a2ab93SGiuseppe CAVALLARO * riwt_off field from the platform. 278062a2ab93SGiuseppe CAVALLARO */ 278162a2ab93SGiuseppe CAVALLARO if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { 278262a2ab93SGiuseppe CAVALLARO priv->use_riwt = 1; 278362a2ab93SGiuseppe CAVALLARO pr_info(" Enable RX Mitigation via HW Watchdog Timer\n"); 278462a2ab93SGiuseppe CAVALLARO } 278562a2ab93SGiuseppe CAVALLARO 2786bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 27877ac6653aSJeff Kirsher 27887ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 2789a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 27907ac6653aSJeff Kirsher 2791bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 27927ac6653aSJeff Kirsher if (ret) { 2793cf3f047bSGiuseppe CAVALLARO pr_err("%s: ERROR %i registering the device\n", __func__, ret); 27946a81c26fSViresh Kumar goto error_netdev_register; 27957ac6653aSJeff Kirsher } 27967ac6653aSJeff Kirsher 2797cd7201f4SGiuseppe CAVALLARO /* If a specific clk_csr value is passed from the platform 2798cd7201f4SGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 2799cd7201f4SGiuseppe CAVALLARO * changed at run-time and it is fixed. Viceversa the driver'll try to 2800cd7201f4SGiuseppe CAVALLARO * set the MDC clock dynamically according to the csr actual 2801cd7201f4SGiuseppe CAVALLARO * clock input. 2802cd7201f4SGiuseppe CAVALLARO */ 2803cd7201f4SGiuseppe CAVALLARO if (!priv->plat->clk_csr) 2804cd7201f4SGiuseppe CAVALLARO stmmac_clk_csr_set(priv); 2805cd7201f4SGiuseppe CAVALLARO else 2806cd7201f4SGiuseppe CAVALLARO priv->clk_csr = priv->plat->clk_csr; 2807cd7201f4SGiuseppe CAVALLARO 2808e58bb43fSGiuseppe CAVALLARO stmmac_check_pcs_mode(priv); 2809e58bb43fSGiuseppe CAVALLARO 28104d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 28114d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 28124bfcbd7aSFrancesco Virlinzi /* MDIO bus Registration */ 28134bfcbd7aSFrancesco Virlinzi ret = stmmac_mdio_register(ndev); 28144bfcbd7aSFrancesco Virlinzi if (ret < 0) { 28154bfcbd7aSFrancesco Virlinzi pr_debug("%s: MDIO bus (id: %d) registration failed", 28164bfcbd7aSFrancesco Virlinzi __func__, priv->plat->bus_id); 28176a81c26fSViresh Kumar goto error_mdio_register; 28184bfcbd7aSFrancesco Virlinzi } 2819e58bb43fSGiuseppe CAVALLARO } 28204bfcbd7aSFrancesco Virlinzi 2821bfab27a1SGiuseppe CAVALLARO return priv; 28227ac6653aSJeff Kirsher 28236a81c26fSViresh Kumar error_mdio_register: 28247ac6653aSJeff Kirsher unregister_netdev(ndev); 28256a81c26fSViresh Kumar error_netdev_register: 28266a81c26fSViresh Kumar netif_napi_del(&priv->napi); 282762866e98SChen-Yu Tsai error_hw_init: 282862866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 282962866e98SChen-Yu Tsai error_clk_get: 28307ac6653aSJeff Kirsher free_netdev(ndev); 28317ac6653aSJeff Kirsher 2832c5e4ddbdSChen-Yu Tsai return ERR_PTR(ret); 28337ac6653aSJeff Kirsher } 28347ac6653aSJeff Kirsher 28357ac6653aSJeff Kirsher /** 28367ac6653aSJeff Kirsher * stmmac_dvr_remove 2837bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 28387ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 2839bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 28407ac6653aSJeff Kirsher */ 2841bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 28427ac6653aSJeff Kirsher { 28437ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 28447ac6653aSJeff Kirsher 28457ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 28467ac6653aSJeff Kirsher 28477ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 28487ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 28497ac6653aSJeff Kirsher 2850bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 28514d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 28524d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) 28534bfcbd7aSFrancesco Virlinzi stmmac_mdio_unregister(ndev); 28547ac6653aSJeff Kirsher netif_carrier_off(ndev); 28557ac6653aSJeff Kirsher unregister_netdev(ndev); 2856c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2857c5e4ddbdSChen-Yu Tsai reset_control_assert(priv->stmmac_rst); 285862866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 28597ac6653aSJeff Kirsher free_netdev(ndev); 28607ac6653aSJeff Kirsher 28617ac6653aSJeff Kirsher return 0; 28627ac6653aSJeff Kirsher } 28637ac6653aSJeff Kirsher 28647ac6653aSJeff Kirsher #ifdef CONFIG_PM 2865bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 28667ac6653aSJeff Kirsher { 28677ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2868f8c5a875SGiuseppe CAVALLARO unsigned long flags; 28697ac6653aSJeff Kirsher 28707ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 28717ac6653aSJeff Kirsher return 0; 28727ac6653aSJeff Kirsher 2873102463b1SFrancesco Virlinzi if (priv->phydev) 2874102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 2875102463b1SFrancesco Virlinzi 2876f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 28777ac6653aSJeff Kirsher 28787ac6653aSJeff Kirsher netif_device_detach(ndev); 28797ac6653aSJeff Kirsher netif_stop_queue(ndev); 28807ac6653aSJeff Kirsher 28817ac6653aSJeff Kirsher napi_disable(&priv->napi); 28827ac6653aSJeff Kirsher 28837ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 28847ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 28857ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 2886c24602efSGiuseppe CAVALLARO 2887c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 28887ac6653aSJeff Kirsher 28897ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 289089f7f2cfSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 28917ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 289289f7f2cfSSrinivas Kandagatla priv->irq_wake = 1; 289389f7f2cfSSrinivas Kandagatla } else { 2894bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 2895db88f10aSSrinivas Kandagatla pinctrl_pm_select_sleep_state(priv->device); 2896ba1377ffSGiuseppe CAVALLARO /* Disable clock in case of PWM is off */ 2897a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 2898ba1377ffSGiuseppe CAVALLARO } 2899f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 29007ac6653aSJeff Kirsher return 0; 29017ac6653aSJeff Kirsher } 29027ac6653aSJeff Kirsher 2903bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 29047ac6653aSJeff Kirsher { 29057ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2906f8c5a875SGiuseppe CAVALLARO unsigned long flags; 29077ac6653aSJeff Kirsher 29087ac6653aSJeff Kirsher if (!netif_running(ndev)) 29097ac6653aSJeff Kirsher return 0; 29107ac6653aSJeff Kirsher 2911f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 29127ac6653aSJeff Kirsher 29137ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 29147ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 29157ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 29167ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 2917ceb69499SGiuseppe CAVALLARO * from another devices (e.g. serial console). 2918ceb69499SGiuseppe CAVALLARO */ 2919623997fbSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 29207ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, 0); 292189f7f2cfSSrinivas Kandagatla priv->irq_wake = 0; 2922623997fbSSrinivas Kandagatla } else { 2923db88f10aSSrinivas Kandagatla pinctrl_pm_select_default_state(priv->device); 2924ba1377ffSGiuseppe CAVALLARO /* enable the clk prevously disabled */ 2925a630844dSStefan Roese clk_prepare_enable(priv->stmmac_clk); 2926623997fbSSrinivas Kandagatla /* reset the phy so that it's ready */ 2927623997fbSSrinivas Kandagatla if (priv->mii) 2928623997fbSSrinivas Kandagatla stmmac_mdio_reset(priv->mii); 2929623997fbSSrinivas Kandagatla } 29307ac6653aSJeff Kirsher 29317ac6653aSJeff Kirsher netif_device_attach(ndev); 29327ac6653aSJeff Kirsher 2933623997fbSSrinivas Kandagatla stmmac_hw_setup(ndev); 29347ac6653aSJeff Kirsher 29357ac6653aSJeff Kirsher napi_enable(&priv->napi); 29367ac6653aSJeff Kirsher 29377ac6653aSJeff Kirsher netif_start_queue(ndev); 29387ac6653aSJeff Kirsher 2939f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 2940102463b1SFrancesco Virlinzi 2941102463b1SFrancesco Virlinzi if (priv->phydev) 2942102463b1SFrancesco Virlinzi phy_start(priv->phydev); 2943102463b1SFrancesco Virlinzi 29447ac6653aSJeff Kirsher return 0; 29457ac6653aSJeff Kirsher } 29467ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 29477ac6653aSJeff Kirsher 294833d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers 294933d5e332SGiuseppe CAVALLARO * depending on the configuration selected. 295033d5e332SGiuseppe CAVALLARO */ 2951ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void) 2952ba27ec66SGiuseppe CAVALLARO { 2953493682b8SKonstantin Khlebnikov int ret; 2954ba27ec66SGiuseppe CAVALLARO 2955493682b8SKonstantin Khlebnikov ret = stmmac_register_platform(); 2956493682b8SKonstantin Khlebnikov if (ret) 2957493682b8SKonstantin Khlebnikov goto err; 2958493682b8SKonstantin Khlebnikov ret = stmmac_register_pci(); 2959493682b8SKonstantin Khlebnikov if (ret) 2960493682b8SKonstantin Khlebnikov goto err_pci; 296133d5e332SGiuseppe CAVALLARO return 0; 2962493682b8SKonstantin Khlebnikov err_pci: 2963493682b8SKonstantin Khlebnikov stmmac_unregister_platform(); 2964493682b8SKonstantin Khlebnikov err: 2965493682b8SKonstantin Khlebnikov pr_err("stmmac: driver registration failed\n"); 2966493682b8SKonstantin Khlebnikov return ret; 2967ba27ec66SGiuseppe CAVALLARO } 2968ba27ec66SGiuseppe CAVALLARO 2969ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void) 2970ba27ec66SGiuseppe CAVALLARO { 297133d5e332SGiuseppe CAVALLARO stmmac_unregister_platform(); 297233d5e332SGiuseppe CAVALLARO stmmac_unregister_pci(); 2973ba27ec66SGiuseppe CAVALLARO } 2974ba27ec66SGiuseppe CAVALLARO 2975ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init); 2976ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit); 2977ba27ec66SGiuseppe CAVALLARO 29787ac6653aSJeff Kirsher #ifndef MODULE 29797ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 29807ac6653aSJeff Kirsher { 29817ac6653aSJeff Kirsher char *opt; 29827ac6653aSJeff Kirsher 29837ac6653aSJeff Kirsher if (!str || !*str) 29847ac6653aSJeff Kirsher return -EINVAL; 29857ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 29867ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 2987ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &debug)) 29887ac6653aSJeff Kirsher goto err; 29897ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 2990ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 8, 0, &phyaddr)) 29917ac6653aSJeff Kirsher goto err; 29927ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 2993ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_txsize)) 29947ac6653aSJeff Kirsher goto err; 29957ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 2996ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_rxsize)) 29977ac6653aSJeff Kirsher goto err; 29987ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 2999ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &buf_sz)) 30007ac6653aSJeff Kirsher goto err; 30017ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 3002ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 3, 0, &tc)) 30037ac6653aSJeff Kirsher goto err; 30047ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 3005ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 9, 0, &watchdog)) 30067ac6653aSJeff Kirsher goto err; 30077ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 3008ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &flow_ctrl)) 30097ac6653aSJeff Kirsher goto err; 30107ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 3011ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &pause)) 30127ac6653aSJeff Kirsher goto err; 3013506f669cSGiuseppe CAVALLARO } else if (!strncmp(opt, "eee_timer:", 10)) { 3014d765955dSGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &eee_timer)) 3015d765955dSGiuseppe CAVALLARO goto err; 30164a7d666aSGiuseppe CAVALLARO } else if (!strncmp(opt, "chain_mode:", 11)) { 30174a7d666aSGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &chain_mode)) 30184a7d666aSGiuseppe CAVALLARO goto err; 30197ac6653aSJeff Kirsher } 30207ac6653aSJeff Kirsher } 30217ac6653aSJeff Kirsher return 0; 30227ac6653aSJeff Kirsher 30237ac6653aSJeff Kirsher err: 30247ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 30257ac6653aSJeff Kirsher return -EINVAL; 30267ac6653aSJeff Kirsher } 30277ac6653aSJeff Kirsher 30287ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 3029ceb69499SGiuseppe CAVALLARO #endif /* MODULE */ 30306fc0d0f2SGiuseppe Cavallaro 30316fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 30326fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 30336fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 3034