17ac6653aSJeff Kirsher /******************************************************************************* 27ac6653aSJeff Kirsher This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers. 37ac6653aSJeff Kirsher ST Ethernet IPs are built around a Synopsys IP Core. 47ac6653aSJeff Kirsher 5286a8372SGiuseppe CAVALLARO Copyright(C) 2007-2011 STMicroelectronics Ltd 67ac6653aSJeff Kirsher 77ac6653aSJeff Kirsher This program is free software; you can redistribute it and/or modify it 87ac6653aSJeff Kirsher under the terms and conditions of the GNU General Public License, 97ac6653aSJeff Kirsher version 2, as published by the Free Software Foundation. 107ac6653aSJeff Kirsher 117ac6653aSJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 127ac6653aSJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137ac6653aSJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 147ac6653aSJeff Kirsher more details. 157ac6653aSJeff Kirsher 167ac6653aSJeff Kirsher You should have received a copy of the GNU General Public License along with 177ac6653aSJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 187ac6653aSJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 197ac6653aSJeff Kirsher 207ac6653aSJeff Kirsher The full GNU General Public License is included in this distribution in 217ac6653aSJeff Kirsher the file called "COPYING". 227ac6653aSJeff Kirsher 237ac6653aSJeff Kirsher Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 247ac6653aSJeff Kirsher 257ac6653aSJeff Kirsher Documentation available at: 267ac6653aSJeff Kirsher http://www.stlinux.com 277ac6653aSJeff Kirsher Support available at: 287ac6653aSJeff Kirsher https://bugzilla.stlinux.com/ 297ac6653aSJeff Kirsher *******************************************************************************/ 307ac6653aSJeff Kirsher 316a81c26fSViresh Kumar #include <linux/clk.h> 327ac6653aSJeff Kirsher #include <linux/kernel.h> 337ac6653aSJeff Kirsher #include <linux/interrupt.h> 347ac6653aSJeff Kirsher #include <linux/ip.h> 357ac6653aSJeff Kirsher #include <linux/tcp.h> 367ac6653aSJeff Kirsher #include <linux/skbuff.h> 377ac6653aSJeff Kirsher #include <linux/ethtool.h> 387ac6653aSJeff Kirsher #include <linux/if_ether.h> 397ac6653aSJeff Kirsher #include <linux/crc32.h> 407ac6653aSJeff Kirsher #include <linux/mii.h> 4101789349SJiri Pirko #include <linux/if.h> 427ac6653aSJeff Kirsher #include <linux/if_vlan.h> 437ac6653aSJeff Kirsher #include <linux/dma-mapping.h> 447ac6653aSJeff Kirsher #include <linux/slab.h> 457ac6653aSJeff Kirsher #include <linux/prefetch.h> 467ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 477ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h> 487ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h> 497ac29055SGiuseppe CAVALLARO #endif 50286a8372SGiuseppe CAVALLARO #include "stmmac.h" 517ac6653aSJeff Kirsher 527ac6653aSJeff Kirsher #undef STMMAC_DEBUG 537ac6653aSJeff Kirsher /*#define STMMAC_DEBUG*/ 547ac6653aSJeff Kirsher #ifdef STMMAC_DEBUG 557ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) \ 567ac6653aSJeff Kirsher ((void)(netif_msg_##nlevel(priv) && \ 577ac6653aSJeff Kirsher printk(KERN_##klevel fmt, ## args))) 587ac6653aSJeff Kirsher #else 597ac6653aSJeff Kirsher #define DBG(nlevel, klevel, fmt, args...) do { } while (0) 607ac6653aSJeff Kirsher #endif 617ac6653aSJeff Kirsher 627ac6653aSJeff Kirsher #undef STMMAC_RX_DEBUG 637ac6653aSJeff Kirsher /*#define STMMAC_RX_DEBUG*/ 647ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 657ac6653aSJeff Kirsher #define RX_DBG(fmt, args...) printk(fmt, ## args) 667ac6653aSJeff Kirsher #else 677ac6653aSJeff Kirsher #define RX_DBG(fmt, args...) do { } while (0) 687ac6653aSJeff Kirsher #endif 697ac6653aSJeff Kirsher 707ac6653aSJeff Kirsher #undef STMMAC_XMIT_DEBUG 717ac6653aSJeff Kirsher /*#define STMMAC_XMIT_DEBUG*/ 727ac6653aSJeff Kirsher #ifdef STMMAC_TX_DEBUG 737ac6653aSJeff Kirsher #define TX_DBG(fmt, args...) printk(fmt, ## args) 747ac6653aSJeff Kirsher #else 757ac6653aSJeff Kirsher #define TX_DBG(fmt, args...) do { } while (0) 767ac6653aSJeff Kirsher #endif 777ac6653aSJeff Kirsher 787ac6653aSJeff Kirsher #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) 797ac6653aSJeff Kirsher #define JUMBO_LEN 9000 807ac6653aSJeff Kirsher 817ac6653aSJeff Kirsher /* Module parameters */ 827ac6653aSJeff Kirsher #define TX_TIMEO 5000 /* default 5 seconds */ 837ac6653aSJeff Kirsher static int watchdog = TX_TIMEO; 847ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR); 857ac6653aSJeff Kirsher MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds"); 867ac6653aSJeff Kirsher 877ac6653aSJeff Kirsher static int debug = -1; /* -1: default, 0: no output, 16: all */ 887ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR); 897ac6653aSJeff Kirsher MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)"); 907ac6653aSJeff Kirsher 91bfab27a1SGiuseppe CAVALLARO int phyaddr = -1; 927ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO); 937ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address"); 947ac6653aSJeff Kirsher 957ac6653aSJeff Kirsher #define DMA_TX_SIZE 256 967ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE; 977ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR); 987ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list"); 997ac6653aSJeff Kirsher 1007ac6653aSJeff Kirsher #define DMA_RX_SIZE 256 1017ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE; 1027ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR); 1037ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list"); 1047ac6653aSJeff Kirsher 1057ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF; 1067ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); 1077ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); 1087ac6653aSJeff Kirsher 1097ac6653aSJeff Kirsher static int pause = PAUSE_TIME; 1107ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR); 1117ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time"); 1127ac6653aSJeff Kirsher 1137ac6653aSJeff Kirsher #define TC_DEFAULT 64 1147ac6653aSJeff Kirsher static int tc = TC_DEFAULT; 1157ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR); 1167ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value"); 1177ac6653aSJeff Kirsher 1187ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE BUF_SIZE_2KiB 1197ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE; 1207ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 1217ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 1227ac6653aSJeff Kirsher 1237ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1247ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1257ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1267ac6653aSJeff Kirsher 127d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER 1000 128d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; 129d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR); 130d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); 131d765955dSGiuseppe CAVALLARO #define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x)) 132d765955dSGiuseppe CAVALLARO 1337ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1347ac6653aSJeff Kirsher 135bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 136bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev); 137bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void); 138bfab27a1SGiuseppe CAVALLARO #endif 139bfab27a1SGiuseppe CAVALLARO 1409125cdd1SGiuseppe CAVALLARO #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) 1419125cdd1SGiuseppe CAVALLARO 1427ac6653aSJeff Kirsher /** 1437ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1447ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1457ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1467ac6653aSJeff Kirsher */ 1477ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1487ac6653aSJeff Kirsher { 1497ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1507ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1517ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1527ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1537ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1547ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 1557ac6653aSJeff Kirsher if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) 1567ac6653aSJeff Kirsher buf_sz = DMA_BUFFER_SIZE; 1577ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1587ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1597ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1607ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1617ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1627ac6653aSJeff Kirsher pause = PAUSE_TIME; 163d765955dSGiuseppe CAVALLARO if (eee_timer < 0) 164d765955dSGiuseppe CAVALLARO eee_timer = STMMAC_DEFAULT_LPI_TIMER; 1657ac6653aSJeff Kirsher } 1667ac6653aSJeff Kirsher 167cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv) 168cd7201f4SGiuseppe CAVALLARO { 169cd7201f4SGiuseppe CAVALLARO u32 clk_rate; 170cd7201f4SGiuseppe CAVALLARO 171cd7201f4SGiuseppe CAVALLARO clk_rate = clk_get_rate(priv->stmmac_clk); 172cd7201f4SGiuseppe CAVALLARO 173cd7201f4SGiuseppe CAVALLARO /* Platform provided default clk_csr would be assumed valid 174cd7201f4SGiuseppe CAVALLARO * for all other cases except for the below mentioned ones. */ 175cd7201f4SGiuseppe CAVALLARO if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) { 176cd7201f4SGiuseppe CAVALLARO if (clk_rate < CSR_F_35M) 177cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_20_35M; 178cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M)) 179cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_35_60M; 180cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M)) 181cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_60_100M; 182cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M)) 183cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_100_150M; 184cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) 185cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_150_250M; 186cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) 187cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_250_300M; 188cd7201f4SGiuseppe CAVALLARO } /* For values higher than the IEEE 802.3 specified frequency 189cd7201f4SGiuseppe CAVALLARO * we can not estimate the proper divider as it is not known 190cd7201f4SGiuseppe CAVALLARO * the frequency of clk_csr_i. So we do not change the default 191cd7201f4SGiuseppe CAVALLARO * divider. */ 192cd7201f4SGiuseppe CAVALLARO } 193cd7201f4SGiuseppe CAVALLARO 1947ac6653aSJeff Kirsher #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) 1957ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1967ac6653aSJeff Kirsher { 1977ac6653aSJeff Kirsher int j; 1987ac6653aSJeff Kirsher pr_info("len = %d byte, buf addr: 0x%p", len, buf); 1997ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 2007ac6653aSJeff Kirsher if ((j % 16) == 0) 2017ac6653aSJeff Kirsher pr_info("\n %03x:", j); 2027ac6653aSJeff Kirsher pr_info(" %02x", buf[j]); 2037ac6653aSJeff Kirsher } 2047ac6653aSJeff Kirsher pr_info("\n"); 2057ac6653aSJeff Kirsher } 2067ac6653aSJeff Kirsher #endif 2077ac6653aSJeff Kirsher 2087ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 2097ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 2107ac6653aSJeff Kirsher 2117ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 2127ac6653aSJeff Kirsher { 2137ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 2147ac6653aSJeff Kirsher } 2157ac6653aSJeff Kirsher 2167ac6653aSJeff Kirsher /* On some ST platforms, some HW system configuraton registers have to be 2177ac6653aSJeff Kirsher * set according to the link speed negotiated. 2187ac6653aSJeff Kirsher */ 2197ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 2207ac6653aSJeff Kirsher { 2217ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2227ac6653aSJeff Kirsher 2237ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 2247ac6653aSJeff Kirsher priv->plat->fix_mac_speed(priv->plat->bsp_priv, 2257ac6653aSJeff Kirsher phydev->speed); 2267ac6653aSJeff Kirsher } 2277ac6653aSJeff Kirsher 228d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv) 229d765955dSGiuseppe CAVALLARO { 230d765955dSGiuseppe CAVALLARO /* Check and enter in LPI mode */ 231d765955dSGiuseppe CAVALLARO if ((priv->dirty_tx == priv->cur_tx) && 232d765955dSGiuseppe CAVALLARO (priv->tx_path_in_lpi_mode == false)) 233d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_mode(priv->ioaddr); 234d765955dSGiuseppe CAVALLARO } 235d765955dSGiuseppe CAVALLARO 236d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv) 237d765955dSGiuseppe CAVALLARO { 238d765955dSGiuseppe CAVALLARO /* Exit and disable EEE in case of we are are in LPI state. */ 239d765955dSGiuseppe CAVALLARO priv->hw->mac->reset_eee_mode(priv->ioaddr); 240d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 241d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 242d765955dSGiuseppe CAVALLARO } 243d765955dSGiuseppe CAVALLARO 244d765955dSGiuseppe CAVALLARO /** 245d765955dSGiuseppe CAVALLARO * stmmac_eee_ctrl_timer 246d765955dSGiuseppe CAVALLARO * @arg : data hook 247d765955dSGiuseppe CAVALLARO * Description: 248d765955dSGiuseppe CAVALLARO * If there is no data transfer and if we are not in LPI state, 249d765955dSGiuseppe CAVALLARO * then MAC Transmitter can be moved to LPI state. 250d765955dSGiuseppe CAVALLARO */ 251d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg) 252d765955dSGiuseppe CAVALLARO { 253d765955dSGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)arg; 254d765955dSGiuseppe CAVALLARO 255d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 256d765955dSGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); 257d765955dSGiuseppe CAVALLARO } 258d765955dSGiuseppe CAVALLARO 259d765955dSGiuseppe CAVALLARO /** 260d765955dSGiuseppe CAVALLARO * stmmac_eee_init 261d765955dSGiuseppe CAVALLARO * @priv: private device pointer 262d765955dSGiuseppe CAVALLARO * Description: 263d765955dSGiuseppe CAVALLARO * If the EEE support has been enabled while configuring the driver, 264d765955dSGiuseppe CAVALLARO * if the GMAC actually supports the EEE (from the HW cap reg) and the 265d765955dSGiuseppe CAVALLARO * phy can also manage EEE, so enable the LPI state and start the timer 266d765955dSGiuseppe CAVALLARO * to verify if the tx path can enter in LPI state. 267d765955dSGiuseppe CAVALLARO */ 268d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv) 269d765955dSGiuseppe CAVALLARO { 270d765955dSGiuseppe CAVALLARO bool ret = false; 271d765955dSGiuseppe CAVALLARO 272d765955dSGiuseppe CAVALLARO /* MAC core supports the EEE feature. */ 273d765955dSGiuseppe CAVALLARO if (priv->dma_cap.eee) { 274d765955dSGiuseppe CAVALLARO /* Check if the PHY supports EEE */ 275d765955dSGiuseppe CAVALLARO if (phy_init_eee(priv->phydev, 1)) 276d765955dSGiuseppe CAVALLARO goto out; 277d765955dSGiuseppe CAVALLARO 278d765955dSGiuseppe CAVALLARO priv->eee_active = 1; 279d765955dSGiuseppe CAVALLARO init_timer(&priv->eee_ctrl_timer); 280d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; 281d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.data = (unsigned long)priv; 282d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer); 283d765955dSGiuseppe CAVALLARO add_timer(&priv->eee_ctrl_timer); 284d765955dSGiuseppe CAVALLARO 285d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_timer(priv->ioaddr, 286d765955dSGiuseppe CAVALLARO STMMAC_DEFAULT_LIT_LS_TIMER, 287d765955dSGiuseppe CAVALLARO priv->tx_lpi_timer); 288d765955dSGiuseppe CAVALLARO 289d765955dSGiuseppe CAVALLARO pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); 290d765955dSGiuseppe CAVALLARO 291d765955dSGiuseppe CAVALLARO ret = true; 292d765955dSGiuseppe CAVALLARO } 293d765955dSGiuseppe CAVALLARO out: 294d765955dSGiuseppe CAVALLARO return ret; 295d765955dSGiuseppe CAVALLARO } 296d765955dSGiuseppe CAVALLARO 297d765955dSGiuseppe CAVALLARO static void stmmac_eee_adjust(struct stmmac_priv *priv) 298d765955dSGiuseppe CAVALLARO { 299d765955dSGiuseppe CAVALLARO /* When the EEE has been already initialised we have to 300d765955dSGiuseppe CAVALLARO * modify the PLS bit in the LPI ctrl & status reg according 301d765955dSGiuseppe CAVALLARO * to the PHY link status. For this reason. 302d765955dSGiuseppe CAVALLARO */ 303d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 304d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link); 305d765955dSGiuseppe CAVALLARO } 306d765955dSGiuseppe CAVALLARO 3077ac6653aSJeff Kirsher /** 3087ac6653aSJeff Kirsher * stmmac_adjust_link 3097ac6653aSJeff Kirsher * @dev: net device structure 3107ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 3117ac6653aSJeff Kirsher */ 3127ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 3137ac6653aSJeff Kirsher { 3147ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 3157ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 3167ac6653aSJeff Kirsher unsigned long flags; 3177ac6653aSJeff Kirsher int new_state = 0; 3187ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 3197ac6653aSJeff Kirsher 3207ac6653aSJeff Kirsher if (phydev == NULL) 3217ac6653aSJeff Kirsher return; 3227ac6653aSJeff Kirsher 3237ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n", 3247ac6653aSJeff Kirsher phydev->addr, phydev->link); 3257ac6653aSJeff Kirsher 3267ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 327d765955dSGiuseppe CAVALLARO 3287ac6653aSJeff Kirsher if (phydev->link) { 3297ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 3307ac6653aSJeff Kirsher 3317ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 3327ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 3337ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 3347ac6653aSJeff Kirsher new_state = 1; 3357ac6653aSJeff Kirsher if (!(phydev->duplex)) 3367ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 3377ac6653aSJeff Kirsher else 3387ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 3397ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 3407ac6653aSJeff Kirsher } 3417ac6653aSJeff Kirsher /* Flow Control operation */ 3427ac6653aSJeff Kirsher if (phydev->pause) 3437ac6653aSJeff Kirsher priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, 3447ac6653aSJeff Kirsher fc, pause_time); 3457ac6653aSJeff Kirsher 3467ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 3477ac6653aSJeff Kirsher new_state = 1; 3487ac6653aSJeff Kirsher switch (phydev->speed) { 3497ac6653aSJeff Kirsher case 1000: 3507ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 3517ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 3527ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 3537ac6653aSJeff Kirsher break; 3547ac6653aSJeff Kirsher case 100: 3557ac6653aSJeff Kirsher case 10: 3567ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 3577ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 3587ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 3597ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 3607ac6653aSJeff Kirsher } else { 3617ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 3627ac6653aSJeff Kirsher } 3637ac6653aSJeff Kirsher } else { 3647ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 3657ac6653aSJeff Kirsher } 3667ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 3677ac6653aSJeff Kirsher break; 3687ac6653aSJeff Kirsher default: 3697ac6653aSJeff Kirsher if (netif_msg_link(priv)) 3707ac6653aSJeff Kirsher pr_warning("%s: Speed (%d) is not 10" 3717ac6653aSJeff Kirsher " or 100!\n", dev->name, phydev->speed); 3727ac6653aSJeff Kirsher break; 3737ac6653aSJeff Kirsher } 3747ac6653aSJeff Kirsher 3757ac6653aSJeff Kirsher priv->speed = phydev->speed; 3767ac6653aSJeff Kirsher } 3777ac6653aSJeff Kirsher 3787ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 3797ac6653aSJeff Kirsher 3807ac6653aSJeff Kirsher if (!priv->oldlink) { 3817ac6653aSJeff Kirsher new_state = 1; 3827ac6653aSJeff Kirsher priv->oldlink = 1; 3837ac6653aSJeff Kirsher } 3847ac6653aSJeff Kirsher } else if (priv->oldlink) { 3857ac6653aSJeff Kirsher new_state = 1; 3867ac6653aSJeff Kirsher priv->oldlink = 0; 3877ac6653aSJeff Kirsher priv->speed = 0; 3887ac6653aSJeff Kirsher priv->oldduplex = -1; 3897ac6653aSJeff Kirsher } 3907ac6653aSJeff Kirsher 3917ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 3927ac6653aSJeff Kirsher phy_print_status(phydev); 3937ac6653aSJeff Kirsher 394d765955dSGiuseppe CAVALLARO stmmac_eee_adjust(priv); 395d765955dSGiuseppe CAVALLARO 3967ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 3977ac6653aSJeff Kirsher 3987ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n"); 3997ac6653aSJeff Kirsher } 4007ac6653aSJeff Kirsher 4017ac6653aSJeff Kirsher /** 4027ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 4037ac6653aSJeff Kirsher * @dev: net device structure 4047ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 4057ac6653aSJeff Kirsher * to the mac driver. 4067ac6653aSJeff Kirsher * Return value: 4077ac6653aSJeff Kirsher * 0 on success 4087ac6653aSJeff Kirsher */ 4097ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 4107ac6653aSJeff Kirsher { 4117ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 4127ac6653aSJeff Kirsher struct phy_device *phydev; 413d765955dSGiuseppe CAVALLARO char phy_id_fmt[MII_BUS_ID_SIZE + 3]; 4147ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 41579ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 4167ac6653aSJeff Kirsher priv->oldlink = 0; 4177ac6653aSJeff Kirsher priv->speed = 0; 4187ac6653aSJeff Kirsher priv->oldduplex = -1; 4197ac6653aSJeff Kirsher 420f142af2eSSrinivas Kandagatla if (priv->plat->phy_bus_name) 421f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", 422f142af2eSSrinivas Kandagatla priv->plat->phy_bus_name, priv->plat->bus_id); 423f142af2eSSrinivas Kandagatla else 424f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", 425f142af2eSSrinivas Kandagatla priv->plat->bus_id); 426f142af2eSSrinivas Kandagatla 427d765955dSGiuseppe CAVALLARO snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 4287ac6653aSJeff Kirsher priv->plat->phy_addr); 429d765955dSGiuseppe CAVALLARO pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 4307ac6653aSJeff Kirsher 431d765955dSGiuseppe CAVALLARO phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, 0, 432d765955dSGiuseppe CAVALLARO interface); 4337ac6653aSJeff Kirsher 4347ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 4357ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 4367ac6653aSJeff Kirsher return PTR_ERR(phydev); 4377ac6653aSJeff Kirsher } 4387ac6653aSJeff Kirsher 43979ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 440c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 441c5b9b4e4SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII)) 442c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 443c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 44479ee1dc3SSrinivas Kandagatla 4457ac6653aSJeff Kirsher /* 4467ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 4477ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 4487ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 4497ac6653aSJeff Kirsher * device as well. 4507ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 4517ac6653aSJeff Kirsher */ 4527ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 4537ac6653aSJeff Kirsher phy_disconnect(phydev); 4547ac6653aSJeff Kirsher return -ENODEV; 4557ac6653aSJeff Kirsher } 4567ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 4577ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 4587ac6653aSJeff Kirsher 4597ac6653aSJeff Kirsher priv->phydev = phydev; 4607ac6653aSJeff Kirsher 4617ac6653aSJeff Kirsher return 0; 4627ac6653aSJeff Kirsher } 4637ac6653aSJeff Kirsher 4647ac6653aSJeff Kirsher /** 4657ac6653aSJeff Kirsher * display_ring 4667ac6653aSJeff Kirsher * @p: pointer to the ring. 4677ac6653aSJeff Kirsher * @size: size of the ring. 4687ac6653aSJeff Kirsher * Description: display all the descriptors within the ring. 4697ac6653aSJeff Kirsher */ 4707ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size) 4717ac6653aSJeff Kirsher { 4727ac6653aSJeff Kirsher struct tmp_s { 4737ac6653aSJeff Kirsher u64 a; 4747ac6653aSJeff Kirsher unsigned int b; 4757ac6653aSJeff Kirsher unsigned int c; 4767ac6653aSJeff Kirsher }; 4777ac6653aSJeff Kirsher int i; 4787ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 4797ac6653aSJeff Kirsher struct tmp_s *x = (struct tmp_s *)(p + i); 4807ac6653aSJeff Kirsher pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 4817ac6653aSJeff Kirsher i, (unsigned int)virt_to_phys(&p[i]), 4827ac6653aSJeff Kirsher (unsigned int)(x->a), (unsigned int)((x->a) >> 32), 4837ac6653aSJeff Kirsher x->b, x->c); 4847ac6653aSJeff Kirsher pr_info("\n"); 4857ac6653aSJeff Kirsher } 4867ac6653aSJeff Kirsher } 4877ac6653aSJeff Kirsher 488286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 489286a8372SGiuseppe CAVALLARO { 490286a8372SGiuseppe CAVALLARO int ret = bufsize; 491286a8372SGiuseppe CAVALLARO 492286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 493286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 494286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 495286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 496286a8372SGiuseppe CAVALLARO else if (mtu >= DMA_BUFFER_SIZE) 497286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 498286a8372SGiuseppe CAVALLARO else 499286a8372SGiuseppe CAVALLARO ret = DMA_BUFFER_SIZE; 500286a8372SGiuseppe CAVALLARO 501286a8372SGiuseppe CAVALLARO return ret; 502286a8372SGiuseppe CAVALLARO } 503286a8372SGiuseppe CAVALLARO 5047ac6653aSJeff Kirsher /** 5057ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 5067ac6653aSJeff Kirsher * @dev: net device structure 5077ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 508286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 509286a8372SGiuseppe CAVALLARO * modes. 5107ac6653aSJeff Kirsher */ 5117ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev) 5127ac6653aSJeff Kirsher { 5137ac6653aSJeff Kirsher int i; 5147ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 5157ac6653aSJeff Kirsher struct sk_buff *skb; 5167ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 5177ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 518286a8372SGiuseppe CAVALLARO unsigned int bfsize; 519286a8372SGiuseppe CAVALLARO int dis_ic = 0; 520286a8372SGiuseppe CAVALLARO int des3_as_data_buf = 0; 5217ac6653aSJeff Kirsher 522286a8372SGiuseppe CAVALLARO /* Set the max buffer size according to the DESC mode 523286a8372SGiuseppe CAVALLARO * and the MTU. Note that RING mode allows 16KiB bsize. */ 524286a8372SGiuseppe CAVALLARO bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu); 525286a8372SGiuseppe CAVALLARO 526286a8372SGiuseppe CAVALLARO if (bfsize == BUF_SIZE_16KiB) 527286a8372SGiuseppe CAVALLARO des3_as_data_buf = 1; 5287ac6653aSJeff Kirsher else 529286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 5307ac6653aSJeff Kirsher 5317ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n", 5327ac6653aSJeff Kirsher txsize, rxsize, bfsize); 5337ac6653aSJeff Kirsher 5347ac6653aSJeff Kirsher priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL); 5357ac6653aSJeff Kirsher priv->rx_skbuff = 5367ac6653aSJeff Kirsher kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL); 5377ac6653aSJeff Kirsher priv->dma_rx = 5387ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 5397ac6653aSJeff Kirsher rxsize * 5407ac6653aSJeff Kirsher sizeof(struct dma_desc), 5417ac6653aSJeff Kirsher &priv->dma_rx_phy, 5427ac6653aSJeff Kirsher GFP_KERNEL); 5437ac6653aSJeff Kirsher priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize, 5447ac6653aSJeff Kirsher GFP_KERNEL); 5457ac6653aSJeff Kirsher priv->dma_tx = 5467ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 5477ac6653aSJeff Kirsher txsize * 5487ac6653aSJeff Kirsher sizeof(struct dma_desc), 5497ac6653aSJeff Kirsher &priv->dma_tx_phy, 5507ac6653aSJeff Kirsher GFP_KERNEL); 5517ac6653aSJeff Kirsher 5527ac6653aSJeff Kirsher if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) { 5537ac6653aSJeff Kirsher pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__); 5547ac6653aSJeff Kirsher return; 5557ac6653aSJeff Kirsher } 5567ac6653aSJeff Kirsher 557286a8372SGiuseppe CAVALLARO DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, " 5587ac6653aSJeff Kirsher "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 5597ac6653aSJeff Kirsher dev->name, priv->dma_rx, priv->dma_tx, 5607ac6653aSJeff Kirsher (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 5617ac6653aSJeff Kirsher 5627ac6653aSJeff Kirsher /* RX INITIALIZATION */ 5637ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: SKB addresses:\n" 5647ac6653aSJeff Kirsher "skb\t\tskb data\tdma data\n"); 5657ac6653aSJeff Kirsher 5667ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 5677ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + i; 5687ac6653aSJeff Kirsher 56945db81e1SGiuseppe CAVALLARO skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN, 57045db81e1SGiuseppe CAVALLARO GFP_KERNEL); 5717ac6653aSJeff Kirsher if (unlikely(skb == NULL)) { 5727ac6653aSJeff Kirsher pr_err("%s: Rx init fails; skb is NULL\n", __func__); 5737ac6653aSJeff Kirsher break; 5747ac6653aSJeff Kirsher } 57545db81e1SGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 5767ac6653aSJeff Kirsher priv->rx_skbuff[i] = skb; 5777ac6653aSJeff Kirsher priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 5787ac6653aSJeff Kirsher bfsize, DMA_FROM_DEVICE); 5797ac6653aSJeff Kirsher 5807ac6653aSJeff Kirsher p->des2 = priv->rx_skbuff_dma[i]; 581286a8372SGiuseppe CAVALLARO 582286a8372SGiuseppe CAVALLARO priv->hw->ring->init_desc3(des3_as_data_buf, p); 583286a8372SGiuseppe CAVALLARO 5847ac6653aSJeff Kirsher DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 5857ac6653aSJeff Kirsher priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]); 5867ac6653aSJeff Kirsher } 5877ac6653aSJeff Kirsher priv->cur_rx = 0; 5887ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 5897ac6653aSJeff Kirsher priv->dma_buf_sz = bfsize; 5907ac6653aSJeff Kirsher buf_sz = bfsize; 5917ac6653aSJeff Kirsher 5927ac6653aSJeff Kirsher /* TX INITIALIZATION */ 5937ac6653aSJeff Kirsher for (i = 0; i < txsize; i++) { 5947ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 5957ac6653aSJeff Kirsher priv->dma_tx[i].des2 = 0; 5967ac6653aSJeff Kirsher } 597286a8372SGiuseppe CAVALLARO 598286a8372SGiuseppe CAVALLARO /* In case of Chained mode this sets the des3 to the next 599286a8372SGiuseppe CAVALLARO * element in the chain */ 600286a8372SGiuseppe CAVALLARO priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize); 601286a8372SGiuseppe CAVALLARO priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize); 602286a8372SGiuseppe CAVALLARO 6037ac6653aSJeff Kirsher priv->dirty_tx = 0; 6047ac6653aSJeff Kirsher priv->cur_tx = 0; 6057ac6653aSJeff Kirsher 60662a2ab93SGiuseppe CAVALLARO if (priv->use_riwt) 60762a2ab93SGiuseppe CAVALLARO dis_ic = 1; 6087ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 6097ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic); 6107ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, txsize); 6117ac6653aSJeff Kirsher 6127ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 6137ac6653aSJeff Kirsher pr_info("RX descriptor ring:\n"); 6147ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 6157ac6653aSJeff Kirsher pr_info("TX descriptor ring:\n"); 6167ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 6177ac6653aSJeff Kirsher } 6187ac6653aSJeff Kirsher } 6197ac6653aSJeff Kirsher 6207ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 6217ac6653aSJeff Kirsher { 6227ac6653aSJeff Kirsher int i; 6237ac6653aSJeff Kirsher 6247ac6653aSJeff Kirsher for (i = 0; i < priv->dma_rx_size; i++) { 6257ac6653aSJeff Kirsher if (priv->rx_skbuff[i]) { 6267ac6653aSJeff Kirsher dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 6277ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 6287ac6653aSJeff Kirsher dev_kfree_skb_any(priv->rx_skbuff[i]); 6297ac6653aSJeff Kirsher } 6307ac6653aSJeff Kirsher priv->rx_skbuff[i] = NULL; 6317ac6653aSJeff Kirsher } 6327ac6653aSJeff Kirsher } 6337ac6653aSJeff Kirsher 6347ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 6357ac6653aSJeff Kirsher { 6367ac6653aSJeff Kirsher int i; 6377ac6653aSJeff Kirsher 6387ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 6397ac6653aSJeff Kirsher if (priv->tx_skbuff[i] != NULL) { 6407ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + i; 6417ac6653aSJeff Kirsher if (p->des2) 6427ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 6437ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 6447ac6653aSJeff Kirsher DMA_TO_DEVICE); 6457ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 6467ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 6477ac6653aSJeff Kirsher } 6487ac6653aSJeff Kirsher } 6497ac6653aSJeff Kirsher } 6507ac6653aSJeff Kirsher 6517ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 6527ac6653aSJeff Kirsher { 6537ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 6547ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 6557ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 6567ac6653aSJeff Kirsher 6577ac6653aSJeff Kirsher /* Free the region of consistent memory previously allocated for 6587ac6653aSJeff Kirsher * the DMA */ 6597ac6653aSJeff Kirsher dma_free_coherent(priv->device, 6607ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 6617ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 6627ac6653aSJeff Kirsher dma_free_coherent(priv->device, 6637ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 6647ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 6657ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 6667ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 6677ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 6687ac6653aSJeff Kirsher } 6697ac6653aSJeff Kirsher 6707ac6653aSJeff Kirsher /** 6717ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 6727ac6653aSJeff Kirsher * @priv : pointer to the private device structure. 6737ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 6747ac6653aSJeff Kirsher * or Store-And-Forward capability. 6757ac6653aSJeff Kirsher */ 6767ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 6777ac6653aSJeff Kirsher { 6787ac6653aSJeff Kirsher if (likely(priv->plat->force_sf_dma_mode || 6797ac6653aSJeff Kirsher ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) { 6807ac6653aSJeff Kirsher /* 6817ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 6827ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 6837ac6653aSJeff Kirsher * 1) TX COE if actually supported 6847ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 6857ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 6867ac6653aSJeff Kirsher */ 6877ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, 6887ac6653aSJeff Kirsher SF_DMA_MODE, SF_DMA_MODE); 6897ac6653aSJeff Kirsher tc = SF_DMA_MODE; 6907ac6653aSJeff Kirsher } else 6917ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 6927ac6653aSJeff Kirsher } 6937ac6653aSJeff Kirsher 6947ac6653aSJeff Kirsher /** 6959125cdd1SGiuseppe CAVALLARO * stmmac_tx_clean: 6969125cdd1SGiuseppe CAVALLARO * @priv: private data pointer 6977ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 6987ac6653aSJeff Kirsher */ 6999125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv) 7007ac6653aSJeff Kirsher { 7017ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 7027ac6653aSJeff Kirsher 703a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 704a9097a96SGiuseppe CAVALLARO 7059125cdd1SGiuseppe CAVALLARO priv->xstats.tx_clean++; 7069125cdd1SGiuseppe CAVALLARO 7077ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 7087ac6653aSJeff Kirsher int last; 7097ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 7107ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 7117ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + entry; 7127ac6653aSJeff Kirsher 7137ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 7147ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 7157ac6653aSJeff Kirsher break; 7167ac6653aSJeff Kirsher 7177ac6653aSJeff Kirsher /* Verify tx error by looking at the last segment */ 7187ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 7197ac6653aSJeff Kirsher if (likely(last)) { 7207ac6653aSJeff Kirsher int tx_error = 7217ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 7227ac6653aSJeff Kirsher &priv->xstats, p, 7237ac6653aSJeff Kirsher priv->ioaddr); 7247ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 7257ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 7267ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 7277ac6653aSJeff Kirsher } else 7287ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 7297ac6653aSJeff Kirsher } 7307ac6653aSJeff Kirsher TX_DBG("%s: curr %d, dirty %d\n", __func__, 7317ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 7327ac6653aSJeff Kirsher 7337ac6653aSJeff Kirsher if (likely(p->des2)) 7347ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 7357ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 7367ac6653aSJeff Kirsher DMA_TO_DEVICE); 737286a8372SGiuseppe CAVALLARO priv->hw->ring->clean_desc3(p); 7387ac6653aSJeff Kirsher 7397ac6653aSJeff Kirsher if (likely(skb != NULL)) { 7407ac6653aSJeff Kirsher dev_kfree_skb(skb); 7417ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 7427ac6653aSJeff Kirsher } 7437ac6653aSJeff Kirsher 7447ac6653aSJeff Kirsher priv->hw->desc->release_tx_desc(p); 7457ac6653aSJeff Kirsher 74613497f58SGiuseppe CAVALLARO priv->dirty_tx++; 7477ac6653aSJeff Kirsher } 7487ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 7497ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 7507ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 7517ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 7527ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 7537ac6653aSJeff Kirsher TX_DBG("%s: restart transmit\n", __func__); 7547ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 7557ac6653aSJeff Kirsher } 7567ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 7577ac6653aSJeff Kirsher } 758d765955dSGiuseppe CAVALLARO 759d765955dSGiuseppe CAVALLARO if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { 760d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 761d765955dSGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); 762d765955dSGiuseppe CAVALLARO } 763a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 7647ac6653aSJeff Kirsher } 7657ac6653aSJeff Kirsher 7669125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv) 7677ac6653aSJeff Kirsher { 7687ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 7697ac6653aSJeff Kirsher } 7707ac6653aSJeff Kirsher 7719125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv) 7727ac6653aSJeff Kirsher { 7737ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 7747ac6653aSJeff Kirsher } 7757ac6653aSJeff Kirsher 7767ac6653aSJeff Kirsher 7777ac6653aSJeff Kirsher /** 7787ac6653aSJeff Kirsher * stmmac_tx_err: 7797ac6653aSJeff Kirsher * @priv: pointer to the private device structure 7807ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 7817ac6653aSJeff Kirsher * in case of errors. 7827ac6653aSJeff Kirsher */ 7837ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 7847ac6653aSJeff Kirsher { 7857ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 7867ac6653aSJeff Kirsher 7877ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 7887ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 7897ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 7907ac6653aSJeff Kirsher priv->dirty_tx = 0; 7917ac6653aSJeff Kirsher priv->cur_tx = 0; 7927ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 7937ac6653aSJeff Kirsher 7947ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 7957ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 7967ac6653aSJeff Kirsher } 7977ac6653aSJeff Kirsher 7987ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 7997ac6653aSJeff Kirsher { 8007ac6653aSJeff Kirsher int status; 8017ac6653aSJeff Kirsher 8027ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 8039125cdd1SGiuseppe CAVALLARO if (likely((status & handle_rx)) || (status & handle_tx)) { 8049125cdd1SGiuseppe CAVALLARO if (likely(napi_schedule_prep(&priv->napi))) { 8059125cdd1SGiuseppe CAVALLARO stmmac_disable_dma_irq(priv); 8069125cdd1SGiuseppe CAVALLARO __napi_schedule(&priv->napi); 8079125cdd1SGiuseppe CAVALLARO } 8089125cdd1SGiuseppe CAVALLARO } 8099125cdd1SGiuseppe CAVALLARO if (unlikely(status & tx_hard_error_bump_tc)) { 8107ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 8117ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 8127ac6653aSJeff Kirsher tc += 64; 8137ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 8147ac6653aSJeff Kirsher priv->xstats.threshold = tc; 8157ac6653aSJeff Kirsher } 8167ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 8177ac6653aSJeff Kirsher stmmac_tx_err(priv); 8187ac6653aSJeff Kirsher } 8197ac6653aSJeff Kirsher 8201c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 8211c901a46SGiuseppe CAVALLARO { 8221c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 8231c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 8241c901a46SGiuseppe CAVALLARO 8254f795b25SGiuseppe CAVALLARO /* Mask MMC irq, counters are managed in SW and registers 8264f795b25SGiuseppe CAVALLARO * are cleared on each READ eventually. */ 8271c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 8284f795b25SGiuseppe CAVALLARO 8294f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 8301c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 8311c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 8324f795b25SGiuseppe CAVALLARO } else 833aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 8341c901a46SGiuseppe CAVALLARO } 8351c901a46SGiuseppe CAVALLARO 836f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 837f0b9d786SGiuseppe CAVALLARO { 838f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 839f0b9d786SGiuseppe CAVALLARO 840f0b9d786SGiuseppe CAVALLARO /* Only check valid Synopsys Id because old MAC chips 841f0b9d786SGiuseppe CAVALLARO * have no HW registers where get the ID */ 842f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 843f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 844f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 845f0b9d786SGiuseppe CAVALLARO 846cf3f047bSGiuseppe CAVALLARO pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", 847f0b9d786SGiuseppe CAVALLARO uid, synid); 848f0b9d786SGiuseppe CAVALLARO 849f0b9d786SGiuseppe CAVALLARO return synid; 850f0b9d786SGiuseppe CAVALLARO } 851f0b9d786SGiuseppe CAVALLARO return 0; 852f0b9d786SGiuseppe CAVALLARO } 853e7434821SGiuseppe CAVALLARO 85419e30c14SGiuseppe CAVALLARO /** 85519e30c14SGiuseppe CAVALLARO * stmmac_selec_desc_mode 856ff3dd78cSGiuseppe CAVALLARO * @priv : private structure 857ff3dd78cSGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors 858ff3dd78cSGiuseppe CAVALLARO */ 85919e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 86019e30c14SGiuseppe CAVALLARO { 86119e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 86219e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 86319e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 86419e30c14SGiuseppe CAVALLARO } else { 86519e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 86619e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 86719e30c14SGiuseppe CAVALLARO } 86819e30c14SGiuseppe CAVALLARO } 86919e30c14SGiuseppe CAVALLARO 87019e30c14SGiuseppe CAVALLARO /** 87119e30c14SGiuseppe CAVALLARO * stmmac_get_hw_features 87219e30c14SGiuseppe CAVALLARO * @priv : private device pointer 87319e30c14SGiuseppe CAVALLARO * Description: 87419e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 875e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 87619e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 87719e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 878e7434821SGiuseppe CAVALLARO */ 879e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 880e7434821SGiuseppe CAVALLARO { 8815e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 8823c20f72fSGiuseppe CAVALLARO 8835e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 8845e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 885e7434821SGiuseppe CAVALLARO 8861db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 8871db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 8881db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 8891db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 8901db123fbSRayagond Kokatanur priv->dma_cap.multi_addr = 8911db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_ADDMACADRSEL) >> 5; 8921db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 8931db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 8941db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 8951db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 8961db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 8971db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 8981db123fbSRayagond Kokatanur /* MMC */ 8991db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 900e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002*/ 9011db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 9021db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 903e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008*/ 9041db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 9051db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 906e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 9071db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 9081db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 909e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 9101db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 9111db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 9121db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 9131db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 9141db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 9151db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 9161db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 917e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 9181db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 9191db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 9201db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 9211db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 922e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode*/ 9231db123fbSRayagond Kokatanur priv->dma_cap.enh_desc = 9241db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 92519e30c14SGiuseppe CAVALLARO } 926e7434821SGiuseppe CAVALLARO 927e7434821SGiuseppe CAVALLARO return hw_cap; 928e7434821SGiuseppe CAVALLARO } 929e7434821SGiuseppe CAVALLARO 930bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 931bfab27a1SGiuseppe CAVALLARO { 932bfab27a1SGiuseppe CAVALLARO /* verify if the MAC address is valid, in case of failures it 933bfab27a1SGiuseppe CAVALLARO * generates a random MAC address */ 934bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 935bfab27a1SGiuseppe CAVALLARO priv->hw->mac->get_umac_addr((void __iomem *) 936bfab27a1SGiuseppe CAVALLARO priv->dev->base_addr, 937bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 938bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 939f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 940bfab27a1SGiuseppe CAVALLARO } 941bfab27a1SGiuseppe CAVALLARO pr_warning("%s: device MAC address %pM\n", priv->dev->name, 942bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 943bfab27a1SGiuseppe CAVALLARO } 944bfab27a1SGiuseppe CAVALLARO 9450f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv) 9460f1f88a8SGiuseppe CAVALLARO { 9470f1f88a8SGiuseppe CAVALLARO int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; 948b9cde0a8SGiuseppe CAVALLARO int mixed_burst = 0; 9490f1f88a8SGiuseppe CAVALLARO 9500f1f88a8SGiuseppe CAVALLARO /* Some DMA parameters can be passed from the platform; 9510f1f88a8SGiuseppe CAVALLARO * in case of these are not passed we keep a default 9520f1f88a8SGiuseppe CAVALLARO * (good for all the chips) and init the DMA! */ 9530f1f88a8SGiuseppe CAVALLARO if (priv->plat->dma_cfg) { 9540f1f88a8SGiuseppe CAVALLARO pbl = priv->plat->dma_cfg->pbl; 9550f1f88a8SGiuseppe CAVALLARO fixed_burst = priv->plat->dma_cfg->fixed_burst; 956b9cde0a8SGiuseppe CAVALLARO mixed_burst = priv->plat->dma_cfg->mixed_burst; 9570f1f88a8SGiuseppe CAVALLARO burst_len = priv->plat->dma_cfg->burst_len; 9580f1f88a8SGiuseppe CAVALLARO } 9590f1f88a8SGiuseppe CAVALLARO 960b9cde0a8SGiuseppe CAVALLARO return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, 9610f1f88a8SGiuseppe CAVALLARO burst_len, priv->dma_tx_phy, 9620f1f88a8SGiuseppe CAVALLARO priv->dma_rx_phy); 9630f1f88a8SGiuseppe CAVALLARO } 9640f1f88a8SGiuseppe CAVALLARO 965bfab27a1SGiuseppe CAVALLARO /** 9669125cdd1SGiuseppe CAVALLARO * stmmac_tx_timer: 9679125cdd1SGiuseppe CAVALLARO * @data: data pointer 9689125cdd1SGiuseppe CAVALLARO * Description: 9699125cdd1SGiuseppe CAVALLARO * This is the timer handler to directly invoke the stmmac_tx_clean. 9709125cdd1SGiuseppe CAVALLARO */ 9719125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data) 9729125cdd1SGiuseppe CAVALLARO { 9739125cdd1SGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)data; 9749125cdd1SGiuseppe CAVALLARO 9759125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 9769125cdd1SGiuseppe CAVALLARO } 9779125cdd1SGiuseppe CAVALLARO 9789125cdd1SGiuseppe CAVALLARO /** 9799125cdd1SGiuseppe CAVALLARO * stmmac_tx_timer: 9809125cdd1SGiuseppe CAVALLARO * @priv: private data structure 9819125cdd1SGiuseppe CAVALLARO * Description: 9829125cdd1SGiuseppe CAVALLARO * This inits the transmit coalesce parameters: i.e. timer rate, 9839125cdd1SGiuseppe CAVALLARO * timer handler and default threshold used for enabling the 9849125cdd1SGiuseppe CAVALLARO * interrupt on completion bit. 9859125cdd1SGiuseppe CAVALLARO */ 9869125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) 9879125cdd1SGiuseppe CAVALLARO { 9889125cdd1SGiuseppe CAVALLARO priv->tx_coal_frames = STMMAC_TX_FRAMES; 9899125cdd1SGiuseppe CAVALLARO priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; 9909125cdd1SGiuseppe CAVALLARO init_timer(&priv->txtimer); 9919125cdd1SGiuseppe CAVALLARO priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); 9929125cdd1SGiuseppe CAVALLARO priv->txtimer.data = (unsigned long)priv; 9939125cdd1SGiuseppe CAVALLARO priv->txtimer.function = stmmac_tx_timer; 9949125cdd1SGiuseppe CAVALLARO add_timer(&priv->txtimer); 9959125cdd1SGiuseppe CAVALLARO } 9969125cdd1SGiuseppe CAVALLARO 9979125cdd1SGiuseppe CAVALLARO /** 9987ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 9997ac6653aSJeff Kirsher * @dev : pointer to the device structure. 10007ac6653aSJeff Kirsher * Description: 10017ac6653aSJeff Kirsher * This function is the open entry point of the driver. 10027ac6653aSJeff Kirsher * Return value: 10037ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 10047ac6653aSJeff Kirsher * file on failure. 10057ac6653aSJeff Kirsher */ 10067ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 10077ac6653aSJeff Kirsher { 10087ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 10097ac6653aSJeff Kirsher int ret; 10107ac6653aSJeff Kirsher 1011a630844dSStefan Roese clk_prepare_enable(priv->stmmac_clk); 10124bfcbd7aSFrancesco Virlinzi 10134bfcbd7aSFrancesco Virlinzi stmmac_check_ether_addr(priv); 10144bfcbd7aSFrancesco Virlinzi 10157ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 10167ac6653aSJeff Kirsher if (unlikely(ret)) { 10177ac6653aSJeff Kirsher pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); 10187ac6653aSJeff Kirsher goto open_error; 10197ac6653aSJeff Kirsher } 10207ac6653aSJeff Kirsher 10217ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 10227ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 10237ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 10247ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 10257ac6653aSJeff Kirsher init_dma_desc_rings(dev); 10267ac6653aSJeff Kirsher 10277ac6653aSJeff Kirsher /* DMA initialization and SW reset */ 10280f1f88a8SGiuseppe CAVALLARO ret = stmmac_init_dma_engine(priv); 10297ac6653aSJeff Kirsher if (ret < 0) { 10307ac6653aSJeff Kirsher pr_err("%s: DMA initialization failed\n", __func__); 10317ac6653aSJeff Kirsher goto open_error; 10327ac6653aSJeff Kirsher } 10337ac6653aSJeff Kirsher 10347ac6653aSJeff Kirsher /* Copy the MAC addr into the HW */ 10357ac6653aSJeff Kirsher priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); 1036cf3f047bSGiuseppe CAVALLARO 10377ac6653aSJeff Kirsher /* If required, perform hw setup of the bus. */ 10387ac6653aSJeff Kirsher if (priv->plat->bus_setup) 10397ac6653aSJeff Kirsher priv->plat->bus_setup(priv->ioaddr); 1040cf3f047bSGiuseppe CAVALLARO 10417ac6653aSJeff Kirsher /* Initialize the MAC Core */ 10427ac6653aSJeff Kirsher priv->hw->mac->core_init(priv->ioaddr); 10437ac6653aSJeff Kirsher 10447ac6653aSJeff Kirsher /* Request the IRQ lines */ 10457ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 10467ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 10477ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 10487ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 10497ac6653aSJeff Kirsher __func__, dev->irq, ret); 10507ac6653aSJeff Kirsher goto open_error; 10517ac6653aSJeff Kirsher } 10527ac6653aSJeff Kirsher 10537a13f8f5SFrancesco Virlinzi /* Request the Wake IRQ in case of another line is used for WoL */ 10547a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) { 10557a13f8f5SFrancesco Virlinzi ret = request_irq(priv->wol_irq, stmmac_interrupt, 10567a13f8f5SFrancesco Virlinzi IRQF_SHARED, dev->name, dev); 10577a13f8f5SFrancesco Virlinzi if (unlikely(ret < 0)) { 10587a13f8f5SFrancesco Virlinzi pr_err("%s: ERROR: allocating the ext WoL IRQ %d " 10597a13f8f5SFrancesco Virlinzi "(error: %d)\n", __func__, priv->wol_irq, ret); 10607a13f8f5SFrancesco Virlinzi goto open_error_wolirq; 10617a13f8f5SFrancesco Virlinzi } 10627a13f8f5SFrancesco Virlinzi } 10637a13f8f5SFrancesco Virlinzi 1064d765955dSGiuseppe CAVALLARO /* Request the IRQ lines */ 1065d765955dSGiuseppe CAVALLARO if (priv->lpi_irq != -ENXIO) { 1066d765955dSGiuseppe CAVALLARO ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, 1067d765955dSGiuseppe CAVALLARO dev->name, dev); 1068d765955dSGiuseppe CAVALLARO if (unlikely(ret < 0)) { 1069d765955dSGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", 1070d765955dSGiuseppe CAVALLARO __func__, priv->lpi_irq, ret); 1071d765955dSGiuseppe CAVALLARO goto open_error_lpiirq; 1072d765955dSGiuseppe CAVALLARO } 1073d765955dSGiuseppe CAVALLARO } 1074d765955dSGiuseppe CAVALLARO 10757ac6653aSJeff Kirsher /* Enable the MAC Rx/Tx */ 1076bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, true); 10777ac6653aSJeff Kirsher 10787ac6653aSJeff Kirsher /* Set the HW DMA mode and the COE */ 10797ac6653aSJeff Kirsher stmmac_dma_operation_mode(priv); 10807ac6653aSJeff Kirsher 10817ac6653aSJeff Kirsher /* Extra statistics */ 10827ac6653aSJeff Kirsher memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 10837ac6653aSJeff Kirsher priv->xstats.threshold = tc; 10847ac6653aSJeff Kirsher 10851c901a46SGiuseppe CAVALLARO stmmac_mmc_setup(priv); 10861c901a46SGiuseppe CAVALLARO 1087bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1088bfab27a1SGiuseppe CAVALLARO ret = stmmac_init_fs(dev); 1089bfab27a1SGiuseppe CAVALLARO if (ret < 0) 1090cf3f047bSGiuseppe CAVALLARO pr_warning("%s: failed debugFS registration\n", __func__); 1091bfab27a1SGiuseppe CAVALLARO #endif 10927ac6653aSJeff Kirsher /* Start the ball rolling... */ 10937ac6653aSJeff Kirsher DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); 10947ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 10957ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 10967ac6653aSJeff Kirsher 10977ac6653aSJeff Kirsher /* Dump DMA/MAC registers */ 10987ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 10997ac6653aSJeff Kirsher priv->hw->mac->dump_regs(priv->ioaddr); 11007ac6653aSJeff Kirsher priv->hw->dma->dump_regs(priv->ioaddr); 11017ac6653aSJeff Kirsher } 11027ac6653aSJeff Kirsher 11037ac6653aSJeff Kirsher if (priv->phydev) 11047ac6653aSJeff Kirsher phy_start(priv->phydev); 11057ac6653aSJeff Kirsher 1106d765955dSGiuseppe CAVALLARO priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER; 1107d765955dSGiuseppe CAVALLARO priv->eee_enabled = stmmac_eee_init(priv); 1108d765955dSGiuseppe CAVALLARO 11099125cdd1SGiuseppe CAVALLARO stmmac_init_tx_coalesce(priv); 11109125cdd1SGiuseppe CAVALLARO 111162a2ab93SGiuseppe CAVALLARO if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { 111262a2ab93SGiuseppe CAVALLARO priv->rx_riwt = MAX_DMA_RIWT; 111362a2ab93SGiuseppe CAVALLARO priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); 111462a2ab93SGiuseppe CAVALLARO } 111562a2ab93SGiuseppe CAVALLARO 11167ac6653aSJeff Kirsher napi_enable(&priv->napi); 11177ac6653aSJeff Kirsher netif_start_queue(dev); 11187ac6653aSJeff Kirsher 11197ac6653aSJeff Kirsher return 0; 11207ac6653aSJeff Kirsher 1121d765955dSGiuseppe CAVALLARO open_error_lpiirq: 1122d765955dSGiuseppe CAVALLARO if (priv->wol_irq != dev->irq) 1123d765955dSGiuseppe CAVALLARO free_irq(priv->wol_irq, dev); 1124d765955dSGiuseppe CAVALLARO 11257a13f8f5SFrancesco Virlinzi open_error_wolirq: 11267a13f8f5SFrancesco Virlinzi free_irq(dev->irq, dev); 11277a13f8f5SFrancesco Virlinzi 11287ac6653aSJeff Kirsher open_error: 11297ac6653aSJeff Kirsher if (priv->phydev) 11307ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 11317ac6653aSJeff Kirsher 1132a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 11334bfcbd7aSFrancesco Virlinzi 11347ac6653aSJeff Kirsher return ret; 11357ac6653aSJeff Kirsher } 11367ac6653aSJeff Kirsher 11377ac6653aSJeff Kirsher /** 11387ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 11397ac6653aSJeff Kirsher * @dev : device pointer. 11407ac6653aSJeff Kirsher * Description: 11417ac6653aSJeff Kirsher * This is the stop entry point of the driver. 11427ac6653aSJeff Kirsher */ 11437ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 11447ac6653aSJeff Kirsher { 11457ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 11467ac6653aSJeff Kirsher 1147d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 1148d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 1149d765955dSGiuseppe CAVALLARO 11507ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 11517ac6653aSJeff Kirsher if (priv->phydev) { 11527ac6653aSJeff Kirsher phy_stop(priv->phydev); 11537ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 11547ac6653aSJeff Kirsher priv->phydev = NULL; 11557ac6653aSJeff Kirsher } 11567ac6653aSJeff Kirsher 11577ac6653aSJeff Kirsher netif_stop_queue(dev); 11587ac6653aSJeff Kirsher 11597ac6653aSJeff Kirsher napi_disable(&priv->napi); 11607ac6653aSJeff Kirsher 11619125cdd1SGiuseppe CAVALLARO del_timer_sync(&priv->txtimer); 11629125cdd1SGiuseppe CAVALLARO 11637ac6653aSJeff Kirsher /* Free the IRQ lines */ 11647ac6653aSJeff Kirsher free_irq(dev->irq, dev); 11657a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) 11667a13f8f5SFrancesco Virlinzi free_irq(priv->wol_irq, dev); 1167d765955dSGiuseppe CAVALLARO if (priv->lpi_irq != -ENXIO) 1168d765955dSGiuseppe CAVALLARO free_irq(priv->lpi_irq, dev); 11697ac6653aSJeff Kirsher 11707ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 11717ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 11727ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 11737ac6653aSJeff Kirsher 11747ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 11757ac6653aSJeff Kirsher free_dma_desc_resources(priv); 11767ac6653aSJeff Kirsher 11777ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1178bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 11797ac6653aSJeff Kirsher 11807ac6653aSJeff Kirsher netif_carrier_off(dev); 11817ac6653aSJeff Kirsher 1182bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1183bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1184bfab27a1SGiuseppe CAVALLARO #endif 1185a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 1186bfab27a1SGiuseppe CAVALLARO 11877ac6653aSJeff Kirsher return 0; 11887ac6653aSJeff Kirsher } 11897ac6653aSJeff Kirsher 11907ac6653aSJeff Kirsher /** 11917ac6653aSJeff Kirsher * stmmac_xmit: 11927ac6653aSJeff Kirsher * @skb : the socket buffer 11937ac6653aSJeff Kirsher * @dev : device pointer 11947ac6653aSJeff Kirsher * Description : Tx entry point of the driver. 11957ac6653aSJeff Kirsher */ 11967ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 11977ac6653aSJeff Kirsher { 11987ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 11997ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 12007ac6653aSJeff Kirsher unsigned int entry; 12017ac6653aSJeff Kirsher int i, csum_insertion = 0; 12027ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 12037ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1204286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 12057ac6653aSJeff Kirsher 12067ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 12077ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 12087ac6653aSJeff Kirsher netif_stop_queue(dev); 12097ac6653aSJeff Kirsher /* This is a hard error, log it. */ 12107ac6653aSJeff Kirsher pr_err("%s: BUG! Tx Ring full when queue awake\n", 12117ac6653aSJeff Kirsher __func__); 12127ac6653aSJeff Kirsher } 12137ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 12147ac6653aSJeff Kirsher } 12157ac6653aSJeff Kirsher 1216a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1217a9097a96SGiuseppe CAVALLARO 1218d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1219d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1220d765955dSGiuseppe CAVALLARO 12217ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 12227ac6653aSJeff Kirsher 12237ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 12247ac6653aSJeff Kirsher if ((skb->len > ETH_FRAME_LEN) || nfrags) 12259125cdd1SGiuseppe CAVALLARO pr_debug("stmmac xmit: [entry %d]\n" 12267ac6653aSJeff Kirsher "\tskb addr %p - len: %d - nopaged_len: %d\n" 12279125cdd1SGiuseppe CAVALLARO "\tn_frags: %d - ip_summed: %d - %s gso\n" 12289125cdd1SGiuseppe CAVALLARO "\ttx_count_frames %d\n", entry, 1229286a8372SGiuseppe CAVALLARO skb, skb->len, nopaged_len, nfrags, skb->ip_summed, 12309125cdd1SGiuseppe CAVALLARO !skb_is_gso(skb) ? "isn't" : "is", 12319125cdd1SGiuseppe CAVALLARO priv->tx_count_frames); 12327ac6653aSJeff Kirsher #endif 12337ac6653aSJeff Kirsher 12347ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 12357ac6653aSJeff Kirsher 12367ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 12377ac6653aSJeff Kirsher first = desc; 12387ac6653aSJeff Kirsher 12397ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 12407ac6653aSJeff Kirsher if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN)) 12419125cdd1SGiuseppe CAVALLARO pr_debug("\tskb len: %d, nopaged_len: %d,\n" 12427ac6653aSJeff Kirsher "\t\tn_frags: %d, ip_summed: %d\n", 1243286a8372SGiuseppe CAVALLARO skb->len, nopaged_len, nfrags, skb->ip_summed); 12447ac6653aSJeff Kirsher #endif 12457ac6653aSJeff Kirsher priv->tx_skbuff[entry] = skb; 1246286a8372SGiuseppe CAVALLARO 1247286a8372SGiuseppe CAVALLARO if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) { 1248286a8372SGiuseppe CAVALLARO entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion); 12497ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 12507ac6653aSJeff Kirsher } else { 12517ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 12527ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 12537ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 12547ac6653aSJeff Kirsher csum_insertion); 12557ac6653aSJeff Kirsher } 12567ac6653aSJeff Kirsher 12577ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 12589e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 12599e903e08SEric Dumazet int len = skb_frag_size(frag); 12607ac6653aSJeff Kirsher 12617ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 12627ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 12637ac6653aSJeff Kirsher 12647ac6653aSJeff Kirsher TX_DBG("\t[entry %d] segment len: %d\n", entry, len); 1265f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1266f722380dSIan Campbell DMA_TO_DEVICE); 12677ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 12687ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); 12697ac6653aSJeff Kirsher wmb(); 12707ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 12718e839891SDeepak Sikri wmb(); 12727ac6653aSJeff Kirsher } 12737ac6653aSJeff Kirsher 12749125cdd1SGiuseppe CAVALLARO /* Finalize the latest segment. */ 12757ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 12767ac6653aSJeff Kirsher 12777ac6653aSJeff Kirsher wmb(); 12789125cdd1SGiuseppe CAVALLARO /* According to the coalesce parameter the IC bit for the latest 12799125cdd1SGiuseppe CAVALLARO * segment could be reset and the timer re-started to invoke the 12809125cdd1SGiuseppe CAVALLARO * stmmac_tx function. This approach takes care about the fragments. 12819125cdd1SGiuseppe CAVALLARO */ 12829125cdd1SGiuseppe CAVALLARO priv->tx_count_frames += nfrags + 1; 12839125cdd1SGiuseppe CAVALLARO if (priv->tx_coal_frames > priv->tx_count_frames) { 12849125cdd1SGiuseppe CAVALLARO priv->hw->desc->clear_tx_ic(desc); 12859125cdd1SGiuseppe CAVALLARO priv->xstats.tx_reset_ic_bit++; 12869125cdd1SGiuseppe CAVALLARO TX_DBG("\t[entry %d]: tx_count_frames %d\n", entry, 12879125cdd1SGiuseppe CAVALLARO priv->tx_count_frames); 12889125cdd1SGiuseppe CAVALLARO mod_timer(&priv->txtimer, 12899125cdd1SGiuseppe CAVALLARO STMMAC_COAL_TIMER(priv->tx_coal_timer)); 12909125cdd1SGiuseppe CAVALLARO } else 12919125cdd1SGiuseppe CAVALLARO priv->tx_count_frames = 0; 12927ac6653aSJeff Kirsher 12937ac6653aSJeff Kirsher /* To avoid raise condition */ 12947ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 12958e839891SDeepak Sikri wmb(); 12967ac6653aSJeff Kirsher 12977ac6653aSJeff Kirsher priv->cur_tx++; 12987ac6653aSJeff Kirsher 12997ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 13007ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 13017ac6653aSJeff Kirsher pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, " 13027ac6653aSJeff Kirsher "first=%p, nfrags=%d\n", 13037ac6653aSJeff Kirsher (priv->cur_tx % txsize), (priv->dirty_tx % txsize), 13047ac6653aSJeff Kirsher entry, first, nfrags); 13057ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 13067ac6653aSJeff Kirsher pr_info(">>> frame to be transmitted: "); 13077ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 13087ac6653aSJeff Kirsher } 13097ac6653aSJeff Kirsher #endif 13107ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 13117ac6653aSJeff Kirsher TX_DBG("%s: stop transmitted packets\n", __func__); 13127ac6653aSJeff Kirsher netif_stop_queue(dev); 13137ac6653aSJeff Kirsher } 13147ac6653aSJeff Kirsher 13157ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 13167ac6653aSJeff Kirsher 13177ac6653aSJeff Kirsher skb_tx_timestamp(skb); 13187ac6653aSJeff Kirsher 13197ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 13207ac6653aSJeff Kirsher 1321a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 1322a9097a96SGiuseppe CAVALLARO 13237ac6653aSJeff Kirsher return NETDEV_TX_OK; 13247ac6653aSJeff Kirsher } 13257ac6653aSJeff Kirsher 13267ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 13277ac6653aSJeff Kirsher { 13287ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 13297ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 13307ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx; 13317ac6653aSJeff Kirsher 13327ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 13337ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 13347ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 13357ac6653aSJeff Kirsher struct sk_buff *skb; 13367ac6653aSJeff Kirsher 1337acb600deSEric Dumazet skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); 13387ac6653aSJeff Kirsher 13397ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 13407ac6653aSJeff Kirsher break; 13417ac6653aSJeff Kirsher 13427ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 13437ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 13447ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 13457ac6653aSJeff Kirsher DMA_FROM_DEVICE); 13467ac6653aSJeff Kirsher 13477ac6653aSJeff Kirsher (p + entry)->des2 = priv->rx_skbuff_dma[entry]; 1348286a8372SGiuseppe CAVALLARO 1349286a8372SGiuseppe CAVALLARO if (unlikely(priv->plat->has_gmac)) 1350286a8372SGiuseppe CAVALLARO priv->hw->ring->refill_desc3(bfsize, p + entry); 1351286a8372SGiuseppe CAVALLARO 13527ac6653aSJeff Kirsher RX_DBG(KERN_INFO "\trefill entry #%d\n", entry); 13537ac6653aSJeff Kirsher } 13547ac6653aSJeff Kirsher wmb(); 13557ac6653aSJeff Kirsher priv->hw->desc->set_rx_owner(p + entry); 13568e839891SDeepak Sikri wmb(); 13577ac6653aSJeff Kirsher } 13587ac6653aSJeff Kirsher } 13597ac6653aSJeff Kirsher 13607ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 13617ac6653aSJeff Kirsher { 13627ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 13637ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 13647ac6653aSJeff Kirsher unsigned int next_entry; 13657ac6653aSJeff Kirsher unsigned int count = 0; 13667ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + entry; 13677ac6653aSJeff Kirsher struct dma_desc *p_next; 13687ac6653aSJeff Kirsher 13697ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 13707ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 13717ac6653aSJeff Kirsher pr_debug(">>> stmmac_rx: descriptor ring:\n"); 13727ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 13737ac6653aSJeff Kirsher } 13747ac6653aSJeff Kirsher #endif 13757ac6653aSJeff Kirsher while (!priv->hw->desc->get_rx_owner(p)) { 13767ac6653aSJeff Kirsher int status; 13777ac6653aSJeff Kirsher 13787ac6653aSJeff Kirsher if (count >= limit) 13797ac6653aSJeff Kirsher break; 13807ac6653aSJeff Kirsher 13817ac6653aSJeff Kirsher count++; 13827ac6653aSJeff Kirsher 13837ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 13847ac6653aSJeff Kirsher p_next = priv->dma_rx + next_entry; 13857ac6653aSJeff Kirsher prefetch(p_next); 13867ac6653aSJeff Kirsher 13877ac6653aSJeff Kirsher /* read the status of the incoming frame */ 13887ac6653aSJeff Kirsher status = (priv->hw->desc->rx_status(&priv->dev->stats, 13897ac6653aSJeff Kirsher &priv->xstats, p)); 13907ac6653aSJeff Kirsher if (unlikely(status == discard_frame)) 13917ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 13927ac6653aSJeff Kirsher else { 13937ac6653aSJeff Kirsher struct sk_buff *skb; 13947ac6653aSJeff Kirsher int frame_len; 13957ac6653aSJeff Kirsher 139638912bdbSDeepak SIKRI frame_len = priv->hw->desc->get_rx_frame_len(p, 139738912bdbSDeepak SIKRI priv->plat->rx_coe); 13987ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 13997ac6653aSJeff Kirsher * Type frames (LLC/LLC-SNAP) */ 14007ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 14017ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 14027ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 14037ac6653aSJeff Kirsher if (frame_len > ETH_FRAME_LEN) 14047ac6653aSJeff Kirsher pr_debug("\tRX frame size %d, COE status: %d\n", 14057ac6653aSJeff Kirsher frame_len, status); 14067ac6653aSJeff Kirsher 14077ac6653aSJeff Kirsher if (netif_msg_hw(priv)) 14087ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 14097ac6653aSJeff Kirsher p, entry, p->des2); 14107ac6653aSJeff Kirsher #endif 14117ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 14127ac6653aSJeff Kirsher if (unlikely(!skb)) { 14137ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 14147ac6653aSJeff Kirsher priv->dev->name); 14157ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 14167ac6653aSJeff Kirsher break; 14177ac6653aSJeff Kirsher } 14187ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 14197ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 14207ac6653aSJeff Kirsher 14217ac6653aSJeff Kirsher skb_put(skb, frame_len); 14227ac6653aSJeff Kirsher dma_unmap_single(priv->device, 14237ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 14247ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 14257ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 14267ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 14277ac6653aSJeff Kirsher pr_info(" frame received (%dbytes)", frame_len); 14287ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 14297ac6653aSJeff Kirsher } 14307ac6653aSJeff Kirsher #endif 14317ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 14327ac6653aSJeff Kirsher 143362a2ab93SGiuseppe CAVALLARO if (unlikely(!priv->plat->rx_coe)) 14347ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 143562a2ab93SGiuseppe CAVALLARO else 14367ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 143762a2ab93SGiuseppe CAVALLARO 14387ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 14397ac6653aSJeff Kirsher 14407ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 14417ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 14427ac6653aSJeff Kirsher } 14437ac6653aSJeff Kirsher entry = next_entry; 14447ac6653aSJeff Kirsher p = p_next; /* use prefetched values */ 14457ac6653aSJeff Kirsher } 14467ac6653aSJeff Kirsher 14477ac6653aSJeff Kirsher stmmac_rx_refill(priv); 14487ac6653aSJeff Kirsher 14497ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 14507ac6653aSJeff Kirsher 14517ac6653aSJeff Kirsher return count; 14527ac6653aSJeff Kirsher } 14537ac6653aSJeff Kirsher 14547ac6653aSJeff Kirsher /** 14557ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 14567ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 14577ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 14587ac6653aSJeff Kirsher * all interfaces. 14597ac6653aSJeff Kirsher * Description : 14609125cdd1SGiuseppe CAVALLARO * To look at the incoming frames and clear the tx resources. 14617ac6653aSJeff Kirsher */ 14627ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 14637ac6653aSJeff Kirsher { 14647ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 14657ac6653aSJeff Kirsher int work_done = 0; 14667ac6653aSJeff Kirsher 14679125cdd1SGiuseppe CAVALLARO priv->xstats.napi_poll++; 14689125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 14697ac6653aSJeff Kirsher 14709125cdd1SGiuseppe CAVALLARO work_done = stmmac_rx(priv, budget); 14717ac6653aSJeff Kirsher if (work_done < budget) { 14727ac6653aSJeff Kirsher napi_complete(napi); 14739125cdd1SGiuseppe CAVALLARO stmmac_enable_dma_irq(priv); 14747ac6653aSJeff Kirsher } 14757ac6653aSJeff Kirsher return work_done; 14767ac6653aSJeff Kirsher } 14777ac6653aSJeff Kirsher 14787ac6653aSJeff Kirsher /** 14797ac6653aSJeff Kirsher * stmmac_tx_timeout 14807ac6653aSJeff Kirsher * @dev : Pointer to net device structure 14817ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 14827284a3f1SGiuseppe CAVALLARO * complete within a reasonable time. The driver will mark the error in the 14837ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 14847ac6653aSJeff Kirsher * in order to transmit a new packet. 14857ac6653aSJeff Kirsher */ 14867ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 14877ac6653aSJeff Kirsher { 14887ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 14897ac6653aSJeff Kirsher 14907ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 14917ac6653aSJeff Kirsher stmmac_tx_err(priv); 14927ac6653aSJeff Kirsher } 14937ac6653aSJeff Kirsher 14947ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */ 14957ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map) 14967ac6653aSJeff Kirsher { 14977ac6653aSJeff Kirsher if (dev->flags & IFF_UP) /* can't act on a running interface */ 14987ac6653aSJeff Kirsher return -EBUSY; 14997ac6653aSJeff Kirsher 15007ac6653aSJeff Kirsher /* Don't allow changing the I/O address */ 15017ac6653aSJeff Kirsher if (map->base_addr != dev->base_addr) { 15027ac6653aSJeff Kirsher pr_warning("%s: can't change I/O address\n", dev->name); 15037ac6653aSJeff Kirsher return -EOPNOTSUPP; 15047ac6653aSJeff Kirsher } 15057ac6653aSJeff Kirsher 15067ac6653aSJeff Kirsher /* Don't allow changing the IRQ */ 15077ac6653aSJeff Kirsher if (map->irq != dev->irq) { 15087ac6653aSJeff Kirsher pr_warning("%s: can't change IRQ number %d\n", 15097ac6653aSJeff Kirsher dev->name, dev->irq); 15107ac6653aSJeff Kirsher return -EOPNOTSUPP; 15117ac6653aSJeff Kirsher } 15127ac6653aSJeff Kirsher 15137ac6653aSJeff Kirsher /* ignore other fields */ 15147ac6653aSJeff Kirsher return 0; 15157ac6653aSJeff Kirsher } 15167ac6653aSJeff Kirsher 15177ac6653aSJeff Kirsher /** 151801789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 15197ac6653aSJeff Kirsher * @dev : pointer to the device structure 15207ac6653aSJeff Kirsher * Description: 15217ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 15227ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 15237ac6653aSJeff Kirsher * Return value: 15247ac6653aSJeff Kirsher * void. 15257ac6653aSJeff Kirsher */ 152601789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 15277ac6653aSJeff Kirsher { 15287ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15297ac6653aSJeff Kirsher 15307ac6653aSJeff Kirsher spin_lock(&priv->lock); 1531cffb13f4SGiuseppe CAVALLARO priv->hw->mac->set_filter(dev, priv->synopsys_id); 15327ac6653aSJeff Kirsher spin_unlock(&priv->lock); 15337ac6653aSJeff Kirsher } 15347ac6653aSJeff Kirsher 15357ac6653aSJeff Kirsher /** 15367ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 15377ac6653aSJeff Kirsher * @dev : device pointer. 15387ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 15397ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 15407ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 15417ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 15427ac6653aSJeff Kirsher * Return value: 15437ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 15447ac6653aSJeff Kirsher * file on failure. 15457ac6653aSJeff Kirsher */ 15467ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 15477ac6653aSJeff Kirsher { 15487ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15497ac6653aSJeff Kirsher int max_mtu; 15507ac6653aSJeff Kirsher 15517ac6653aSJeff Kirsher if (netif_running(dev)) { 15527ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 15537ac6653aSJeff Kirsher return -EBUSY; 15547ac6653aSJeff Kirsher } 15557ac6653aSJeff Kirsher 155648febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 15577ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 15587ac6653aSJeff Kirsher else 155945db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 15607ac6653aSJeff Kirsher 15617ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 15627ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 15637ac6653aSJeff Kirsher return -EINVAL; 15647ac6653aSJeff Kirsher } 15657ac6653aSJeff Kirsher 15667ac6653aSJeff Kirsher dev->mtu = new_mtu; 15677ac6653aSJeff Kirsher netdev_update_features(dev); 15687ac6653aSJeff Kirsher 15697ac6653aSJeff Kirsher return 0; 15707ac6653aSJeff Kirsher } 15717ac6653aSJeff Kirsher 1572c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 1573c8f44affSMichał Mirosław netdev_features_t features) 15747ac6653aSJeff Kirsher { 15757ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15767ac6653aSJeff Kirsher 157738912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 15787ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 157938912bdbSDeepak SIKRI else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) 158038912bdbSDeepak SIKRI features &= ~NETIF_F_IPV6_CSUM; 15817ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 15827ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 15837ac6653aSJeff Kirsher 15847ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 15857ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 15867ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 15877ac6653aSJeff Kirsher * the TX csum insertionin the TDES and not use SF. */ 15887ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 15897ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 15907ac6653aSJeff Kirsher 15917ac6653aSJeff Kirsher return features; 15927ac6653aSJeff Kirsher } 15937ac6653aSJeff Kirsher 15947ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 15957ac6653aSJeff Kirsher { 15967ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 15977ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15987ac6653aSJeff Kirsher 15997ac6653aSJeff Kirsher if (unlikely(!dev)) { 16007ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 16017ac6653aSJeff Kirsher return IRQ_NONE; 16027ac6653aSJeff Kirsher } 16037ac6653aSJeff Kirsher 16047ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 1605d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 1606d765955dSGiuseppe CAVALLARO int status = priv->hw->mac->host_irq_status((void __iomem *) 1607d765955dSGiuseppe CAVALLARO dev->base_addr); 1608d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 1609d765955dSGiuseppe CAVALLARO if (status & core_mmc_tx_irq) 1610d765955dSGiuseppe CAVALLARO priv->xstats.mmc_tx_irq_n++; 1611d765955dSGiuseppe CAVALLARO if (status & core_mmc_rx_irq) 1612d765955dSGiuseppe CAVALLARO priv->xstats.mmc_rx_irq_n++; 1613d765955dSGiuseppe CAVALLARO if (status & core_mmc_rx_csum_offload_irq) 1614d765955dSGiuseppe CAVALLARO priv->xstats.mmc_rx_csum_offload_irq_n++; 1615d765955dSGiuseppe CAVALLARO if (status & core_irq_receive_pmt_irq) 1616d765955dSGiuseppe CAVALLARO priv->xstats.irq_receive_pmt_irq_n++; 16177ac6653aSJeff Kirsher 1618d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 1619d765955dSGiuseppe CAVALLARO if (status & core_irq_tx_path_in_lpi_mode) { 1620d765955dSGiuseppe CAVALLARO priv->xstats.irq_tx_path_in_lpi_mode_n++; 1621d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 1622d765955dSGiuseppe CAVALLARO } 1623d765955dSGiuseppe CAVALLARO if (status & core_irq_tx_path_exit_lpi_mode) { 1624d765955dSGiuseppe CAVALLARO priv->xstats.irq_tx_path_exit_lpi_mode_n++; 1625d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 1626d765955dSGiuseppe CAVALLARO } 1627d765955dSGiuseppe CAVALLARO if (status & core_irq_rx_path_in_lpi_mode) 1628d765955dSGiuseppe CAVALLARO priv->xstats.irq_rx_path_in_lpi_mode_n++; 1629d765955dSGiuseppe CAVALLARO if (status & core_irq_rx_path_exit_lpi_mode) 1630d765955dSGiuseppe CAVALLARO priv->xstats.irq_rx_path_exit_lpi_mode_n++; 1631d765955dSGiuseppe CAVALLARO } 1632d765955dSGiuseppe CAVALLARO } 1633d765955dSGiuseppe CAVALLARO 1634d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 16357ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 16367ac6653aSJeff Kirsher 16377ac6653aSJeff Kirsher return IRQ_HANDLED; 16387ac6653aSJeff Kirsher } 16397ac6653aSJeff Kirsher 16407ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 16417ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 16427ac6653aSJeff Kirsher * to allow network I/O with interrupts disabled. */ 16437ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 16447ac6653aSJeff Kirsher { 16457ac6653aSJeff Kirsher disable_irq(dev->irq); 16467ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 16477ac6653aSJeff Kirsher enable_irq(dev->irq); 16487ac6653aSJeff Kirsher } 16497ac6653aSJeff Kirsher #endif 16507ac6653aSJeff Kirsher 16517ac6653aSJeff Kirsher /** 16527ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 16537ac6653aSJeff Kirsher * @dev: Device pointer. 16547ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 16557ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 16567ac6653aSJeff Kirsher * @cmd: IOCTL command 16577ac6653aSJeff Kirsher * Description: 16587ac6653aSJeff Kirsher * Currently there are no special functionality supported in IOCTL, just the 16597ac6653aSJeff Kirsher * phy_mii_ioctl(...) can be invoked. 16607ac6653aSJeff Kirsher */ 16617ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 16627ac6653aSJeff Kirsher { 16637ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16647ac6653aSJeff Kirsher int ret; 16657ac6653aSJeff Kirsher 16667ac6653aSJeff Kirsher if (!netif_running(dev)) 16677ac6653aSJeff Kirsher return -EINVAL; 16687ac6653aSJeff Kirsher 16697ac6653aSJeff Kirsher if (!priv->phydev) 16707ac6653aSJeff Kirsher return -EINVAL; 16717ac6653aSJeff Kirsher 16727ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 16737ac6653aSJeff Kirsher 16747ac6653aSJeff Kirsher return ret; 16757ac6653aSJeff Kirsher } 16767ac6653aSJeff Kirsher 16777ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 16787ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 16797ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 1680e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 16817ac29055SGiuseppe CAVALLARO 16827ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 16837ac29055SGiuseppe CAVALLARO { 16847ac29055SGiuseppe CAVALLARO struct tmp_s { 16857ac29055SGiuseppe CAVALLARO u64 a; 16867ac29055SGiuseppe CAVALLARO unsigned int b; 16877ac29055SGiuseppe CAVALLARO unsigned int c; 16887ac29055SGiuseppe CAVALLARO }; 16897ac29055SGiuseppe CAVALLARO int i; 16907ac29055SGiuseppe CAVALLARO struct net_device *dev = seq->private; 16917ac29055SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 16927ac29055SGiuseppe CAVALLARO 16937ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 16947ac29055SGiuseppe CAVALLARO seq_printf(seq, " RX descriptor ring\n"); 16957ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 16967ac29055SGiuseppe CAVALLARO 16977ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_rx_size; i++) { 16987ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i); 16997ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 17007ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 17017ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 17027ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 17037ac29055SGiuseppe CAVALLARO } 17047ac29055SGiuseppe CAVALLARO 17057ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 17067ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 17077ac29055SGiuseppe CAVALLARO seq_printf(seq, " TX descriptor ring\n"); 17087ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 17097ac29055SGiuseppe CAVALLARO 17107ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_tx_size; i++) { 17117ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i); 17127ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 17137ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 17147ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 17157ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 17167ac29055SGiuseppe CAVALLARO } 17177ac29055SGiuseppe CAVALLARO 17187ac29055SGiuseppe CAVALLARO return 0; 17197ac29055SGiuseppe CAVALLARO } 17207ac29055SGiuseppe CAVALLARO 17217ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 17227ac29055SGiuseppe CAVALLARO { 17237ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 17247ac29055SGiuseppe CAVALLARO } 17257ac29055SGiuseppe CAVALLARO 17267ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 17277ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 17287ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 17297ac29055SGiuseppe CAVALLARO .read = seq_read, 17307ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 173174863948SDjalal Harouni .release = single_release, 17327ac29055SGiuseppe CAVALLARO }; 17337ac29055SGiuseppe CAVALLARO 1734e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 1735e7434821SGiuseppe CAVALLARO { 1736e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 1737e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 1738e7434821SGiuseppe CAVALLARO 173919e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 1740e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 1741e7434821SGiuseppe CAVALLARO return 0; 1742e7434821SGiuseppe CAVALLARO } 1743e7434821SGiuseppe CAVALLARO 1744e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 1745e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 1746e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 1747e7434821SGiuseppe CAVALLARO 1748e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 1749e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 1750e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 1751e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 1752e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 1753e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 1754e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 1755e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 1756e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 1757e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 1758e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 1759e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 1760e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 1761e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 1762e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 1763e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 1764e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 1765e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 1766e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 1767e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 1768e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 1769e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 1770e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 1771e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 1772e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 1773e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 1774e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 1775e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 1776e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 1777e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 1778e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 1779e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 1780e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 1781e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 1782e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 1783e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 1784e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 1785e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 1786e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 1787e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 1788e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 1789e7434821SGiuseppe CAVALLARO 1790e7434821SGiuseppe CAVALLARO return 0; 1791e7434821SGiuseppe CAVALLARO } 1792e7434821SGiuseppe CAVALLARO 1793e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 1794e7434821SGiuseppe CAVALLARO { 1795e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 1796e7434821SGiuseppe CAVALLARO } 1797e7434821SGiuseppe CAVALLARO 1798e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 1799e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 1800e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 1801e7434821SGiuseppe CAVALLARO .read = seq_read, 1802e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 180374863948SDjalal Harouni .release = single_release, 1804e7434821SGiuseppe CAVALLARO }; 1805e7434821SGiuseppe CAVALLARO 18067ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 18077ac29055SGiuseppe CAVALLARO { 18087ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 18097ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 18107ac29055SGiuseppe CAVALLARO 18117ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 18127ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 18137ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 18147ac29055SGiuseppe CAVALLARO 18157ac29055SGiuseppe CAVALLARO return -ENOMEM; 18167ac29055SGiuseppe CAVALLARO } 18177ac29055SGiuseppe CAVALLARO 18187ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 18197ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 18207ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 18217ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 18227ac29055SGiuseppe CAVALLARO 18237ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 18247ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 18257ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 18267ac29055SGiuseppe CAVALLARO 18277ac29055SGiuseppe CAVALLARO return -ENOMEM; 18287ac29055SGiuseppe CAVALLARO } 18297ac29055SGiuseppe CAVALLARO 1830e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 1831e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 1832e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 1833e7434821SGiuseppe CAVALLARO 1834e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 1835e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 1836e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 1837e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 1838e7434821SGiuseppe CAVALLARO 1839e7434821SGiuseppe CAVALLARO return -ENOMEM; 1840e7434821SGiuseppe CAVALLARO } 1841e7434821SGiuseppe CAVALLARO 18427ac29055SGiuseppe CAVALLARO return 0; 18437ac29055SGiuseppe CAVALLARO } 18447ac29055SGiuseppe CAVALLARO 18457ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 18467ac29055SGiuseppe CAVALLARO { 18477ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 1848e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 18497ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 18507ac29055SGiuseppe CAVALLARO } 18517ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 18527ac29055SGiuseppe CAVALLARO 18537ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 18547ac6653aSJeff Kirsher .ndo_open = stmmac_open, 18557ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 18567ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 18577ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 18587ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 185901789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 18607ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 18617ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 18627ac6653aSJeff Kirsher .ndo_set_config = stmmac_config, 18637ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 18647ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 18657ac6653aSJeff Kirsher #endif 18667ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 18677ac6653aSJeff Kirsher }; 18687ac6653aSJeff Kirsher 18697ac6653aSJeff Kirsher /** 1870cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 1871cf3f047bSGiuseppe CAVALLARO * @priv : pointer to the private device structure. 1872cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 1873cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 1874cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 1875cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 1876cf3f047bSGiuseppe CAVALLARO * descriptor structure). 1877cf3f047bSGiuseppe CAVALLARO */ 1878cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 1879cf3f047bSGiuseppe CAVALLARO { 1880cf3f047bSGiuseppe CAVALLARO int ret = 0; 1881cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 1882cf3f047bSGiuseppe CAVALLARO 1883cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 188403f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 188503f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 1886cf3f047bSGiuseppe CAVALLARO mac = dwmac1000_setup(priv->ioaddr); 188703f2eecdSMarc Kleine-Budde } else { 1888cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 188903f2eecdSMarc Kleine-Budde } 1890cf3f047bSGiuseppe CAVALLARO if (!mac) 1891cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 1892cf3f047bSGiuseppe CAVALLARO 1893cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 1894cf3f047bSGiuseppe CAVALLARO 1895cf3f047bSGiuseppe CAVALLARO /* To use the chained or ring mode */ 1896cf3f047bSGiuseppe CAVALLARO priv->hw->ring = &ring_mode_ops; 1897cf3f047bSGiuseppe CAVALLARO 1898cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 1899cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 1900cf3f047bSGiuseppe CAVALLARO 1901cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 1902cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 1903cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 1904cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 1905cf3f047bSGiuseppe CAVALLARO 1906cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 1907cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 1908cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 1909cf3f047bSGiuseppe CAVALLARO * register (if supported). 1910cf3f047bSGiuseppe CAVALLARO */ 1911cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 1912cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 191338912bdbSDeepak SIKRI 191438912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 191538912bdbSDeepak SIKRI 191638912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 191738912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 191838912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 191938912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 192038912bdbSDeepak SIKRI 1921cf3f047bSGiuseppe CAVALLARO } else 1922cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 1923cf3f047bSGiuseppe CAVALLARO 1924cf3f047bSGiuseppe CAVALLARO /* Select the enhnaced/normal descriptor structures */ 1925cf3f047bSGiuseppe CAVALLARO stmmac_selec_desc_mode(priv); 1926cf3f047bSGiuseppe CAVALLARO 192738912bdbSDeepak SIKRI /* Enable the IPC (Checksum Offload) and check if the feature has been 192838912bdbSDeepak SIKRI * enabled during the core configuration. */ 192938912bdbSDeepak SIKRI ret = priv->hw->mac->rx_ipc(priv->ioaddr); 193038912bdbSDeepak SIKRI if (!ret) { 193138912bdbSDeepak SIKRI pr_warning(" RX IPC Checksum Offload not configured.\n"); 193238912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_NONE; 193338912bdbSDeepak SIKRI } 193438912bdbSDeepak SIKRI 193538912bdbSDeepak SIKRI if (priv->plat->rx_coe) 193638912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 193738912bdbSDeepak SIKRI priv->plat->rx_coe); 1938cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 1939cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 1940cf3f047bSGiuseppe CAVALLARO 1941cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 1942cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 1943cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 1944cf3f047bSGiuseppe CAVALLARO } 1945cf3f047bSGiuseppe CAVALLARO 1946cf3f047bSGiuseppe CAVALLARO return ret; 1947cf3f047bSGiuseppe CAVALLARO } 1948cf3f047bSGiuseppe CAVALLARO 1949cf3f047bSGiuseppe CAVALLARO /** 1950bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 1951bfab27a1SGiuseppe CAVALLARO * @device: device pointer 1952ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 1953ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 1954bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 1955bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 19567ac6653aSJeff Kirsher */ 1957bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 1958cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 1959cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 19607ac6653aSJeff Kirsher { 19617ac6653aSJeff Kirsher int ret = 0; 1962bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 1963bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 19647ac6653aSJeff Kirsher 1965bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 196641de8d4cSJoe Perches if (!ndev) 1967bfab27a1SGiuseppe CAVALLARO return NULL; 19687ac6653aSJeff Kirsher 1969bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 19707ac6653aSJeff Kirsher 1971bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 1972bfab27a1SGiuseppe CAVALLARO priv->device = device; 1973bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 1974bfab27a1SGiuseppe CAVALLARO 1975bfab27a1SGiuseppe CAVALLARO ether_setup(ndev); 1976bfab27a1SGiuseppe CAVALLARO 1977bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 1978cf3f047bSGiuseppe CAVALLARO priv->pause = pause; 1979cf3f047bSGiuseppe CAVALLARO priv->plat = plat_dat; 1980cf3f047bSGiuseppe CAVALLARO priv->ioaddr = addr; 1981cf3f047bSGiuseppe CAVALLARO priv->dev->base_addr = (unsigned long)addr; 1982bfab27a1SGiuseppe CAVALLARO 1983cf3f047bSGiuseppe CAVALLARO /* Verify driver arguments */ 1984cf3f047bSGiuseppe CAVALLARO stmmac_verify_args(); 1985cf3f047bSGiuseppe CAVALLARO 1986cf3f047bSGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 1987cf3f047bSGiuseppe CAVALLARO * this needs to have multiple instances */ 1988cf3f047bSGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 1989cf3f047bSGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 1990cf3f047bSGiuseppe CAVALLARO 1991cf3f047bSGiuseppe CAVALLARO /* Init MAC and get the capabilities */ 1992cf3f047bSGiuseppe CAVALLARO stmmac_hw_init(priv); 1993cf3f047bSGiuseppe CAVALLARO 1994cf3f047bSGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 1995cf3f047bSGiuseppe CAVALLARO 1996cf3f047bSGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 1997cf3f047bSGiuseppe CAVALLARO NETIF_F_RXCSUM; 1998bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 1999bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 20007ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 20017ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 2002bfab27a1SGiuseppe CAVALLARO ndev->features |= NETIF_F_HW_VLAN_RX; 20037ac6653aSJeff Kirsher #endif 20047ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 20057ac6653aSJeff Kirsher 20067ac6653aSJeff Kirsher if (flow_ctrl) 20077ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 20087ac6653aSJeff Kirsher 200962a2ab93SGiuseppe CAVALLARO /* Rx Watchdog is available in the COREs newer than the 3.40. 201062a2ab93SGiuseppe CAVALLARO * In some case, for example on bugged HW this feature 201162a2ab93SGiuseppe CAVALLARO * has to be disable and this can be done by passing the 201262a2ab93SGiuseppe CAVALLARO * riwt_off field from the platform. 201362a2ab93SGiuseppe CAVALLARO */ 201462a2ab93SGiuseppe CAVALLARO if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { 201562a2ab93SGiuseppe CAVALLARO priv->use_riwt = 1; 201662a2ab93SGiuseppe CAVALLARO pr_info(" Enable RX Mitigation via HW Watchdog Timer\n"); 201762a2ab93SGiuseppe CAVALLARO } 201862a2ab93SGiuseppe CAVALLARO 2019bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 20207ac6653aSJeff Kirsher 20217ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 2022a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 20237ac6653aSJeff Kirsher 2024bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 20257ac6653aSJeff Kirsher if (ret) { 2026cf3f047bSGiuseppe CAVALLARO pr_err("%s: ERROR %i registering the device\n", __func__, ret); 20276a81c26fSViresh Kumar goto error_netdev_register; 20287ac6653aSJeff Kirsher } 20297ac6653aSJeff Kirsher 2030ae4d8cf2SKelvin Cheung priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME); 20316a81c26fSViresh Kumar if (IS_ERR(priv->stmmac_clk)) { 203231ea38eeSGiuseppe CAVALLARO pr_warning("%s: warning: cannot get CSR clock\n", __func__); 20336a81c26fSViresh Kumar goto error_clk_get; 20346a81c26fSViresh Kumar } 2035ba1377ffSGiuseppe CAVALLARO 2036cd7201f4SGiuseppe CAVALLARO /* If a specific clk_csr value is passed from the platform 2037cd7201f4SGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 2038cd7201f4SGiuseppe CAVALLARO * changed at run-time and it is fixed. Viceversa the driver'll try to 2039cd7201f4SGiuseppe CAVALLARO * set the MDC clock dynamically according to the csr actual 2040cd7201f4SGiuseppe CAVALLARO * clock input. 2041cd7201f4SGiuseppe CAVALLARO */ 2042cd7201f4SGiuseppe CAVALLARO if (!priv->plat->clk_csr) 2043cd7201f4SGiuseppe CAVALLARO stmmac_clk_csr_set(priv); 2044cd7201f4SGiuseppe CAVALLARO else 2045cd7201f4SGiuseppe CAVALLARO priv->clk_csr = priv->plat->clk_csr; 2046cd7201f4SGiuseppe CAVALLARO 20474bfcbd7aSFrancesco Virlinzi /* MDIO bus Registration */ 20484bfcbd7aSFrancesco Virlinzi ret = stmmac_mdio_register(ndev); 20494bfcbd7aSFrancesco Virlinzi if (ret < 0) { 20504bfcbd7aSFrancesco Virlinzi pr_debug("%s: MDIO bus (id: %d) registration failed", 20514bfcbd7aSFrancesco Virlinzi __func__, priv->plat->bus_id); 20526a81c26fSViresh Kumar goto error_mdio_register; 20534bfcbd7aSFrancesco Virlinzi } 20544bfcbd7aSFrancesco Virlinzi 2055bfab27a1SGiuseppe CAVALLARO return priv; 20567ac6653aSJeff Kirsher 20576a81c26fSViresh Kumar error_mdio_register: 20586a81c26fSViresh Kumar clk_put(priv->stmmac_clk); 20596a81c26fSViresh Kumar error_clk_get: 20607ac6653aSJeff Kirsher unregister_netdev(ndev); 20616a81c26fSViresh Kumar error_netdev_register: 20626a81c26fSViresh Kumar netif_napi_del(&priv->napi); 20637ac6653aSJeff Kirsher free_netdev(ndev); 20647ac6653aSJeff Kirsher 2065bfab27a1SGiuseppe CAVALLARO return NULL; 20667ac6653aSJeff Kirsher } 20677ac6653aSJeff Kirsher 20687ac6653aSJeff Kirsher /** 20697ac6653aSJeff Kirsher * stmmac_dvr_remove 2070bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 20717ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 2072bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 20737ac6653aSJeff Kirsher */ 2074bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 20757ac6653aSJeff Kirsher { 20767ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 20777ac6653aSJeff Kirsher 20787ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 20797ac6653aSJeff Kirsher 20807ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 20817ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 20827ac6653aSJeff Kirsher 2083bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 20844bfcbd7aSFrancesco Virlinzi stmmac_mdio_unregister(ndev); 20857ac6653aSJeff Kirsher netif_carrier_off(ndev); 20867ac6653aSJeff Kirsher unregister_netdev(ndev); 20877ac6653aSJeff Kirsher free_netdev(ndev); 20887ac6653aSJeff Kirsher 20897ac6653aSJeff Kirsher return 0; 20907ac6653aSJeff Kirsher } 20917ac6653aSJeff Kirsher 20927ac6653aSJeff Kirsher #ifdef CONFIG_PM 2093bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 20947ac6653aSJeff Kirsher { 20957ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 20967ac6653aSJeff Kirsher int dis_ic = 0; 2097f8c5a875SGiuseppe CAVALLARO unsigned long flags; 20987ac6653aSJeff Kirsher 20997ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 21007ac6653aSJeff Kirsher return 0; 21017ac6653aSJeff Kirsher 2102102463b1SFrancesco Virlinzi if (priv->phydev) 2103102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 2104102463b1SFrancesco Virlinzi 2105f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 21067ac6653aSJeff Kirsher 21077ac6653aSJeff Kirsher netif_device_detach(ndev); 21087ac6653aSJeff Kirsher netif_stop_queue(ndev); 21097ac6653aSJeff Kirsher 211062a2ab93SGiuseppe CAVALLARO if (priv->use_riwt) 211162a2ab93SGiuseppe CAVALLARO dis_ic = 1; 211262a2ab93SGiuseppe CAVALLARO 21137ac6653aSJeff Kirsher napi_disable(&priv->napi); 21147ac6653aSJeff Kirsher 21157ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 21167ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 21177ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 21187ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 21197ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, 21207ac6653aSJeff Kirsher dis_ic); 21217ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 21227ac6653aSJeff Kirsher 21237ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 21247ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 21257ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 2126ba1377ffSGiuseppe CAVALLARO else { 2127bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 2128ba1377ffSGiuseppe CAVALLARO /* Disable clock in case of PWM is off */ 2129a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 2130ba1377ffSGiuseppe CAVALLARO } 2131f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 21327ac6653aSJeff Kirsher return 0; 21337ac6653aSJeff Kirsher } 21347ac6653aSJeff Kirsher 2135bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 21367ac6653aSJeff Kirsher { 21377ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2138f8c5a875SGiuseppe CAVALLARO unsigned long flags; 21397ac6653aSJeff Kirsher 21407ac6653aSJeff Kirsher if (!netif_running(ndev)) 21417ac6653aSJeff Kirsher return 0; 21427ac6653aSJeff Kirsher 2143f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 21447ac6653aSJeff Kirsher 21457ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 21467ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 21477ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 21487ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 21497ac6653aSJeff Kirsher * from another devices (e.g. serial console). */ 21507ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 21517ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, 0); 2152ba1377ffSGiuseppe CAVALLARO else 2153ba1377ffSGiuseppe CAVALLARO /* enable the clk prevously disabled */ 2154a630844dSStefan Roese clk_prepare_enable(priv->stmmac_clk); 21557ac6653aSJeff Kirsher 21567ac6653aSJeff Kirsher netif_device_attach(ndev); 21577ac6653aSJeff Kirsher 21587ac6653aSJeff Kirsher /* Enable the MAC and DMA */ 2159bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, true); 21607ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 21617ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 21627ac6653aSJeff Kirsher 21637ac6653aSJeff Kirsher napi_enable(&priv->napi); 21647ac6653aSJeff Kirsher 21657ac6653aSJeff Kirsher netif_start_queue(ndev); 21667ac6653aSJeff Kirsher 2167f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 2168102463b1SFrancesco Virlinzi 2169102463b1SFrancesco Virlinzi if (priv->phydev) 2170102463b1SFrancesco Virlinzi phy_start(priv->phydev); 2171102463b1SFrancesco Virlinzi 21727ac6653aSJeff Kirsher return 0; 21737ac6653aSJeff Kirsher } 21747ac6653aSJeff Kirsher 2175bfab27a1SGiuseppe CAVALLARO int stmmac_freeze(struct net_device *ndev) 21767ac6653aSJeff Kirsher { 21777ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 21787ac6653aSJeff Kirsher return 0; 21797ac6653aSJeff Kirsher 21807ac6653aSJeff Kirsher return stmmac_release(ndev); 21817ac6653aSJeff Kirsher } 21827ac6653aSJeff Kirsher 2183bfab27a1SGiuseppe CAVALLARO int stmmac_restore(struct net_device *ndev) 21847ac6653aSJeff Kirsher { 21857ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 21867ac6653aSJeff Kirsher return 0; 21877ac6653aSJeff Kirsher 21887ac6653aSJeff Kirsher return stmmac_open(ndev); 21897ac6653aSJeff Kirsher } 21907ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 21917ac6653aSJeff Kirsher 219233d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers 219333d5e332SGiuseppe CAVALLARO * depending on the configuration selected. 219433d5e332SGiuseppe CAVALLARO */ 2195ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void) 2196ba27ec66SGiuseppe CAVALLARO { 219733d5e332SGiuseppe CAVALLARO int err_plt = 0; 219833d5e332SGiuseppe CAVALLARO int err_pci = 0; 2199ba27ec66SGiuseppe CAVALLARO 220033d5e332SGiuseppe CAVALLARO err_plt = stmmac_register_platform(); 220133d5e332SGiuseppe CAVALLARO err_pci = stmmac_register_pci(); 2202ba27ec66SGiuseppe CAVALLARO 220333d5e332SGiuseppe CAVALLARO if ((err_pci) && (err_plt)) { 220433d5e332SGiuseppe CAVALLARO pr_err("stmmac: driver registration failed\n"); 220533d5e332SGiuseppe CAVALLARO return -EINVAL; 2206ba27ec66SGiuseppe CAVALLARO } 2207ba27ec66SGiuseppe CAVALLARO 220833d5e332SGiuseppe CAVALLARO return 0; 2209ba27ec66SGiuseppe CAVALLARO } 2210ba27ec66SGiuseppe CAVALLARO 2211ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void) 2212ba27ec66SGiuseppe CAVALLARO { 221333d5e332SGiuseppe CAVALLARO stmmac_unregister_platform(); 221433d5e332SGiuseppe CAVALLARO stmmac_unregister_pci(); 2215ba27ec66SGiuseppe CAVALLARO } 2216ba27ec66SGiuseppe CAVALLARO 2217ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init); 2218ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit); 2219ba27ec66SGiuseppe CAVALLARO 22207ac6653aSJeff Kirsher #ifndef MODULE 22217ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 22227ac6653aSJeff Kirsher { 22237ac6653aSJeff Kirsher char *opt; 22247ac6653aSJeff Kirsher 22257ac6653aSJeff Kirsher if (!str || !*str) 22267ac6653aSJeff Kirsher return -EINVAL; 22277ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 22287ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 2229ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &debug)) 22307ac6653aSJeff Kirsher goto err; 22317ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 2232ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 8, 0, &phyaddr)) 22337ac6653aSJeff Kirsher goto err; 22347ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 2235ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_txsize)) 22367ac6653aSJeff Kirsher goto err; 22377ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 2238ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_rxsize)) 22397ac6653aSJeff Kirsher goto err; 22407ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 2241ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &buf_sz)) 22427ac6653aSJeff Kirsher goto err; 22437ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 2244ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 3, 0, &tc)) 22457ac6653aSJeff Kirsher goto err; 22467ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 2247ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 9, 0, &watchdog)) 22487ac6653aSJeff Kirsher goto err; 22497ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 2250ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &flow_ctrl)) 22517ac6653aSJeff Kirsher goto err; 22527ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 2253ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &pause)) 22547ac6653aSJeff Kirsher goto err; 2255d765955dSGiuseppe CAVALLARO } else if (!strncmp(opt, "eee_timer:", 6)) { 2256d765955dSGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &eee_timer)) 2257d765955dSGiuseppe CAVALLARO goto err; 22587ac6653aSJeff Kirsher } 22597ac6653aSJeff Kirsher } 22607ac6653aSJeff Kirsher return 0; 22617ac6653aSJeff Kirsher 22627ac6653aSJeff Kirsher err: 22637ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 22647ac6653aSJeff Kirsher return -EINVAL; 22657ac6653aSJeff Kirsher } 22667ac6653aSJeff Kirsher 22677ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 22687ac6653aSJeff Kirsher #endif 22696fc0d0f2SGiuseppe Cavallaro 22706fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 22716fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 22726fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 2273