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 /* Pay attention to tune this parameter; take care of both 1197ac6653aSJeff Kirsher * hardware capability and network stabitily/performance impact. 1207ac6653aSJeff Kirsher * Many tests showed that ~4ms latency seems to be good enough. */ 1217ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 1227ac6653aSJeff Kirsher #define DEFAULT_PERIODIC_RATE 256 1237ac6653aSJeff Kirsher static int tmrate = DEFAULT_PERIODIC_RATE; 1247ac6653aSJeff Kirsher module_param(tmrate, int, S_IRUGO | S_IWUSR); 1257ac6653aSJeff Kirsher MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)"); 1267ac6653aSJeff Kirsher #endif 1277ac6653aSJeff Kirsher 1287ac6653aSJeff Kirsher #define DMA_BUFFER_SIZE BUF_SIZE_2KiB 1297ac6653aSJeff Kirsher static int buf_sz = DMA_BUFFER_SIZE; 1307ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 1317ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 1327ac6653aSJeff Kirsher 1337ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1347ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1357ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1367ac6653aSJeff Kirsher 137d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER 1000 138d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; 139d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR); 140d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); 141d765955dSGiuseppe CAVALLARO #define STMMAC_LPI_TIMER(x) (jiffies + msecs_to_jiffies(x)) 142d765955dSGiuseppe CAVALLARO 1437ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1447ac6653aSJeff Kirsher 145bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 146bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev); 147bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void); 148bfab27a1SGiuseppe CAVALLARO #endif 149bfab27a1SGiuseppe CAVALLARO 1507ac6653aSJeff Kirsher /** 1517ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1527ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1537ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1547ac6653aSJeff Kirsher */ 1557ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1567ac6653aSJeff Kirsher { 1577ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1587ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1597ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1607ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1617ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1627ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 1637ac6653aSJeff Kirsher if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) 1647ac6653aSJeff Kirsher buf_sz = DMA_BUFFER_SIZE; 1657ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1667ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1677ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1687ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1697ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1707ac6653aSJeff Kirsher pause = PAUSE_TIME; 171d765955dSGiuseppe CAVALLARO if (eee_timer < 0) 172d765955dSGiuseppe CAVALLARO eee_timer = STMMAC_DEFAULT_LPI_TIMER; 1737ac6653aSJeff Kirsher } 1747ac6653aSJeff Kirsher 175cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv) 176cd7201f4SGiuseppe CAVALLARO { 177cd7201f4SGiuseppe CAVALLARO u32 clk_rate; 178cd7201f4SGiuseppe CAVALLARO 179cd7201f4SGiuseppe CAVALLARO clk_rate = clk_get_rate(priv->stmmac_clk); 180cd7201f4SGiuseppe CAVALLARO 181cd7201f4SGiuseppe CAVALLARO /* Platform provided default clk_csr would be assumed valid 182cd7201f4SGiuseppe CAVALLARO * for all other cases except for the below mentioned ones. */ 183cd7201f4SGiuseppe CAVALLARO if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) { 184cd7201f4SGiuseppe CAVALLARO if (clk_rate < CSR_F_35M) 185cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_20_35M; 186cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M)) 187cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_35_60M; 188cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M)) 189cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_60_100M; 190cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M)) 191cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_100_150M; 192cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) 193cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_150_250M; 194cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) 195cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_250_300M; 196cd7201f4SGiuseppe CAVALLARO } /* For values higher than the IEEE 802.3 specified frequency 197cd7201f4SGiuseppe CAVALLARO * we can not estimate the proper divider as it is not known 198cd7201f4SGiuseppe CAVALLARO * the frequency of clk_csr_i. So we do not change the default 199cd7201f4SGiuseppe CAVALLARO * divider. */ 200cd7201f4SGiuseppe CAVALLARO } 201cd7201f4SGiuseppe CAVALLARO 2027ac6653aSJeff Kirsher #if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) 2037ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 2047ac6653aSJeff Kirsher { 2057ac6653aSJeff Kirsher int j; 2067ac6653aSJeff Kirsher pr_info("len = %d byte, buf addr: 0x%p", len, buf); 2077ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 2087ac6653aSJeff Kirsher if ((j % 16) == 0) 2097ac6653aSJeff Kirsher pr_info("\n %03x:", j); 2107ac6653aSJeff Kirsher pr_info(" %02x", buf[j]); 2117ac6653aSJeff Kirsher } 2127ac6653aSJeff Kirsher pr_info("\n"); 2137ac6653aSJeff Kirsher } 2147ac6653aSJeff Kirsher #endif 2157ac6653aSJeff Kirsher 2167ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 2177ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 2187ac6653aSJeff Kirsher 2197ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 2207ac6653aSJeff Kirsher { 2217ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 2227ac6653aSJeff Kirsher } 2237ac6653aSJeff Kirsher 2247ac6653aSJeff Kirsher /* On some ST platforms, some HW system configuraton registers have to be 2257ac6653aSJeff Kirsher * set according to the link speed negotiated. 2267ac6653aSJeff Kirsher */ 2277ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 2287ac6653aSJeff Kirsher { 2297ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2307ac6653aSJeff Kirsher 2317ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 2327ac6653aSJeff Kirsher priv->plat->fix_mac_speed(priv->plat->bsp_priv, 2337ac6653aSJeff Kirsher phydev->speed); 2347ac6653aSJeff Kirsher } 2357ac6653aSJeff Kirsher 236d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv) 237d765955dSGiuseppe CAVALLARO { 238d765955dSGiuseppe CAVALLARO /* Check and enter in LPI mode */ 239d765955dSGiuseppe CAVALLARO if ((priv->dirty_tx == priv->cur_tx) && 240d765955dSGiuseppe CAVALLARO (priv->tx_path_in_lpi_mode == false)) 241d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_mode(priv->ioaddr); 242d765955dSGiuseppe CAVALLARO } 243d765955dSGiuseppe CAVALLARO 244d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv) 245d765955dSGiuseppe CAVALLARO { 246d765955dSGiuseppe CAVALLARO /* Exit and disable EEE in case of we are are in LPI state. */ 247d765955dSGiuseppe CAVALLARO priv->hw->mac->reset_eee_mode(priv->ioaddr); 248d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 249d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 250d765955dSGiuseppe CAVALLARO } 251d765955dSGiuseppe CAVALLARO 252d765955dSGiuseppe CAVALLARO /** 253d765955dSGiuseppe CAVALLARO * stmmac_eee_ctrl_timer 254d765955dSGiuseppe CAVALLARO * @arg : data hook 255d765955dSGiuseppe CAVALLARO * Description: 256d765955dSGiuseppe CAVALLARO * If there is no data transfer and if we are not in LPI state, 257d765955dSGiuseppe CAVALLARO * then MAC Transmitter can be moved to LPI state. 258d765955dSGiuseppe CAVALLARO */ 259d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg) 260d765955dSGiuseppe CAVALLARO { 261d765955dSGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)arg; 262d765955dSGiuseppe CAVALLARO 263d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 264d765955dSGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); 265d765955dSGiuseppe CAVALLARO } 266d765955dSGiuseppe CAVALLARO 267d765955dSGiuseppe CAVALLARO /** 268d765955dSGiuseppe CAVALLARO * stmmac_eee_init 269d765955dSGiuseppe CAVALLARO * @priv: private device pointer 270d765955dSGiuseppe CAVALLARO * Description: 271d765955dSGiuseppe CAVALLARO * If the EEE support has been enabled while configuring the driver, 272d765955dSGiuseppe CAVALLARO * if the GMAC actually supports the EEE (from the HW cap reg) and the 273d765955dSGiuseppe CAVALLARO * phy can also manage EEE, so enable the LPI state and start the timer 274d765955dSGiuseppe CAVALLARO * to verify if the tx path can enter in LPI state. 275d765955dSGiuseppe CAVALLARO */ 276d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv) 277d765955dSGiuseppe CAVALLARO { 278d765955dSGiuseppe CAVALLARO bool ret = false; 279d765955dSGiuseppe CAVALLARO 280d765955dSGiuseppe CAVALLARO /* MAC core supports the EEE feature. */ 281d765955dSGiuseppe CAVALLARO if (priv->dma_cap.eee) { 282d765955dSGiuseppe CAVALLARO /* Check if the PHY supports EEE */ 283d765955dSGiuseppe CAVALLARO if (phy_init_eee(priv->phydev, 1)) 284d765955dSGiuseppe CAVALLARO goto out; 285d765955dSGiuseppe CAVALLARO 286d765955dSGiuseppe CAVALLARO priv->eee_active = 1; 287d765955dSGiuseppe CAVALLARO init_timer(&priv->eee_ctrl_timer); 288d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; 289d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.data = (unsigned long)priv; 290d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.expires = STMMAC_LPI_TIMER(eee_timer); 291d765955dSGiuseppe CAVALLARO add_timer(&priv->eee_ctrl_timer); 292d765955dSGiuseppe CAVALLARO 293d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_timer(priv->ioaddr, 294d765955dSGiuseppe CAVALLARO STMMAC_DEFAULT_LIT_LS_TIMER, 295d765955dSGiuseppe CAVALLARO priv->tx_lpi_timer); 296d765955dSGiuseppe CAVALLARO 297d765955dSGiuseppe CAVALLARO pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); 298d765955dSGiuseppe CAVALLARO 299d765955dSGiuseppe CAVALLARO ret = true; 300d765955dSGiuseppe CAVALLARO } 301d765955dSGiuseppe CAVALLARO out: 302d765955dSGiuseppe CAVALLARO return ret; 303d765955dSGiuseppe CAVALLARO } 304d765955dSGiuseppe CAVALLARO 305d765955dSGiuseppe CAVALLARO static void stmmac_eee_adjust(struct stmmac_priv *priv) 306d765955dSGiuseppe CAVALLARO { 307d765955dSGiuseppe CAVALLARO /* When the EEE has been already initialised we have to 308d765955dSGiuseppe CAVALLARO * modify the PLS bit in the LPI ctrl & status reg according 309d765955dSGiuseppe CAVALLARO * to the PHY link status. For this reason. 310d765955dSGiuseppe CAVALLARO */ 311d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 312d765955dSGiuseppe CAVALLARO priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link); 313d765955dSGiuseppe CAVALLARO } 314d765955dSGiuseppe CAVALLARO 3157ac6653aSJeff Kirsher /** 3167ac6653aSJeff Kirsher * stmmac_adjust_link 3177ac6653aSJeff Kirsher * @dev: net device structure 3187ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 3197ac6653aSJeff Kirsher */ 3207ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 3217ac6653aSJeff Kirsher { 3227ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 3237ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 3247ac6653aSJeff Kirsher unsigned long flags; 3257ac6653aSJeff Kirsher int new_state = 0; 3267ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 3277ac6653aSJeff Kirsher 3287ac6653aSJeff Kirsher if (phydev == NULL) 3297ac6653aSJeff Kirsher return; 3307ac6653aSJeff Kirsher 3317ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n", 3327ac6653aSJeff Kirsher phydev->addr, phydev->link); 3337ac6653aSJeff Kirsher 3347ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 335d765955dSGiuseppe CAVALLARO 3367ac6653aSJeff Kirsher if (phydev->link) { 3377ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 3387ac6653aSJeff Kirsher 3397ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 3407ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 3417ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 3427ac6653aSJeff Kirsher new_state = 1; 3437ac6653aSJeff Kirsher if (!(phydev->duplex)) 3447ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 3457ac6653aSJeff Kirsher else 3467ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 3477ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 3487ac6653aSJeff Kirsher } 3497ac6653aSJeff Kirsher /* Flow Control operation */ 3507ac6653aSJeff Kirsher if (phydev->pause) 3517ac6653aSJeff Kirsher priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, 3527ac6653aSJeff Kirsher fc, pause_time); 3537ac6653aSJeff Kirsher 3547ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 3557ac6653aSJeff Kirsher new_state = 1; 3567ac6653aSJeff Kirsher switch (phydev->speed) { 3577ac6653aSJeff Kirsher case 1000: 3587ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 3597ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 3607ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 3617ac6653aSJeff Kirsher break; 3627ac6653aSJeff Kirsher case 100: 3637ac6653aSJeff Kirsher case 10: 3647ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 3657ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 3667ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 3677ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 3687ac6653aSJeff Kirsher } else { 3697ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 3707ac6653aSJeff Kirsher } 3717ac6653aSJeff Kirsher } else { 3727ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 3737ac6653aSJeff Kirsher } 3747ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 3757ac6653aSJeff Kirsher break; 3767ac6653aSJeff Kirsher default: 3777ac6653aSJeff Kirsher if (netif_msg_link(priv)) 3787ac6653aSJeff Kirsher pr_warning("%s: Speed (%d) is not 10" 3797ac6653aSJeff Kirsher " or 100!\n", dev->name, phydev->speed); 3807ac6653aSJeff Kirsher break; 3817ac6653aSJeff Kirsher } 3827ac6653aSJeff Kirsher 3837ac6653aSJeff Kirsher priv->speed = phydev->speed; 3847ac6653aSJeff Kirsher } 3857ac6653aSJeff Kirsher 3867ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 3877ac6653aSJeff Kirsher 3887ac6653aSJeff Kirsher if (!priv->oldlink) { 3897ac6653aSJeff Kirsher new_state = 1; 3907ac6653aSJeff Kirsher priv->oldlink = 1; 3917ac6653aSJeff Kirsher } 3927ac6653aSJeff Kirsher } else if (priv->oldlink) { 3937ac6653aSJeff Kirsher new_state = 1; 3947ac6653aSJeff Kirsher priv->oldlink = 0; 3957ac6653aSJeff Kirsher priv->speed = 0; 3967ac6653aSJeff Kirsher priv->oldduplex = -1; 3977ac6653aSJeff Kirsher } 3987ac6653aSJeff Kirsher 3997ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 4007ac6653aSJeff Kirsher phy_print_status(phydev); 4017ac6653aSJeff Kirsher 402d765955dSGiuseppe CAVALLARO stmmac_eee_adjust(priv); 403d765955dSGiuseppe CAVALLARO 4047ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 4057ac6653aSJeff Kirsher 4067ac6653aSJeff Kirsher DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n"); 4077ac6653aSJeff Kirsher } 4087ac6653aSJeff Kirsher 4097ac6653aSJeff Kirsher /** 4107ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 4117ac6653aSJeff Kirsher * @dev: net device structure 4127ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 4137ac6653aSJeff Kirsher * to the mac driver. 4147ac6653aSJeff Kirsher * Return value: 4157ac6653aSJeff Kirsher * 0 on success 4167ac6653aSJeff Kirsher */ 4177ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 4187ac6653aSJeff Kirsher { 4197ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 4207ac6653aSJeff Kirsher struct phy_device *phydev; 421d765955dSGiuseppe CAVALLARO char phy_id_fmt[MII_BUS_ID_SIZE + 3]; 4227ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 42379ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 4247ac6653aSJeff Kirsher priv->oldlink = 0; 4257ac6653aSJeff Kirsher priv->speed = 0; 4267ac6653aSJeff Kirsher priv->oldduplex = -1; 4277ac6653aSJeff Kirsher 428f142af2eSSrinivas Kandagatla if (priv->plat->phy_bus_name) 429f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", 430f142af2eSSrinivas Kandagatla priv->plat->phy_bus_name, priv->plat->bus_id); 431f142af2eSSrinivas Kandagatla else 432f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", 433f142af2eSSrinivas Kandagatla priv->plat->bus_id); 434f142af2eSSrinivas Kandagatla 435d765955dSGiuseppe CAVALLARO snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 4367ac6653aSJeff Kirsher priv->plat->phy_addr); 437d765955dSGiuseppe CAVALLARO pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 4387ac6653aSJeff Kirsher 439d765955dSGiuseppe CAVALLARO phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, 0, 440d765955dSGiuseppe CAVALLARO interface); 4417ac6653aSJeff Kirsher 4427ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 4437ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 4447ac6653aSJeff Kirsher return PTR_ERR(phydev); 4457ac6653aSJeff Kirsher } 4467ac6653aSJeff Kirsher 44779ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 448c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 449c5b9b4e4SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII)) 450c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 451c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 45279ee1dc3SSrinivas Kandagatla 4537ac6653aSJeff Kirsher /* 4547ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 4557ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 4567ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 4577ac6653aSJeff Kirsher * device as well. 4587ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 4597ac6653aSJeff Kirsher */ 4607ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 4617ac6653aSJeff Kirsher phy_disconnect(phydev); 4627ac6653aSJeff Kirsher return -ENODEV; 4637ac6653aSJeff Kirsher } 4647ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 4657ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 4667ac6653aSJeff Kirsher 4677ac6653aSJeff Kirsher priv->phydev = phydev; 4687ac6653aSJeff Kirsher 4697ac6653aSJeff Kirsher return 0; 4707ac6653aSJeff Kirsher } 4717ac6653aSJeff Kirsher 4727ac6653aSJeff Kirsher /** 4737ac6653aSJeff Kirsher * display_ring 4747ac6653aSJeff Kirsher * @p: pointer to the ring. 4757ac6653aSJeff Kirsher * @size: size of the ring. 4767ac6653aSJeff Kirsher * Description: display all the descriptors within the ring. 4777ac6653aSJeff Kirsher */ 4787ac6653aSJeff Kirsher static void display_ring(struct dma_desc *p, int size) 4797ac6653aSJeff Kirsher { 4807ac6653aSJeff Kirsher struct tmp_s { 4817ac6653aSJeff Kirsher u64 a; 4827ac6653aSJeff Kirsher unsigned int b; 4837ac6653aSJeff Kirsher unsigned int c; 4847ac6653aSJeff Kirsher }; 4857ac6653aSJeff Kirsher int i; 4867ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 4877ac6653aSJeff Kirsher struct tmp_s *x = (struct tmp_s *)(p + i); 4887ac6653aSJeff Kirsher pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 4897ac6653aSJeff Kirsher i, (unsigned int)virt_to_phys(&p[i]), 4907ac6653aSJeff Kirsher (unsigned int)(x->a), (unsigned int)((x->a) >> 32), 4917ac6653aSJeff Kirsher x->b, x->c); 4927ac6653aSJeff Kirsher pr_info("\n"); 4937ac6653aSJeff Kirsher } 4947ac6653aSJeff Kirsher } 4957ac6653aSJeff Kirsher 496286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 497286a8372SGiuseppe CAVALLARO { 498286a8372SGiuseppe CAVALLARO int ret = bufsize; 499286a8372SGiuseppe CAVALLARO 500286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 501286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 502286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 503286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 504286a8372SGiuseppe CAVALLARO else if (mtu >= DMA_BUFFER_SIZE) 505286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 506286a8372SGiuseppe CAVALLARO else 507286a8372SGiuseppe CAVALLARO ret = DMA_BUFFER_SIZE; 508286a8372SGiuseppe CAVALLARO 509286a8372SGiuseppe CAVALLARO return ret; 510286a8372SGiuseppe CAVALLARO } 511286a8372SGiuseppe CAVALLARO 5127ac6653aSJeff Kirsher /** 5137ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 5147ac6653aSJeff Kirsher * @dev: net device structure 5157ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 516286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 517286a8372SGiuseppe CAVALLARO * modes. 5187ac6653aSJeff Kirsher */ 5197ac6653aSJeff Kirsher static void init_dma_desc_rings(struct net_device *dev) 5207ac6653aSJeff Kirsher { 5217ac6653aSJeff Kirsher int i; 5227ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 5237ac6653aSJeff Kirsher struct sk_buff *skb; 5247ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 5257ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 526286a8372SGiuseppe CAVALLARO unsigned int bfsize; 527286a8372SGiuseppe CAVALLARO int dis_ic = 0; 528286a8372SGiuseppe CAVALLARO int des3_as_data_buf = 0; 5297ac6653aSJeff Kirsher 530286a8372SGiuseppe CAVALLARO /* Set the max buffer size according to the DESC mode 531286a8372SGiuseppe CAVALLARO * and the MTU. Note that RING mode allows 16KiB bsize. */ 532286a8372SGiuseppe CAVALLARO bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu); 533286a8372SGiuseppe CAVALLARO 534286a8372SGiuseppe CAVALLARO if (bfsize == BUF_SIZE_16KiB) 535286a8372SGiuseppe CAVALLARO des3_as_data_buf = 1; 5367ac6653aSJeff Kirsher else 537286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 5387ac6653aSJeff Kirsher 5397ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 5407ac6653aSJeff Kirsher /* Disable interrupts on completion for the reception if timer is on */ 5417ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 5427ac6653aSJeff Kirsher dis_ic = 1; 5437ac6653aSJeff Kirsher #endif 5447ac6653aSJeff Kirsher 5457ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n", 5467ac6653aSJeff Kirsher txsize, rxsize, bfsize); 5477ac6653aSJeff Kirsher 5487ac6653aSJeff Kirsher priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL); 5497ac6653aSJeff Kirsher priv->rx_skbuff = 5507ac6653aSJeff Kirsher kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL); 5517ac6653aSJeff Kirsher priv->dma_rx = 5527ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 5537ac6653aSJeff Kirsher rxsize * 5547ac6653aSJeff Kirsher sizeof(struct dma_desc), 5557ac6653aSJeff Kirsher &priv->dma_rx_phy, 5567ac6653aSJeff Kirsher GFP_KERNEL); 5577ac6653aSJeff Kirsher priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize, 5587ac6653aSJeff Kirsher GFP_KERNEL); 5597ac6653aSJeff Kirsher priv->dma_tx = 5607ac6653aSJeff Kirsher (struct dma_desc *)dma_alloc_coherent(priv->device, 5617ac6653aSJeff Kirsher txsize * 5627ac6653aSJeff Kirsher sizeof(struct dma_desc), 5637ac6653aSJeff Kirsher &priv->dma_tx_phy, 5647ac6653aSJeff Kirsher GFP_KERNEL); 5657ac6653aSJeff Kirsher 5667ac6653aSJeff Kirsher if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) { 5677ac6653aSJeff Kirsher pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__); 5687ac6653aSJeff Kirsher return; 5697ac6653aSJeff Kirsher } 5707ac6653aSJeff Kirsher 571286a8372SGiuseppe CAVALLARO DBG(probe, INFO, "stmmac (%s) DMA desc: virt addr (Rx %p, " 5727ac6653aSJeff Kirsher "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n", 5737ac6653aSJeff Kirsher dev->name, priv->dma_rx, priv->dma_tx, 5747ac6653aSJeff Kirsher (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy); 5757ac6653aSJeff Kirsher 5767ac6653aSJeff Kirsher /* RX INITIALIZATION */ 5777ac6653aSJeff Kirsher DBG(probe, INFO, "stmmac: SKB addresses:\n" 5787ac6653aSJeff Kirsher "skb\t\tskb data\tdma data\n"); 5797ac6653aSJeff Kirsher 5807ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 5817ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + i; 5827ac6653aSJeff Kirsher 58345db81e1SGiuseppe CAVALLARO skb = __netdev_alloc_skb(dev, bfsize + NET_IP_ALIGN, 58445db81e1SGiuseppe CAVALLARO GFP_KERNEL); 5857ac6653aSJeff Kirsher if (unlikely(skb == NULL)) { 5867ac6653aSJeff Kirsher pr_err("%s: Rx init fails; skb is NULL\n", __func__); 5877ac6653aSJeff Kirsher break; 5887ac6653aSJeff Kirsher } 58945db81e1SGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 5907ac6653aSJeff Kirsher priv->rx_skbuff[i] = skb; 5917ac6653aSJeff Kirsher priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 5927ac6653aSJeff Kirsher bfsize, DMA_FROM_DEVICE); 5937ac6653aSJeff Kirsher 5947ac6653aSJeff Kirsher p->des2 = priv->rx_skbuff_dma[i]; 595286a8372SGiuseppe CAVALLARO 596286a8372SGiuseppe CAVALLARO priv->hw->ring->init_desc3(des3_as_data_buf, p); 597286a8372SGiuseppe CAVALLARO 5987ac6653aSJeff Kirsher DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 5997ac6653aSJeff Kirsher priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]); 6007ac6653aSJeff Kirsher } 6017ac6653aSJeff Kirsher priv->cur_rx = 0; 6027ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 6037ac6653aSJeff Kirsher priv->dma_buf_sz = bfsize; 6047ac6653aSJeff Kirsher buf_sz = bfsize; 6057ac6653aSJeff Kirsher 6067ac6653aSJeff Kirsher /* TX INITIALIZATION */ 6077ac6653aSJeff Kirsher for (i = 0; i < txsize; i++) { 6087ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 6097ac6653aSJeff Kirsher priv->dma_tx[i].des2 = 0; 6107ac6653aSJeff Kirsher } 611286a8372SGiuseppe CAVALLARO 612286a8372SGiuseppe CAVALLARO /* In case of Chained mode this sets the des3 to the next 613286a8372SGiuseppe CAVALLARO * element in the chain */ 614286a8372SGiuseppe CAVALLARO priv->hw->ring->init_dma_chain(priv->dma_rx, priv->dma_rx_phy, rxsize); 615286a8372SGiuseppe CAVALLARO priv->hw->ring->init_dma_chain(priv->dma_tx, priv->dma_tx_phy, txsize); 616286a8372SGiuseppe CAVALLARO 6177ac6653aSJeff Kirsher priv->dirty_tx = 0; 6187ac6653aSJeff Kirsher priv->cur_tx = 0; 6197ac6653aSJeff Kirsher 6207ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 6217ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic); 6227ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, txsize); 6237ac6653aSJeff Kirsher 6247ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 6257ac6653aSJeff Kirsher pr_info("RX descriptor ring:\n"); 6267ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 6277ac6653aSJeff Kirsher pr_info("TX descriptor ring:\n"); 6287ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 6297ac6653aSJeff Kirsher } 6307ac6653aSJeff Kirsher } 6317ac6653aSJeff Kirsher 6327ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 6337ac6653aSJeff Kirsher { 6347ac6653aSJeff Kirsher int i; 6357ac6653aSJeff Kirsher 6367ac6653aSJeff Kirsher for (i = 0; i < priv->dma_rx_size; i++) { 6377ac6653aSJeff Kirsher if (priv->rx_skbuff[i]) { 6387ac6653aSJeff Kirsher dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 6397ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 6407ac6653aSJeff Kirsher dev_kfree_skb_any(priv->rx_skbuff[i]); 6417ac6653aSJeff Kirsher } 6427ac6653aSJeff Kirsher priv->rx_skbuff[i] = NULL; 6437ac6653aSJeff Kirsher } 6447ac6653aSJeff Kirsher } 6457ac6653aSJeff Kirsher 6467ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 6477ac6653aSJeff Kirsher { 6487ac6653aSJeff Kirsher int i; 6497ac6653aSJeff Kirsher 6507ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 6517ac6653aSJeff Kirsher if (priv->tx_skbuff[i] != NULL) { 6527ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + i; 6537ac6653aSJeff Kirsher if (p->des2) 6547ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 6557ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 6567ac6653aSJeff Kirsher DMA_TO_DEVICE); 6577ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 6587ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 6597ac6653aSJeff Kirsher } 6607ac6653aSJeff Kirsher } 6617ac6653aSJeff Kirsher } 6627ac6653aSJeff Kirsher 6637ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 6647ac6653aSJeff Kirsher { 6657ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 6667ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 6677ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 6687ac6653aSJeff Kirsher 6697ac6653aSJeff Kirsher /* Free the region of consistent memory previously allocated for 6707ac6653aSJeff Kirsher * the DMA */ 6717ac6653aSJeff Kirsher dma_free_coherent(priv->device, 6727ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 6737ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 6747ac6653aSJeff Kirsher dma_free_coherent(priv->device, 6757ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 6767ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 6777ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 6787ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 6797ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 6807ac6653aSJeff Kirsher } 6817ac6653aSJeff Kirsher 6827ac6653aSJeff Kirsher /** 6837ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 6847ac6653aSJeff Kirsher * @priv : pointer to the private device structure. 6857ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 6867ac6653aSJeff Kirsher * or Store-And-Forward capability. 6877ac6653aSJeff Kirsher */ 6887ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 6897ac6653aSJeff Kirsher { 6907ac6653aSJeff Kirsher if (likely(priv->plat->force_sf_dma_mode || 6917ac6653aSJeff Kirsher ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) { 6927ac6653aSJeff Kirsher /* 6937ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 6947ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 6957ac6653aSJeff Kirsher * 1) TX COE if actually supported 6967ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 6977ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 6987ac6653aSJeff Kirsher */ 6997ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, 7007ac6653aSJeff Kirsher SF_DMA_MODE, SF_DMA_MODE); 7017ac6653aSJeff Kirsher tc = SF_DMA_MODE; 7027ac6653aSJeff Kirsher } else 7037ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 7047ac6653aSJeff Kirsher } 7057ac6653aSJeff Kirsher 7067ac6653aSJeff Kirsher /** 7077ac6653aSJeff Kirsher * stmmac_tx: 7087ac6653aSJeff Kirsher * @priv: private driver structure 7097ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 7107ac6653aSJeff Kirsher */ 7117ac6653aSJeff Kirsher static void stmmac_tx(struct stmmac_priv *priv) 7127ac6653aSJeff Kirsher { 7137ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 7147ac6653aSJeff Kirsher 715a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 716a9097a96SGiuseppe CAVALLARO 7177ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 7187ac6653aSJeff Kirsher int last; 7197ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 7207ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 7217ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_tx + entry; 7227ac6653aSJeff Kirsher 7237ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 7247ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 7257ac6653aSJeff Kirsher break; 7267ac6653aSJeff Kirsher 7277ac6653aSJeff Kirsher /* Verify tx error by looking at the last segment */ 7287ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 7297ac6653aSJeff Kirsher if (likely(last)) { 7307ac6653aSJeff Kirsher int tx_error = 7317ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 7327ac6653aSJeff Kirsher &priv->xstats, p, 7337ac6653aSJeff Kirsher priv->ioaddr); 7347ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 7357ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 7367ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 7377ac6653aSJeff Kirsher } else 7387ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 7397ac6653aSJeff Kirsher } 7407ac6653aSJeff Kirsher TX_DBG("%s: curr %d, dirty %d\n", __func__, 7417ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 7427ac6653aSJeff Kirsher 7437ac6653aSJeff Kirsher if (likely(p->des2)) 7447ac6653aSJeff Kirsher dma_unmap_single(priv->device, p->des2, 7457ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 7467ac6653aSJeff Kirsher DMA_TO_DEVICE); 747286a8372SGiuseppe CAVALLARO priv->hw->ring->clean_desc3(p); 7487ac6653aSJeff Kirsher 7497ac6653aSJeff Kirsher if (likely(skb != NULL)) { 7507ac6653aSJeff Kirsher /* 7517ac6653aSJeff Kirsher * If there's room in the queue (limit it to size) 7527ac6653aSJeff Kirsher * we add this skb back into the pool, 7537ac6653aSJeff Kirsher * if it's the right size. 7547ac6653aSJeff Kirsher */ 7557ac6653aSJeff Kirsher if ((skb_queue_len(&priv->rx_recycle) < 7567ac6653aSJeff Kirsher priv->dma_rx_size) && 7577ac6653aSJeff Kirsher skb_recycle_check(skb, priv->dma_buf_sz)) 7587ac6653aSJeff Kirsher __skb_queue_head(&priv->rx_recycle, skb); 7597ac6653aSJeff Kirsher else 7607ac6653aSJeff Kirsher dev_kfree_skb(skb); 7617ac6653aSJeff Kirsher 7627ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 7637ac6653aSJeff Kirsher } 7647ac6653aSJeff Kirsher 7657ac6653aSJeff Kirsher priv->hw->desc->release_tx_desc(p); 7667ac6653aSJeff Kirsher 76713497f58SGiuseppe CAVALLARO priv->dirty_tx++; 7687ac6653aSJeff Kirsher } 7697ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 7707ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 7717ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 7727ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 7737ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 7747ac6653aSJeff Kirsher TX_DBG("%s: restart transmit\n", __func__); 7757ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 7767ac6653aSJeff Kirsher } 7777ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 7787ac6653aSJeff Kirsher } 779d765955dSGiuseppe CAVALLARO 780d765955dSGiuseppe CAVALLARO if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { 781d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 782d765955dSGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_TIMER(eee_timer)); 783d765955dSGiuseppe CAVALLARO } 784a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 7857ac6653aSJeff Kirsher } 7867ac6653aSJeff Kirsher 7877ac6653aSJeff Kirsher static inline void stmmac_enable_irq(struct stmmac_priv *priv) 7887ac6653aSJeff Kirsher { 7897ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 7907ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 7917ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 7927ac6653aSJeff Kirsher else 7937ac6653aSJeff Kirsher #endif 7947ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 7957ac6653aSJeff Kirsher } 7967ac6653aSJeff Kirsher 7977ac6653aSJeff Kirsher static inline void stmmac_disable_irq(struct stmmac_priv *priv) 7987ac6653aSJeff Kirsher { 7997ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 8007ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 8017ac6653aSJeff Kirsher priv->tm->timer_stop(); 8027ac6653aSJeff Kirsher else 8037ac6653aSJeff Kirsher #endif 8047ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 8057ac6653aSJeff Kirsher } 8067ac6653aSJeff Kirsher 8077ac6653aSJeff Kirsher static int stmmac_has_work(struct stmmac_priv *priv) 8087ac6653aSJeff Kirsher { 8097ac6653aSJeff Kirsher unsigned int has_work = 0; 8107ac6653aSJeff Kirsher int rxret, tx_work = 0; 8117ac6653aSJeff Kirsher 8127ac6653aSJeff Kirsher rxret = priv->hw->desc->get_rx_owner(priv->dma_rx + 8137ac6653aSJeff Kirsher (priv->cur_rx % priv->dma_rx_size)); 8147ac6653aSJeff Kirsher 8157ac6653aSJeff Kirsher if (priv->dirty_tx != priv->cur_tx) 8167ac6653aSJeff Kirsher tx_work = 1; 8177ac6653aSJeff Kirsher 8187ac6653aSJeff Kirsher if (likely(!rxret || tx_work)) 8197ac6653aSJeff Kirsher has_work = 1; 8207ac6653aSJeff Kirsher 8217ac6653aSJeff Kirsher return has_work; 8227ac6653aSJeff Kirsher } 8237ac6653aSJeff Kirsher 8247ac6653aSJeff Kirsher static inline void _stmmac_schedule(struct stmmac_priv *priv) 8257ac6653aSJeff Kirsher { 8267ac6653aSJeff Kirsher if (likely(stmmac_has_work(priv))) { 8277ac6653aSJeff Kirsher stmmac_disable_irq(priv); 8287ac6653aSJeff Kirsher napi_schedule(&priv->napi); 8297ac6653aSJeff Kirsher } 8307ac6653aSJeff Kirsher } 8317ac6653aSJeff Kirsher 8327ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 8337ac6653aSJeff Kirsher void stmmac_schedule(struct net_device *dev) 8347ac6653aSJeff Kirsher { 8357ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 8367ac6653aSJeff Kirsher 8377ac6653aSJeff Kirsher priv->xstats.sched_timer_n++; 8387ac6653aSJeff Kirsher 8397ac6653aSJeff Kirsher _stmmac_schedule(priv); 8407ac6653aSJeff Kirsher } 8417ac6653aSJeff Kirsher 8427ac6653aSJeff Kirsher static void stmmac_no_timer_started(unsigned int x) 8437ac6653aSJeff Kirsher {; 8447ac6653aSJeff Kirsher }; 8457ac6653aSJeff Kirsher 8467ac6653aSJeff Kirsher static void stmmac_no_timer_stopped(void) 8477ac6653aSJeff Kirsher {; 8487ac6653aSJeff Kirsher }; 8497ac6653aSJeff Kirsher #endif 8507ac6653aSJeff Kirsher 8517ac6653aSJeff Kirsher /** 8527ac6653aSJeff Kirsher * stmmac_tx_err: 8537ac6653aSJeff Kirsher * @priv: pointer to the private device structure 8547ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 8557ac6653aSJeff Kirsher * in case of errors. 8567ac6653aSJeff Kirsher */ 8577ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 8587ac6653aSJeff Kirsher { 8597ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 8607ac6653aSJeff Kirsher 8617ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 8627ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 8637ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 8647ac6653aSJeff Kirsher priv->dirty_tx = 0; 8657ac6653aSJeff Kirsher priv->cur_tx = 0; 8667ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 8677ac6653aSJeff Kirsher 8687ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 8697ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 8707ac6653aSJeff Kirsher } 8717ac6653aSJeff Kirsher 8727ac6653aSJeff Kirsher 8737ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 8747ac6653aSJeff Kirsher { 8757ac6653aSJeff Kirsher int status; 8767ac6653aSJeff Kirsher 8777ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 8787ac6653aSJeff Kirsher if (likely(status == handle_tx_rx)) 8797ac6653aSJeff Kirsher _stmmac_schedule(priv); 8807ac6653aSJeff Kirsher 8817ac6653aSJeff Kirsher else if (unlikely(status == tx_hard_error_bump_tc)) { 8827ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 8837ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 8847ac6653aSJeff Kirsher tc += 64; 8857ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 8867ac6653aSJeff Kirsher priv->xstats.threshold = tc; 8877ac6653aSJeff Kirsher } 8887ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 8897ac6653aSJeff Kirsher stmmac_tx_err(priv); 8907ac6653aSJeff Kirsher } 8917ac6653aSJeff Kirsher 8921c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 8931c901a46SGiuseppe CAVALLARO { 8941c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 8951c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 8961c901a46SGiuseppe CAVALLARO 8974f795b25SGiuseppe CAVALLARO /* Mask MMC irq, counters are managed in SW and registers 8984f795b25SGiuseppe CAVALLARO * are cleared on each READ eventually. */ 8991c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 9004f795b25SGiuseppe CAVALLARO 9014f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 9021c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 9031c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 9044f795b25SGiuseppe CAVALLARO } else 905aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 9061c901a46SGiuseppe CAVALLARO } 9071c901a46SGiuseppe CAVALLARO 908f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 909f0b9d786SGiuseppe CAVALLARO { 910f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 911f0b9d786SGiuseppe CAVALLARO 912f0b9d786SGiuseppe CAVALLARO /* Only check valid Synopsys Id because old MAC chips 913f0b9d786SGiuseppe CAVALLARO * have no HW registers where get the ID */ 914f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 915f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 916f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 917f0b9d786SGiuseppe CAVALLARO 918cf3f047bSGiuseppe CAVALLARO pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", 919f0b9d786SGiuseppe CAVALLARO uid, synid); 920f0b9d786SGiuseppe CAVALLARO 921f0b9d786SGiuseppe CAVALLARO return synid; 922f0b9d786SGiuseppe CAVALLARO } 923f0b9d786SGiuseppe CAVALLARO return 0; 924f0b9d786SGiuseppe CAVALLARO } 925e7434821SGiuseppe CAVALLARO 92619e30c14SGiuseppe CAVALLARO /** 92719e30c14SGiuseppe CAVALLARO * stmmac_selec_desc_mode 928ff3dd78cSGiuseppe CAVALLARO * @priv : private structure 929ff3dd78cSGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors 930ff3dd78cSGiuseppe CAVALLARO */ 93119e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 93219e30c14SGiuseppe CAVALLARO { 93319e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 93419e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 93519e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 93619e30c14SGiuseppe CAVALLARO } else { 93719e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 93819e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 93919e30c14SGiuseppe CAVALLARO } 94019e30c14SGiuseppe CAVALLARO } 94119e30c14SGiuseppe CAVALLARO 94219e30c14SGiuseppe CAVALLARO /** 94319e30c14SGiuseppe CAVALLARO * stmmac_get_hw_features 94419e30c14SGiuseppe CAVALLARO * @priv : private device pointer 94519e30c14SGiuseppe CAVALLARO * Description: 94619e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 947e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 94819e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 94919e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 950e7434821SGiuseppe CAVALLARO */ 951e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 952e7434821SGiuseppe CAVALLARO { 9535e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 9543c20f72fSGiuseppe CAVALLARO 9555e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 9565e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 957e7434821SGiuseppe CAVALLARO 9581db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 9591db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 9601db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 9611db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 9621db123fbSRayagond Kokatanur priv->dma_cap.multi_addr = 9631db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_ADDMACADRSEL) >> 5; 9641db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 9651db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 9661db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 9671db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 9681db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 9691db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 9701db123fbSRayagond Kokatanur /* MMC */ 9711db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 972e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002*/ 9731db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 9741db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 975e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008*/ 9761db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 9771db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 978e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 9791db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 9801db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 981e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 9821db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 9831db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 9841db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 9851db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 9861db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 9871db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 9881db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 989e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 9901db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 9911db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 9921db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 9931db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 994e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode*/ 9951db123fbSRayagond Kokatanur priv->dma_cap.enh_desc = 9961db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 997e7434821SGiuseppe CAVALLARO 99819e30c14SGiuseppe CAVALLARO } 999e7434821SGiuseppe CAVALLARO 1000e7434821SGiuseppe CAVALLARO return hw_cap; 1001e7434821SGiuseppe CAVALLARO } 1002e7434821SGiuseppe CAVALLARO 1003bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 1004bfab27a1SGiuseppe CAVALLARO { 1005bfab27a1SGiuseppe CAVALLARO /* verify if the MAC address is valid, in case of failures it 1006bfab27a1SGiuseppe CAVALLARO * generates a random MAC address */ 1007bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 1008bfab27a1SGiuseppe CAVALLARO priv->hw->mac->get_umac_addr((void __iomem *) 1009bfab27a1SGiuseppe CAVALLARO priv->dev->base_addr, 1010bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 1011bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 1012f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 1013bfab27a1SGiuseppe CAVALLARO } 1014bfab27a1SGiuseppe CAVALLARO pr_warning("%s: device MAC address %pM\n", priv->dev->name, 1015bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 1016bfab27a1SGiuseppe CAVALLARO } 1017bfab27a1SGiuseppe CAVALLARO 10180f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv) 10190f1f88a8SGiuseppe CAVALLARO { 10200f1f88a8SGiuseppe CAVALLARO int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; 1021b9cde0a8SGiuseppe CAVALLARO int mixed_burst = 0; 10220f1f88a8SGiuseppe CAVALLARO 10230f1f88a8SGiuseppe CAVALLARO /* Some DMA parameters can be passed from the platform; 10240f1f88a8SGiuseppe CAVALLARO * in case of these are not passed we keep a default 10250f1f88a8SGiuseppe CAVALLARO * (good for all the chips) and init the DMA! */ 10260f1f88a8SGiuseppe CAVALLARO if (priv->plat->dma_cfg) { 10270f1f88a8SGiuseppe CAVALLARO pbl = priv->plat->dma_cfg->pbl; 10280f1f88a8SGiuseppe CAVALLARO fixed_burst = priv->plat->dma_cfg->fixed_burst; 1029b9cde0a8SGiuseppe CAVALLARO mixed_burst = priv->plat->dma_cfg->mixed_burst; 10300f1f88a8SGiuseppe CAVALLARO burst_len = priv->plat->dma_cfg->burst_len; 10310f1f88a8SGiuseppe CAVALLARO } 10320f1f88a8SGiuseppe CAVALLARO 1033b9cde0a8SGiuseppe CAVALLARO return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, 10340f1f88a8SGiuseppe CAVALLARO burst_len, priv->dma_tx_phy, 10350f1f88a8SGiuseppe CAVALLARO priv->dma_rx_phy); 10360f1f88a8SGiuseppe CAVALLARO } 10370f1f88a8SGiuseppe CAVALLARO 1038bfab27a1SGiuseppe CAVALLARO /** 10397ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 10407ac6653aSJeff Kirsher * @dev : pointer to the device structure. 10417ac6653aSJeff Kirsher * Description: 10427ac6653aSJeff Kirsher * This function is the open entry point of the driver. 10437ac6653aSJeff Kirsher * Return value: 10447ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 10457ac6653aSJeff Kirsher * file on failure. 10467ac6653aSJeff Kirsher */ 10477ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 10487ac6653aSJeff Kirsher { 10497ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 10507ac6653aSJeff Kirsher int ret; 10517ac6653aSJeff Kirsher 10527ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 10537ac6653aSJeff Kirsher priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); 10544bfcbd7aSFrancesco Virlinzi if (unlikely(priv->tm == NULL)) 10554bfcbd7aSFrancesco Virlinzi return -ENOMEM; 1056e404decbSJoe Perches 10577ac6653aSJeff Kirsher priv->tm->freq = tmrate; 10587ac6653aSJeff Kirsher 10597ac6653aSJeff Kirsher /* Test if the external timer can be actually used. 10607ac6653aSJeff Kirsher * In case of failure continue without timer. */ 10617ac6653aSJeff Kirsher if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { 10627ac6653aSJeff Kirsher pr_warning("stmmaceth: cannot attach the external timer.\n"); 10637ac6653aSJeff Kirsher priv->tm->freq = 0; 10647ac6653aSJeff Kirsher priv->tm->timer_start = stmmac_no_timer_started; 10657ac6653aSJeff Kirsher priv->tm->timer_stop = stmmac_no_timer_stopped; 10667ac6653aSJeff Kirsher } else 10677ac6653aSJeff Kirsher priv->tm->enable = 1; 10687ac6653aSJeff Kirsher #endif 10696a81c26fSViresh Kumar clk_enable(priv->stmmac_clk); 10704bfcbd7aSFrancesco Virlinzi 10714bfcbd7aSFrancesco Virlinzi stmmac_check_ether_addr(priv); 10724bfcbd7aSFrancesco Virlinzi 10737ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 10747ac6653aSJeff Kirsher if (unlikely(ret)) { 10757ac6653aSJeff Kirsher pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); 10767ac6653aSJeff Kirsher goto open_error; 10777ac6653aSJeff Kirsher } 10787ac6653aSJeff Kirsher 10797ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 10807ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 10817ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 10827ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 10837ac6653aSJeff Kirsher init_dma_desc_rings(dev); 10847ac6653aSJeff Kirsher 10857ac6653aSJeff Kirsher /* DMA initialization and SW reset */ 10860f1f88a8SGiuseppe CAVALLARO ret = stmmac_init_dma_engine(priv); 10877ac6653aSJeff Kirsher if (ret < 0) { 10887ac6653aSJeff Kirsher pr_err("%s: DMA initialization failed\n", __func__); 10897ac6653aSJeff Kirsher goto open_error; 10907ac6653aSJeff Kirsher } 10917ac6653aSJeff Kirsher 10927ac6653aSJeff Kirsher /* Copy the MAC addr into the HW */ 10937ac6653aSJeff Kirsher priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); 1094cf3f047bSGiuseppe CAVALLARO 10957ac6653aSJeff Kirsher /* If required, perform hw setup of the bus. */ 10967ac6653aSJeff Kirsher if (priv->plat->bus_setup) 10977ac6653aSJeff Kirsher priv->plat->bus_setup(priv->ioaddr); 1098cf3f047bSGiuseppe CAVALLARO 10997ac6653aSJeff Kirsher /* Initialize the MAC Core */ 11007ac6653aSJeff Kirsher priv->hw->mac->core_init(priv->ioaddr); 11017ac6653aSJeff Kirsher 11027ac6653aSJeff Kirsher /* Request the IRQ lines */ 11037ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 11047ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 11057ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 11067ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 11077ac6653aSJeff Kirsher __func__, dev->irq, ret); 11087ac6653aSJeff Kirsher goto open_error; 11097ac6653aSJeff Kirsher } 11107ac6653aSJeff Kirsher 11117a13f8f5SFrancesco Virlinzi /* Request the Wake IRQ in case of another line is used for WoL */ 11127a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) { 11137a13f8f5SFrancesco Virlinzi ret = request_irq(priv->wol_irq, stmmac_interrupt, 11147a13f8f5SFrancesco Virlinzi IRQF_SHARED, dev->name, dev); 11157a13f8f5SFrancesco Virlinzi if (unlikely(ret < 0)) { 11167a13f8f5SFrancesco Virlinzi pr_err("%s: ERROR: allocating the ext WoL IRQ %d " 11177a13f8f5SFrancesco Virlinzi "(error: %d)\n", __func__, priv->wol_irq, ret); 11187a13f8f5SFrancesco Virlinzi goto open_error_wolirq; 11197a13f8f5SFrancesco Virlinzi } 11207a13f8f5SFrancesco Virlinzi } 11217a13f8f5SFrancesco Virlinzi 1122d765955dSGiuseppe CAVALLARO /* Request the IRQ lines */ 1123d765955dSGiuseppe CAVALLARO if (priv->lpi_irq != -ENXIO) { 1124d765955dSGiuseppe CAVALLARO ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, 1125d765955dSGiuseppe CAVALLARO dev->name, dev); 1126d765955dSGiuseppe CAVALLARO if (unlikely(ret < 0)) { 1127d765955dSGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", 1128d765955dSGiuseppe CAVALLARO __func__, priv->lpi_irq, ret); 1129d765955dSGiuseppe CAVALLARO goto open_error_lpiirq; 1130d765955dSGiuseppe CAVALLARO } 1131d765955dSGiuseppe CAVALLARO } 1132d765955dSGiuseppe CAVALLARO 11337ac6653aSJeff Kirsher /* Enable the MAC Rx/Tx */ 1134bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, true); 11357ac6653aSJeff Kirsher 11367ac6653aSJeff Kirsher /* Set the HW DMA mode and the COE */ 11377ac6653aSJeff Kirsher stmmac_dma_operation_mode(priv); 11387ac6653aSJeff Kirsher 11397ac6653aSJeff Kirsher /* Extra statistics */ 11407ac6653aSJeff Kirsher memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 11417ac6653aSJeff Kirsher priv->xstats.threshold = tc; 11427ac6653aSJeff Kirsher 11431c901a46SGiuseppe CAVALLARO stmmac_mmc_setup(priv); 11441c901a46SGiuseppe CAVALLARO 1145bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1146bfab27a1SGiuseppe CAVALLARO ret = stmmac_init_fs(dev); 1147bfab27a1SGiuseppe CAVALLARO if (ret < 0) 1148cf3f047bSGiuseppe CAVALLARO pr_warning("%s: failed debugFS registration\n", __func__); 1149bfab27a1SGiuseppe CAVALLARO #endif 11507ac6653aSJeff Kirsher /* Start the ball rolling... */ 11517ac6653aSJeff Kirsher DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); 11527ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 11537ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 11547ac6653aSJeff Kirsher 11557ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 11567ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 11577ac6653aSJeff Kirsher #endif 1158cf3f047bSGiuseppe CAVALLARO 11597ac6653aSJeff Kirsher /* Dump DMA/MAC registers */ 11607ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 11617ac6653aSJeff Kirsher priv->hw->mac->dump_regs(priv->ioaddr); 11627ac6653aSJeff Kirsher priv->hw->dma->dump_regs(priv->ioaddr); 11637ac6653aSJeff Kirsher } 11647ac6653aSJeff Kirsher 11657ac6653aSJeff Kirsher if (priv->phydev) 11667ac6653aSJeff Kirsher phy_start(priv->phydev); 11677ac6653aSJeff Kirsher 1168d765955dSGiuseppe CAVALLARO priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS_TIMER; 1169d765955dSGiuseppe CAVALLARO priv->eee_enabled = stmmac_eee_init(priv); 1170d765955dSGiuseppe CAVALLARO 11717ac6653aSJeff Kirsher napi_enable(&priv->napi); 11727ac6653aSJeff Kirsher skb_queue_head_init(&priv->rx_recycle); 11737ac6653aSJeff Kirsher netif_start_queue(dev); 11747ac6653aSJeff Kirsher 11757ac6653aSJeff Kirsher return 0; 11767ac6653aSJeff Kirsher 1177d765955dSGiuseppe CAVALLARO open_error_lpiirq: 1178d765955dSGiuseppe CAVALLARO if (priv->wol_irq != dev->irq) 1179d765955dSGiuseppe CAVALLARO free_irq(priv->wol_irq, dev); 1180d765955dSGiuseppe CAVALLARO 11817a13f8f5SFrancesco Virlinzi open_error_wolirq: 11827a13f8f5SFrancesco Virlinzi free_irq(dev->irq, dev); 11837a13f8f5SFrancesco Virlinzi 11847ac6653aSJeff Kirsher open_error: 11857ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 11867ac6653aSJeff Kirsher kfree(priv->tm); 11877ac6653aSJeff Kirsher #endif 11887ac6653aSJeff Kirsher if (priv->phydev) 11897ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 11907ac6653aSJeff Kirsher 11916a81c26fSViresh Kumar clk_disable(priv->stmmac_clk); 11924bfcbd7aSFrancesco Virlinzi 11937ac6653aSJeff Kirsher return ret; 11947ac6653aSJeff Kirsher } 11957ac6653aSJeff Kirsher 11967ac6653aSJeff Kirsher /** 11977ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 11987ac6653aSJeff Kirsher * @dev : device pointer. 11997ac6653aSJeff Kirsher * Description: 12007ac6653aSJeff Kirsher * This is the stop entry point of the driver. 12017ac6653aSJeff Kirsher */ 12027ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 12037ac6653aSJeff Kirsher { 12047ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 12057ac6653aSJeff Kirsher 1206d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 1207d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 1208d765955dSGiuseppe CAVALLARO 12097ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 12107ac6653aSJeff Kirsher if (priv->phydev) { 12117ac6653aSJeff Kirsher phy_stop(priv->phydev); 12127ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 12137ac6653aSJeff Kirsher priv->phydev = NULL; 12147ac6653aSJeff Kirsher } 12157ac6653aSJeff Kirsher 12167ac6653aSJeff Kirsher netif_stop_queue(dev); 12177ac6653aSJeff Kirsher 12187ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 12197ac6653aSJeff Kirsher /* Stop and release the timer */ 12207ac6653aSJeff Kirsher stmmac_close_ext_timer(); 12217ac6653aSJeff Kirsher if (priv->tm != NULL) 12227ac6653aSJeff Kirsher kfree(priv->tm); 12237ac6653aSJeff Kirsher #endif 12247ac6653aSJeff Kirsher napi_disable(&priv->napi); 12257ac6653aSJeff Kirsher skb_queue_purge(&priv->rx_recycle); 12267ac6653aSJeff Kirsher 12277ac6653aSJeff Kirsher /* Free the IRQ lines */ 12287ac6653aSJeff Kirsher free_irq(dev->irq, dev); 12297a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) 12307a13f8f5SFrancesco Virlinzi free_irq(priv->wol_irq, dev); 1231d765955dSGiuseppe CAVALLARO if (priv->lpi_irq != -ENXIO) 1232d765955dSGiuseppe CAVALLARO free_irq(priv->lpi_irq, dev); 12337ac6653aSJeff Kirsher 12347ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 12357ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 12367ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 12377ac6653aSJeff Kirsher 12387ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 12397ac6653aSJeff Kirsher free_dma_desc_resources(priv); 12407ac6653aSJeff Kirsher 12417ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1242bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 12437ac6653aSJeff Kirsher 12447ac6653aSJeff Kirsher netif_carrier_off(dev); 12457ac6653aSJeff Kirsher 1246bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1247bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1248bfab27a1SGiuseppe CAVALLARO #endif 12496a81c26fSViresh Kumar clk_disable(priv->stmmac_clk); 1250bfab27a1SGiuseppe CAVALLARO 12517ac6653aSJeff Kirsher return 0; 12527ac6653aSJeff Kirsher } 12537ac6653aSJeff Kirsher 12547ac6653aSJeff Kirsher /** 12557ac6653aSJeff Kirsher * stmmac_xmit: 12567ac6653aSJeff Kirsher * @skb : the socket buffer 12577ac6653aSJeff Kirsher * @dev : device pointer 12587ac6653aSJeff Kirsher * Description : Tx entry point of the driver. 12597ac6653aSJeff Kirsher */ 12607ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 12617ac6653aSJeff Kirsher { 12627ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 12637ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 12647ac6653aSJeff Kirsher unsigned int entry; 12657ac6653aSJeff Kirsher int i, csum_insertion = 0; 12667ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 12677ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1268286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 12697ac6653aSJeff Kirsher 12707ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 12717ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 12727ac6653aSJeff Kirsher netif_stop_queue(dev); 12737ac6653aSJeff Kirsher /* This is a hard error, log it. */ 12747ac6653aSJeff Kirsher pr_err("%s: BUG! Tx Ring full when queue awake\n", 12757ac6653aSJeff Kirsher __func__); 12767ac6653aSJeff Kirsher } 12777ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 12787ac6653aSJeff Kirsher } 12797ac6653aSJeff Kirsher 1280a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1281a9097a96SGiuseppe CAVALLARO 1282d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1283d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1284d765955dSGiuseppe CAVALLARO 12857ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 12867ac6653aSJeff Kirsher 12877ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 12887ac6653aSJeff Kirsher if ((skb->len > ETH_FRAME_LEN) || nfrags) 12897ac6653aSJeff Kirsher pr_info("stmmac xmit:\n" 12907ac6653aSJeff Kirsher "\tskb addr %p - len: %d - nopaged_len: %d\n" 12917ac6653aSJeff Kirsher "\tn_frags: %d - ip_summed: %d - %s gso\n", 1292286a8372SGiuseppe CAVALLARO skb, skb->len, nopaged_len, nfrags, skb->ip_summed, 12937ac6653aSJeff Kirsher !skb_is_gso(skb) ? "isn't" : "is"); 12947ac6653aSJeff Kirsher #endif 12957ac6653aSJeff Kirsher 12967ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 12977ac6653aSJeff Kirsher 12987ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 12997ac6653aSJeff Kirsher first = desc; 13007ac6653aSJeff Kirsher 13017ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 13027ac6653aSJeff Kirsher if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN)) 13037ac6653aSJeff Kirsher pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n" 13047ac6653aSJeff Kirsher "\t\tn_frags: %d, ip_summed: %d\n", 1305286a8372SGiuseppe CAVALLARO skb->len, nopaged_len, nfrags, skb->ip_summed); 13067ac6653aSJeff Kirsher #endif 13077ac6653aSJeff Kirsher priv->tx_skbuff[entry] = skb; 1308286a8372SGiuseppe CAVALLARO 1309286a8372SGiuseppe CAVALLARO if (priv->hw->ring->is_jumbo_frm(skb->len, priv->plat->enh_desc)) { 1310286a8372SGiuseppe CAVALLARO entry = priv->hw->ring->jumbo_frm(priv, skb, csum_insertion); 13117ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 13127ac6653aSJeff Kirsher } else { 13137ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 13147ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 13157ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 13167ac6653aSJeff Kirsher csum_insertion); 13177ac6653aSJeff Kirsher } 13187ac6653aSJeff Kirsher 13197ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 13209e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 13219e903e08SEric Dumazet int len = skb_frag_size(frag); 13227ac6653aSJeff Kirsher 13237ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 13247ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 13257ac6653aSJeff Kirsher 13267ac6653aSJeff Kirsher TX_DBG("\t[entry %d] segment len: %d\n", entry, len); 1327f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1328f722380dSIan Campbell DMA_TO_DEVICE); 13297ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 13307ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); 13317ac6653aSJeff Kirsher wmb(); 13327ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 13338e839891SDeepak Sikri wmb(); 13347ac6653aSJeff Kirsher } 13357ac6653aSJeff Kirsher 13367ac6653aSJeff Kirsher /* Interrupt on completition only for the latest segment */ 13377ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 13387ac6653aSJeff Kirsher 13397ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 13407ac6653aSJeff Kirsher /* Clean IC while using timer */ 13417ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 13427ac6653aSJeff Kirsher priv->hw->desc->clear_tx_ic(desc); 13437ac6653aSJeff Kirsher #endif 13447ac6653aSJeff Kirsher 13457ac6653aSJeff Kirsher wmb(); 13467ac6653aSJeff Kirsher 13477ac6653aSJeff Kirsher /* To avoid raise condition */ 13487ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 13498e839891SDeepak Sikri wmb(); 13507ac6653aSJeff Kirsher 13517ac6653aSJeff Kirsher priv->cur_tx++; 13527ac6653aSJeff Kirsher 13537ac6653aSJeff Kirsher #ifdef STMMAC_XMIT_DEBUG 13547ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 13557ac6653aSJeff Kirsher pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, " 13567ac6653aSJeff Kirsher "first=%p, nfrags=%d\n", 13577ac6653aSJeff Kirsher (priv->cur_tx % txsize), (priv->dirty_tx % txsize), 13587ac6653aSJeff Kirsher entry, first, nfrags); 13597ac6653aSJeff Kirsher display_ring(priv->dma_tx, txsize); 13607ac6653aSJeff Kirsher pr_info(">>> frame to be transmitted: "); 13617ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 13627ac6653aSJeff Kirsher } 13637ac6653aSJeff Kirsher #endif 13647ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 13657ac6653aSJeff Kirsher TX_DBG("%s: stop transmitted packets\n", __func__); 13667ac6653aSJeff Kirsher netif_stop_queue(dev); 13677ac6653aSJeff Kirsher } 13687ac6653aSJeff Kirsher 13697ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 13707ac6653aSJeff Kirsher 13717ac6653aSJeff Kirsher skb_tx_timestamp(skb); 13727ac6653aSJeff Kirsher 13737ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 13747ac6653aSJeff Kirsher 1375a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 1376a9097a96SGiuseppe CAVALLARO 13777ac6653aSJeff Kirsher return NETDEV_TX_OK; 13787ac6653aSJeff Kirsher } 13797ac6653aSJeff Kirsher 13807ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 13817ac6653aSJeff Kirsher { 13827ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 13837ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 13847ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx; 13857ac6653aSJeff Kirsher 13867ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 13877ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 13887ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 13897ac6653aSJeff Kirsher struct sk_buff *skb; 13907ac6653aSJeff Kirsher 13917ac6653aSJeff Kirsher skb = __skb_dequeue(&priv->rx_recycle); 13927ac6653aSJeff Kirsher if (skb == NULL) 13937ac6653aSJeff Kirsher skb = netdev_alloc_skb_ip_align(priv->dev, 13947ac6653aSJeff Kirsher bfsize); 13957ac6653aSJeff Kirsher 13967ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 13977ac6653aSJeff Kirsher break; 13987ac6653aSJeff Kirsher 13997ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 14007ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 14017ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 14027ac6653aSJeff Kirsher DMA_FROM_DEVICE); 14037ac6653aSJeff Kirsher 14047ac6653aSJeff Kirsher (p + entry)->des2 = priv->rx_skbuff_dma[entry]; 1405286a8372SGiuseppe CAVALLARO 1406286a8372SGiuseppe CAVALLARO if (unlikely(priv->plat->has_gmac)) 1407286a8372SGiuseppe CAVALLARO priv->hw->ring->refill_desc3(bfsize, p + entry); 1408286a8372SGiuseppe CAVALLARO 14097ac6653aSJeff Kirsher RX_DBG(KERN_INFO "\trefill entry #%d\n", entry); 14107ac6653aSJeff Kirsher } 14117ac6653aSJeff Kirsher wmb(); 14127ac6653aSJeff Kirsher priv->hw->desc->set_rx_owner(p + entry); 14138e839891SDeepak Sikri wmb(); 14147ac6653aSJeff Kirsher } 14157ac6653aSJeff Kirsher } 14167ac6653aSJeff Kirsher 14177ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 14187ac6653aSJeff Kirsher { 14197ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 14207ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 14217ac6653aSJeff Kirsher unsigned int next_entry; 14227ac6653aSJeff Kirsher unsigned int count = 0; 14237ac6653aSJeff Kirsher struct dma_desc *p = priv->dma_rx + entry; 14247ac6653aSJeff Kirsher struct dma_desc *p_next; 14257ac6653aSJeff Kirsher 14267ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 14277ac6653aSJeff Kirsher if (netif_msg_hw(priv)) { 14287ac6653aSJeff Kirsher pr_debug(">>> stmmac_rx: descriptor ring:\n"); 14297ac6653aSJeff Kirsher display_ring(priv->dma_rx, rxsize); 14307ac6653aSJeff Kirsher } 14317ac6653aSJeff Kirsher #endif 14327ac6653aSJeff Kirsher while (!priv->hw->desc->get_rx_owner(p)) { 14337ac6653aSJeff Kirsher int status; 14347ac6653aSJeff Kirsher 14357ac6653aSJeff Kirsher if (count >= limit) 14367ac6653aSJeff Kirsher break; 14377ac6653aSJeff Kirsher 14387ac6653aSJeff Kirsher count++; 14397ac6653aSJeff Kirsher 14407ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 14417ac6653aSJeff Kirsher p_next = priv->dma_rx + next_entry; 14427ac6653aSJeff Kirsher prefetch(p_next); 14437ac6653aSJeff Kirsher 14447ac6653aSJeff Kirsher /* read the status of the incoming frame */ 14457ac6653aSJeff Kirsher status = (priv->hw->desc->rx_status(&priv->dev->stats, 14467ac6653aSJeff Kirsher &priv->xstats, p)); 14477ac6653aSJeff Kirsher if (unlikely(status == discard_frame)) 14487ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 14497ac6653aSJeff Kirsher else { 14507ac6653aSJeff Kirsher struct sk_buff *skb; 14517ac6653aSJeff Kirsher int frame_len; 14527ac6653aSJeff Kirsher 145338912bdbSDeepak SIKRI frame_len = priv->hw->desc->get_rx_frame_len(p, 145438912bdbSDeepak SIKRI priv->plat->rx_coe); 14557ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 14567ac6653aSJeff Kirsher * Type frames (LLC/LLC-SNAP) */ 14577ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 14587ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 14597ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 14607ac6653aSJeff Kirsher if (frame_len > ETH_FRAME_LEN) 14617ac6653aSJeff Kirsher pr_debug("\tRX frame size %d, COE status: %d\n", 14627ac6653aSJeff Kirsher frame_len, status); 14637ac6653aSJeff Kirsher 14647ac6653aSJeff Kirsher if (netif_msg_hw(priv)) 14657ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 14667ac6653aSJeff Kirsher p, entry, p->des2); 14677ac6653aSJeff Kirsher #endif 14687ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 14697ac6653aSJeff Kirsher if (unlikely(!skb)) { 14707ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 14717ac6653aSJeff Kirsher priv->dev->name); 14727ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 14737ac6653aSJeff Kirsher break; 14747ac6653aSJeff Kirsher } 14757ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 14767ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 14777ac6653aSJeff Kirsher 14787ac6653aSJeff Kirsher skb_put(skb, frame_len); 14797ac6653aSJeff Kirsher dma_unmap_single(priv->device, 14807ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 14817ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 14827ac6653aSJeff Kirsher #ifdef STMMAC_RX_DEBUG 14837ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 14847ac6653aSJeff Kirsher pr_info(" frame received (%dbytes)", frame_len); 14857ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 14867ac6653aSJeff Kirsher } 14877ac6653aSJeff Kirsher #endif 14887ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 14897ac6653aSJeff Kirsher 149038912bdbSDeepak SIKRI if (unlikely(!priv->plat->rx_coe)) { 14913c20f72fSGiuseppe CAVALLARO /* No RX COE for old mac10/100 devices */ 14927ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 14937ac6653aSJeff Kirsher netif_receive_skb(skb); 14947ac6653aSJeff Kirsher } else { 14957ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 14967ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 14977ac6653aSJeff Kirsher } 14987ac6653aSJeff Kirsher 14997ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 15007ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 15017ac6653aSJeff Kirsher } 15027ac6653aSJeff Kirsher entry = next_entry; 15037ac6653aSJeff Kirsher p = p_next; /* use prefetched values */ 15047ac6653aSJeff Kirsher } 15057ac6653aSJeff Kirsher 15067ac6653aSJeff Kirsher stmmac_rx_refill(priv); 15077ac6653aSJeff Kirsher 15087ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 15097ac6653aSJeff Kirsher 15107ac6653aSJeff Kirsher return count; 15117ac6653aSJeff Kirsher } 15127ac6653aSJeff Kirsher 15137ac6653aSJeff Kirsher /** 15147ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 15157ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 15167ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 15177ac6653aSJeff Kirsher * all interfaces. 15187ac6653aSJeff Kirsher * Description : 15197ac6653aSJeff Kirsher * This function implements the the reception process. 15207ac6653aSJeff Kirsher * Also it runs the TX completion thread 15217ac6653aSJeff Kirsher */ 15227ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 15237ac6653aSJeff Kirsher { 15247ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 15257ac6653aSJeff Kirsher int work_done = 0; 15267ac6653aSJeff Kirsher 15277ac6653aSJeff Kirsher priv->xstats.poll_n++; 15287ac6653aSJeff Kirsher stmmac_tx(priv); 15297ac6653aSJeff Kirsher work_done = stmmac_rx(priv, budget); 15307ac6653aSJeff Kirsher 15317ac6653aSJeff Kirsher if (work_done < budget) { 15327ac6653aSJeff Kirsher napi_complete(napi); 15337ac6653aSJeff Kirsher stmmac_enable_irq(priv); 15347ac6653aSJeff Kirsher } 15357ac6653aSJeff Kirsher return work_done; 15367ac6653aSJeff Kirsher } 15377ac6653aSJeff Kirsher 15387ac6653aSJeff Kirsher /** 15397ac6653aSJeff Kirsher * stmmac_tx_timeout 15407ac6653aSJeff Kirsher * @dev : Pointer to net device structure 15417ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 15427ac6653aSJeff Kirsher * complete within a reasonable tmrate. The driver will mark the error in the 15437ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 15447ac6653aSJeff Kirsher * in order to transmit a new packet. 15457ac6653aSJeff Kirsher */ 15467ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 15477ac6653aSJeff Kirsher { 15487ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15497ac6653aSJeff Kirsher 15507ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 15517ac6653aSJeff Kirsher stmmac_tx_err(priv); 15527ac6653aSJeff Kirsher } 15537ac6653aSJeff Kirsher 15547ac6653aSJeff Kirsher /* Configuration changes (passed on by ifconfig) */ 15557ac6653aSJeff Kirsher static int stmmac_config(struct net_device *dev, struct ifmap *map) 15567ac6653aSJeff Kirsher { 15577ac6653aSJeff Kirsher if (dev->flags & IFF_UP) /* can't act on a running interface */ 15587ac6653aSJeff Kirsher return -EBUSY; 15597ac6653aSJeff Kirsher 15607ac6653aSJeff Kirsher /* Don't allow changing the I/O address */ 15617ac6653aSJeff Kirsher if (map->base_addr != dev->base_addr) { 15627ac6653aSJeff Kirsher pr_warning("%s: can't change I/O address\n", dev->name); 15637ac6653aSJeff Kirsher return -EOPNOTSUPP; 15647ac6653aSJeff Kirsher } 15657ac6653aSJeff Kirsher 15667ac6653aSJeff Kirsher /* Don't allow changing the IRQ */ 15677ac6653aSJeff Kirsher if (map->irq != dev->irq) { 15687ac6653aSJeff Kirsher pr_warning("%s: can't change IRQ number %d\n", 15697ac6653aSJeff Kirsher dev->name, dev->irq); 15707ac6653aSJeff Kirsher return -EOPNOTSUPP; 15717ac6653aSJeff Kirsher } 15727ac6653aSJeff Kirsher 15737ac6653aSJeff Kirsher /* ignore other fields */ 15747ac6653aSJeff Kirsher return 0; 15757ac6653aSJeff Kirsher } 15767ac6653aSJeff Kirsher 15777ac6653aSJeff Kirsher /** 157801789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 15797ac6653aSJeff Kirsher * @dev : pointer to the device structure 15807ac6653aSJeff Kirsher * Description: 15817ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 15827ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 15837ac6653aSJeff Kirsher * Return value: 15847ac6653aSJeff Kirsher * void. 15857ac6653aSJeff Kirsher */ 158601789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 15877ac6653aSJeff Kirsher { 15887ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 15897ac6653aSJeff Kirsher 15907ac6653aSJeff Kirsher spin_lock(&priv->lock); 1591cffb13f4SGiuseppe CAVALLARO priv->hw->mac->set_filter(dev, priv->synopsys_id); 15927ac6653aSJeff Kirsher spin_unlock(&priv->lock); 15937ac6653aSJeff Kirsher } 15947ac6653aSJeff Kirsher 15957ac6653aSJeff Kirsher /** 15967ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 15977ac6653aSJeff Kirsher * @dev : device pointer. 15987ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 15997ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 16007ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 16017ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 16027ac6653aSJeff Kirsher * Return value: 16037ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 16047ac6653aSJeff Kirsher * file on failure. 16057ac6653aSJeff Kirsher */ 16067ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 16077ac6653aSJeff Kirsher { 16087ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16097ac6653aSJeff Kirsher int max_mtu; 16107ac6653aSJeff Kirsher 16117ac6653aSJeff Kirsher if (netif_running(dev)) { 16127ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 16137ac6653aSJeff Kirsher return -EBUSY; 16147ac6653aSJeff Kirsher } 16157ac6653aSJeff Kirsher 161648febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 16177ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 16187ac6653aSJeff Kirsher else 161945db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 16207ac6653aSJeff Kirsher 16217ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 16227ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 16237ac6653aSJeff Kirsher return -EINVAL; 16247ac6653aSJeff Kirsher } 16257ac6653aSJeff Kirsher 16267ac6653aSJeff Kirsher dev->mtu = new_mtu; 16277ac6653aSJeff Kirsher netdev_update_features(dev); 16287ac6653aSJeff Kirsher 16297ac6653aSJeff Kirsher return 0; 16307ac6653aSJeff Kirsher } 16317ac6653aSJeff Kirsher 1632c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 1633c8f44affSMichał Mirosław netdev_features_t features) 16347ac6653aSJeff Kirsher { 16357ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16367ac6653aSJeff Kirsher 163738912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 16387ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 163938912bdbSDeepak SIKRI else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1) 164038912bdbSDeepak SIKRI features &= ~NETIF_F_IPV6_CSUM; 16417ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 16427ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 16437ac6653aSJeff Kirsher 16447ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 16457ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 16467ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 16477ac6653aSJeff Kirsher * the TX csum insertionin the TDES and not use SF. */ 16487ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 16497ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 16507ac6653aSJeff Kirsher 16517ac6653aSJeff Kirsher return features; 16527ac6653aSJeff Kirsher } 16537ac6653aSJeff Kirsher 16547ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 16557ac6653aSJeff Kirsher { 16567ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 16577ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 16587ac6653aSJeff Kirsher 16597ac6653aSJeff Kirsher if (unlikely(!dev)) { 16607ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 16617ac6653aSJeff Kirsher return IRQ_NONE; 16627ac6653aSJeff Kirsher } 16637ac6653aSJeff Kirsher 16647ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 1665d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 1666d765955dSGiuseppe CAVALLARO int status = priv->hw->mac->host_irq_status((void __iomem *) 1667d765955dSGiuseppe CAVALLARO dev->base_addr); 1668d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 1669d765955dSGiuseppe CAVALLARO if (status & core_mmc_tx_irq) 1670d765955dSGiuseppe CAVALLARO priv->xstats.mmc_tx_irq_n++; 1671d765955dSGiuseppe CAVALLARO if (status & core_mmc_rx_irq) 1672d765955dSGiuseppe CAVALLARO priv->xstats.mmc_rx_irq_n++; 1673d765955dSGiuseppe CAVALLARO if (status & core_mmc_rx_csum_offload_irq) 1674d765955dSGiuseppe CAVALLARO priv->xstats.mmc_rx_csum_offload_irq_n++; 1675d765955dSGiuseppe CAVALLARO if (status & core_irq_receive_pmt_irq) 1676d765955dSGiuseppe CAVALLARO priv->xstats.irq_receive_pmt_irq_n++; 16777ac6653aSJeff Kirsher 1678d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 1679d765955dSGiuseppe CAVALLARO if (status & core_irq_tx_path_in_lpi_mode) { 1680d765955dSGiuseppe CAVALLARO priv->xstats.irq_tx_path_in_lpi_mode_n++; 1681d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 1682d765955dSGiuseppe CAVALLARO } 1683d765955dSGiuseppe CAVALLARO if (status & core_irq_tx_path_exit_lpi_mode) { 1684d765955dSGiuseppe CAVALLARO priv->xstats.irq_tx_path_exit_lpi_mode_n++; 1685d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 1686d765955dSGiuseppe CAVALLARO } 1687d765955dSGiuseppe CAVALLARO if (status & core_irq_rx_path_in_lpi_mode) 1688d765955dSGiuseppe CAVALLARO priv->xstats.irq_rx_path_in_lpi_mode_n++; 1689d765955dSGiuseppe CAVALLARO if (status & core_irq_rx_path_exit_lpi_mode) 1690d765955dSGiuseppe CAVALLARO priv->xstats.irq_rx_path_exit_lpi_mode_n++; 1691d765955dSGiuseppe CAVALLARO } 1692d765955dSGiuseppe CAVALLARO } 1693d765955dSGiuseppe CAVALLARO 1694d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 16957ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 16967ac6653aSJeff Kirsher 16977ac6653aSJeff Kirsher return IRQ_HANDLED; 16987ac6653aSJeff Kirsher } 16997ac6653aSJeff Kirsher 17007ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 17017ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 17027ac6653aSJeff Kirsher * to allow network I/O with interrupts disabled. */ 17037ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 17047ac6653aSJeff Kirsher { 17057ac6653aSJeff Kirsher disable_irq(dev->irq); 17067ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 17077ac6653aSJeff Kirsher enable_irq(dev->irq); 17087ac6653aSJeff Kirsher } 17097ac6653aSJeff Kirsher #endif 17107ac6653aSJeff Kirsher 17117ac6653aSJeff Kirsher /** 17127ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 17137ac6653aSJeff Kirsher * @dev: Device pointer. 17147ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 17157ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 17167ac6653aSJeff Kirsher * @cmd: IOCTL command 17177ac6653aSJeff Kirsher * Description: 17187ac6653aSJeff Kirsher * Currently there are no special functionality supported in IOCTL, just the 17197ac6653aSJeff Kirsher * phy_mii_ioctl(...) can be invoked. 17207ac6653aSJeff Kirsher */ 17217ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 17227ac6653aSJeff Kirsher { 17237ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 17247ac6653aSJeff Kirsher int ret; 17257ac6653aSJeff Kirsher 17267ac6653aSJeff Kirsher if (!netif_running(dev)) 17277ac6653aSJeff Kirsher return -EINVAL; 17287ac6653aSJeff Kirsher 17297ac6653aSJeff Kirsher if (!priv->phydev) 17307ac6653aSJeff Kirsher return -EINVAL; 17317ac6653aSJeff Kirsher 17327ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 17337ac6653aSJeff Kirsher 17347ac6653aSJeff Kirsher return ret; 17357ac6653aSJeff Kirsher } 17367ac6653aSJeff Kirsher 17377ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 17387ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 17397ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 1740e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 17417ac29055SGiuseppe CAVALLARO 17427ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 17437ac29055SGiuseppe CAVALLARO { 17447ac29055SGiuseppe CAVALLARO struct tmp_s { 17457ac29055SGiuseppe CAVALLARO u64 a; 17467ac29055SGiuseppe CAVALLARO unsigned int b; 17477ac29055SGiuseppe CAVALLARO unsigned int c; 17487ac29055SGiuseppe CAVALLARO }; 17497ac29055SGiuseppe CAVALLARO int i; 17507ac29055SGiuseppe CAVALLARO struct net_device *dev = seq->private; 17517ac29055SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 17527ac29055SGiuseppe CAVALLARO 17537ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 17547ac29055SGiuseppe CAVALLARO seq_printf(seq, " RX descriptor ring\n"); 17557ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 17567ac29055SGiuseppe CAVALLARO 17577ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_rx_size; i++) { 17587ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_rx + i); 17597ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 17607ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 17617ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 17627ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 17637ac29055SGiuseppe CAVALLARO } 17647ac29055SGiuseppe CAVALLARO 17657ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 17667ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 17677ac29055SGiuseppe CAVALLARO seq_printf(seq, " TX descriptor ring\n"); 17687ac29055SGiuseppe CAVALLARO seq_printf(seq, "=======================\n"); 17697ac29055SGiuseppe CAVALLARO 17707ac29055SGiuseppe CAVALLARO for (i = 0; i < priv->dma_tx_size; i++) { 17717ac29055SGiuseppe CAVALLARO struct tmp_s *x = (struct tmp_s *)(priv->dma_tx + i); 17727ac29055SGiuseppe CAVALLARO seq_printf(seq, "[%d] DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x", 17737ac29055SGiuseppe CAVALLARO i, (unsigned int)(x->a), 17747ac29055SGiuseppe CAVALLARO (unsigned int)((x->a) >> 32), x->b, x->c); 17757ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 17767ac29055SGiuseppe CAVALLARO } 17777ac29055SGiuseppe CAVALLARO 17787ac29055SGiuseppe CAVALLARO return 0; 17797ac29055SGiuseppe CAVALLARO } 17807ac29055SGiuseppe CAVALLARO 17817ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 17827ac29055SGiuseppe CAVALLARO { 17837ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 17847ac29055SGiuseppe CAVALLARO } 17857ac29055SGiuseppe CAVALLARO 17867ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 17877ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 17887ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 17897ac29055SGiuseppe CAVALLARO .read = seq_read, 17907ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 179174863948SDjalal Harouni .release = single_release, 17927ac29055SGiuseppe CAVALLARO }; 17937ac29055SGiuseppe CAVALLARO 1794e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 1795e7434821SGiuseppe CAVALLARO { 1796e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 1797e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 1798e7434821SGiuseppe CAVALLARO 179919e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 1800e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 1801e7434821SGiuseppe CAVALLARO return 0; 1802e7434821SGiuseppe CAVALLARO } 1803e7434821SGiuseppe CAVALLARO 1804e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 1805e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 1806e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 1807e7434821SGiuseppe CAVALLARO 1808e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 1809e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 1810e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 1811e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 1812e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 1813e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 1814e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 1815e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 1816e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 1817e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 1818e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 1819e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 1820e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 1821e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 1822e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 1823e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 1824e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 1825e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 1826e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 1827e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 1828e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 1829e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 1830e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 1831e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 1832e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 1833e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 1834e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 1835e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 1836e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 1837e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 1838e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 1839e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 1840e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 1841e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 1842e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 1843e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 1844e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 1845e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 1846e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 1847e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 1848e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 1849e7434821SGiuseppe CAVALLARO 1850e7434821SGiuseppe CAVALLARO return 0; 1851e7434821SGiuseppe CAVALLARO } 1852e7434821SGiuseppe CAVALLARO 1853e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 1854e7434821SGiuseppe CAVALLARO { 1855e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 1856e7434821SGiuseppe CAVALLARO } 1857e7434821SGiuseppe CAVALLARO 1858e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 1859e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 1860e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 1861e7434821SGiuseppe CAVALLARO .read = seq_read, 1862e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 186374863948SDjalal Harouni .release = single_release, 1864e7434821SGiuseppe CAVALLARO }; 1865e7434821SGiuseppe CAVALLARO 18667ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 18677ac29055SGiuseppe CAVALLARO { 18687ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 18697ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 18707ac29055SGiuseppe CAVALLARO 18717ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 18727ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 18737ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 18747ac29055SGiuseppe CAVALLARO 18757ac29055SGiuseppe CAVALLARO return -ENOMEM; 18767ac29055SGiuseppe CAVALLARO } 18777ac29055SGiuseppe CAVALLARO 18787ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 18797ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 18807ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 18817ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 18827ac29055SGiuseppe CAVALLARO 18837ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 18847ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 18857ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 18867ac29055SGiuseppe CAVALLARO 18877ac29055SGiuseppe CAVALLARO return -ENOMEM; 18887ac29055SGiuseppe CAVALLARO } 18897ac29055SGiuseppe CAVALLARO 1890e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 1891e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 1892e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 1893e7434821SGiuseppe CAVALLARO 1894e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 1895e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 1896e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 1897e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 1898e7434821SGiuseppe CAVALLARO 1899e7434821SGiuseppe CAVALLARO return -ENOMEM; 1900e7434821SGiuseppe CAVALLARO } 1901e7434821SGiuseppe CAVALLARO 19027ac29055SGiuseppe CAVALLARO return 0; 19037ac29055SGiuseppe CAVALLARO } 19047ac29055SGiuseppe CAVALLARO 19057ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 19067ac29055SGiuseppe CAVALLARO { 19077ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 1908e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 19097ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 19107ac29055SGiuseppe CAVALLARO } 19117ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 19127ac29055SGiuseppe CAVALLARO 19137ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 19147ac6653aSJeff Kirsher .ndo_open = stmmac_open, 19157ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 19167ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 19177ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 19187ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 191901789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 19207ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 19217ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 19227ac6653aSJeff Kirsher .ndo_set_config = stmmac_config, 19237ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 19247ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 19257ac6653aSJeff Kirsher #endif 19267ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 19277ac6653aSJeff Kirsher }; 19287ac6653aSJeff Kirsher 19297ac6653aSJeff Kirsher /** 1930cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 1931cf3f047bSGiuseppe CAVALLARO * @priv : pointer to the private device structure. 1932cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 1933cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 1934cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 1935cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 1936cf3f047bSGiuseppe CAVALLARO * descriptor structure). 1937cf3f047bSGiuseppe CAVALLARO */ 1938cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 1939cf3f047bSGiuseppe CAVALLARO { 1940cf3f047bSGiuseppe CAVALLARO int ret = 0; 1941cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 1942cf3f047bSGiuseppe CAVALLARO 1943cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 194403f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 194503f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 1946cf3f047bSGiuseppe CAVALLARO mac = dwmac1000_setup(priv->ioaddr); 194703f2eecdSMarc Kleine-Budde } else { 1948cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 194903f2eecdSMarc Kleine-Budde } 1950cf3f047bSGiuseppe CAVALLARO if (!mac) 1951cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 1952cf3f047bSGiuseppe CAVALLARO 1953cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 1954cf3f047bSGiuseppe CAVALLARO 1955cf3f047bSGiuseppe CAVALLARO /* To use the chained or ring mode */ 1956cf3f047bSGiuseppe CAVALLARO priv->hw->ring = &ring_mode_ops; 1957cf3f047bSGiuseppe CAVALLARO 1958cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 1959cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 1960cf3f047bSGiuseppe CAVALLARO 1961cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 1962cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 1963cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 1964cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 1965cf3f047bSGiuseppe CAVALLARO 1966cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 1967cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 1968cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 1969cf3f047bSGiuseppe CAVALLARO * register (if supported). 1970cf3f047bSGiuseppe CAVALLARO */ 1971cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 1972cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 197338912bdbSDeepak SIKRI 197438912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 197538912bdbSDeepak SIKRI 197638912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 197738912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 197838912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 197938912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 198038912bdbSDeepak SIKRI 1981cf3f047bSGiuseppe CAVALLARO } else 1982cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 1983cf3f047bSGiuseppe CAVALLARO 1984cf3f047bSGiuseppe CAVALLARO /* Select the enhnaced/normal descriptor structures */ 1985cf3f047bSGiuseppe CAVALLARO stmmac_selec_desc_mode(priv); 1986cf3f047bSGiuseppe CAVALLARO 198738912bdbSDeepak SIKRI /* Enable the IPC (Checksum Offload) and check if the feature has been 198838912bdbSDeepak SIKRI * enabled during the core configuration. */ 198938912bdbSDeepak SIKRI ret = priv->hw->mac->rx_ipc(priv->ioaddr); 199038912bdbSDeepak SIKRI if (!ret) { 199138912bdbSDeepak SIKRI pr_warning(" RX IPC Checksum Offload not configured.\n"); 199238912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_NONE; 199338912bdbSDeepak SIKRI } 199438912bdbSDeepak SIKRI 199538912bdbSDeepak SIKRI if (priv->plat->rx_coe) 199638912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 199738912bdbSDeepak SIKRI priv->plat->rx_coe); 1998cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 1999cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 2000cf3f047bSGiuseppe CAVALLARO 2001cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 2002cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 2003cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 2004cf3f047bSGiuseppe CAVALLARO } 2005cf3f047bSGiuseppe CAVALLARO 2006cf3f047bSGiuseppe CAVALLARO return ret; 2007cf3f047bSGiuseppe CAVALLARO } 2008cf3f047bSGiuseppe CAVALLARO 2009cf3f047bSGiuseppe CAVALLARO /** 2010bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 2011bfab27a1SGiuseppe CAVALLARO * @device: device pointer 2012ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 2013ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 2014bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 2015bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 20167ac6653aSJeff Kirsher */ 2017bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 2018cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 2019cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 20207ac6653aSJeff Kirsher { 20217ac6653aSJeff Kirsher int ret = 0; 2022bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 2023bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 20247ac6653aSJeff Kirsher 2025bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 202641de8d4cSJoe Perches if (!ndev) 2027bfab27a1SGiuseppe CAVALLARO return NULL; 20287ac6653aSJeff Kirsher 2029bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 20307ac6653aSJeff Kirsher 2031bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 2032bfab27a1SGiuseppe CAVALLARO priv->device = device; 2033bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 2034bfab27a1SGiuseppe CAVALLARO 2035bfab27a1SGiuseppe CAVALLARO ether_setup(ndev); 2036bfab27a1SGiuseppe CAVALLARO 2037bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 2038cf3f047bSGiuseppe CAVALLARO priv->pause = pause; 2039cf3f047bSGiuseppe CAVALLARO priv->plat = plat_dat; 2040cf3f047bSGiuseppe CAVALLARO priv->ioaddr = addr; 2041cf3f047bSGiuseppe CAVALLARO priv->dev->base_addr = (unsigned long)addr; 2042bfab27a1SGiuseppe CAVALLARO 2043cf3f047bSGiuseppe CAVALLARO /* Verify driver arguments */ 2044cf3f047bSGiuseppe CAVALLARO stmmac_verify_args(); 2045cf3f047bSGiuseppe CAVALLARO 2046cf3f047bSGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 2047cf3f047bSGiuseppe CAVALLARO * this needs to have multiple instances */ 2048cf3f047bSGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 2049cf3f047bSGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 2050cf3f047bSGiuseppe CAVALLARO 2051cf3f047bSGiuseppe CAVALLARO /* Init MAC and get the capabilities */ 2052cf3f047bSGiuseppe CAVALLARO stmmac_hw_init(priv); 2053cf3f047bSGiuseppe CAVALLARO 2054cf3f047bSGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 2055cf3f047bSGiuseppe CAVALLARO 2056cf3f047bSGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 2057cf3f047bSGiuseppe CAVALLARO NETIF_F_RXCSUM; 2058bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 2059bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 20607ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 20617ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 2062bfab27a1SGiuseppe CAVALLARO ndev->features |= NETIF_F_HW_VLAN_RX; 20637ac6653aSJeff Kirsher #endif 20647ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 20657ac6653aSJeff Kirsher 20667ac6653aSJeff Kirsher if (flow_ctrl) 20677ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 20687ac6653aSJeff Kirsher 2069bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 20707ac6653aSJeff Kirsher 20717ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 2072a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 20737ac6653aSJeff Kirsher 2074bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 20757ac6653aSJeff Kirsher if (ret) { 2076cf3f047bSGiuseppe CAVALLARO pr_err("%s: ERROR %i registering the device\n", __func__, ret); 20776a81c26fSViresh Kumar goto error_netdev_register; 20787ac6653aSJeff Kirsher } 20797ac6653aSJeff Kirsher 2080ae4d8cf2SKelvin Cheung priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME); 20816a81c26fSViresh Kumar if (IS_ERR(priv->stmmac_clk)) { 208231ea38eeSGiuseppe CAVALLARO pr_warning("%s: warning: cannot get CSR clock\n", __func__); 20836a81c26fSViresh Kumar goto error_clk_get; 20846a81c26fSViresh Kumar } 2085ba1377ffSGiuseppe CAVALLARO 2086cd7201f4SGiuseppe CAVALLARO /* If a specific clk_csr value is passed from the platform 2087cd7201f4SGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 2088cd7201f4SGiuseppe CAVALLARO * changed at run-time and it is fixed. Viceversa the driver'll try to 2089cd7201f4SGiuseppe CAVALLARO * set the MDC clock dynamically according to the csr actual 2090cd7201f4SGiuseppe CAVALLARO * clock input. 2091cd7201f4SGiuseppe CAVALLARO */ 2092cd7201f4SGiuseppe CAVALLARO if (!priv->plat->clk_csr) 2093cd7201f4SGiuseppe CAVALLARO stmmac_clk_csr_set(priv); 2094cd7201f4SGiuseppe CAVALLARO else 2095cd7201f4SGiuseppe CAVALLARO priv->clk_csr = priv->plat->clk_csr; 2096cd7201f4SGiuseppe CAVALLARO 20974bfcbd7aSFrancesco Virlinzi /* MDIO bus Registration */ 20984bfcbd7aSFrancesco Virlinzi ret = stmmac_mdio_register(ndev); 20994bfcbd7aSFrancesco Virlinzi if (ret < 0) { 21004bfcbd7aSFrancesco Virlinzi pr_debug("%s: MDIO bus (id: %d) registration failed", 21014bfcbd7aSFrancesco Virlinzi __func__, priv->plat->bus_id); 21026a81c26fSViresh Kumar goto error_mdio_register; 21034bfcbd7aSFrancesco Virlinzi } 21044bfcbd7aSFrancesco Virlinzi 2105bfab27a1SGiuseppe CAVALLARO return priv; 21067ac6653aSJeff Kirsher 21076a81c26fSViresh Kumar error_mdio_register: 21086a81c26fSViresh Kumar clk_put(priv->stmmac_clk); 21096a81c26fSViresh Kumar error_clk_get: 21107ac6653aSJeff Kirsher unregister_netdev(ndev); 21116a81c26fSViresh Kumar error_netdev_register: 21126a81c26fSViresh Kumar netif_napi_del(&priv->napi); 21137ac6653aSJeff Kirsher free_netdev(ndev); 21147ac6653aSJeff Kirsher 2115bfab27a1SGiuseppe CAVALLARO return NULL; 21167ac6653aSJeff Kirsher } 21177ac6653aSJeff Kirsher 21187ac6653aSJeff Kirsher /** 21197ac6653aSJeff Kirsher * stmmac_dvr_remove 2120bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 21217ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 2122bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 21237ac6653aSJeff Kirsher */ 2124bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 21257ac6653aSJeff Kirsher { 21267ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 21277ac6653aSJeff Kirsher 21287ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 21297ac6653aSJeff Kirsher 21307ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 21317ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 21327ac6653aSJeff Kirsher 2133bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 21344bfcbd7aSFrancesco Virlinzi stmmac_mdio_unregister(ndev); 21357ac6653aSJeff Kirsher netif_carrier_off(ndev); 21367ac6653aSJeff Kirsher unregister_netdev(ndev); 21377ac6653aSJeff Kirsher free_netdev(ndev); 21387ac6653aSJeff Kirsher 21397ac6653aSJeff Kirsher return 0; 21407ac6653aSJeff Kirsher } 21417ac6653aSJeff Kirsher 21427ac6653aSJeff Kirsher #ifdef CONFIG_PM 2143bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 21447ac6653aSJeff Kirsher { 21457ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 21467ac6653aSJeff Kirsher int dis_ic = 0; 2147f8c5a875SGiuseppe CAVALLARO unsigned long flags; 21487ac6653aSJeff Kirsher 21497ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 21507ac6653aSJeff Kirsher return 0; 21517ac6653aSJeff Kirsher 2152102463b1SFrancesco Virlinzi if (priv->phydev) 2153102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 2154102463b1SFrancesco Virlinzi 2155f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 21567ac6653aSJeff Kirsher 21577ac6653aSJeff Kirsher netif_device_detach(ndev); 21587ac6653aSJeff Kirsher netif_stop_queue(ndev); 21597ac6653aSJeff Kirsher 21607ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 21617ac6653aSJeff Kirsher priv->tm->timer_stop(); 21627ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 21637ac6653aSJeff Kirsher dis_ic = 1; 21647ac6653aSJeff Kirsher #endif 21657ac6653aSJeff Kirsher napi_disable(&priv->napi); 21667ac6653aSJeff Kirsher 21677ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 21687ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 21697ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 21707ac6653aSJeff Kirsher /* Clear the Rx/Tx descriptors */ 21717ac6653aSJeff Kirsher priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, 21727ac6653aSJeff Kirsher dis_ic); 21737ac6653aSJeff Kirsher priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 21747ac6653aSJeff Kirsher 21757ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 21767ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 21777ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 2178ba1377ffSGiuseppe CAVALLARO else { 2179bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 2180ba1377ffSGiuseppe CAVALLARO /* Disable clock in case of PWM is off */ 21816a81c26fSViresh Kumar clk_disable(priv->stmmac_clk); 2182ba1377ffSGiuseppe CAVALLARO } 2183f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 21847ac6653aSJeff Kirsher return 0; 21857ac6653aSJeff Kirsher } 21867ac6653aSJeff Kirsher 2187bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 21887ac6653aSJeff Kirsher { 21897ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2190f8c5a875SGiuseppe CAVALLARO unsigned long flags; 21917ac6653aSJeff Kirsher 21927ac6653aSJeff Kirsher if (!netif_running(ndev)) 21937ac6653aSJeff Kirsher return 0; 21947ac6653aSJeff Kirsher 2195f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 21967ac6653aSJeff Kirsher 21977ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 21987ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 21997ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 22007ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 22017ac6653aSJeff Kirsher * from another devices (e.g. serial console). */ 22027ac6653aSJeff Kirsher if (device_may_wakeup(priv->device)) 22037ac6653aSJeff Kirsher priv->hw->mac->pmt(priv->ioaddr, 0); 2204ba1377ffSGiuseppe CAVALLARO else 2205ba1377ffSGiuseppe CAVALLARO /* enable the clk prevously disabled */ 22066a81c26fSViresh Kumar clk_enable(priv->stmmac_clk); 22077ac6653aSJeff Kirsher 22087ac6653aSJeff Kirsher netif_device_attach(ndev); 22097ac6653aSJeff Kirsher 22107ac6653aSJeff Kirsher /* Enable the MAC and DMA */ 2211bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, true); 22127ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 22137ac6653aSJeff Kirsher priv->hw->dma->start_rx(priv->ioaddr); 22147ac6653aSJeff Kirsher 22157ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 22167ac6653aSJeff Kirsher if (likely(priv->tm->enable)) 22177ac6653aSJeff Kirsher priv->tm->timer_start(tmrate); 22187ac6653aSJeff Kirsher #endif 22197ac6653aSJeff Kirsher napi_enable(&priv->napi); 22207ac6653aSJeff Kirsher 22217ac6653aSJeff Kirsher netif_start_queue(ndev); 22227ac6653aSJeff Kirsher 2223f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 2224102463b1SFrancesco Virlinzi 2225102463b1SFrancesco Virlinzi if (priv->phydev) 2226102463b1SFrancesco Virlinzi phy_start(priv->phydev); 2227102463b1SFrancesco Virlinzi 22287ac6653aSJeff Kirsher return 0; 22297ac6653aSJeff Kirsher } 22307ac6653aSJeff Kirsher 2231bfab27a1SGiuseppe CAVALLARO int stmmac_freeze(struct net_device *ndev) 22327ac6653aSJeff Kirsher { 22337ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 22347ac6653aSJeff Kirsher return 0; 22357ac6653aSJeff Kirsher 22367ac6653aSJeff Kirsher return stmmac_release(ndev); 22377ac6653aSJeff Kirsher } 22387ac6653aSJeff Kirsher 2239bfab27a1SGiuseppe CAVALLARO int stmmac_restore(struct net_device *ndev) 22407ac6653aSJeff Kirsher { 22417ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 22427ac6653aSJeff Kirsher return 0; 22437ac6653aSJeff Kirsher 22447ac6653aSJeff Kirsher return stmmac_open(ndev); 22457ac6653aSJeff Kirsher } 22467ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 22477ac6653aSJeff Kirsher 224833d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers 224933d5e332SGiuseppe CAVALLARO * depending on the configuration selected. 225033d5e332SGiuseppe CAVALLARO */ 2251ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void) 2252ba27ec66SGiuseppe CAVALLARO { 225333d5e332SGiuseppe CAVALLARO int err_plt = 0; 225433d5e332SGiuseppe CAVALLARO int err_pci = 0; 2255ba27ec66SGiuseppe CAVALLARO 225633d5e332SGiuseppe CAVALLARO err_plt = stmmac_register_platform(); 225733d5e332SGiuseppe CAVALLARO err_pci = stmmac_register_pci(); 2258ba27ec66SGiuseppe CAVALLARO 225933d5e332SGiuseppe CAVALLARO if ((err_pci) && (err_plt)) { 226033d5e332SGiuseppe CAVALLARO pr_err("stmmac: driver registration failed\n"); 226133d5e332SGiuseppe CAVALLARO return -EINVAL; 2262ba27ec66SGiuseppe CAVALLARO } 2263ba27ec66SGiuseppe CAVALLARO 226433d5e332SGiuseppe CAVALLARO return 0; 2265ba27ec66SGiuseppe CAVALLARO } 2266ba27ec66SGiuseppe CAVALLARO 2267ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void) 2268ba27ec66SGiuseppe CAVALLARO { 226933d5e332SGiuseppe CAVALLARO stmmac_unregister_platform(); 227033d5e332SGiuseppe CAVALLARO stmmac_unregister_pci(); 2271ba27ec66SGiuseppe CAVALLARO } 2272ba27ec66SGiuseppe CAVALLARO 2273ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init); 2274ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit); 2275ba27ec66SGiuseppe CAVALLARO 22767ac6653aSJeff Kirsher #ifndef MODULE 22777ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 22787ac6653aSJeff Kirsher { 22797ac6653aSJeff Kirsher char *opt; 22807ac6653aSJeff Kirsher 22817ac6653aSJeff Kirsher if (!str || !*str) 22827ac6653aSJeff Kirsher return -EINVAL; 22837ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 22847ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 2285ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &debug)) 22867ac6653aSJeff Kirsher goto err; 22877ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 2288ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 8, 0, &phyaddr)) 22897ac6653aSJeff Kirsher goto err; 22907ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 2291ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_txsize)) 22927ac6653aSJeff Kirsher goto err; 22937ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 2294ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_rxsize)) 22957ac6653aSJeff Kirsher goto err; 22967ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 2297ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &buf_sz)) 22987ac6653aSJeff Kirsher goto err; 22997ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 2300ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 3, 0, &tc)) 23017ac6653aSJeff Kirsher goto err; 23027ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 2303ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 9, 0, &watchdog)) 23047ac6653aSJeff Kirsher goto err; 23057ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 2306ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &flow_ctrl)) 23077ac6653aSJeff Kirsher goto err; 23087ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 2309ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &pause)) 23107ac6653aSJeff Kirsher goto err; 2311d765955dSGiuseppe CAVALLARO } else if (!strncmp(opt, "eee_timer:", 6)) { 2312d765955dSGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &eee_timer)) 2313d765955dSGiuseppe CAVALLARO goto err; 23147ac6653aSJeff Kirsher #ifdef CONFIG_STMMAC_TIMER 23157ac6653aSJeff Kirsher } else if (!strncmp(opt, "tmrate:", 7)) { 2316ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &tmrate)) 23177ac6653aSJeff Kirsher goto err; 23187ac6653aSJeff Kirsher #endif 23197ac6653aSJeff Kirsher } 23207ac6653aSJeff Kirsher } 23217ac6653aSJeff Kirsher return 0; 23227ac6653aSJeff Kirsher 23237ac6653aSJeff Kirsher err: 23247ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 23257ac6653aSJeff Kirsher return -EINVAL; 23267ac6653aSJeff Kirsher } 23277ac6653aSJeff Kirsher 23287ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 23297ac6653aSJeff Kirsher #endif 23306fc0d0f2SGiuseppe Cavallaro 23316fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 23326fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 23336fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 2334