17ac6653aSJeff Kirsher /******************************************************************************* 27ac6653aSJeff Kirsher This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers. 37ac6653aSJeff Kirsher ST Ethernet IPs are built around a Synopsys IP Core. 47ac6653aSJeff Kirsher 5286a8372SGiuseppe CAVALLARO Copyright(C) 2007-2011 STMicroelectronics Ltd 67ac6653aSJeff Kirsher 77ac6653aSJeff Kirsher This program is free software; you can redistribute it and/or modify it 87ac6653aSJeff Kirsher under the terms and conditions of the GNU General Public License, 97ac6653aSJeff Kirsher version 2, as published by the Free Software Foundation. 107ac6653aSJeff Kirsher 117ac6653aSJeff Kirsher This program is distributed in the hope it will be useful, but WITHOUT 127ac6653aSJeff Kirsher ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 137ac6653aSJeff Kirsher FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 147ac6653aSJeff Kirsher more details. 157ac6653aSJeff Kirsher 167ac6653aSJeff Kirsher You should have received a copy of the GNU General Public License along with 177ac6653aSJeff Kirsher this program; if not, write to the Free Software Foundation, Inc., 187ac6653aSJeff Kirsher 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 197ac6653aSJeff Kirsher 207ac6653aSJeff Kirsher The full GNU General Public License is included in this distribution in 217ac6653aSJeff Kirsher the file called "COPYING". 227ac6653aSJeff Kirsher 237ac6653aSJeff Kirsher Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 247ac6653aSJeff Kirsher 257ac6653aSJeff Kirsher Documentation available at: 267ac6653aSJeff Kirsher http://www.stlinux.com 277ac6653aSJeff Kirsher Support available at: 287ac6653aSJeff Kirsher https://bugzilla.stlinux.com/ 297ac6653aSJeff Kirsher *******************************************************************************/ 307ac6653aSJeff Kirsher 316a81c26fSViresh Kumar #include <linux/clk.h> 327ac6653aSJeff Kirsher #include <linux/kernel.h> 337ac6653aSJeff Kirsher #include <linux/interrupt.h> 347ac6653aSJeff Kirsher #include <linux/ip.h> 357ac6653aSJeff Kirsher #include <linux/tcp.h> 367ac6653aSJeff Kirsher #include <linux/skbuff.h> 377ac6653aSJeff Kirsher #include <linux/ethtool.h> 387ac6653aSJeff Kirsher #include <linux/if_ether.h> 397ac6653aSJeff Kirsher #include <linux/crc32.h> 407ac6653aSJeff Kirsher #include <linux/mii.h> 4101789349SJiri Pirko #include <linux/if.h> 427ac6653aSJeff Kirsher #include <linux/if_vlan.h> 437ac6653aSJeff Kirsher #include <linux/dma-mapping.h> 447ac6653aSJeff Kirsher #include <linux/slab.h> 457ac6653aSJeff Kirsher #include <linux/prefetch.h> 46db88f10aSSrinivas Kandagatla #include <linux/pinctrl/consumer.h> 477ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 487ac29055SGiuseppe CAVALLARO #include <linux/debugfs.h> 497ac29055SGiuseppe CAVALLARO #include <linux/seq_file.h> 50ceb69499SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 51891434b1SRayagond Kokatanur #include <linux/net_tstamp.h> 52891434b1SRayagond Kokatanur #include "stmmac_ptp.h" 53286a8372SGiuseppe CAVALLARO #include "stmmac.h" 54c5e4ddbdSChen-Yu Tsai #include <linux/reset.h> 557ac6653aSJeff Kirsher 567ac6653aSJeff Kirsher #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) 577ac6653aSJeff Kirsher 587ac6653aSJeff Kirsher /* Module parameters */ 5932ceabcaSGiuseppe CAVALLARO #define TX_TIMEO 5000 607ac6653aSJeff Kirsher static int watchdog = TX_TIMEO; 617ac6653aSJeff Kirsher module_param(watchdog, int, S_IRUGO | S_IWUSR); 6232ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds (default 5s)"); 637ac6653aSJeff Kirsher 6432ceabcaSGiuseppe CAVALLARO static int debug = -1; 657ac6653aSJeff Kirsher module_param(debug, int, S_IRUGO | S_IWUSR); 6632ceabcaSGiuseppe CAVALLARO MODULE_PARM_DESC(debug, "Message Level (-1: default, 0: no output, 16: all)"); 677ac6653aSJeff Kirsher 6847d1f71fSstephen hemminger static int phyaddr = -1; 697ac6653aSJeff Kirsher module_param(phyaddr, int, S_IRUGO); 707ac6653aSJeff Kirsher MODULE_PARM_DESC(phyaddr, "Physical device address"); 717ac6653aSJeff Kirsher 727ac6653aSJeff Kirsher #define DMA_TX_SIZE 256 737ac6653aSJeff Kirsher static int dma_txsize = DMA_TX_SIZE; 747ac6653aSJeff Kirsher module_param(dma_txsize, int, S_IRUGO | S_IWUSR); 757ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list"); 767ac6653aSJeff Kirsher 777ac6653aSJeff Kirsher #define DMA_RX_SIZE 256 787ac6653aSJeff Kirsher static int dma_rxsize = DMA_RX_SIZE; 797ac6653aSJeff Kirsher module_param(dma_rxsize, int, S_IRUGO | S_IWUSR); 807ac6653aSJeff Kirsher MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list"); 817ac6653aSJeff Kirsher 827ac6653aSJeff Kirsher static int flow_ctrl = FLOW_OFF; 837ac6653aSJeff Kirsher module_param(flow_ctrl, int, S_IRUGO | S_IWUSR); 847ac6653aSJeff Kirsher MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]"); 857ac6653aSJeff Kirsher 867ac6653aSJeff Kirsher static int pause = PAUSE_TIME; 877ac6653aSJeff Kirsher module_param(pause, int, S_IRUGO | S_IWUSR); 887ac6653aSJeff Kirsher MODULE_PARM_DESC(pause, "Flow Control Pause Time"); 897ac6653aSJeff Kirsher 907ac6653aSJeff Kirsher #define TC_DEFAULT 64 917ac6653aSJeff Kirsher static int tc = TC_DEFAULT; 927ac6653aSJeff Kirsher module_param(tc, int, S_IRUGO | S_IWUSR); 937ac6653aSJeff Kirsher MODULE_PARM_DESC(tc, "DMA threshold control value"); 947ac6653aSJeff Kirsher 95d916701cSGiuseppe CAVALLARO #define DEFAULT_BUFSIZE 1536 96d916701cSGiuseppe CAVALLARO static int buf_sz = DEFAULT_BUFSIZE; 977ac6653aSJeff Kirsher module_param(buf_sz, int, S_IRUGO | S_IWUSR); 987ac6653aSJeff Kirsher MODULE_PARM_DESC(buf_sz, "DMA buffer size"); 997ac6653aSJeff Kirsher 1007ac6653aSJeff Kirsher static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 1017ac6653aSJeff Kirsher NETIF_MSG_LINK | NETIF_MSG_IFUP | 1027ac6653aSJeff Kirsher NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); 1037ac6653aSJeff Kirsher 104d765955dSGiuseppe CAVALLARO #define STMMAC_DEFAULT_LPI_TIMER 1000 105d765955dSGiuseppe CAVALLARO static int eee_timer = STMMAC_DEFAULT_LPI_TIMER; 106d765955dSGiuseppe CAVALLARO module_param(eee_timer, int, S_IRUGO | S_IWUSR); 107d765955dSGiuseppe CAVALLARO MODULE_PARM_DESC(eee_timer, "LPI tx expiration time in msec"); 108f5351ef7SGiuseppe CAVALLARO #define STMMAC_LPI_T(x) (jiffies + msecs_to_jiffies(x)) 109d765955dSGiuseppe CAVALLARO 1104a7d666aSGiuseppe CAVALLARO /* By default the driver will use the ring mode to manage tx and rx descriptors 1114a7d666aSGiuseppe CAVALLARO * but passing this value so user can force to use the chain instead of the ring 1124a7d666aSGiuseppe CAVALLARO */ 1134a7d666aSGiuseppe CAVALLARO static unsigned int chain_mode; 1144a7d666aSGiuseppe CAVALLARO module_param(chain_mode, int, S_IRUGO); 1154a7d666aSGiuseppe CAVALLARO MODULE_PARM_DESC(chain_mode, "To use chain instead of ring mode"); 1164a7d666aSGiuseppe CAVALLARO 1177ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 1187ac6653aSJeff Kirsher 119bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 120bfab27a1SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev); 121bfab27a1SGiuseppe CAVALLARO static void stmmac_exit_fs(void); 122bfab27a1SGiuseppe CAVALLARO #endif 123bfab27a1SGiuseppe CAVALLARO 1249125cdd1SGiuseppe CAVALLARO #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) 1259125cdd1SGiuseppe CAVALLARO 1267ac6653aSJeff Kirsher /** 1277ac6653aSJeff Kirsher * stmmac_verify_args - verify the driver parameters. 1287ac6653aSJeff Kirsher * Description: it verifies if some wrong parameter is passed to the driver. 1297ac6653aSJeff Kirsher * Note that wrong parameters are replaced with the default values. 1307ac6653aSJeff Kirsher */ 1317ac6653aSJeff Kirsher static void stmmac_verify_args(void) 1327ac6653aSJeff Kirsher { 1337ac6653aSJeff Kirsher if (unlikely(watchdog < 0)) 1347ac6653aSJeff Kirsher watchdog = TX_TIMEO; 1357ac6653aSJeff Kirsher if (unlikely(dma_rxsize < 0)) 1367ac6653aSJeff Kirsher dma_rxsize = DMA_RX_SIZE; 1377ac6653aSJeff Kirsher if (unlikely(dma_txsize < 0)) 1387ac6653aSJeff Kirsher dma_txsize = DMA_TX_SIZE; 139d916701cSGiuseppe CAVALLARO if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB))) 140d916701cSGiuseppe CAVALLARO buf_sz = DEFAULT_BUFSIZE; 1417ac6653aSJeff Kirsher if (unlikely(flow_ctrl > 1)) 1427ac6653aSJeff Kirsher flow_ctrl = FLOW_AUTO; 1437ac6653aSJeff Kirsher else if (likely(flow_ctrl < 0)) 1447ac6653aSJeff Kirsher flow_ctrl = FLOW_OFF; 1457ac6653aSJeff Kirsher if (unlikely((pause < 0) || (pause > 0xffff))) 1467ac6653aSJeff Kirsher pause = PAUSE_TIME; 147d765955dSGiuseppe CAVALLARO if (eee_timer < 0) 148d765955dSGiuseppe CAVALLARO eee_timer = STMMAC_DEFAULT_LPI_TIMER; 1497ac6653aSJeff Kirsher } 1507ac6653aSJeff Kirsher 15132ceabcaSGiuseppe CAVALLARO /** 15232ceabcaSGiuseppe CAVALLARO * stmmac_clk_csr_set - dynamically set the MDC clock 15332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 15432ceabcaSGiuseppe CAVALLARO * Description: this is to dynamically set the MDC clock according to the csr 15532ceabcaSGiuseppe CAVALLARO * clock input. 15632ceabcaSGiuseppe CAVALLARO * Note: 15732ceabcaSGiuseppe CAVALLARO * If a specific clk_csr value is passed from the platform 15832ceabcaSGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 15932ceabcaSGiuseppe CAVALLARO * changed at run-time and it is fixed (as reported in the driver 16032ceabcaSGiuseppe CAVALLARO * documentation). Viceversa the driver will try to set the MDC 16132ceabcaSGiuseppe CAVALLARO * clock dynamically according to the actual clock input. 16232ceabcaSGiuseppe CAVALLARO */ 163cd7201f4SGiuseppe CAVALLARO static void stmmac_clk_csr_set(struct stmmac_priv *priv) 164cd7201f4SGiuseppe CAVALLARO { 165cd7201f4SGiuseppe CAVALLARO u32 clk_rate; 166cd7201f4SGiuseppe CAVALLARO 167cd7201f4SGiuseppe CAVALLARO clk_rate = clk_get_rate(priv->stmmac_clk); 168cd7201f4SGiuseppe CAVALLARO 169cd7201f4SGiuseppe CAVALLARO /* Platform provided default clk_csr would be assumed valid 170ceb69499SGiuseppe CAVALLARO * for all other cases except for the below mentioned ones. 171ceb69499SGiuseppe CAVALLARO * For values higher than the IEEE 802.3 specified frequency 172ceb69499SGiuseppe CAVALLARO * we can not estimate the proper divider as it is not known 173ceb69499SGiuseppe CAVALLARO * the frequency of clk_csr_i. So we do not change the default 174ceb69499SGiuseppe CAVALLARO * divider. 175ceb69499SGiuseppe CAVALLARO */ 176cd7201f4SGiuseppe CAVALLARO if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) { 177cd7201f4SGiuseppe CAVALLARO if (clk_rate < CSR_F_35M) 178cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_20_35M; 179cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M)) 180cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_35_60M; 181cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M)) 182cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_60_100M; 183cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M)) 184cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_100_150M; 185cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) 186cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_150_250M; 187cd7201f4SGiuseppe CAVALLARO else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) 188cd7201f4SGiuseppe CAVALLARO priv->clk_csr = STMMAC_CSR_250_300M; 189ceb69499SGiuseppe CAVALLARO } 190cd7201f4SGiuseppe CAVALLARO } 191cd7201f4SGiuseppe CAVALLARO 1927ac6653aSJeff Kirsher static void print_pkt(unsigned char *buf, int len) 1937ac6653aSJeff Kirsher { 1947ac6653aSJeff Kirsher int j; 19583d7af64SGiuseppe CAVALLARO pr_debug("len = %d byte, buf addr: 0x%p", len, buf); 1967ac6653aSJeff Kirsher for (j = 0; j < len; j++) { 1977ac6653aSJeff Kirsher if ((j % 16) == 0) 19883d7af64SGiuseppe CAVALLARO pr_debug("\n %03x:", j); 19983d7af64SGiuseppe CAVALLARO pr_debug(" %02x", buf[j]); 2007ac6653aSJeff Kirsher } 20183d7af64SGiuseppe CAVALLARO pr_debug("\n"); 2027ac6653aSJeff Kirsher } 2037ac6653aSJeff Kirsher 2047ac6653aSJeff Kirsher /* minimum number of free TX descriptors required to wake up TX process */ 2057ac6653aSJeff Kirsher #define STMMAC_TX_THRESH(x) (x->dma_tx_size/4) 2067ac6653aSJeff Kirsher 2077ac6653aSJeff Kirsher static inline u32 stmmac_tx_avail(struct stmmac_priv *priv) 2087ac6653aSJeff Kirsher { 2097ac6653aSJeff Kirsher return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1; 2107ac6653aSJeff Kirsher } 2117ac6653aSJeff Kirsher 21232ceabcaSGiuseppe CAVALLARO /** 21332ceabcaSGiuseppe CAVALLARO * stmmac_hw_fix_mac_speed: callback for speed selection 21432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 21532ceabcaSGiuseppe CAVALLARO * Description: on some platforms (e.g. ST), some HW system configuraton 21632ceabcaSGiuseppe CAVALLARO * registers have to be set according to the link speed negotiated. 2177ac6653aSJeff Kirsher */ 2187ac6653aSJeff Kirsher static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv) 2197ac6653aSJeff Kirsher { 2207ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 2217ac6653aSJeff Kirsher 2227ac6653aSJeff Kirsher if (likely(priv->plat->fix_mac_speed)) 223ceb69499SGiuseppe CAVALLARO priv->plat->fix_mac_speed(priv->plat->bsp_priv, phydev->speed); 2247ac6653aSJeff Kirsher } 2257ac6653aSJeff Kirsher 22632ceabcaSGiuseppe CAVALLARO /** 22732ceabcaSGiuseppe CAVALLARO * stmmac_enable_eee_mode: Check and enter in LPI mode 22832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 22932ceabcaSGiuseppe CAVALLARO * Description: this function is to verify and enter in LPI mode for EEE. 23032ceabcaSGiuseppe CAVALLARO */ 231d765955dSGiuseppe CAVALLARO static void stmmac_enable_eee_mode(struct stmmac_priv *priv) 232d765955dSGiuseppe CAVALLARO { 233d765955dSGiuseppe CAVALLARO /* Check and enter in LPI mode */ 234d765955dSGiuseppe CAVALLARO if ((priv->dirty_tx == priv->cur_tx) && 235d765955dSGiuseppe CAVALLARO (priv->tx_path_in_lpi_mode == false)) 2367ed24bbeSVince Bridgers priv->hw->mac->set_eee_mode(priv->hw); 237d765955dSGiuseppe CAVALLARO } 238d765955dSGiuseppe CAVALLARO 23932ceabcaSGiuseppe CAVALLARO /** 24032ceabcaSGiuseppe CAVALLARO * stmmac_disable_eee_mode: disable/exit from EEE 24132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 24232ceabcaSGiuseppe CAVALLARO * Description: this function is to exit and disable EEE in case of 24332ceabcaSGiuseppe CAVALLARO * LPI state is true. This is called by the xmit. 24432ceabcaSGiuseppe CAVALLARO */ 245d765955dSGiuseppe CAVALLARO void stmmac_disable_eee_mode(struct stmmac_priv *priv) 246d765955dSGiuseppe CAVALLARO { 2477ed24bbeSVince Bridgers priv->hw->mac->reset_eee_mode(priv->hw); 248d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 249d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 250d765955dSGiuseppe CAVALLARO } 251d765955dSGiuseppe CAVALLARO 252d765955dSGiuseppe CAVALLARO /** 25332ceabcaSGiuseppe CAVALLARO * stmmac_eee_ctrl_timer: EEE TX SW timer. 254d765955dSGiuseppe CAVALLARO * @arg : data hook 255d765955dSGiuseppe CAVALLARO * Description: 25632ceabcaSGiuseppe CAVALLARO * if there is no data transfer and if we are not in LPI state, 257d765955dSGiuseppe CAVALLARO * then MAC Transmitter can be moved to LPI state. 258d765955dSGiuseppe CAVALLARO */ 259d765955dSGiuseppe CAVALLARO static void stmmac_eee_ctrl_timer(unsigned long arg) 260d765955dSGiuseppe CAVALLARO { 261d765955dSGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)arg; 262d765955dSGiuseppe CAVALLARO 263d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 264f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 265d765955dSGiuseppe CAVALLARO } 266d765955dSGiuseppe CAVALLARO 267d765955dSGiuseppe CAVALLARO /** 26832ceabcaSGiuseppe CAVALLARO * stmmac_eee_init: init EEE 26932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 270d765955dSGiuseppe CAVALLARO * Description: 271d765955dSGiuseppe CAVALLARO * If the EEE support has been enabled while configuring the driver, 272d765955dSGiuseppe CAVALLARO * if the GMAC actually supports the EEE (from the HW cap reg) and the 273d765955dSGiuseppe CAVALLARO * phy can also manage EEE, so enable the LPI state and start the timer 274d765955dSGiuseppe CAVALLARO * to verify if the tx path can enter in LPI state. 275d765955dSGiuseppe CAVALLARO */ 276d765955dSGiuseppe CAVALLARO bool stmmac_eee_init(struct stmmac_priv *priv) 277d765955dSGiuseppe CAVALLARO { 27856b88c25SGiuseppe CAVALLARO char *phy_bus_name = priv->plat->phy_bus_name; 279d765955dSGiuseppe CAVALLARO bool ret = false; 280d765955dSGiuseppe CAVALLARO 281f5351ef7SGiuseppe CAVALLARO /* Using PCS we cannot dial with the phy registers at this stage 282f5351ef7SGiuseppe CAVALLARO * so we do not support extra feature like EEE. 283f5351ef7SGiuseppe CAVALLARO */ 284f5351ef7SGiuseppe CAVALLARO if ((priv->pcs == STMMAC_PCS_RGMII) || (priv->pcs == STMMAC_PCS_TBI) || 285f5351ef7SGiuseppe CAVALLARO (priv->pcs == STMMAC_PCS_RTBI)) 286f5351ef7SGiuseppe CAVALLARO goto out; 287f5351ef7SGiuseppe CAVALLARO 28856b88c25SGiuseppe CAVALLARO /* Never init EEE in case of a switch is attached */ 28956b88c25SGiuseppe CAVALLARO if (phy_bus_name && (!strcmp(phy_bus_name, "fixed"))) 29056b88c25SGiuseppe CAVALLARO goto out; 29156b88c25SGiuseppe CAVALLARO 292d765955dSGiuseppe CAVALLARO /* MAC core supports the EEE feature. */ 293d765955dSGiuseppe CAVALLARO if (priv->dma_cap.eee) { 29483bf79b6SGiuseppe CAVALLARO int tx_lpi_timer = priv->tx_lpi_timer; 295d765955dSGiuseppe CAVALLARO 29683bf79b6SGiuseppe CAVALLARO /* Check if the PHY supports EEE */ 29783bf79b6SGiuseppe CAVALLARO if (phy_init_eee(priv->phydev, 1)) { 29883bf79b6SGiuseppe CAVALLARO /* To manage at run-time if the EEE cannot be supported 29983bf79b6SGiuseppe CAVALLARO * anymore (for example because the lp caps have been 30083bf79b6SGiuseppe CAVALLARO * changed). 30183bf79b6SGiuseppe CAVALLARO * In that case the driver disable own timers. 30283bf79b6SGiuseppe CAVALLARO */ 30383bf79b6SGiuseppe CAVALLARO if (priv->eee_active) { 30483bf79b6SGiuseppe CAVALLARO pr_debug("stmmac: disable EEE\n"); 30583bf79b6SGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 3067ed24bbeSVince Bridgers priv->hw->mac->set_eee_timer(priv->hw, 0, 30783bf79b6SGiuseppe CAVALLARO tx_lpi_timer); 30883bf79b6SGiuseppe CAVALLARO } 30983bf79b6SGiuseppe CAVALLARO priv->eee_active = 0; 31083bf79b6SGiuseppe CAVALLARO goto out; 31183bf79b6SGiuseppe CAVALLARO } 31283bf79b6SGiuseppe CAVALLARO /* Activate the EEE and start timers */ 313f5351ef7SGiuseppe CAVALLARO if (!priv->eee_active) { 314d765955dSGiuseppe CAVALLARO priv->eee_active = 1; 315d765955dSGiuseppe CAVALLARO init_timer(&priv->eee_ctrl_timer); 316d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.function = stmmac_eee_ctrl_timer; 317d765955dSGiuseppe CAVALLARO priv->eee_ctrl_timer.data = (unsigned long)priv; 318f5351ef7SGiuseppe CAVALLARO priv->eee_ctrl_timer.expires = STMMAC_LPI_T(eee_timer); 319d765955dSGiuseppe CAVALLARO add_timer(&priv->eee_ctrl_timer); 320d765955dSGiuseppe CAVALLARO 3217ed24bbeSVince Bridgers priv->hw->mac->set_eee_timer(priv->hw, 322f5351ef7SGiuseppe CAVALLARO STMMAC_DEFAULT_LIT_LS, 32383bf79b6SGiuseppe CAVALLARO tx_lpi_timer); 32471965352SGiuseppe CAVALLARO } 325f5351ef7SGiuseppe CAVALLARO /* Set HW EEE according to the speed */ 32671965352SGiuseppe CAVALLARO priv->hw->mac->set_eee_pls(priv->hw, priv->phydev->link); 327d765955dSGiuseppe CAVALLARO 32883bf79b6SGiuseppe CAVALLARO pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); 329d765955dSGiuseppe CAVALLARO 330d765955dSGiuseppe CAVALLARO ret = true; 331d765955dSGiuseppe CAVALLARO } 332d765955dSGiuseppe CAVALLARO out: 333d765955dSGiuseppe CAVALLARO return ret; 334d765955dSGiuseppe CAVALLARO } 335d765955dSGiuseppe CAVALLARO 33632ceabcaSGiuseppe CAVALLARO /* stmmac_get_tx_hwtstamp: get HW TX timestamps 33732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 338891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 339891434b1SRayagond Kokatanur * @skb : the socket buffer 340891434b1SRayagond Kokatanur * Description : 341891434b1SRayagond Kokatanur * This function will read timestamp from the descriptor & pass it to stack. 342891434b1SRayagond Kokatanur * and also perform some sanity checks. 343891434b1SRayagond Kokatanur */ 344891434b1SRayagond Kokatanur static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv, 345ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 346891434b1SRayagond Kokatanur { 347891434b1SRayagond Kokatanur struct skb_shared_hwtstamps shhwtstamp; 348891434b1SRayagond Kokatanur u64 ns; 349891434b1SRayagond Kokatanur void *desc = NULL; 350891434b1SRayagond Kokatanur 351891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 352891434b1SRayagond Kokatanur return; 353891434b1SRayagond Kokatanur 354ceb69499SGiuseppe CAVALLARO /* exit if skb doesn't support hw tstamp */ 35575e4364fSdamuzi000 if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))) 356891434b1SRayagond Kokatanur return; 357891434b1SRayagond Kokatanur 358891434b1SRayagond Kokatanur if (priv->adv_ts) 359891434b1SRayagond Kokatanur desc = (priv->dma_etx + entry); 360891434b1SRayagond Kokatanur else 361891434b1SRayagond Kokatanur desc = (priv->dma_tx + entry); 362891434b1SRayagond Kokatanur 363891434b1SRayagond Kokatanur /* check tx tstamp status */ 364891434b1SRayagond Kokatanur if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc)) 365891434b1SRayagond Kokatanur return; 366891434b1SRayagond Kokatanur 367891434b1SRayagond Kokatanur /* get the valid tstamp */ 368891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 369891434b1SRayagond Kokatanur 370891434b1SRayagond Kokatanur memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 371891434b1SRayagond Kokatanur shhwtstamp.hwtstamp = ns_to_ktime(ns); 372891434b1SRayagond Kokatanur /* pass tstamp to stack */ 373891434b1SRayagond Kokatanur skb_tstamp_tx(skb, &shhwtstamp); 374891434b1SRayagond Kokatanur 375891434b1SRayagond Kokatanur return; 376891434b1SRayagond Kokatanur } 377891434b1SRayagond Kokatanur 37832ceabcaSGiuseppe CAVALLARO /* stmmac_get_rx_hwtstamp: get HW RX timestamps 37932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 380891434b1SRayagond Kokatanur * @entry : descriptor index to be used. 381891434b1SRayagond Kokatanur * @skb : the socket buffer 382891434b1SRayagond Kokatanur * Description : 383891434b1SRayagond Kokatanur * This function will read received packet's timestamp from the descriptor 384891434b1SRayagond Kokatanur * and pass it to stack. It also perform some sanity checks. 385891434b1SRayagond Kokatanur */ 386891434b1SRayagond Kokatanur static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, 387ceb69499SGiuseppe CAVALLARO unsigned int entry, struct sk_buff *skb) 388891434b1SRayagond Kokatanur { 389891434b1SRayagond Kokatanur struct skb_shared_hwtstamps *shhwtstamp = NULL; 390891434b1SRayagond Kokatanur u64 ns; 391891434b1SRayagond Kokatanur void *desc = NULL; 392891434b1SRayagond Kokatanur 393891434b1SRayagond Kokatanur if (!priv->hwts_rx_en) 394891434b1SRayagond Kokatanur return; 395891434b1SRayagond Kokatanur 396891434b1SRayagond Kokatanur if (priv->adv_ts) 397891434b1SRayagond Kokatanur desc = (priv->dma_erx + entry); 398891434b1SRayagond Kokatanur else 399891434b1SRayagond Kokatanur desc = (priv->dma_rx + entry); 400891434b1SRayagond Kokatanur 401ceb69499SGiuseppe CAVALLARO /* exit if rx tstamp is not valid */ 402891434b1SRayagond Kokatanur if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) 403891434b1SRayagond Kokatanur return; 404891434b1SRayagond Kokatanur 405891434b1SRayagond Kokatanur /* get valid tstamp */ 406891434b1SRayagond Kokatanur ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 407891434b1SRayagond Kokatanur shhwtstamp = skb_hwtstamps(skb); 408891434b1SRayagond Kokatanur memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); 409891434b1SRayagond Kokatanur shhwtstamp->hwtstamp = ns_to_ktime(ns); 410891434b1SRayagond Kokatanur } 411891434b1SRayagond Kokatanur 412891434b1SRayagond Kokatanur /** 413891434b1SRayagond Kokatanur * stmmac_hwtstamp_ioctl - control hardware timestamping. 414891434b1SRayagond Kokatanur * @dev: device pointer. 415891434b1SRayagond Kokatanur * @ifr: An IOCTL specefic structure, that can contain a pointer to 416891434b1SRayagond Kokatanur * a proprietary structure used to pass information to the driver. 417891434b1SRayagond Kokatanur * Description: 418891434b1SRayagond Kokatanur * This function configures the MAC to enable/disable both outgoing(TX) 419891434b1SRayagond Kokatanur * and incoming(RX) packets time stamping based on user input. 420891434b1SRayagond Kokatanur * Return Value: 421891434b1SRayagond Kokatanur * 0 on success and an appropriate -ve integer on failure. 422891434b1SRayagond Kokatanur */ 423891434b1SRayagond Kokatanur static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr) 424891434b1SRayagond Kokatanur { 425891434b1SRayagond Kokatanur struct stmmac_priv *priv = netdev_priv(dev); 426891434b1SRayagond Kokatanur struct hwtstamp_config config; 427891434b1SRayagond Kokatanur struct timespec now; 428891434b1SRayagond Kokatanur u64 temp = 0; 429891434b1SRayagond Kokatanur u32 ptp_v2 = 0; 430891434b1SRayagond Kokatanur u32 tstamp_all = 0; 431891434b1SRayagond Kokatanur u32 ptp_over_ipv4_udp = 0; 432891434b1SRayagond Kokatanur u32 ptp_over_ipv6_udp = 0; 433891434b1SRayagond Kokatanur u32 ptp_over_ethernet = 0; 434891434b1SRayagond Kokatanur u32 snap_type_sel = 0; 435891434b1SRayagond Kokatanur u32 ts_master_en = 0; 436891434b1SRayagond Kokatanur u32 ts_event_en = 0; 437891434b1SRayagond Kokatanur u32 value = 0; 438891434b1SRayagond Kokatanur 439891434b1SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->adv_ts)) { 440891434b1SRayagond Kokatanur netdev_alert(priv->dev, "No support for HW time stamping\n"); 441891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 442891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 443891434b1SRayagond Kokatanur 444891434b1SRayagond Kokatanur return -EOPNOTSUPP; 445891434b1SRayagond Kokatanur } 446891434b1SRayagond Kokatanur 447891434b1SRayagond Kokatanur if (copy_from_user(&config, ifr->ifr_data, 448891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config))) 449891434b1SRayagond Kokatanur return -EFAULT; 450891434b1SRayagond Kokatanur 451891434b1SRayagond Kokatanur pr_debug("%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n", 452891434b1SRayagond Kokatanur __func__, config.flags, config.tx_type, config.rx_filter); 453891434b1SRayagond Kokatanur 454891434b1SRayagond Kokatanur /* reserved for future extensions */ 455891434b1SRayagond Kokatanur if (config.flags) 456891434b1SRayagond Kokatanur return -EINVAL; 457891434b1SRayagond Kokatanur 4585f3da328SBen Hutchings if (config.tx_type != HWTSTAMP_TX_OFF && 4595f3da328SBen Hutchings config.tx_type != HWTSTAMP_TX_ON) 460891434b1SRayagond Kokatanur return -ERANGE; 461891434b1SRayagond Kokatanur 462891434b1SRayagond Kokatanur if (priv->adv_ts) { 463891434b1SRayagond Kokatanur switch (config.rx_filter) { 464891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 465ceb69499SGiuseppe CAVALLARO /* time stamp no incoming packet at all */ 466891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 467891434b1SRayagond Kokatanur break; 468891434b1SRayagond Kokatanur 469891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 470ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, any kind of event packet */ 471891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 472891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 473891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 474891434b1SRayagond Kokatanur 475891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 476891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 477891434b1SRayagond Kokatanur break; 478891434b1SRayagond Kokatanur 479891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 480ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Sync packet */ 481891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC; 482891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 483891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 484891434b1SRayagond Kokatanur 485891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 486891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 487891434b1SRayagond Kokatanur break; 488891434b1SRayagond Kokatanur 489891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 490ceb69499SGiuseppe CAVALLARO /* PTP v1, UDP, Delay_req packet */ 491891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ; 492891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 493891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 494891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 495891434b1SRayagond Kokatanur 496891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 497891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 498891434b1SRayagond Kokatanur break; 499891434b1SRayagond Kokatanur 500891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 501ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, any kind of event packet */ 502891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 503891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 504891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 505891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 506891434b1SRayagond Kokatanur 507891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 508891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 509891434b1SRayagond Kokatanur break; 510891434b1SRayagond Kokatanur 511891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 512ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Sync packet */ 513891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_SYNC; 514891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 515891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 516891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 517891434b1SRayagond Kokatanur 518891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 519891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 520891434b1SRayagond Kokatanur break; 521891434b1SRayagond Kokatanur 522891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 523ceb69499SGiuseppe CAVALLARO /* PTP v2, UDP, Delay_req packet */ 524891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ; 525891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 526891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 527891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 528891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 529891434b1SRayagond Kokatanur 530891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 531891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 532891434b1SRayagond Kokatanur break; 533891434b1SRayagond Kokatanur 534891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_EVENT: 535ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1 any layer, any kind of event packet */ 536891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 537891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 538891434b1SRayagond Kokatanur /* take time stamp for all event messages */ 539891434b1SRayagond Kokatanur snap_type_sel = PTP_TCR_SNAPTYPSEL_1; 540891434b1SRayagond Kokatanur 541891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 542891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 543891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 544891434b1SRayagond Kokatanur break; 545891434b1SRayagond Kokatanur 546891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_SYNC: 547ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Sync packet */ 548891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_SYNC; 549891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 550891434b1SRayagond Kokatanur /* take time stamp for SYNC messages only */ 551891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 552891434b1SRayagond Kokatanur 553891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 554891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 555891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 556891434b1SRayagond Kokatanur break; 557891434b1SRayagond Kokatanur 558891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 559ceb69499SGiuseppe CAVALLARO /* PTP v2/802.AS1, any layer, Delay_req packet */ 560891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V2_DELAY_REQ; 561891434b1SRayagond Kokatanur ptp_v2 = PTP_TCR_TSVER2ENA; 562891434b1SRayagond Kokatanur /* take time stamp for Delay_Req messages only */ 563891434b1SRayagond Kokatanur ts_master_en = PTP_TCR_TSMSTRENA; 564891434b1SRayagond Kokatanur ts_event_en = PTP_TCR_TSEVNTENA; 565891434b1SRayagond Kokatanur 566891434b1SRayagond Kokatanur ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; 567891434b1SRayagond Kokatanur ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; 568891434b1SRayagond Kokatanur ptp_over_ethernet = PTP_TCR_TSIPENA; 569891434b1SRayagond Kokatanur break; 570891434b1SRayagond Kokatanur 571891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_ALL: 572ceb69499SGiuseppe CAVALLARO /* time stamp any incoming packet */ 573891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_ALL; 574891434b1SRayagond Kokatanur tstamp_all = PTP_TCR_TSENALL; 575891434b1SRayagond Kokatanur break; 576891434b1SRayagond Kokatanur 577891434b1SRayagond Kokatanur default: 578891434b1SRayagond Kokatanur return -ERANGE; 579891434b1SRayagond Kokatanur } 580891434b1SRayagond Kokatanur } else { 581891434b1SRayagond Kokatanur switch (config.rx_filter) { 582891434b1SRayagond Kokatanur case HWTSTAMP_FILTER_NONE: 583891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_NONE; 584891434b1SRayagond Kokatanur break; 585891434b1SRayagond Kokatanur default: 586891434b1SRayagond Kokatanur /* PTP v1, UDP, any kind of event packet */ 587891434b1SRayagond Kokatanur config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 588891434b1SRayagond Kokatanur break; 589891434b1SRayagond Kokatanur } 590891434b1SRayagond Kokatanur } 591891434b1SRayagond Kokatanur priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1); 5925f3da328SBen Hutchings priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON; 593891434b1SRayagond Kokatanur 594891434b1SRayagond Kokatanur if (!priv->hwts_tx_en && !priv->hwts_rx_en) 595891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0); 596891434b1SRayagond Kokatanur else { 597891434b1SRayagond Kokatanur value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR | 598891434b1SRayagond Kokatanur tstamp_all | ptp_v2 | ptp_over_ethernet | 599891434b1SRayagond Kokatanur ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en | 600891434b1SRayagond Kokatanur ts_master_en | snap_type_sel); 601891434b1SRayagond Kokatanur 602891434b1SRayagond Kokatanur priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value); 603891434b1SRayagond Kokatanur 604891434b1SRayagond Kokatanur /* program Sub Second Increment reg */ 605891434b1SRayagond Kokatanur priv->hw->ptp->config_sub_second_increment(priv->ioaddr); 606891434b1SRayagond Kokatanur 607891434b1SRayagond Kokatanur /* calculate default added value: 608891434b1SRayagond Kokatanur * formula is : 609891434b1SRayagond Kokatanur * addend = (2^32)/freq_div_ratio; 6105566401fSGiuseppe CAVALLARO * where, freq_div_ratio = clk_ptp_ref_i/50MHz 6115566401fSGiuseppe CAVALLARO * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i; 6125566401fSGiuseppe CAVALLARO * NOTE: clk_ptp_ref_i should be >= 50MHz to 613891434b1SRayagond Kokatanur * achive 20ns accuracy. 614891434b1SRayagond Kokatanur * 615891434b1SRayagond Kokatanur * 2^x * y == (y << x), hence 616891434b1SRayagond Kokatanur * 2^32 * 50000000 ==> (50000000 << 32) 617891434b1SRayagond Kokatanur */ 618891434b1SRayagond Kokatanur temp = (u64) (50000000ULL << 32); 6195566401fSGiuseppe CAVALLARO priv->default_addend = div_u64(temp, priv->clk_ptp_rate); 620891434b1SRayagond Kokatanur priv->hw->ptp->config_addend(priv->ioaddr, 621891434b1SRayagond Kokatanur priv->default_addend); 622891434b1SRayagond Kokatanur 623891434b1SRayagond Kokatanur /* initialize system time */ 624891434b1SRayagond Kokatanur getnstimeofday(&now); 625891434b1SRayagond Kokatanur priv->hw->ptp->init_systime(priv->ioaddr, now.tv_sec, 626891434b1SRayagond Kokatanur now.tv_nsec); 627891434b1SRayagond Kokatanur } 628891434b1SRayagond Kokatanur 629891434b1SRayagond Kokatanur return copy_to_user(ifr->ifr_data, &config, 630891434b1SRayagond Kokatanur sizeof(struct hwtstamp_config)) ? -EFAULT : 0; 631891434b1SRayagond Kokatanur } 632891434b1SRayagond Kokatanur 63332ceabcaSGiuseppe CAVALLARO /** 63432ceabcaSGiuseppe CAVALLARO * stmmac_init_ptp: init PTP 63532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 63632ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PTPv1 or v2. 63732ceabcaSGiuseppe CAVALLARO * This is done by looking at the HW cap. register. 63832ceabcaSGiuseppe CAVALLARO * Also it registers the ptp driver. 63932ceabcaSGiuseppe CAVALLARO */ 64092ba6888SRayagond Kokatanur static int stmmac_init_ptp(struct stmmac_priv *priv) 641891434b1SRayagond Kokatanur { 64292ba6888SRayagond Kokatanur if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp)) 64392ba6888SRayagond Kokatanur return -EOPNOTSUPP; 64492ba6888SRayagond Kokatanur 6455566401fSGiuseppe CAVALLARO /* Fall-back to main clock in case of no PTP ref is passed */ 6465566401fSGiuseppe CAVALLARO priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref"); 6475566401fSGiuseppe CAVALLARO if (IS_ERR(priv->clk_ptp_ref)) { 6485566401fSGiuseppe CAVALLARO priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk); 6495566401fSGiuseppe CAVALLARO priv->clk_ptp_ref = NULL; 6505566401fSGiuseppe CAVALLARO } else { 6515566401fSGiuseppe CAVALLARO clk_prepare_enable(priv->clk_ptp_ref); 6525566401fSGiuseppe CAVALLARO priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref); 6535566401fSGiuseppe CAVALLARO } 6545566401fSGiuseppe CAVALLARO 655891434b1SRayagond Kokatanur priv->adv_ts = 0; 6567cd01399SVince Bridgers if (priv->dma_cap.atime_stamp && priv->extend_desc) 657891434b1SRayagond Kokatanur priv->adv_ts = 1; 6587cd01399SVince Bridgers 6597cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->dma_cap.time_stamp) 6607cd01399SVince Bridgers pr_debug("IEEE 1588-2002 Time Stamp supported\n"); 6617cd01399SVince Bridgers 6627cd01399SVince Bridgers if (netif_msg_hw(priv) && priv->adv_ts) 6637cd01399SVince Bridgers pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); 664891434b1SRayagond Kokatanur 665891434b1SRayagond Kokatanur priv->hw->ptp = &stmmac_ptp; 666891434b1SRayagond Kokatanur priv->hwts_tx_en = 0; 667891434b1SRayagond Kokatanur priv->hwts_rx_en = 0; 66892ba6888SRayagond Kokatanur 66992ba6888SRayagond Kokatanur return stmmac_ptp_register(priv); 67092ba6888SRayagond Kokatanur } 67192ba6888SRayagond Kokatanur 67292ba6888SRayagond Kokatanur static void stmmac_release_ptp(struct stmmac_priv *priv) 67392ba6888SRayagond Kokatanur { 6745566401fSGiuseppe CAVALLARO if (priv->clk_ptp_ref) 6755566401fSGiuseppe CAVALLARO clk_disable_unprepare(priv->clk_ptp_ref); 67692ba6888SRayagond Kokatanur stmmac_ptp_unregister(priv); 677891434b1SRayagond Kokatanur } 678891434b1SRayagond Kokatanur 6797ac6653aSJeff Kirsher /** 6807ac6653aSJeff Kirsher * stmmac_adjust_link 6817ac6653aSJeff Kirsher * @dev: net device structure 6827ac6653aSJeff Kirsher * Description: it adjusts the link parameters. 6837ac6653aSJeff Kirsher */ 6847ac6653aSJeff Kirsher static void stmmac_adjust_link(struct net_device *dev) 6857ac6653aSJeff Kirsher { 6867ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 6877ac6653aSJeff Kirsher struct phy_device *phydev = priv->phydev; 6887ac6653aSJeff Kirsher unsigned long flags; 6897ac6653aSJeff Kirsher int new_state = 0; 6907ac6653aSJeff Kirsher unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; 6917ac6653aSJeff Kirsher 6927ac6653aSJeff Kirsher if (phydev == NULL) 6937ac6653aSJeff Kirsher return; 6947ac6653aSJeff Kirsher 6957ac6653aSJeff Kirsher spin_lock_irqsave(&priv->lock, flags); 696d765955dSGiuseppe CAVALLARO 6977ac6653aSJeff Kirsher if (phydev->link) { 6987ac6653aSJeff Kirsher u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); 6997ac6653aSJeff Kirsher 7007ac6653aSJeff Kirsher /* Now we make sure that we can be in full duplex mode. 7017ac6653aSJeff Kirsher * If not, we operate in half-duplex mode. */ 7027ac6653aSJeff Kirsher if (phydev->duplex != priv->oldduplex) { 7037ac6653aSJeff Kirsher new_state = 1; 7047ac6653aSJeff Kirsher if (!(phydev->duplex)) 7057ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.duplex; 7067ac6653aSJeff Kirsher else 7077ac6653aSJeff Kirsher ctrl |= priv->hw->link.duplex; 7087ac6653aSJeff Kirsher priv->oldduplex = phydev->duplex; 7097ac6653aSJeff Kirsher } 7107ac6653aSJeff Kirsher /* Flow Control operation */ 7117ac6653aSJeff Kirsher if (phydev->pause) 7127ed24bbeSVince Bridgers priv->hw->mac->flow_ctrl(priv->hw, phydev->duplex, 7137ac6653aSJeff Kirsher fc, pause_time); 7147ac6653aSJeff Kirsher 7157ac6653aSJeff Kirsher if (phydev->speed != priv->speed) { 7167ac6653aSJeff Kirsher new_state = 1; 7177ac6653aSJeff Kirsher switch (phydev->speed) { 7187ac6653aSJeff Kirsher case 1000: 7197ac6653aSJeff Kirsher if (likely(priv->plat->has_gmac)) 7207ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7217ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7227ac6653aSJeff Kirsher break; 7237ac6653aSJeff Kirsher case 100: 7247ac6653aSJeff Kirsher case 10: 7257ac6653aSJeff Kirsher if (priv->plat->has_gmac) { 7267ac6653aSJeff Kirsher ctrl |= priv->hw->link.port; 7277ac6653aSJeff Kirsher if (phydev->speed == SPEED_100) { 7287ac6653aSJeff Kirsher ctrl |= priv->hw->link.speed; 7297ac6653aSJeff Kirsher } else { 7307ac6653aSJeff Kirsher ctrl &= ~(priv->hw->link.speed); 7317ac6653aSJeff Kirsher } 7327ac6653aSJeff Kirsher } else { 7337ac6653aSJeff Kirsher ctrl &= ~priv->hw->link.port; 7347ac6653aSJeff Kirsher } 7357ac6653aSJeff Kirsher stmmac_hw_fix_mac_speed(priv); 7367ac6653aSJeff Kirsher break; 7377ac6653aSJeff Kirsher default: 7387ac6653aSJeff Kirsher if (netif_msg_link(priv)) 739ceb69499SGiuseppe CAVALLARO pr_warn("%s: Speed (%d) not 10/100\n", 740ceb69499SGiuseppe CAVALLARO dev->name, phydev->speed); 7417ac6653aSJeff Kirsher break; 7427ac6653aSJeff Kirsher } 7437ac6653aSJeff Kirsher 7447ac6653aSJeff Kirsher priv->speed = phydev->speed; 7457ac6653aSJeff Kirsher } 7467ac6653aSJeff Kirsher 7477ac6653aSJeff Kirsher writel(ctrl, priv->ioaddr + MAC_CTRL_REG); 7487ac6653aSJeff Kirsher 7497ac6653aSJeff Kirsher if (!priv->oldlink) { 7507ac6653aSJeff Kirsher new_state = 1; 7517ac6653aSJeff Kirsher priv->oldlink = 1; 7527ac6653aSJeff Kirsher } 7537ac6653aSJeff Kirsher } else if (priv->oldlink) { 7547ac6653aSJeff Kirsher new_state = 1; 7557ac6653aSJeff Kirsher priv->oldlink = 0; 7567ac6653aSJeff Kirsher priv->speed = 0; 7577ac6653aSJeff Kirsher priv->oldduplex = -1; 7587ac6653aSJeff Kirsher } 7597ac6653aSJeff Kirsher 7607ac6653aSJeff Kirsher if (new_state && netif_msg_link(priv)) 7617ac6653aSJeff Kirsher phy_print_status(phydev); 7627ac6653aSJeff Kirsher 763f5351ef7SGiuseppe CAVALLARO /* At this stage, it could be needed to setup the EEE or adjust some 764f5351ef7SGiuseppe CAVALLARO * MAC related HW registers. 765f5351ef7SGiuseppe CAVALLARO */ 766f5351ef7SGiuseppe CAVALLARO priv->eee_enabled = stmmac_eee_init(priv); 767d765955dSGiuseppe CAVALLARO 7687ac6653aSJeff Kirsher spin_unlock_irqrestore(&priv->lock, flags); 7697ac6653aSJeff Kirsher } 7707ac6653aSJeff Kirsher 77132ceabcaSGiuseppe CAVALLARO /** 77232ceabcaSGiuseppe CAVALLARO * stmmac_check_pcs_mode: verify if RGMII/SGMII is supported 77332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 77432ceabcaSGiuseppe CAVALLARO * Description: this is to verify if the HW supports the PCS. 77532ceabcaSGiuseppe CAVALLARO * Physical Coding Sublayer (PCS) interface that can be used when the MAC is 77632ceabcaSGiuseppe CAVALLARO * configured for the TBI, RTBI, or SGMII PHY interface. 77732ceabcaSGiuseppe CAVALLARO */ 778e58bb43fSGiuseppe CAVALLARO static void stmmac_check_pcs_mode(struct stmmac_priv *priv) 779e58bb43fSGiuseppe CAVALLARO { 780e58bb43fSGiuseppe CAVALLARO int interface = priv->plat->interface; 781e58bb43fSGiuseppe CAVALLARO 782e58bb43fSGiuseppe CAVALLARO if (priv->dma_cap.pcs) { 7830d909dcdSByungho An if ((interface == PHY_INTERFACE_MODE_RGMII) || 7840d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_ID) || 7850d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_RXID) || 7860d909dcdSByungho An (interface == PHY_INTERFACE_MODE_RGMII_TXID)) { 787e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS RGMII support enable\n"); 788e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_RGMII; 7890d909dcdSByungho An } else if (interface == PHY_INTERFACE_MODE_SGMII) { 790e58bb43fSGiuseppe CAVALLARO pr_debug("STMMAC: PCS SGMII support enable\n"); 791e58bb43fSGiuseppe CAVALLARO priv->pcs = STMMAC_PCS_SGMII; 792e58bb43fSGiuseppe CAVALLARO } 793e58bb43fSGiuseppe CAVALLARO } 794e58bb43fSGiuseppe CAVALLARO } 795e58bb43fSGiuseppe CAVALLARO 7967ac6653aSJeff Kirsher /** 7977ac6653aSJeff Kirsher * stmmac_init_phy - PHY initialization 7987ac6653aSJeff Kirsher * @dev: net device structure 7997ac6653aSJeff Kirsher * Description: it initializes the driver's PHY state, and attaches the PHY 8007ac6653aSJeff Kirsher * to the mac driver. 8017ac6653aSJeff Kirsher * Return value: 8027ac6653aSJeff Kirsher * 0 on success 8037ac6653aSJeff Kirsher */ 8047ac6653aSJeff Kirsher static int stmmac_init_phy(struct net_device *dev) 8057ac6653aSJeff Kirsher { 8067ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 8077ac6653aSJeff Kirsher struct phy_device *phydev; 808d765955dSGiuseppe CAVALLARO char phy_id_fmt[MII_BUS_ID_SIZE + 3]; 8097ac6653aSJeff Kirsher char bus_id[MII_BUS_ID_SIZE]; 81079ee1dc3SSrinivas Kandagatla int interface = priv->plat->interface; 8119cbadf09SSrinivas Kandagatla int max_speed = priv->plat->max_speed; 8127ac6653aSJeff Kirsher priv->oldlink = 0; 8137ac6653aSJeff Kirsher priv->speed = 0; 8147ac6653aSJeff Kirsher priv->oldduplex = -1; 8157ac6653aSJeff Kirsher 816f142af2eSSrinivas Kandagatla if (priv->plat->phy_bus_name) 817f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", 818f142af2eSSrinivas Kandagatla priv->plat->phy_bus_name, priv->plat->bus_id); 819f142af2eSSrinivas Kandagatla else 820f142af2eSSrinivas Kandagatla snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", 821f142af2eSSrinivas Kandagatla priv->plat->bus_id); 822f142af2eSSrinivas Kandagatla 823d765955dSGiuseppe CAVALLARO snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, 8247ac6653aSJeff Kirsher priv->plat->phy_addr); 825d765955dSGiuseppe CAVALLARO pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); 8267ac6653aSJeff Kirsher 827f9a8f83bSFlorian Fainelli phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface); 8287ac6653aSJeff Kirsher 8297ac6653aSJeff Kirsher if (IS_ERR(phydev)) { 8307ac6653aSJeff Kirsher pr_err("%s: Could not attach to PHY\n", dev->name); 8317ac6653aSJeff Kirsher return PTR_ERR(phydev); 8327ac6653aSJeff Kirsher } 8337ac6653aSJeff Kirsher 83479ee1dc3SSrinivas Kandagatla /* Stop Advertising 1000BASE Capability if interface is not GMII */ 835c5b9b4e4SSrinivas Kandagatla if ((interface == PHY_INTERFACE_MODE_MII) || 8369cbadf09SSrinivas Kandagatla (interface == PHY_INTERFACE_MODE_RMII) || 8379cbadf09SSrinivas Kandagatla (max_speed < 1000 && max_speed > 0)) 838c5b9b4e4SSrinivas Kandagatla phydev->advertising &= ~(SUPPORTED_1000baseT_Half | 839c5b9b4e4SSrinivas Kandagatla SUPPORTED_1000baseT_Full); 84079ee1dc3SSrinivas Kandagatla 8417ac6653aSJeff Kirsher /* 8427ac6653aSJeff Kirsher * Broken HW is sometimes missing the pull-up resistor on the 8437ac6653aSJeff Kirsher * MDIO line, which results in reads to non-existent devices returning 8447ac6653aSJeff Kirsher * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent 8457ac6653aSJeff Kirsher * device as well. 8467ac6653aSJeff Kirsher * Note: phydev->phy_id is the result of reading the UID PHY registers. 8477ac6653aSJeff Kirsher */ 8487ac6653aSJeff Kirsher if (phydev->phy_id == 0) { 8497ac6653aSJeff Kirsher phy_disconnect(phydev); 8507ac6653aSJeff Kirsher return -ENODEV; 8517ac6653aSJeff Kirsher } 8527ac6653aSJeff Kirsher pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)" 8537ac6653aSJeff Kirsher " Link = %d\n", dev->name, phydev->phy_id, phydev->link); 8547ac6653aSJeff Kirsher 8557ac6653aSJeff Kirsher priv->phydev = phydev; 8567ac6653aSJeff Kirsher 8577ac6653aSJeff Kirsher return 0; 8587ac6653aSJeff Kirsher } 8597ac6653aSJeff Kirsher 8607ac6653aSJeff Kirsher /** 86132ceabcaSGiuseppe CAVALLARO * stmmac_display_ring: display ring 86232ceabcaSGiuseppe CAVALLARO * @head: pointer to the head of the ring passed. 8637ac6653aSJeff Kirsher * @size: size of the ring. 86432ceabcaSGiuseppe CAVALLARO * @extend_desc: to verify if extended descriptors are used. 865c24602efSGiuseppe CAVALLARO * Description: display the control/status and buffer descriptors. 8667ac6653aSJeff Kirsher */ 867c24602efSGiuseppe CAVALLARO static void stmmac_display_ring(void *head, int size, int extend_desc) 8687ac6653aSJeff Kirsher { 8697ac6653aSJeff Kirsher int i; 870c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 871c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 872c24602efSGiuseppe CAVALLARO 8737ac6653aSJeff Kirsher for (i = 0; i < size; i++) { 874c24602efSGiuseppe CAVALLARO u64 x; 875c24602efSGiuseppe CAVALLARO if (extend_desc) { 876c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 877c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 878c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 879c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 880c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 881c24602efSGiuseppe CAVALLARO ep++; 882c24602efSGiuseppe CAVALLARO } else { 883c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 884c24602efSGiuseppe CAVALLARO pr_info("%d [0x%x]: 0x%x 0x%x 0x%x 0x%x", 885c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(p), 886c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 887c24602efSGiuseppe CAVALLARO p->des2, p->des3); 888c24602efSGiuseppe CAVALLARO p++; 889c24602efSGiuseppe CAVALLARO } 8907ac6653aSJeff Kirsher pr_info("\n"); 8917ac6653aSJeff Kirsher } 8927ac6653aSJeff Kirsher } 8937ac6653aSJeff Kirsher 894c24602efSGiuseppe CAVALLARO static void stmmac_display_rings(struct stmmac_priv *priv) 895c24602efSGiuseppe CAVALLARO { 896c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 897c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 898c24602efSGiuseppe CAVALLARO 899c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 900c24602efSGiuseppe CAVALLARO pr_info("Extended RX descriptor ring:\n"); 901c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 902c24602efSGiuseppe CAVALLARO pr_info("Extended TX descriptor ring:\n"); 903c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 904c24602efSGiuseppe CAVALLARO } else { 905c24602efSGiuseppe CAVALLARO pr_info("RX descriptor ring:\n"); 906c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 907c24602efSGiuseppe CAVALLARO pr_info("TX descriptor ring:\n"); 908c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 909c24602efSGiuseppe CAVALLARO } 910c24602efSGiuseppe CAVALLARO } 911c24602efSGiuseppe CAVALLARO 912286a8372SGiuseppe CAVALLARO static int stmmac_set_bfsize(int mtu, int bufsize) 913286a8372SGiuseppe CAVALLARO { 914286a8372SGiuseppe CAVALLARO int ret = bufsize; 915286a8372SGiuseppe CAVALLARO 916286a8372SGiuseppe CAVALLARO if (mtu >= BUF_SIZE_4KiB) 917286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_8KiB; 918286a8372SGiuseppe CAVALLARO else if (mtu >= BUF_SIZE_2KiB) 919286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_4KiB; 920d916701cSGiuseppe CAVALLARO else if (mtu > DEFAULT_BUFSIZE) 921286a8372SGiuseppe CAVALLARO ret = BUF_SIZE_2KiB; 922286a8372SGiuseppe CAVALLARO else 923d916701cSGiuseppe CAVALLARO ret = DEFAULT_BUFSIZE; 924286a8372SGiuseppe CAVALLARO 925286a8372SGiuseppe CAVALLARO return ret; 926286a8372SGiuseppe CAVALLARO } 927286a8372SGiuseppe CAVALLARO 92832ceabcaSGiuseppe CAVALLARO /** 92932ceabcaSGiuseppe CAVALLARO * stmmac_clear_descriptors: clear descriptors 93032ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 93132ceabcaSGiuseppe CAVALLARO * Description: this function is called to clear the tx and rx descriptors 93232ceabcaSGiuseppe CAVALLARO * in case of both basic and extended descriptors are used. 93332ceabcaSGiuseppe CAVALLARO */ 934c24602efSGiuseppe CAVALLARO static void stmmac_clear_descriptors(struct stmmac_priv *priv) 935c24602efSGiuseppe CAVALLARO { 936c24602efSGiuseppe CAVALLARO int i; 937c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 938c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 939c24602efSGiuseppe CAVALLARO 940c24602efSGiuseppe CAVALLARO /* Clear the Rx/Tx descriptors */ 941c24602efSGiuseppe CAVALLARO for (i = 0; i < rxsize; i++) 942c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 943c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_erx[i].basic, 944c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 945c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 946c24602efSGiuseppe CAVALLARO else 947c24602efSGiuseppe CAVALLARO priv->hw->desc->init_rx_desc(&priv->dma_rx[i], 948c24602efSGiuseppe CAVALLARO priv->use_riwt, priv->mode, 949c24602efSGiuseppe CAVALLARO (i == rxsize - 1)); 950c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 951c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 952c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 953c24602efSGiuseppe CAVALLARO priv->mode, 954c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 955c24602efSGiuseppe CAVALLARO else 956c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 957c24602efSGiuseppe CAVALLARO priv->mode, 958c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 959c24602efSGiuseppe CAVALLARO } 960c24602efSGiuseppe CAVALLARO 961c24602efSGiuseppe CAVALLARO static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, 962c24602efSGiuseppe CAVALLARO int i) 963c24602efSGiuseppe CAVALLARO { 964c24602efSGiuseppe CAVALLARO struct sk_buff *skb; 965c24602efSGiuseppe CAVALLARO 966c24602efSGiuseppe CAVALLARO skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN, 967c24602efSGiuseppe CAVALLARO GFP_KERNEL); 96856329137SBartlomiej Zolnierkiewicz if (!skb) { 969c24602efSGiuseppe CAVALLARO pr_err("%s: Rx init fails; skb is NULL\n", __func__); 97056329137SBartlomiej Zolnierkiewicz return -ENOMEM; 971c24602efSGiuseppe CAVALLARO } 972c24602efSGiuseppe CAVALLARO skb_reserve(skb, NET_IP_ALIGN); 973c24602efSGiuseppe CAVALLARO priv->rx_skbuff[i] = skb; 974c24602efSGiuseppe CAVALLARO priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data, 975c24602efSGiuseppe CAVALLARO priv->dma_buf_sz, 976c24602efSGiuseppe CAVALLARO DMA_FROM_DEVICE); 97756329137SBartlomiej Zolnierkiewicz if (dma_mapping_error(priv->device, priv->rx_skbuff_dma[i])) { 97856329137SBartlomiej Zolnierkiewicz pr_err("%s: DMA mapping error\n", __func__); 97956329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(skb); 98056329137SBartlomiej Zolnierkiewicz return -EINVAL; 98156329137SBartlomiej Zolnierkiewicz } 982c24602efSGiuseppe CAVALLARO 983c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[i]; 984c24602efSGiuseppe CAVALLARO 98529896a67SGiuseppe CAVALLARO if ((priv->hw->mode->init_desc3) && 986c24602efSGiuseppe CAVALLARO (priv->dma_buf_sz == BUF_SIZE_16KiB)) 98729896a67SGiuseppe CAVALLARO priv->hw->mode->init_desc3(p); 988c24602efSGiuseppe CAVALLARO 989c24602efSGiuseppe CAVALLARO return 0; 990c24602efSGiuseppe CAVALLARO } 991c24602efSGiuseppe CAVALLARO 99256329137SBartlomiej Zolnierkiewicz static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) 99356329137SBartlomiej Zolnierkiewicz { 99456329137SBartlomiej Zolnierkiewicz if (priv->rx_skbuff[i]) { 99556329137SBartlomiej Zolnierkiewicz dma_unmap_single(priv->device, priv->rx_skbuff_dma[i], 99656329137SBartlomiej Zolnierkiewicz priv->dma_buf_sz, DMA_FROM_DEVICE); 99756329137SBartlomiej Zolnierkiewicz dev_kfree_skb_any(priv->rx_skbuff[i]); 99856329137SBartlomiej Zolnierkiewicz } 99956329137SBartlomiej Zolnierkiewicz priv->rx_skbuff[i] = NULL; 100056329137SBartlomiej Zolnierkiewicz } 100156329137SBartlomiej Zolnierkiewicz 10027ac6653aSJeff Kirsher /** 10037ac6653aSJeff Kirsher * init_dma_desc_rings - init the RX/TX descriptor rings 10047ac6653aSJeff Kirsher * @dev: net device structure 10057ac6653aSJeff Kirsher * Description: this function initializes the DMA RX/TX descriptors 1006286a8372SGiuseppe CAVALLARO * and allocates the socket buffers. It suppors the chained and ring 1007286a8372SGiuseppe CAVALLARO * modes. 10087ac6653aSJeff Kirsher */ 100956329137SBartlomiej Zolnierkiewicz static int init_dma_desc_rings(struct net_device *dev) 10107ac6653aSJeff Kirsher { 10117ac6653aSJeff Kirsher int i; 10127ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 10137ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 10147ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 10154a7d666aSGiuseppe CAVALLARO unsigned int bfsize = 0; 101656329137SBartlomiej Zolnierkiewicz int ret = -ENOMEM; 10177ac6653aSJeff Kirsher 101829896a67SGiuseppe CAVALLARO if (priv->hw->mode->set_16kib_bfsize) 101929896a67SGiuseppe CAVALLARO bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu); 1020286a8372SGiuseppe CAVALLARO 10214a7d666aSGiuseppe CAVALLARO if (bfsize < BUF_SIZE_16KiB) 1022286a8372SGiuseppe CAVALLARO bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); 10237ac6653aSJeff Kirsher 10242618abb7SVince Bridgers priv->dma_buf_sz = bfsize; 10252618abb7SVince Bridgers 102683d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 102783d7af64SGiuseppe CAVALLARO pr_debug("%s: txsize %d, rxsize %d, bfsize %d\n", __func__, 10287ac6653aSJeff Kirsher txsize, rxsize, bfsize); 10297ac6653aSJeff Kirsher 103083d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) { 1031c24602efSGiuseppe CAVALLARO pr_debug("(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n", __func__, 1032c24602efSGiuseppe CAVALLARO (u32) priv->dma_rx_phy, (u32) priv->dma_tx_phy); 10337ac6653aSJeff Kirsher 10347ac6653aSJeff Kirsher /* RX INITIALIZATION */ 103583d7af64SGiuseppe CAVALLARO pr_debug("\tSKB addresses:\nskb\t\tskb data\tdma data\n"); 103683d7af64SGiuseppe CAVALLARO } 10377ac6653aSJeff Kirsher for (i = 0; i < rxsize; i++) { 1038c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1039c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1040c24602efSGiuseppe CAVALLARO p = &((priv->dma_erx + i)->basic); 1041c24602efSGiuseppe CAVALLARO else 1042c24602efSGiuseppe CAVALLARO p = priv->dma_rx + i; 10437ac6653aSJeff Kirsher 104456329137SBartlomiej Zolnierkiewicz ret = stmmac_init_rx_buffers(priv, p, i); 104556329137SBartlomiej Zolnierkiewicz if (ret) 104656329137SBartlomiej Zolnierkiewicz goto err_init_rx_buffers; 1047286a8372SGiuseppe CAVALLARO 104883d7af64SGiuseppe CAVALLARO if (netif_msg_probe(priv)) 104983d7af64SGiuseppe CAVALLARO pr_debug("[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i], 105083d7af64SGiuseppe CAVALLARO priv->rx_skbuff[i]->data, 105183d7af64SGiuseppe CAVALLARO (unsigned int)priv->rx_skbuff_dma[i]); 10527ac6653aSJeff Kirsher } 10537ac6653aSJeff Kirsher priv->cur_rx = 0; 10547ac6653aSJeff Kirsher priv->dirty_rx = (unsigned int)(i - rxsize); 10557ac6653aSJeff Kirsher buf_sz = bfsize; 10567ac6653aSJeff Kirsher 1057c24602efSGiuseppe CAVALLARO /* Setup the chained descriptor addresses */ 1058c24602efSGiuseppe CAVALLARO if (priv->mode == STMMAC_CHAIN_MODE) { 1059c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 106029896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_erx, priv->dma_rx_phy, 1061c24602efSGiuseppe CAVALLARO rxsize, 1); 106229896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_etx, priv->dma_tx_phy, 1063c24602efSGiuseppe CAVALLARO txsize, 1); 1064c24602efSGiuseppe CAVALLARO } else { 106529896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_rx, priv->dma_rx_phy, 1066c24602efSGiuseppe CAVALLARO rxsize, 0); 106729896a67SGiuseppe CAVALLARO priv->hw->mode->init(priv->dma_tx, priv->dma_tx_phy, 1068c24602efSGiuseppe CAVALLARO txsize, 0); 1069c24602efSGiuseppe CAVALLARO } 10707ac6653aSJeff Kirsher } 1071286a8372SGiuseppe CAVALLARO 1072c24602efSGiuseppe CAVALLARO /* TX INITIALIZATION */ 1073c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) { 1074c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1075c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1076c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1077c24602efSGiuseppe CAVALLARO else 1078c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1079c24602efSGiuseppe CAVALLARO p->des2 = 0; 1080362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[i].buf = 0; 1081362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[i].map_as_page = false; 1082c24602efSGiuseppe CAVALLARO priv->tx_skbuff[i] = NULL; 10834a7d666aSGiuseppe CAVALLARO } 1084c24602efSGiuseppe CAVALLARO 10857ac6653aSJeff Kirsher priv->dirty_tx = 0; 10867ac6653aSJeff Kirsher priv->cur_tx = 0; 10877ac6653aSJeff Kirsher 1088c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 10897ac6653aSJeff Kirsher 1090c24602efSGiuseppe CAVALLARO if (netif_msg_hw(priv)) 1091c24602efSGiuseppe CAVALLARO stmmac_display_rings(priv); 109256329137SBartlomiej Zolnierkiewicz 109356329137SBartlomiej Zolnierkiewicz return 0; 109456329137SBartlomiej Zolnierkiewicz err_init_rx_buffers: 109556329137SBartlomiej Zolnierkiewicz while (--i >= 0) 109656329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 109756329137SBartlomiej Zolnierkiewicz return ret; 10987ac6653aSJeff Kirsher } 10997ac6653aSJeff Kirsher 11007ac6653aSJeff Kirsher static void dma_free_rx_skbufs(struct stmmac_priv *priv) 11017ac6653aSJeff Kirsher { 11027ac6653aSJeff Kirsher int i; 11037ac6653aSJeff Kirsher 110456329137SBartlomiej Zolnierkiewicz for (i = 0; i < priv->dma_rx_size; i++) 110556329137SBartlomiej Zolnierkiewicz stmmac_free_rx_buffers(priv, i); 11067ac6653aSJeff Kirsher } 11077ac6653aSJeff Kirsher 11087ac6653aSJeff Kirsher static void dma_free_tx_skbufs(struct stmmac_priv *priv) 11097ac6653aSJeff Kirsher { 11107ac6653aSJeff Kirsher int i; 11117ac6653aSJeff Kirsher 11127ac6653aSJeff Kirsher for (i = 0; i < priv->dma_tx_size; i++) { 1113c24602efSGiuseppe CAVALLARO struct dma_desc *p; 111475e4364fSdamuzi000 1115c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1116c24602efSGiuseppe CAVALLARO p = &((priv->dma_etx + i)->basic); 1117c24602efSGiuseppe CAVALLARO else 1118c24602efSGiuseppe CAVALLARO p = priv->dma_tx + i; 1119c24602efSGiuseppe CAVALLARO 1120362b37beSGiuseppe CAVALLARO if (priv->tx_skbuff_dma[i].buf) { 1121362b37beSGiuseppe CAVALLARO if (priv->tx_skbuff_dma[i].map_as_page) 1122362b37beSGiuseppe CAVALLARO dma_unmap_page(priv->device, 1123362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[i].buf, 11247ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 11257ac6653aSJeff Kirsher DMA_TO_DEVICE); 1126362b37beSGiuseppe CAVALLARO else 1127362b37beSGiuseppe CAVALLARO dma_unmap_single(priv->device, 1128362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[i].buf, 1129362b37beSGiuseppe CAVALLARO priv->hw->desc->get_tx_len(p), 1130362b37beSGiuseppe CAVALLARO DMA_TO_DEVICE); 113175e4364fSdamuzi000 } 113275e4364fSdamuzi000 113375e4364fSdamuzi000 if (priv->tx_skbuff[i] != NULL) { 11347ac6653aSJeff Kirsher dev_kfree_skb_any(priv->tx_skbuff[i]); 11357ac6653aSJeff Kirsher priv->tx_skbuff[i] = NULL; 1136362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[i].buf = 0; 1137362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[i].map_as_page = false; 11387ac6653aSJeff Kirsher } 11397ac6653aSJeff Kirsher } 11407ac6653aSJeff Kirsher } 11417ac6653aSJeff Kirsher 114209f8d696SSrinivas Kandagatla static int alloc_dma_desc_resources(struct stmmac_priv *priv) 114309f8d696SSrinivas Kandagatla { 114409f8d696SSrinivas Kandagatla unsigned int txsize = priv->dma_tx_size; 114509f8d696SSrinivas Kandagatla unsigned int rxsize = priv->dma_rx_size; 114609f8d696SSrinivas Kandagatla int ret = -ENOMEM; 114709f8d696SSrinivas Kandagatla 114809f8d696SSrinivas Kandagatla priv->rx_skbuff_dma = kmalloc_array(rxsize, sizeof(dma_addr_t), 114909f8d696SSrinivas Kandagatla GFP_KERNEL); 115009f8d696SSrinivas Kandagatla if (!priv->rx_skbuff_dma) 115109f8d696SSrinivas Kandagatla return -ENOMEM; 115209f8d696SSrinivas Kandagatla 115309f8d696SSrinivas Kandagatla priv->rx_skbuff = kmalloc_array(rxsize, sizeof(struct sk_buff *), 115409f8d696SSrinivas Kandagatla GFP_KERNEL); 115509f8d696SSrinivas Kandagatla if (!priv->rx_skbuff) 115609f8d696SSrinivas Kandagatla goto err_rx_skbuff; 115709f8d696SSrinivas Kandagatla 1158362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma = kmalloc_array(txsize, 1159362b37beSGiuseppe CAVALLARO sizeof(*priv->tx_skbuff_dma), 116009f8d696SSrinivas Kandagatla GFP_KERNEL); 116109f8d696SSrinivas Kandagatla if (!priv->tx_skbuff_dma) 116209f8d696SSrinivas Kandagatla goto err_tx_skbuff_dma; 116309f8d696SSrinivas Kandagatla 116409f8d696SSrinivas Kandagatla priv->tx_skbuff = kmalloc_array(txsize, sizeof(struct sk_buff *), 116509f8d696SSrinivas Kandagatla GFP_KERNEL); 116609f8d696SSrinivas Kandagatla if (!priv->tx_skbuff) 116709f8d696SSrinivas Kandagatla goto err_tx_skbuff; 116809f8d696SSrinivas Kandagatla 116909f8d696SSrinivas Kandagatla if (priv->extend_desc) { 117009f8d696SSrinivas Kandagatla priv->dma_erx = dma_alloc_coherent(priv->device, rxsize * 117109f8d696SSrinivas Kandagatla sizeof(struct 117209f8d696SSrinivas Kandagatla dma_extended_desc), 117309f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 117409f8d696SSrinivas Kandagatla GFP_KERNEL); 117509f8d696SSrinivas Kandagatla if (!priv->dma_erx) 117609f8d696SSrinivas Kandagatla goto err_dma; 117709f8d696SSrinivas Kandagatla 117809f8d696SSrinivas Kandagatla priv->dma_etx = dma_alloc_coherent(priv->device, txsize * 117909f8d696SSrinivas Kandagatla sizeof(struct 118009f8d696SSrinivas Kandagatla dma_extended_desc), 118109f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 118209f8d696SSrinivas Kandagatla GFP_KERNEL); 118309f8d696SSrinivas Kandagatla if (!priv->dma_etx) { 118409f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 118509f8d696SSrinivas Kandagatla sizeof(struct dma_extended_desc), 118609f8d696SSrinivas Kandagatla priv->dma_erx, priv->dma_rx_phy); 118709f8d696SSrinivas Kandagatla goto err_dma; 118809f8d696SSrinivas Kandagatla } 118909f8d696SSrinivas Kandagatla } else { 119009f8d696SSrinivas Kandagatla priv->dma_rx = dma_alloc_coherent(priv->device, rxsize * 119109f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 119209f8d696SSrinivas Kandagatla &priv->dma_rx_phy, 119309f8d696SSrinivas Kandagatla GFP_KERNEL); 119409f8d696SSrinivas Kandagatla if (!priv->dma_rx) 119509f8d696SSrinivas Kandagatla goto err_dma; 119609f8d696SSrinivas Kandagatla 119709f8d696SSrinivas Kandagatla priv->dma_tx = dma_alloc_coherent(priv->device, txsize * 119809f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 119909f8d696SSrinivas Kandagatla &priv->dma_tx_phy, 120009f8d696SSrinivas Kandagatla GFP_KERNEL); 120109f8d696SSrinivas Kandagatla if (!priv->dma_tx) { 120209f8d696SSrinivas Kandagatla dma_free_coherent(priv->device, priv->dma_rx_size * 120309f8d696SSrinivas Kandagatla sizeof(struct dma_desc), 120409f8d696SSrinivas Kandagatla priv->dma_rx, priv->dma_rx_phy); 120509f8d696SSrinivas Kandagatla goto err_dma; 120609f8d696SSrinivas Kandagatla } 120709f8d696SSrinivas Kandagatla } 120809f8d696SSrinivas Kandagatla 120909f8d696SSrinivas Kandagatla return 0; 121009f8d696SSrinivas Kandagatla 121109f8d696SSrinivas Kandagatla err_dma: 121209f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff); 121309f8d696SSrinivas Kandagatla err_tx_skbuff: 121409f8d696SSrinivas Kandagatla kfree(priv->tx_skbuff_dma); 121509f8d696SSrinivas Kandagatla err_tx_skbuff_dma: 121609f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff); 121709f8d696SSrinivas Kandagatla err_rx_skbuff: 121809f8d696SSrinivas Kandagatla kfree(priv->rx_skbuff_dma); 121909f8d696SSrinivas Kandagatla return ret; 122009f8d696SSrinivas Kandagatla } 122109f8d696SSrinivas Kandagatla 12227ac6653aSJeff Kirsher static void free_dma_desc_resources(struct stmmac_priv *priv) 12237ac6653aSJeff Kirsher { 12247ac6653aSJeff Kirsher /* Release the DMA TX/RX socket buffers */ 12257ac6653aSJeff Kirsher dma_free_rx_skbufs(priv); 12267ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 12277ac6653aSJeff Kirsher 1228ceb69499SGiuseppe CAVALLARO /* Free DMA regions of consistent memory previously allocated */ 1229c24602efSGiuseppe CAVALLARO if (!priv->extend_desc) { 12307ac6653aSJeff Kirsher dma_free_coherent(priv->device, 12317ac6653aSJeff Kirsher priv->dma_tx_size * sizeof(struct dma_desc), 12327ac6653aSJeff Kirsher priv->dma_tx, priv->dma_tx_phy); 12337ac6653aSJeff Kirsher dma_free_coherent(priv->device, 12347ac6653aSJeff Kirsher priv->dma_rx_size * sizeof(struct dma_desc), 12357ac6653aSJeff Kirsher priv->dma_rx, priv->dma_rx_phy); 1236c24602efSGiuseppe CAVALLARO } else { 1237c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_tx_size * 1238c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1239c24602efSGiuseppe CAVALLARO priv->dma_etx, priv->dma_tx_phy); 1240c24602efSGiuseppe CAVALLARO dma_free_coherent(priv->device, priv->dma_rx_size * 1241c24602efSGiuseppe CAVALLARO sizeof(struct dma_extended_desc), 1242c24602efSGiuseppe CAVALLARO priv->dma_erx, priv->dma_rx_phy); 1243c24602efSGiuseppe CAVALLARO } 12447ac6653aSJeff Kirsher kfree(priv->rx_skbuff_dma); 12457ac6653aSJeff Kirsher kfree(priv->rx_skbuff); 1246cf32deecSRayagond Kokatanur kfree(priv->tx_skbuff_dma); 12477ac6653aSJeff Kirsher kfree(priv->tx_skbuff); 12487ac6653aSJeff Kirsher } 12497ac6653aSJeff Kirsher 12507ac6653aSJeff Kirsher /** 12517ac6653aSJeff Kirsher * stmmac_dma_operation_mode - HW DMA operation mode 125232ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12537ac6653aSJeff Kirsher * Description: it sets the DMA operation mode: tx/rx DMA thresholds 12547ac6653aSJeff Kirsher * or Store-And-Forward capability. 12557ac6653aSJeff Kirsher */ 12567ac6653aSJeff Kirsher static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 12577ac6653aSJeff Kirsher { 1258e2a240c7SSonic Zhang if (priv->plat->force_thresh_dma_mode) 1259e2a240c7SSonic Zhang priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); 1260e2a240c7SSonic Zhang else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { 12617ac6653aSJeff Kirsher /* 12627ac6653aSJeff Kirsher * In case of GMAC, SF mode can be enabled 12637ac6653aSJeff Kirsher * to perform the TX COE in HW. This depends on: 12647ac6653aSJeff Kirsher * 1) TX COE if actually supported 12657ac6653aSJeff Kirsher * 2) There is no bugged Jumbo frame support 12667ac6653aSJeff Kirsher * that needs to not insert csum in the TDES. 12677ac6653aSJeff Kirsher */ 1268ceb69499SGiuseppe CAVALLARO priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); 12697ac6653aSJeff Kirsher tc = SF_DMA_MODE; 12707ac6653aSJeff Kirsher } else 12717ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 12727ac6653aSJeff Kirsher } 12737ac6653aSJeff Kirsher 12747ac6653aSJeff Kirsher /** 12759125cdd1SGiuseppe CAVALLARO * stmmac_tx_clean: 127632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 12777ac6653aSJeff Kirsher * Description: it reclaims resources after transmission completes. 12787ac6653aSJeff Kirsher */ 12799125cdd1SGiuseppe CAVALLARO static void stmmac_tx_clean(struct stmmac_priv *priv) 12807ac6653aSJeff Kirsher { 12817ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 12827ac6653aSJeff Kirsher 1283a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1284a9097a96SGiuseppe CAVALLARO 12859125cdd1SGiuseppe CAVALLARO priv->xstats.tx_clean++; 12869125cdd1SGiuseppe CAVALLARO 12877ac6653aSJeff Kirsher while (priv->dirty_tx != priv->cur_tx) { 12887ac6653aSJeff Kirsher int last; 12897ac6653aSJeff Kirsher unsigned int entry = priv->dirty_tx % txsize; 12907ac6653aSJeff Kirsher struct sk_buff *skb = priv->tx_skbuff[entry]; 1291c24602efSGiuseppe CAVALLARO struct dma_desc *p; 1292c24602efSGiuseppe CAVALLARO 1293c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1294c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_etx + entry); 1295c24602efSGiuseppe CAVALLARO else 1296c24602efSGiuseppe CAVALLARO p = priv->dma_tx + entry; 12977ac6653aSJeff Kirsher 12987ac6653aSJeff Kirsher /* Check if the descriptor is owned by the DMA. */ 12997ac6653aSJeff Kirsher if (priv->hw->desc->get_tx_owner(p)) 13007ac6653aSJeff Kirsher break; 13017ac6653aSJeff Kirsher 1302c24602efSGiuseppe CAVALLARO /* Verify tx error by looking at the last segment. */ 13037ac6653aSJeff Kirsher last = priv->hw->desc->get_tx_ls(p); 13047ac6653aSJeff Kirsher if (likely(last)) { 13057ac6653aSJeff Kirsher int tx_error = 13067ac6653aSJeff Kirsher priv->hw->desc->tx_status(&priv->dev->stats, 13077ac6653aSJeff Kirsher &priv->xstats, p, 13087ac6653aSJeff Kirsher priv->ioaddr); 13097ac6653aSJeff Kirsher if (likely(tx_error == 0)) { 13107ac6653aSJeff Kirsher priv->dev->stats.tx_packets++; 13117ac6653aSJeff Kirsher priv->xstats.tx_pkt_n++; 13127ac6653aSJeff Kirsher } else 13137ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 1314891434b1SRayagond Kokatanur 1315891434b1SRayagond Kokatanur stmmac_get_tx_hwtstamp(priv, entry, skb); 13167ac6653aSJeff Kirsher } 131783d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 131883d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d, dirty %d\n", __func__, 13197ac6653aSJeff Kirsher priv->cur_tx, priv->dirty_tx); 13207ac6653aSJeff Kirsher 1321362b37beSGiuseppe CAVALLARO if (likely(priv->tx_skbuff_dma[entry].buf)) { 1322362b37beSGiuseppe CAVALLARO if (priv->tx_skbuff_dma[entry].map_as_page) 1323362b37beSGiuseppe CAVALLARO dma_unmap_page(priv->device, 1324362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf, 13257ac6653aSJeff Kirsher priv->hw->desc->get_tx_len(p), 13267ac6653aSJeff Kirsher DMA_TO_DEVICE); 1327362b37beSGiuseppe CAVALLARO else 1328362b37beSGiuseppe CAVALLARO dma_unmap_single(priv->device, 1329362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf, 1330362b37beSGiuseppe CAVALLARO priv->hw->desc->get_tx_len(p), 1331362b37beSGiuseppe CAVALLARO DMA_TO_DEVICE); 1332362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf = 0; 1333362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].map_as_page = false; 1334cf32deecSRayagond Kokatanur } 133529896a67SGiuseppe CAVALLARO priv->hw->mode->clean_desc3(priv, p); 13367ac6653aSJeff Kirsher 13377ac6653aSJeff Kirsher if (likely(skb != NULL)) { 13387c565c33SEric W. Biederman dev_consume_skb_any(skb); 13397ac6653aSJeff Kirsher priv->tx_skbuff[entry] = NULL; 13407ac6653aSJeff Kirsher } 13417ac6653aSJeff Kirsher 13424a7d666aSGiuseppe CAVALLARO priv->hw->desc->release_tx_desc(p, priv->mode); 13437ac6653aSJeff Kirsher 134413497f58SGiuseppe CAVALLARO priv->dirty_tx++; 13457ac6653aSJeff Kirsher } 13467ac6653aSJeff Kirsher if (unlikely(netif_queue_stopped(priv->dev) && 13477ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { 13487ac6653aSJeff Kirsher netif_tx_lock(priv->dev); 13497ac6653aSJeff Kirsher if (netif_queue_stopped(priv->dev) && 13507ac6653aSJeff Kirsher stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) { 135183d7af64SGiuseppe CAVALLARO if (netif_msg_tx_done(priv)) 135283d7af64SGiuseppe CAVALLARO pr_debug("%s: restart transmit\n", __func__); 13537ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 13547ac6653aSJeff Kirsher } 13557ac6653aSJeff Kirsher netif_tx_unlock(priv->dev); 13567ac6653aSJeff Kirsher } 1357d765955dSGiuseppe CAVALLARO 1358d765955dSGiuseppe CAVALLARO if ((priv->eee_enabled) && (!priv->tx_path_in_lpi_mode)) { 1359d765955dSGiuseppe CAVALLARO stmmac_enable_eee_mode(priv); 1360f5351ef7SGiuseppe CAVALLARO mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer)); 1361d765955dSGiuseppe CAVALLARO } 1362a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 13637ac6653aSJeff Kirsher } 13647ac6653aSJeff Kirsher 13659125cdd1SGiuseppe CAVALLARO static inline void stmmac_enable_dma_irq(struct stmmac_priv *priv) 13667ac6653aSJeff Kirsher { 13677ac6653aSJeff Kirsher priv->hw->dma->enable_dma_irq(priv->ioaddr); 13687ac6653aSJeff Kirsher } 13697ac6653aSJeff Kirsher 13709125cdd1SGiuseppe CAVALLARO static inline void stmmac_disable_dma_irq(struct stmmac_priv *priv) 13717ac6653aSJeff Kirsher { 13727ac6653aSJeff Kirsher priv->hw->dma->disable_dma_irq(priv->ioaddr); 13737ac6653aSJeff Kirsher } 13747ac6653aSJeff Kirsher 13757ac6653aSJeff Kirsher /** 137632ceabcaSGiuseppe CAVALLARO * stmmac_tx_err: irq tx error mng function 137732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 13787ac6653aSJeff Kirsher * Description: it cleans the descriptors and restarts the transmission 13797ac6653aSJeff Kirsher * in case of errors. 13807ac6653aSJeff Kirsher */ 13817ac6653aSJeff Kirsher static void stmmac_tx_err(struct stmmac_priv *priv) 13827ac6653aSJeff Kirsher { 1383c24602efSGiuseppe CAVALLARO int i; 1384c24602efSGiuseppe CAVALLARO int txsize = priv->dma_tx_size; 13857ac6653aSJeff Kirsher netif_stop_queue(priv->dev); 13867ac6653aSJeff Kirsher 13877ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 13887ac6653aSJeff Kirsher dma_free_tx_skbufs(priv); 1389c24602efSGiuseppe CAVALLARO for (i = 0; i < txsize; i++) 1390c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1391c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic, 1392c24602efSGiuseppe CAVALLARO priv->mode, 1393c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 1394c24602efSGiuseppe CAVALLARO else 1395c24602efSGiuseppe CAVALLARO priv->hw->desc->init_tx_desc(&priv->dma_tx[i], 1396c24602efSGiuseppe CAVALLARO priv->mode, 1397c24602efSGiuseppe CAVALLARO (i == txsize - 1)); 13987ac6653aSJeff Kirsher priv->dirty_tx = 0; 13997ac6653aSJeff Kirsher priv->cur_tx = 0; 14007ac6653aSJeff Kirsher priv->hw->dma->start_tx(priv->ioaddr); 14017ac6653aSJeff Kirsher 14027ac6653aSJeff Kirsher priv->dev->stats.tx_errors++; 14037ac6653aSJeff Kirsher netif_wake_queue(priv->dev); 14047ac6653aSJeff Kirsher } 14057ac6653aSJeff Kirsher 140632ceabcaSGiuseppe CAVALLARO /** 140732ceabcaSGiuseppe CAVALLARO * stmmac_dma_interrupt: DMA ISR 140832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 140932ceabcaSGiuseppe CAVALLARO * Description: this is the DMA ISR. It is called by the main ISR. 141032ceabcaSGiuseppe CAVALLARO * It calls the dwmac dma routine to understand which type of interrupt 141132ceabcaSGiuseppe CAVALLARO * happened. In case of there is a Normal interrupt and either TX or RX 141232ceabcaSGiuseppe CAVALLARO * interrupt happened so the NAPI is scheduled. 141332ceabcaSGiuseppe CAVALLARO */ 14147ac6653aSJeff Kirsher static void stmmac_dma_interrupt(struct stmmac_priv *priv) 14157ac6653aSJeff Kirsher { 14167ac6653aSJeff Kirsher int status; 14177ac6653aSJeff Kirsher 14187ac6653aSJeff Kirsher status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 14199125cdd1SGiuseppe CAVALLARO if (likely((status & handle_rx)) || (status & handle_tx)) { 14209125cdd1SGiuseppe CAVALLARO if (likely(napi_schedule_prep(&priv->napi))) { 14219125cdd1SGiuseppe CAVALLARO stmmac_disable_dma_irq(priv); 14229125cdd1SGiuseppe CAVALLARO __napi_schedule(&priv->napi); 14239125cdd1SGiuseppe CAVALLARO } 14249125cdd1SGiuseppe CAVALLARO } 14259125cdd1SGiuseppe CAVALLARO if (unlikely(status & tx_hard_error_bump_tc)) { 14267ac6653aSJeff Kirsher /* Try to bump up the dma threshold on this failure */ 14277ac6653aSJeff Kirsher if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { 14287ac6653aSJeff Kirsher tc += 64; 14297ac6653aSJeff Kirsher priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 14307ac6653aSJeff Kirsher priv->xstats.threshold = tc; 14317ac6653aSJeff Kirsher } 14327ac6653aSJeff Kirsher } else if (unlikely(status == tx_hard_error)) 14337ac6653aSJeff Kirsher stmmac_tx_err(priv); 14347ac6653aSJeff Kirsher } 14357ac6653aSJeff Kirsher 143632ceabcaSGiuseppe CAVALLARO /** 143732ceabcaSGiuseppe CAVALLARO * stmmac_mmc_setup: setup the Mac Management Counters (MMC) 143832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 143932ceabcaSGiuseppe CAVALLARO * Description: this masks the MMC irq, in fact, the counters are managed in SW. 144032ceabcaSGiuseppe CAVALLARO */ 14411c901a46SGiuseppe CAVALLARO static void stmmac_mmc_setup(struct stmmac_priv *priv) 14421c901a46SGiuseppe CAVALLARO { 14431c901a46SGiuseppe CAVALLARO unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | 14441c901a46SGiuseppe CAVALLARO MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; 14451c901a46SGiuseppe CAVALLARO 14461c901a46SGiuseppe CAVALLARO dwmac_mmc_intr_all_mask(priv->ioaddr); 14474f795b25SGiuseppe CAVALLARO 14484f795b25SGiuseppe CAVALLARO if (priv->dma_cap.rmon) { 14491c901a46SGiuseppe CAVALLARO dwmac_mmc_ctrl(priv->ioaddr, mode); 14501c901a46SGiuseppe CAVALLARO memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); 14514f795b25SGiuseppe CAVALLARO } else 1452aae54cffSStefan Roese pr_info(" No MAC Management Counters available\n"); 14531c901a46SGiuseppe CAVALLARO } 14541c901a46SGiuseppe CAVALLARO 1455f0b9d786SGiuseppe CAVALLARO static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) 1456f0b9d786SGiuseppe CAVALLARO { 1457f0b9d786SGiuseppe CAVALLARO u32 hwid = priv->hw->synopsys_uid; 1458f0b9d786SGiuseppe CAVALLARO 1459ceb69499SGiuseppe CAVALLARO /* Check Synopsys Id (not available on old chips) */ 1460f0b9d786SGiuseppe CAVALLARO if (likely(hwid)) { 1461f0b9d786SGiuseppe CAVALLARO u32 uid = ((hwid & 0x0000ff00) >> 8); 1462f0b9d786SGiuseppe CAVALLARO u32 synid = (hwid & 0x000000ff); 1463f0b9d786SGiuseppe CAVALLARO 1464cf3f047bSGiuseppe CAVALLARO pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", 1465f0b9d786SGiuseppe CAVALLARO uid, synid); 1466f0b9d786SGiuseppe CAVALLARO 1467f0b9d786SGiuseppe CAVALLARO return synid; 1468f0b9d786SGiuseppe CAVALLARO } 1469f0b9d786SGiuseppe CAVALLARO return 0; 1470f0b9d786SGiuseppe CAVALLARO } 1471e7434821SGiuseppe CAVALLARO 147219e30c14SGiuseppe CAVALLARO /** 147332ceabcaSGiuseppe CAVALLARO * stmmac_selec_desc_mode: to select among: normal/alternate/extend descriptors 147432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 147532ceabcaSGiuseppe CAVALLARO * Description: select the Enhanced/Alternate or Normal descriptors. 147632ceabcaSGiuseppe CAVALLARO * In case of Enhanced/Alternate, it looks at the extended descriptors are 147732ceabcaSGiuseppe CAVALLARO * supported by the HW cap. register. 1478ff3dd78cSGiuseppe CAVALLARO */ 147919e30c14SGiuseppe CAVALLARO static void stmmac_selec_desc_mode(struct stmmac_priv *priv) 148019e30c14SGiuseppe CAVALLARO { 148119e30c14SGiuseppe CAVALLARO if (priv->plat->enh_desc) { 148219e30c14SGiuseppe CAVALLARO pr_info(" Enhanced/Alternate descriptors\n"); 1483c24602efSGiuseppe CAVALLARO 1484c24602efSGiuseppe CAVALLARO /* GMAC older than 3.50 has no extended descriptors */ 1485c24602efSGiuseppe CAVALLARO if (priv->synopsys_id >= DWMAC_CORE_3_50) { 1486c24602efSGiuseppe CAVALLARO pr_info("\tEnabled extended descriptors\n"); 1487c24602efSGiuseppe CAVALLARO priv->extend_desc = 1; 1488c24602efSGiuseppe CAVALLARO } else 1489c24602efSGiuseppe CAVALLARO pr_warn("Extended descriptors not supported\n"); 1490c24602efSGiuseppe CAVALLARO 149119e30c14SGiuseppe CAVALLARO priv->hw->desc = &enh_desc_ops; 149219e30c14SGiuseppe CAVALLARO } else { 149319e30c14SGiuseppe CAVALLARO pr_info(" Normal descriptors\n"); 149419e30c14SGiuseppe CAVALLARO priv->hw->desc = &ndesc_ops; 149519e30c14SGiuseppe CAVALLARO } 149619e30c14SGiuseppe CAVALLARO } 149719e30c14SGiuseppe CAVALLARO 149819e30c14SGiuseppe CAVALLARO /** 149932ceabcaSGiuseppe CAVALLARO * stmmac_get_hw_features: get MAC capabilities from the HW cap. register. 150032ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 150119e30c14SGiuseppe CAVALLARO * Description: 150219e30c14SGiuseppe CAVALLARO * new GMAC chip generations have a new register to indicate the 1503e7434821SGiuseppe CAVALLARO * presence of the optional feature/functions. 150419e30c14SGiuseppe CAVALLARO * This can be also used to override the value passed through the 150519e30c14SGiuseppe CAVALLARO * platform and necessary for old MAC10/100 and GMAC chips. 1506e7434821SGiuseppe CAVALLARO */ 1507e7434821SGiuseppe CAVALLARO static int stmmac_get_hw_features(struct stmmac_priv *priv) 1508e7434821SGiuseppe CAVALLARO { 15095e6efe88SGiuseppe CAVALLARO u32 hw_cap = 0; 15103c20f72fSGiuseppe CAVALLARO 15115e6efe88SGiuseppe CAVALLARO if (priv->hw->dma->get_hw_feature) { 15125e6efe88SGiuseppe CAVALLARO hw_cap = priv->hw->dma->get_hw_feature(priv->ioaddr); 1513e7434821SGiuseppe CAVALLARO 15141db123fbSRayagond Kokatanur priv->dma_cap.mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); 15151db123fbSRayagond Kokatanur priv->dma_cap.mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; 15161db123fbSRayagond Kokatanur priv->dma_cap.half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; 15171db123fbSRayagond Kokatanur priv->dma_cap.hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4; 1518ceb69499SGiuseppe CAVALLARO priv->dma_cap.multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5; 15191db123fbSRayagond Kokatanur priv->dma_cap.pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6; 15201db123fbSRayagond Kokatanur priv->dma_cap.sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8; 15211db123fbSRayagond Kokatanur priv->dma_cap.pmt_remote_wake_up = 15221db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9; 15231db123fbSRayagond Kokatanur priv->dma_cap.pmt_magic_frame = 15241db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10; 15251db123fbSRayagond Kokatanur /* MMC */ 15261db123fbSRayagond Kokatanur priv->dma_cap.rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11; 1527e7434821SGiuseppe CAVALLARO /* IEEE 1588-2002 */ 15281db123fbSRayagond Kokatanur priv->dma_cap.time_stamp = 15291db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12; 1530e7434821SGiuseppe CAVALLARO /* IEEE 1588-2008 */ 15311db123fbSRayagond Kokatanur priv->dma_cap.atime_stamp = 15321db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13; 1533e7434821SGiuseppe CAVALLARO /* 802.3az - Energy-Efficient Ethernet (EEE) */ 15341db123fbSRayagond Kokatanur priv->dma_cap.eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14; 15351db123fbSRayagond Kokatanur priv->dma_cap.av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15; 1536e7434821SGiuseppe CAVALLARO /* TX and RX csum */ 15371db123fbSRayagond Kokatanur priv->dma_cap.tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16; 15381db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type1 = 15391db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17; 15401db123fbSRayagond Kokatanur priv->dma_cap.rx_coe_type2 = 15411db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18; 15421db123fbSRayagond Kokatanur priv->dma_cap.rxfifo_over_2048 = 15431db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19; 1544e7434821SGiuseppe CAVALLARO /* TX and RX number of channels */ 15451db123fbSRayagond Kokatanur priv->dma_cap.number_rx_channel = 15461db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20; 15471db123fbSRayagond Kokatanur priv->dma_cap.number_tx_channel = 15481db123fbSRayagond Kokatanur (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; 1549e7434821SGiuseppe CAVALLARO /* Alternate (enhanced) DESC mode */ 1550ceb69499SGiuseppe CAVALLARO priv->dma_cap.enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; 155119e30c14SGiuseppe CAVALLARO } 1552e7434821SGiuseppe CAVALLARO 1553e7434821SGiuseppe CAVALLARO return hw_cap; 1554e7434821SGiuseppe CAVALLARO } 1555e7434821SGiuseppe CAVALLARO 155632ceabcaSGiuseppe CAVALLARO /** 155732ceabcaSGiuseppe CAVALLARO * stmmac_check_ether_addr: check if the MAC addr is valid 155832ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 155932ceabcaSGiuseppe CAVALLARO * Description: 156032ceabcaSGiuseppe CAVALLARO * it is to verify if the MAC address is valid, in case of failures it 156132ceabcaSGiuseppe CAVALLARO * generates a random MAC address 156232ceabcaSGiuseppe CAVALLARO */ 1563bfab27a1SGiuseppe CAVALLARO static void stmmac_check_ether_addr(struct stmmac_priv *priv) 1564bfab27a1SGiuseppe CAVALLARO { 1565bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) { 15667ed24bbeSVince Bridgers priv->hw->mac->get_umac_addr(priv->hw, 1567bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr, 0); 1568bfab27a1SGiuseppe CAVALLARO if (!is_valid_ether_addr(priv->dev->dev_addr)) 1569f2cedb63SDanny Kukawka eth_hw_addr_random(priv->dev); 1570c88460b7SHans de Goede pr_info("%s: device MAC address %pM\n", priv->dev->name, 1571bfab27a1SGiuseppe CAVALLARO priv->dev->dev_addr); 1572bfab27a1SGiuseppe CAVALLARO } 1573c88460b7SHans de Goede } 1574bfab27a1SGiuseppe CAVALLARO 157532ceabcaSGiuseppe CAVALLARO /** 157632ceabcaSGiuseppe CAVALLARO * stmmac_init_dma_engine: DMA init. 157732ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 157832ceabcaSGiuseppe CAVALLARO * Description: 157932ceabcaSGiuseppe CAVALLARO * It inits the DMA invoking the specific MAC/GMAC callback. 158032ceabcaSGiuseppe CAVALLARO * Some DMA parameters can be passed from the platform; 158132ceabcaSGiuseppe CAVALLARO * in case of these are not passed a default is kept for the MAC or GMAC. 158232ceabcaSGiuseppe CAVALLARO */ 15830f1f88a8SGiuseppe CAVALLARO static int stmmac_init_dma_engine(struct stmmac_priv *priv) 15840f1f88a8SGiuseppe CAVALLARO { 15850f1f88a8SGiuseppe CAVALLARO int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0; 1586b9cde0a8SGiuseppe CAVALLARO int mixed_burst = 0; 1587c24602efSGiuseppe CAVALLARO int atds = 0; 15880f1f88a8SGiuseppe CAVALLARO 15890f1f88a8SGiuseppe CAVALLARO if (priv->plat->dma_cfg) { 15900f1f88a8SGiuseppe CAVALLARO pbl = priv->plat->dma_cfg->pbl; 15910f1f88a8SGiuseppe CAVALLARO fixed_burst = priv->plat->dma_cfg->fixed_burst; 1592b9cde0a8SGiuseppe CAVALLARO mixed_burst = priv->plat->dma_cfg->mixed_burst; 15930f1f88a8SGiuseppe CAVALLARO burst_len = priv->plat->dma_cfg->burst_len; 15940f1f88a8SGiuseppe CAVALLARO } 15950f1f88a8SGiuseppe CAVALLARO 1596c24602efSGiuseppe CAVALLARO if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE)) 1597c24602efSGiuseppe CAVALLARO atds = 1; 1598c24602efSGiuseppe CAVALLARO 1599b9cde0a8SGiuseppe CAVALLARO return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst, 16000f1f88a8SGiuseppe CAVALLARO burst_len, priv->dma_tx_phy, 1601c24602efSGiuseppe CAVALLARO priv->dma_rx_phy, atds); 16020f1f88a8SGiuseppe CAVALLARO } 16030f1f88a8SGiuseppe CAVALLARO 1604bfab27a1SGiuseppe CAVALLARO /** 160532ceabcaSGiuseppe CAVALLARO * stmmac_tx_timer: mitigation sw timer for tx. 16069125cdd1SGiuseppe CAVALLARO * @data: data pointer 16079125cdd1SGiuseppe CAVALLARO * Description: 16089125cdd1SGiuseppe CAVALLARO * This is the timer handler to directly invoke the stmmac_tx_clean. 16099125cdd1SGiuseppe CAVALLARO */ 16109125cdd1SGiuseppe CAVALLARO static void stmmac_tx_timer(unsigned long data) 16119125cdd1SGiuseppe CAVALLARO { 16129125cdd1SGiuseppe CAVALLARO struct stmmac_priv *priv = (struct stmmac_priv *)data; 16139125cdd1SGiuseppe CAVALLARO 16149125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 16159125cdd1SGiuseppe CAVALLARO } 16169125cdd1SGiuseppe CAVALLARO 16179125cdd1SGiuseppe CAVALLARO /** 161832ceabcaSGiuseppe CAVALLARO * stmmac_init_tx_coalesce: init tx mitigation options. 161932ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 16209125cdd1SGiuseppe CAVALLARO * Description: 16219125cdd1SGiuseppe CAVALLARO * This inits the transmit coalesce parameters: i.e. timer rate, 16229125cdd1SGiuseppe CAVALLARO * timer handler and default threshold used for enabling the 16239125cdd1SGiuseppe CAVALLARO * interrupt on completion bit. 16249125cdd1SGiuseppe CAVALLARO */ 16259125cdd1SGiuseppe CAVALLARO static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) 16269125cdd1SGiuseppe CAVALLARO { 16279125cdd1SGiuseppe CAVALLARO priv->tx_coal_frames = STMMAC_TX_FRAMES; 16289125cdd1SGiuseppe CAVALLARO priv->tx_coal_timer = STMMAC_COAL_TX_TIMER; 16299125cdd1SGiuseppe CAVALLARO init_timer(&priv->txtimer); 16309125cdd1SGiuseppe CAVALLARO priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer); 16319125cdd1SGiuseppe CAVALLARO priv->txtimer.data = (unsigned long)priv; 16329125cdd1SGiuseppe CAVALLARO priv->txtimer.function = stmmac_tx_timer; 16339125cdd1SGiuseppe CAVALLARO add_timer(&priv->txtimer); 16349125cdd1SGiuseppe CAVALLARO } 16359125cdd1SGiuseppe CAVALLARO 16369125cdd1SGiuseppe CAVALLARO /** 1637523f11b5SSrinivas Kandagatla * stmmac_hw_setup: setup mac in a usable state. 1638523f11b5SSrinivas Kandagatla * @dev : pointer to the device structure. 1639523f11b5SSrinivas Kandagatla * Description: 1640523f11b5SSrinivas Kandagatla * This function sets up the ip in a usable state. 1641523f11b5SSrinivas Kandagatla * Return value: 1642523f11b5SSrinivas Kandagatla * 0 on success and an appropriate (-)ve integer as defined in errno.h 1643523f11b5SSrinivas Kandagatla * file on failure. 1644523f11b5SSrinivas Kandagatla */ 1645523f11b5SSrinivas Kandagatla static int stmmac_hw_setup(struct net_device *dev) 1646523f11b5SSrinivas Kandagatla { 1647523f11b5SSrinivas Kandagatla struct stmmac_priv *priv = netdev_priv(dev); 1648523f11b5SSrinivas Kandagatla int ret; 1649523f11b5SSrinivas Kandagatla 1650523f11b5SSrinivas Kandagatla ret = init_dma_desc_rings(dev); 1651523f11b5SSrinivas Kandagatla if (ret < 0) { 1652523f11b5SSrinivas Kandagatla pr_err("%s: DMA descriptors initialization failed\n", __func__); 1653523f11b5SSrinivas Kandagatla return ret; 1654523f11b5SSrinivas Kandagatla } 1655523f11b5SSrinivas Kandagatla /* DMA initialization and SW reset */ 1656523f11b5SSrinivas Kandagatla ret = stmmac_init_dma_engine(priv); 1657523f11b5SSrinivas Kandagatla if (ret < 0) { 1658523f11b5SSrinivas Kandagatla pr_err("%s: DMA engine initialization failed\n", __func__); 1659523f11b5SSrinivas Kandagatla return ret; 1660523f11b5SSrinivas Kandagatla } 1661523f11b5SSrinivas Kandagatla 1662523f11b5SSrinivas Kandagatla /* Copy the MAC addr into the HW */ 16637ed24bbeSVince Bridgers priv->hw->mac->set_umac_addr(priv->hw, dev->dev_addr, 0); 1664523f11b5SSrinivas Kandagatla 1665523f11b5SSrinivas Kandagatla /* If required, perform hw setup of the bus. */ 1666523f11b5SSrinivas Kandagatla if (priv->plat->bus_setup) 1667523f11b5SSrinivas Kandagatla priv->plat->bus_setup(priv->ioaddr); 1668523f11b5SSrinivas Kandagatla 1669523f11b5SSrinivas Kandagatla /* Initialize the MAC Core */ 16707ed24bbeSVince Bridgers priv->hw->mac->core_init(priv->hw, dev->mtu); 1671523f11b5SSrinivas Kandagatla 1672978aded4SGiuseppe CAVALLARO ret = priv->hw->mac->rx_ipc(priv->hw); 1673978aded4SGiuseppe CAVALLARO if (!ret) { 1674978aded4SGiuseppe CAVALLARO pr_warn(" RX IPC Checksum Offload disabled\n"); 1675978aded4SGiuseppe CAVALLARO priv->plat->rx_coe = STMMAC_RX_COE_NONE; 1676d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = 0; 1677978aded4SGiuseppe CAVALLARO } 1678978aded4SGiuseppe CAVALLARO 1679523f11b5SSrinivas Kandagatla /* Enable the MAC Rx/Tx */ 1680523f11b5SSrinivas Kandagatla stmmac_set_mac(priv->ioaddr, true); 1681523f11b5SSrinivas Kandagatla 1682523f11b5SSrinivas Kandagatla /* Set the HW DMA mode and the COE */ 1683523f11b5SSrinivas Kandagatla stmmac_dma_operation_mode(priv); 1684523f11b5SSrinivas Kandagatla 1685523f11b5SSrinivas Kandagatla stmmac_mmc_setup(priv); 1686523f11b5SSrinivas Kandagatla 1687523f11b5SSrinivas Kandagatla ret = stmmac_init_ptp(priv); 16887509edd6SHans de Goede if (ret && ret != -EOPNOTSUPP) 1689523f11b5SSrinivas Kandagatla pr_warn("%s: failed PTP initialisation\n", __func__); 1690523f11b5SSrinivas Kandagatla 1691523f11b5SSrinivas Kandagatla #ifdef CONFIG_STMMAC_DEBUG_FS 1692523f11b5SSrinivas Kandagatla ret = stmmac_init_fs(dev); 1693523f11b5SSrinivas Kandagatla if (ret < 0) 1694523f11b5SSrinivas Kandagatla pr_warn("%s: failed debugFS registration\n", __func__); 1695523f11b5SSrinivas Kandagatla #endif 1696523f11b5SSrinivas Kandagatla /* Start the ball rolling... */ 1697523f11b5SSrinivas Kandagatla pr_debug("%s: DMA RX/TX processes started...\n", dev->name); 1698523f11b5SSrinivas Kandagatla priv->hw->dma->start_tx(priv->ioaddr); 1699523f11b5SSrinivas Kandagatla priv->hw->dma->start_rx(priv->ioaddr); 1700523f11b5SSrinivas Kandagatla 1701523f11b5SSrinivas Kandagatla /* Dump DMA/MAC registers */ 1702523f11b5SSrinivas Kandagatla if (netif_msg_hw(priv)) { 17037ed24bbeSVince Bridgers priv->hw->mac->dump_regs(priv->hw); 1704523f11b5SSrinivas Kandagatla priv->hw->dma->dump_regs(priv->ioaddr); 1705523f11b5SSrinivas Kandagatla } 1706523f11b5SSrinivas Kandagatla priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; 1707523f11b5SSrinivas Kandagatla 1708523f11b5SSrinivas Kandagatla priv->eee_enabled = stmmac_eee_init(priv); 1709523f11b5SSrinivas Kandagatla 1710523f11b5SSrinivas Kandagatla stmmac_init_tx_coalesce(priv); 1711523f11b5SSrinivas Kandagatla 1712523f11b5SSrinivas Kandagatla if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { 1713523f11b5SSrinivas Kandagatla priv->rx_riwt = MAX_DMA_RIWT; 1714523f11b5SSrinivas Kandagatla priv->hw->dma->rx_watchdog(priv->ioaddr, MAX_DMA_RIWT); 1715523f11b5SSrinivas Kandagatla } 1716523f11b5SSrinivas Kandagatla 1717523f11b5SSrinivas Kandagatla if (priv->pcs && priv->hw->mac->ctrl_ane) 17187ed24bbeSVince Bridgers priv->hw->mac->ctrl_ane(priv->hw, 0); 1719523f11b5SSrinivas Kandagatla 1720523f11b5SSrinivas Kandagatla return 0; 1721523f11b5SSrinivas Kandagatla } 1722523f11b5SSrinivas Kandagatla 1723523f11b5SSrinivas Kandagatla /** 17247ac6653aSJeff Kirsher * stmmac_open - open entry point of the driver 17257ac6653aSJeff Kirsher * @dev : pointer to the device structure. 17267ac6653aSJeff Kirsher * Description: 17277ac6653aSJeff Kirsher * This function is the open entry point of the driver. 17287ac6653aSJeff Kirsher * Return value: 17297ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 17307ac6653aSJeff Kirsher * file on failure. 17317ac6653aSJeff Kirsher */ 17327ac6653aSJeff Kirsher static int stmmac_open(struct net_device *dev) 17337ac6653aSJeff Kirsher { 17347ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 17357ac6653aSJeff Kirsher int ret; 17367ac6653aSJeff Kirsher 17374bfcbd7aSFrancesco Virlinzi stmmac_check_ether_addr(priv); 17384bfcbd7aSFrancesco Virlinzi 17394d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 17404d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 17417ac6653aSJeff Kirsher ret = stmmac_init_phy(dev); 1742e58bb43fSGiuseppe CAVALLARO if (ret) { 1743e58bb43fSGiuseppe CAVALLARO pr_err("%s: Cannot attach to PHY (error: %d)\n", 1744e58bb43fSGiuseppe CAVALLARO __func__, ret); 174589df20d9SHans de Goede return ret; 17467ac6653aSJeff Kirsher } 1747e58bb43fSGiuseppe CAVALLARO } 17487ac6653aSJeff Kirsher 1749523f11b5SSrinivas Kandagatla /* Extra statistics */ 1750523f11b5SSrinivas Kandagatla memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 1751523f11b5SSrinivas Kandagatla priv->xstats.threshold = tc; 1752523f11b5SSrinivas Kandagatla 17537ac6653aSJeff Kirsher /* Create and initialize the TX/RX descriptors chains. */ 17547ac6653aSJeff Kirsher priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); 17557ac6653aSJeff Kirsher priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); 17567ac6653aSJeff Kirsher priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); 175756329137SBartlomiej Zolnierkiewicz 17587262b7b2STobias Klauser ret = alloc_dma_desc_resources(priv); 175909f8d696SSrinivas Kandagatla if (ret < 0) { 176009f8d696SSrinivas Kandagatla pr_err("%s: DMA descriptors allocation failed\n", __func__); 176109f8d696SSrinivas Kandagatla goto dma_desc_error; 176209f8d696SSrinivas Kandagatla } 176309f8d696SSrinivas Kandagatla 1764523f11b5SSrinivas Kandagatla ret = stmmac_hw_setup(dev); 176556329137SBartlomiej Zolnierkiewicz if (ret < 0) { 1766523f11b5SSrinivas Kandagatla pr_err("%s: Hw setup failed\n", __func__); 1767c9324d18SGiuseppe CAVALLARO goto init_error; 17687ac6653aSJeff Kirsher } 17697ac6653aSJeff Kirsher 1770523f11b5SSrinivas Kandagatla if (priv->phydev) 1771523f11b5SSrinivas Kandagatla phy_start(priv->phydev); 17727ac6653aSJeff Kirsher 17737ac6653aSJeff Kirsher /* Request the IRQ lines */ 17747ac6653aSJeff Kirsher ret = request_irq(dev->irq, stmmac_interrupt, 17757ac6653aSJeff Kirsher IRQF_SHARED, dev->name, dev); 17767ac6653aSJeff Kirsher if (unlikely(ret < 0)) { 17777ac6653aSJeff Kirsher pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", 17787ac6653aSJeff Kirsher __func__, dev->irq, ret); 1779c9324d18SGiuseppe CAVALLARO goto init_error; 17807ac6653aSJeff Kirsher } 17817ac6653aSJeff Kirsher 17827a13f8f5SFrancesco Virlinzi /* Request the Wake IRQ in case of another line is used for WoL */ 17837a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) { 17847a13f8f5SFrancesco Virlinzi ret = request_irq(priv->wol_irq, stmmac_interrupt, 17857a13f8f5SFrancesco Virlinzi IRQF_SHARED, dev->name, dev); 17867a13f8f5SFrancesco Virlinzi if (unlikely(ret < 0)) { 1787ceb69499SGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the WoL IRQ %d (%d)\n", 1788ceb69499SGiuseppe CAVALLARO __func__, priv->wol_irq, ret); 1789c9324d18SGiuseppe CAVALLARO goto wolirq_error; 17907a13f8f5SFrancesco Virlinzi } 17917a13f8f5SFrancesco Virlinzi } 17927a13f8f5SFrancesco Virlinzi 1793d765955dSGiuseppe CAVALLARO /* Request the IRQ lines */ 1794d7ec8584SChen-Yu Tsai if (priv->lpi_irq > 0) { 1795d765955dSGiuseppe CAVALLARO ret = request_irq(priv->lpi_irq, stmmac_interrupt, IRQF_SHARED, 1796d765955dSGiuseppe CAVALLARO dev->name, dev); 1797d765955dSGiuseppe CAVALLARO if (unlikely(ret < 0)) { 1798d765955dSGiuseppe CAVALLARO pr_err("%s: ERROR: allocating the LPI IRQ %d (%d)\n", 1799d765955dSGiuseppe CAVALLARO __func__, priv->lpi_irq, ret); 1800c9324d18SGiuseppe CAVALLARO goto lpiirq_error; 1801d765955dSGiuseppe CAVALLARO } 1802d765955dSGiuseppe CAVALLARO } 1803d765955dSGiuseppe CAVALLARO 18047ac6653aSJeff Kirsher napi_enable(&priv->napi); 18057ac6653aSJeff Kirsher netif_start_queue(dev); 18067ac6653aSJeff Kirsher 18077ac6653aSJeff Kirsher return 0; 18087ac6653aSJeff Kirsher 1809c9324d18SGiuseppe CAVALLARO lpiirq_error: 1810d765955dSGiuseppe CAVALLARO if (priv->wol_irq != dev->irq) 1811d765955dSGiuseppe CAVALLARO free_irq(priv->wol_irq, dev); 1812c9324d18SGiuseppe CAVALLARO wolirq_error: 18137a13f8f5SFrancesco Virlinzi free_irq(dev->irq, dev); 18147a13f8f5SFrancesco Virlinzi 1815c9324d18SGiuseppe CAVALLARO init_error: 1816c9324d18SGiuseppe CAVALLARO free_dma_desc_resources(priv); 181756329137SBartlomiej Zolnierkiewicz dma_desc_error: 18187ac6653aSJeff Kirsher if (priv->phydev) 18197ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 18204bfcbd7aSFrancesco Virlinzi 18217ac6653aSJeff Kirsher return ret; 18227ac6653aSJeff Kirsher } 18237ac6653aSJeff Kirsher 18247ac6653aSJeff Kirsher /** 18257ac6653aSJeff Kirsher * stmmac_release - close entry point of the driver 18267ac6653aSJeff Kirsher * @dev : device pointer. 18277ac6653aSJeff Kirsher * Description: 18287ac6653aSJeff Kirsher * This is the stop entry point of the driver. 18297ac6653aSJeff Kirsher */ 18307ac6653aSJeff Kirsher static int stmmac_release(struct net_device *dev) 18317ac6653aSJeff Kirsher { 18327ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 18337ac6653aSJeff Kirsher 1834d765955dSGiuseppe CAVALLARO if (priv->eee_enabled) 1835d765955dSGiuseppe CAVALLARO del_timer_sync(&priv->eee_ctrl_timer); 1836d765955dSGiuseppe CAVALLARO 18377ac6653aSJeff Kirsher /* Stop and disconnect the PHY */ 18387ac6653aSJeff Kirsher if (priv->phydev) { 18397ac6653aSJeff Kirsher phy_stop(priv->phydev); 18407ac6653aSJeff Kirsher phy_disconnect(priv->phydev); 18417ac6653aSJeff Kirsher priv->phydev = NULL; 18427ac6653aSJeff Kirsher } 18437ac6653aSJeff Kirsher 18447ac6653aSJeff Kirsher netif_stop_queue(dev); 18457ac6653aSJeff Kirsher 18467ac6653aSJeff Kirsher napi_disable(&priv->napi); 18477ac6653aSJeff Kirsher 18489125cdd1SGiuseppe CAVALLARO del_timer_sync(&priv->txtimer); 18499125cdd1SGiuseppe CAVALLARO 18507ac6653aSJeff Kirsher /* Free the IRQ lines */ 18517ac6653aSJeff Kirsher free_irq(dev->irq, dev); 18527a13f8f5SFrancesco Virlinzi if (priv->wol_irq != dev->irq) 18537a13f8f5SFrancesco Virlinzi free_irq(priv->wol_irq, dev); 1854d7ec8584SChen-Yu Tsai if (priv->lpi_irq > 0) 1855d765955dSGiuseppe CAVALLARO free_irq(priv->lpi_irq, dev); 18567ac6653aSJeff Kirsher 18577ac6653aSJeff Kirsher /* Stop TX/RX DMA and clear the descriptors */ 18587ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 18597ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 18607ac6653aSJeff Kirsher 18617ac6653aSJeff Kirsher /* Release and free the Rx/Tx resources */ 18627ac6653aSJeff Kirsher free_dma_desc_resources(priv); 18637ac6653aSJeff Kirsher 18647ac6653aSJeff Kirsher /* Disable the MAC Rx/Tx */ 1865bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 18667ac6653aSJeff Kirsher 18677ac6653aSJeff Kirsher netif_carrier_off(dev); 18687ac6653aSJeff Kirsher 1869bfab27a1SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 1870bfab27a1SGiuseppe CAVALLARO stmmac_exit_fs(); 1871bfab27a1SGiuseppe CAVALLARO #endif 1872bfab27a1SGiuseppe CAVALLARO 187392ba6888SRayagond Kokatanur stmmac_release_ptp(priv); 187492ba6888SRayagond Kokatanur 18757ac6653aSJeff Kirsher return 0; 18767ac6653aSJeff Kirsher } 18777ac6653aSJeff Kirsher 18787ac6653aSJeff Kirsher /** 187932ceabcaSGiuseppe CAVALLARO * stmmac_xmit: Tx entry point of the driver 18807ac6653aSJeff Kirsher * @skb : the socket buffer 18817ac6653aSJeff Kirsher * @dev : device pointer 188232ceabcaSGiuseppe CAVALLARO * Description : this is the tx entry point of the driver. 188332ceabcaSGiuseppe CAVALLARO * It programs the chain or the ring and supports oversized frames 188432ceabcaSGiuseppe CAVALLARO * and SG feature. 18857ac6653aSJeff Kirsher */ 18867ac6653aSJeff Kirsher static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) 18877ac6653aSJeff Kirsher { 18887ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 18897ac6653aSJeff Kirsher unsigned int txsize = priv->dma_tx_size; 18907ac6653aSJeff Kirsher unsigned int entry; 18914a7d666aSGiuseppe CAVALLARO int i, csum_insertion = 0, is_jumbo = 0; 18927ac6653aSJeff Kirsher int nfrags = skb_shinfo(skb)->nr_frags; 18937ac6653aSJeff Kirsher struct dma_desc *desc, *first; 1894286a8372SGiuseppe CAVALLARO unsigned int nopaged_len = skb_headlen(skb); 189529896a67SGiuseppe CAVALLARO unsigned int enh_desc = priv->plat->enh_desc; 18967ac6653aSJeff Kirsher 189716ee817eSFabrice Gasnier spin_lock(&priv->tx_lock); 189816ee817eSFabrice Gasnier 18997ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 190016ee817eSFabrice Gasnier spin_unlock(&priv->tx_lock); 19017ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 19027ac6653aSJeff Kirsher netif_stop_queue(dev); 19037ac6653aSJeff Kirsher /* This is a hard error, log it. */ 1904ceb69499SGiuseppe CAVALLARO pr_err("%s: Tx Ring full when queue awake\n", __func__); 19057ac6653aSJeff Kirsher } 19067ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 19077ac6653aSJeff Kirsher } 19087ac6653aSJeff Kirsher 1909d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1910d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1911d765955dSGiuseppe CAVALLARO 19127ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 19137ac6653aSJeff Kirsher 19147ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 19157ac6653aSJeff Kirsher 1916c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1917c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1918c24602efSGiuseppe CAVALLARO else 19197ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 1920c24602efSGiuseppe CAVALLARO 19217ac6653aSJeff Kirsher first = desc; 19227ac6653aSJeff Kirsher 19234a7d666aSGiuseppe CAVALLARO /* To program the descriptors according to the size of the frame */ 192429896a67SGiuseppe CAVALLARO if (enh_desc) 192529896a67SGiuseppe CAVALLARO is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc); 192629896a67SGiuseppe CAVALLARO 19274a7d666aSGiuseppe CAVALLARO if (likely(!is_jumbo)) { 19287ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 19297ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 1930362b37beSGiuseppe CAVALLARO if (dma_mapping_error(priv->device, desc->des2)) 1931362b37beSGiuseppe CAVALLARO goto dma_map_err; 1932362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf = desc->des2; 19337ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 19344a7d666aSGiuseppe CAVALLARO csum_insertion, priv->mode); 193529896a67SGiuseppe CAVALLARO } else { 1936c24602efSGiuseppe CAVALLARO desc = first; 193729896a67SGiuseppe CAVALLARO entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); 1938362b37beSGiuseppe CAVALLARO if (unlikely(entry < 0)) 1939362b37beSGiuseppe CAVALLARO goto dma_map_err; 194029896a67SGiuseppe CAVALLARO } 19417ac6653aSJeff Kirsher 19427ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 19439e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 19449e903e08SEric Dumazet int len = skb_frag_size(frag); 19457ac6653aSJeff Kirsher 194675e4364fSdamuzi000 priv->tx_skbuff[entry] = NULL; 19477ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 1948c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1949c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1950c24602efSGiuseppe CAVALLARO else 19517ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 19527ac6653aSJeff Kirsher 1953f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1954f722380dSIan Campbell DMA_TO_DEVICE); 1955362b37beSGiuseppe CAVALLARO if (dma_mapping_error(priv->device, desc->des2)) 1956362b37beSGiuseppe CAVALLARO goto dma_map_err; /* should reuse desc w/o issues */ 1957362b37beSGiuseppe CAVALLARO 1958362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf = desc->des2; 1959362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].map_as_page = true; 19604a7d666aSGiuseppe CAVALLARO priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, 19614a7d666aSGiuseppe CAVALLARO priv->mode); 19627ac6653aSJeff Kirsher wmb(); 19637ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 19648e839891SDeepak Sikri wmb(); 19657ac6653aSJeff Kirsher } 19667ac6653aSJeff Kirsher 196775e4364fSdamuzi000 priv->tx_skbuff[entry] = skb; 196875e4364fSdamuzi000 19699125cdd1SGiuseppe CAVALLARO /* Finalize the latest segment. */ 19707ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 19717ac6653aSJeff Kirsher 19727ac6653aSJeff Kirsher wmb(); 19739125cdd1SGiuseppe CAVALLARO /* According to the coalesce parameter the IC bit for the latest 19749125cdd1SGiuseppe CAVALLARO * segment could be reset and the timer re-started to invoke the 19759125cdd1SGiuseppe CAVALLARO * stmmac_tx function. This approach takes care about the fragments. 19769125cdd1SGiuseppe CAVALLARO */ 19779125cdd1SGiuseppe CAVALLARO priv->tx_count_frames += nfrags + 1; 19789125cdd1SGiuseppe CAVALLARO if (priv->tx_coal_frames > priv->tx_count_frames) { 19799125cdd1SGiuseppe CAVALLARO priv->hw->desc->clear_tx_ic(desc); 19809125cdd1SGiuseppe CAVALLARO priv->xstats.tx_reset_ic_bit++; 19819125cdd1SGiuseppe CAVALLARO mod_timer(&priv->txtimer, 19829125cdd1SGiuseppe CAVALLARO STMMAC_COAL_TIMER(priv->tx_coal_timer)); 19839125cdd1SGiuseppe CAVALLARO } else 19849125cdd1SGiuseppe CAVALLARO priv->tx_count_frames = 0; 19857ac6653aSJeff Kirsher 19867ac6653aSJeff Kirsher /* To avoid raise condition */ 19877ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 19888e839891SDeepak Sikri wmb(); 19897ac6653aSJeff Kirsher 19907ac6653aSJeff Kirsher priv->cur_tx++; 19917ac6653aSJeff Kirsher 19927ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 199383d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", 1994ceb69499SGiuseppe CAVALLARO __func__, (priv->cur_tx % txsize), 1995ceb69499SGiuseppe CAVALLARO (priv->dirty_tx % txsize), entry, first, nfrags); 199683d7af64SGiuseppe CAVALLARO 1997c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1998c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 1999c24602efSGiuseppe CAVALLARO else 2000c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 2001c24602efSGiuseppe CAVALLARO 200283d7af64SGiuseppe CAVALLARO pr_debug(">>> frame to be transmitted: "); 20037ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 20047ac6653aSJeff Kirsher } 20057ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 200683d7af64SGiuseppe CAVALLARO if (netif_msg_hw(priv)) 200783d7af64SGiuseppe CAVALLARO pr_debug("%s: stop transmitted packets\n", __func__); 20087ac6653aSJeff Kirsher netif_stop_queue(dev); 20097ac6653aSJeff Kirsher } 20107ac6653aSJeff Kirsher 20117ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 20127ac6653aSJeff Kirsher 2013891434b1SRayagond Kokatanur if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && 2014891434b1SRayagond Kokatanur priv->hwts_tx_en)) { 2015891434b1SRayagond Kokatanur /* declare that device is doing timestamping */ 2016891434b1SRayagond Kokatanur skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 2017891434b1SRayagond Kokatanur priv->hw->desc->enable_tx_timestamp(first); 2018891434b1SRayagond Kokatanur } 2019891434b1SRayagond Kokatanur 2020891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 20217ac6653aSJeff Kirsher skb_tx_timestamp(skb); 20227ac6653aSJeff Kirsher 20237ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 20247ac6653aSJeff Kirsher 2025a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 2026362b37beSGiuseppe CAVALLARO return NETDEV_TX_OK; 2027a9097a96SGiuseppe CAVALLARO 2028362b37beSGiuseppe CAVALLARO dma_map_err: 2029758a0ab5SFabrice Gasnier spin_unlock(&priv->tx_lock); 2030362b37beSGiuseppe CAVALLARO dev_err(priv->device, "Tx dma map failed\n"); 2031362b37beSGiuseppe CAVALLARO dev_kfree_skb(skb); 2032362b37beSGiuseppe CAVALLARO priv->dev->stats.tx_dropped++; 20337ac6653aSJeff Kirsher return NETDEV_TX_OK; 20347ac6653aSJeff Kirsher } 20357ac6653aSJeff Kirsher 2036b9381985SVince Bridgers static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) 2037b9381985SVince Bridgers { 2038b9381985SVince Bridgers struct ethhdr *ehdr; 2039b9381985SVince Bridgers u16 vlanid; 2040b9381985SVince Bridgers 2041b9381985SVince Bridgers if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) == 2042b9381985SVince Bridgers NETIF_F_HW_VLAN_CTAG_RX && 2043b9381985SVince Bridgers !__vlan_get_tag(skb, &vlanid)) { 2044b9381985SVince Bridgers /* pop the vlan tag */ 2045b9381985SVince Bridgers ehdr = (struct ethhdr *)skb->data; 2046b9381985SVince Bridgers memmove(skb->data + VLAN_HLEN, ehdr, ETH_ALEN * 2); 2047b9381985SVince Bridgers skb_pull(skb, VLAN_HLEN); 2048b9381985SVince Bridgers __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlanid); 2049b9381985SVince Bridgers } 2050b9381985SVince Bridgers } 2051b9381985SVince Bridgers 2052b9381985SVince Bridgers 205332ceabcaSGiuseppe CAVALLARO /** 205432ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 205532ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 205632ceabcaSGiuseppe CAVALLARO * Description : this is to reallocate the skb for the reception process 205732ceabcaSGiuseppe CAVALLARO * that is based on zero-copy. 205832ceabcaSGiuseppe CAVALLARO */ 20597ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 20607ac6653aSJeff Kirsher { 20617ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20627ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 20637ac6653aSJeff Kirsher 20647ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 20657ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 2066c24602efSGiuseppe CAVALLARO struct dma_desc *p; 2067c24602efSGiuseppe CAVALLARO 2068c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2069c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2070c24602efSGiuseppe CAVALLARO else 2071c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2072c24602efSGiuseppe CAVALLARO 20737ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 20747ac6653aSJeff Kirsher struct sk_buff *skb; 20757ac6653aSJeff Kirsher 2076acb600deSEric Dumazet skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); 20777ac6653aSJeff Kirsher 20787ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 20797ac6653aSJeff Kirsher break; 20807ac6653aSJeff Kirsher 20817ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 20827ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 20837ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 20847ac6653aSJeff Kirsher DMA_FROM_DEVICE); 2085362b37beSGiuseppe CAVALLARO if (dma_mapping_error(priv->device, 2086362b37beSGiuseppe CAVALLARO priv->rx_skbuff_dma[entry])) { 2087362b37beSGiuseppe CAVALLARO dev_err(priv->device, "Rx dma map failed\n"); 2088362b37beSGiuseppe CAVALLARO dev_kfree_skb(skb); 2089362b37beSGiuseppe CAVALLARO break; 2090362b37beSGiuseppe CAVALLARO } 2091c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[entry]; 2092286a8372SGiuseppe CAVALLARO 209329896a67SGiuseppe CAVALLARO priv->hw->mode->refill_desc3(priv, p); 2094286a8372SGiuseppe CAVALLARO 209583d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) 209683d7af64SGiuseppe CAVALLARO pr_debug("\trefill entry #%d\n", entry); 20977ac6653aSJeff Kirsher } 20987ac6653aSJeff Kirsher wmb(); 2099c24602efSGiuseppe CAVALLARO priv->hw->desc->set_rx_owner(p); 21008e839891SDeepak Sikri wmb(); 21017ac6653aSJeff Kirsher } 21027ac6653aSJeff Kirsher } 21037ac6653aSJeff Kirsher 210432ceabcaSGiuseppe CAVALLARO /** 210532ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 210632ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 210732ceabcaSGiuseppe CAVALLARO * @limit: napi bugget. 210832ceabcaSGiuseppe CAVALLARO * Description : this the function called by the napi poll method. 210932ceabcaSGiuseppe CAVALLARO * It gets all the frames inside the ring. 211032ceabcaSGiuseppe CAVALLARO */ 21117ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 21127ac6653aSJeff Kirsher { 21137ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 21147ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 21157ac6653aSJeff Kirsher unsigned int next_entry; 21167ac6653aSJeff Kirsher unsigned int count = 0; 2117d2afb5bdSGiuseppe CAVALLARO int coe = priv->hw->rx_csum; 21187ac6653aSJeff Kirsher 211983d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 212083d7af64SGiuseppe CAVALLARO pr_debug("%s: descriptor ring:\n", __func__); 2121c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2122c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 2123c24602efSGiuseppe CAVALLARO else 2124c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 21257ac6653aSJeff Kirsher } 2126c24602efSGiuseppe CAVALLARO while (count < limit) { 21277ac6653aSJeff Kirsher int status; 21289401bb5cSGiuseppe CAVALLARO struct dma_desc *p; 21297ac6653aSJeff Kirsher 2130c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2131c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2132c24602efSGiuseppe CAVALLARO else 2133c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2134c24602efSGiuseppe CAVALLARO 2135c24602efSGiuseppe CAVALLARO if (priv->hw->desc->get_rx_owner(p)) 21367ac6653aSJeff Kirsher break; 21377ac6653aSJeff Kirsher 21387ac6653aSJeff Kirsher count++; 21397ac6653aSJeff Kirsher 21407ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 2141c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 21429401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_erx + next_entry); 2143c24602efSGiuseppe CAVALLARO else 21449401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_rx + next_entry); 21457ac6653aSJeff Kirsher 21467ac6653aSJeff Kirsher /* read the status of the incoming frame */ 2147c24602efSGiuseppe CAVALLARO status = priv->hw->desc->rx_status(&priv->dev->stats, 2148c24602efSGiuseppe CAVALLARO &priv->xstats, p); 2149c24602efSGiuseppe CAVALLARO if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status)) 2150c24602efSGiuseppe CAVALLARO priv->hw->desc->rx_extended_status(&priv->dev->stats, 2151c24602efSGiuseppe CAVALLARO &priv->xstats, 2152c24602efSGiuseppe CAVALLARO priv->dma_erx + 2153c24602efSGiuseppe CAVALLARO entry); 2154891434b1SRayagond Kokatanur if (unlikely(status == discard_frame)) { 21557ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 2156891434b1SRayagond Kokatanur if (priv->hwts_rx_en && !priv->extend_desc) { 2157891434b1SRayagond Kokatanur /* DESC2 & DESC3 will be overwitten by device 2158891434b1SRayagond Kokatanur * with timestamp value, hence reinitialize 2159891434b1SRayagond Kokatanur * them in stmmac_rx_refill() function so that 2160891434b1SRayagond Kokatanur * device can reuse it. 2161891434b1SRayagond Kokatanur */ 2162891434b1SRayagond Kokatanur priv->rx_skbuff[entry] = NULL; 2163891434b1SRayagond Kokatanur dma_unmap_single(priv->device, 2164891434b1SRayagond Kokatanur priv->rx_skbuff_dma[entry], 2165ceb69499SGiuseppe CAVALLARO priv->dma_buf_sz, 2166ceb69499SGiuseppe CAVALLARO DMA_FROM_DEVICE); 2167891434b1SRayagond Kokatanur } 2168891434b1SRayagond Kokatanur } else { 21697ac6653aSJeff Kirsher struct sk_buff *skb; 21707ac6653aSJeff Kirsher int frame_len; 21717ac6653aSJeff Kirsher 2172ceb69499SGiuseppe CAVALLARO frame_len = priv->hw->desc->get_rx_frame_len(p, coe); 2173ceb69499SGiuseppe CAVALLARO 21747ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 2175ceb69499SGiuseppe CAVALLARO * Type frames (LLC/LLC-SNAP) 2176ceb69499SGiuseppe CAVALLARO */ 21777ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 21787ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 21797ac6653aSJeff Kirsher 218083d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 21817ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 21827ac6653aSJeff Kirsher p, entry, p->des2); 218383d7af64SGiuseppe CAVALLARO if (frame_len > ETH_FRAME_LEN) 218483d7af64SGiuseppe CAVALLARO pr_debug("\tframe size %d, COE: %d\n", 218583d7af64SGiuseppe CAVALLARO frame_len, status); 218683d7af64SGiuseppe CAVALLARO } 21877ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 21887ac6653aSJeff Kirsher if (unlikely(!skb)) { 21897ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 21907ac6653aSJeff Kirsher priv->dev->name); 21917ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 21927ac6653aSJeff Kirsher break; 21937ac6653aSJeff Kirsher } 21947ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 21957ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 21967ac6653aSJeff Kirsher 2197891434b1SRayagond Kokatanur stmmac_get_rx_hwtstamp(priv, entry, skb); 2198891434b1SRayagond Kokatanur 21997ac6653aSJeff Kirsher skb_put(skb, frame_len); 22007ac6653aSJeff Kirsher dma_unmap_single(priv->device, 22017ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 22027ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 220383d7af64SGiuseppe CAVALLARO 22047ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 220583d7af64SGiuseppe CAVALLARO pr_debug("frame received (%dbytes)", frame_len); 22067ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 22077ac6653aSJeff Kirsher } 220883d7af64SGiuseppe CAVALLARO 2209b9381985SVince Bridgers stmmac_rx_vlan(priv->dev, skb); 2210b9381985SVince Bridgers 22117ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 22127ac6653aSJeff Kirsher 2213ceb69499SGiuseppe CAVALLARO if (unlikely(!coe)) 22147ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 221562a2ab93SGiuseppe CAVALLARO else 22167ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 221762a2ab93SGiuseppe CAVALLARO 22187ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 22197ac6653aSJeff Kirsher 22207ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 22217ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 22227ac6653aSJeff Kirsher } 22237ac6653aSJeff Kirsher entry = next_entry; 22247ac6653aSJeff Kirsher } 22257ac6653aSJeff Kirsher 22267ac6653aSJeff Kirsher stmmac_rx_refill(priv); 22277ac6653aSJeff Kirsher 22287ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 22297ac6653aSJeff Kirsher 22307ac6653aSJeff Kirsher return count; 22317ac6653aSJeff Kirsher } 22327ac6653aSJeff Kirsher 22337ac6653aSJeff Kirsher /** 22347ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 22357ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 22367ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 22377ac6653aSJeff Kirsher * all interfaces. 22387ac6653aSJeff Kirsher * Description : 22399125cdd1SGiuseppe CAVALLARO * To look at the incoming frames and clear the tx resources. 22407ac6653aSJeff Kirsher */ 22417ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 22427ac6653aSJeff Kirsher { 22437ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 22447ac6653aSJeff Kirsher int work_done = 0; 22457ac6653aSJeff Kirsher 22469125cdd1SGiuseppe CAVALLARO priv->xstats.napi_poll++; 22479125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 22487ac6653aSJeff Kirsher 22499125cdd1SGiuseppe CAVALLARO work_done = stmmac_rx(priv, budget); 22507ac6653aSJeff Kirsher if (work_done < budget) { 22517ac6653aSJeff Kirsher napi_complete(napi); 22529125cdd1SGiuseppe CAVALLARO stmmac_enable_dma_irq(priv); 22537ac6653aSJeff Kirsher } 22547ac6653aSJeff Kirsher return work_done; 22557ac6653aSJeff Kirsher } 22567ac6653aSJeff Kirsher 22577ac6653aSJeff Kirsher /** 22587ac6653aSJeff Kirsher * stmmac_tx_timeout 22597ac6653aSJeff Kirsher * @dev : Pointer to net device structure 22607ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 22617284a3f1SGiuseppe CAVALLARO * complete within a reasonable time. The driver will mark the error in the 22627ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 22637ac6653aSJeff Kirsher * in order to transmit a new packet. 22647ac6653aSJeff Kirsher */ 22657ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 22667ac6653aSJeff Kirsher { 22677ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22687ac6653aSJeff Kirsher 22697ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 22707ac6653aSJeff Kirsher stmmac_tx_err(priv); 22717ac6653aSJeff Kirsher } 22727ac6653aSJeff Kirsher 22737ac6653aSJeff Kirsher /** 227401789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 22757ac6653aSJeff Kirsher * @dev : pointer to the device structure 22767ac6653aSJeff Kirsher * Description: 22777ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 22787ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 22797ac6653aSJeff Kirsher * Return value: 22807ac6653aSJeff Kirsher * void. 22817ac6653aSJeff Kirsher */ 228201789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 22837ac6653aSJeff Kirsher { 22847ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22857ac6653aSJeff Kirsher 22867ac6653aSJeff Kirsher spin_lock(&priv->lock); 22873b57de95SVince Bridgers priv->hw->mac->set_filter(priv->hw, dev); 22887ac6653aSJeff Kirsher spin_unlock(&priv->lock); 22897ac6653aSJeff Kirsher } 22907ac6653aSJeff Kirsher 22917ac6653aSJeff Kirsher /** 22927ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 22937ac6653aSJeff Kirsher * @dev : device pointer. 22947ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 22957ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 22967ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 22977ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 22987ac6653aSJeff Kirsher * Return value: 22997ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 23007ac6653aSJeff Kirsher * file on failure. 23017ac6653aSJeff Kirsher */ 23027ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 23037ac6653aSJeff Kirsher { 23047ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23057ac6653aSJeff Kirsher int max_mtu; 23067ac6653aSJeff Kirsher 23077ac6653aSJeff Kirsher if (netif_running(dev)) { 23087ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 23097ac6653aSJeff Kirsher return -EBUSY; 23107ac6653aSJeff Kirsher } 23117ac6653aSJeff Kirsher 231248febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 23137ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 23147ac6653aSJeff Kirsher else 231545db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 23167ac6653aSJeff Kirsher 23172618abb7SVince Bridgers if (priv->plat->maxmtu < max_mtu) 23182618abb7SVince Bridgers max_mtu = priv->plat->maxmtu; 23192618abb7SVince Bridgers 23207ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 23217ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 23227ac6653aSJeff Kirsher return -EINVAL; 23237ac6653aSJeff Kirsher } 23247ac6653aSJeff Kirsher 23257ac6653aSJeff Kirsher dev->mtu = new_mtu; 23267ac6653aSJeff Kirsher netdev_update_features(dev); 23277ac6653aSJeff Kirsher 23287ac6653aSJeff Kirsher return 0; 23297ac6653aSJeff Kirsher } 23307ac6653aSJeff Kirsher 2331c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 2332c8f44affSMichał Mirosław netdev_features_t features) 23337ac6653aSJeff Kirsher { 23347ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23357ac6653aSJeff Kirsher 233638912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 23377ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 2338d2afb5bdSGiuseppe CAVALLARO 23397ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 23407ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23417ac6653aSJeff Kirsher 23427ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 23437ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 23447ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 2345ceb69499SGiuseppe CAVALLARO * the TX csum insertionin the TDES and not use SF. 2346ceb69499SGiuseppe CAVALLARO */ 23477ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 23487ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23497ac6653aSJeff Kirsher 23507ac6653aSJeff Kirsher return features; 23517ac6653aSJeff Kirsher } 23527ac6653aSJeff Kirsher 2353d2afb5bdSGiuseppe CAVALLARO static int stmmac_set_features(struct net_device *netdev, 2354d2afb5bdSGiuseppe CAVALLARO netdev_features_t features) 2355d2afb5bdSGiuseppe CAVALLARO { 2356d2afb5bdSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(netdev); 2357d2afb5bdSGiuseppe CAVALLARO 2358d2afb5bdSGiuseppe CAVALLARO /* Keep the COE Type in case of csum is supporting */ 2359d2afb5bdSGiuseppe CAVALLARO if (features & NETIF_F_RXCSUM) 2360d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = priv->plat->rx_coe; 2361d2afb5bdSGiuseppe CAVALLARO else 2362d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = 0; 2363d2afb5bdSGiuseppe CAVALLARO /* No check needed because rx_coe has been set before and it will be 2364d2afb5bdSGiuseppe CAVALLARO * fixed in case of issue. 2365d2afb5bdSGiuseppe CAVALLARO */ 2366d2afb5bdSGiuseppe CAVALLARO priv->hw->mac->rx_ipc(priv->hw); 2367d2afb5bdSGiuseppe CAVALLARO 2368d2afb5bdSGiuseppe CAVALLARO return 0; 2369d2afb5bdSGiuseppe CAVALLARO } 2370d2afb5bdSGiuseppe CAVALLARO 237132ceabcaSGiuseppe CAVALLARO /** 237232ceabcaSGiuseppe CAVALLARO * stmmac_interrupt - main ISR 237332ceabcaSGiuseppe CAVALLARO * @irq: interrupt number. 237432ceabcaSGiuseppe CAVALLARO * @dev_id: to pass the net device pointer. 237532ceabcaSGiuseppe CAVALLARO * Description: this is the main driver interrupt service routine. 237632ceabcaSGiuseppe CAVALLARO * It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI 237732ceabcaSGiuseppe CAVALLARO * interrupts. 237832ceabcaSGiuseppe CAVALLARO */ 23797ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 23807ac6653aSJeff Kirsher { 23817ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 23827ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23837ac6653aSJeff Kirsher 238489f7f2cfSSrinivas Kandagatla if (priv->irq_wake) 238589f7f2cfSSrinivas Kandagatla pm_wakeup_event(priv->device, 0); 238689f7f2cfSSrinivas Kandagatla 23877ac6653aSJeff Kirsher if (unlikely(!dev)) { 23887ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 23897ac6653aSJeff Kirsher return IRQ_NONE; 23907ac6653aSJeff Kirsher } 23917ac6653aSJeff Kirsher 23927ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 2393d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 23947ed24bbeSVince Bridgers int status = priv->hw->mac->host_irq_status(priv->hw, 23950982a0f6SGiuseppe CAVALLARO &priv->xstats); 2396d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 2397d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 23980982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) 2399d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 24000982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) 2401d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 2402d765955dSGiuseppe CAVALLARO } 2403d765955dSGiuseppe CAVALLARO } 2404d765955dSGiuseppe CAVALLARO 2405d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 24067ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 24077ac6653aSJeff Kirsher 24087ac6653aSJeff Kirsher return IRQ_HANDLED; 24097ac6653aSJeff Kirsher } 24107ac6653aSJeff Kirsher 24117ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 24127ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 2413ceb69499SGiuseppe CAVALLARO * to allow network I/O with interrupts disabled. 2414ceb69499SGiuseppe CAVALLARO */ 24157ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 24167ac6653aSJeff Kirsher { 24177ac6653aSJeff Kirsher disable_irq(dev->irq); 24187ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 24197ac6653aSJeff Kirsher enable_irq(dev->irq); 24207ac6653aSJeff Kirsher } 24217ac6653aSJeff Kirsher #endif 24227ac6653aSJeff Kirsher 24237ac6653aSJeff Kirsher /** 24247ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 24257ac6653aSJeff Kirsher * @dev: Device pointer. 24267ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 24277ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 24287ac6653aSJeff Kirsher * @cmd: IOCTL command 24297ac6653aSJeff Kirsher * Description: 243032ceabcaSGiuseppe CAVALLARO * Currently it supports the phy_mii_ioctl(...) and HW time stamping. 24317ac6653aSJeff Kirsher */ 24327ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 24337ac6653aSJeff Kirsher { 24347ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2435891434b1SRayagond Kokatanur int ret = -EOPNOTSUPP; 24367ac6653aSJeff Kirsher 24377ac6653aSJeff Kirsher if (!netif_running(dev)) 24387ac6653aSJeff Kirsher return -EINVAL; 24397ac6653aSJeff Kirsher 2440891434b1SRayagond Kokatanur switch (cmd) { 2441891434b1SRayagond Kokatanur case SIOCGMIIPHY: 2442891434b1SRayagond Kokatanur case SIOCGMIIREG: 2443891434b1SRayagond Kokatanur case SIOCSMIIREG: 24447ac6653aSJeff Kirsher if (!priv->phydev) 24457ac6653aSJeff Kirsher return -EINVAL; 24467ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 2447891434b1SRayagond Kokatanur break; 2448891434b1SRayagond Kokatanur case SIOCSHWTSTAMP: 2449891434b1SRayagond Kokatanur ret = stmmac_hwtstamp_ioctl(dev, rq); 2450891434b1SRayagond Kokatanur break; 2451891434b1SRayagond Kokatanur default: 2452891434b1SRayagond Kokatanur break; 2453891434b1SRayagond Kokatanur } 24547ac6653aSJeff Kirsher 24557ac6653aSJeff Kirsher return ret; 24567ac6653aSJeff Kirsher } 24577ac6653aSJeff Kirsher 24587ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 24597ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 24607ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 2461e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 24627ac29055SGiuseppe CAVALLARO 2463c24602efSGiuseppe CAVALLARO static void sysfs_display_ring(void *head, int size, int extend_desc, 2464c24602efSGiuseppe CAVALLARO struct seq_file *seq) 24657ac29055SGiuseppe CAVALLARO { 24667ac29055SGiuseppe CAVALLARO int i; 2467c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 2468c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 24697ac29055SGiuseppe CAVALLARO 2470c24602efSGiuseppe CAVALLARO for (i = 0; i < size; i++) { 2471c24602efSGiuseppe CAVALLARO u64 x; 2472c24602efSGiuseppe CAVALLARO if (extend_desc) { 2473c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 2474c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2475c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2476c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2477c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 2478c24602efSGiuseppe CAVALLARO ep++; 2479c24602efSGiuseppe CAVALLARO } else { 2480c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 2481c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2482c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2483c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2484c24602efSGiuseppe CAVALLARO p->des2, p->des3); 2485c24602efSGiuseppe CAVALLARO p++; 2486c24602efSGiuseppe CAVALLARO } 24877ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 24887ac29055SGiuseppe CAVALLARO } 2489c24602efSGiuseppe CAVALLARO } 24907ac29055SGiuseppe CAVALLARO 2491c24602efSGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 2492c24602efSGiuseppe CAVALLARO { 2493c24602efSGiuseppe CAVALLARO struct net_device *dev = seq->private; 2494c24602efSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2495c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 2496c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 24977ac29055SGiuseppe CAVALLARO 2498c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 2499c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended RX descriptor ring:\n"); 2500c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_erx, rxsize, 1, seq); 2501c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended TX descriptor ring:\n"); 2502c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_etx, txsize, 1, seq); 2503c24602efSGiuseppe CAVALLARO } else { 2504c24602efSGiuseppe CAVALLARO seq_printf(seq, "RX descriptor ring:\n"); 2505c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_rx, rxsize, 0, seq); 2506c24602efSGiuseppe CAVALLARO seq_printf(seq, "TX descriptor ring:\n"); 2507c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_tx, txsize, 0, seq); 25087ac29055SGiuseppe CAVALLARO } 25097ac29055SGiuseppe CAVALLARO 25107ac29055SGiuseppe CAVALLARO return 0; 25117ac29055SGiuseppe CAVALLARO } 25127ac29055SGiuseppe CAVALLARO 25137ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 25147ac29055SGiuseppe CAVALLARO { 25157ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 25167ac29055SGiuseppe CAVALLARO } 25177ac29055SGiuseppe CAVALLARO 25187ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 25197ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 25207ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 25217ac29055SGiuseppe CAVALLARO .read = seq_read, 25227ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 252374863948SDjalal Harouni .release = single_release, 25247ac29055SGiuseppe CAVALLARO }; 25257ac29055SGiuseppe CAVALLARO 2526e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 2527e7434821SGiuseppe CAVALLARO { 2528e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 2529e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2530e7434821SGiuseppe CAVALLARO 253119e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 2532e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 2533e7434821SGiuseppe CAVALLARO return 0; 2534e7434821SGiuseppe CAVALLARO } 2535e7434821SGiuseppe CAVALLARO 2536e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2537e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 2538e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2539e7434821SGiuseppe CAVALLARO 2540e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 2541e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 2542e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 2543e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 2544e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 2545e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 2546e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 2547e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 2548e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 2549e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 2550e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 2551e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 2552e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 2553e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 2554e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 2555e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 2556e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 2557e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 2558e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 2559e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 2560e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 2561e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 2562e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 2563e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 2564e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 2565e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 2566e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 2567e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 2568e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 2569e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 2570e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 2571e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 2572e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 2573e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 2574e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 2575e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 2576e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 2577e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 2578e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 2579e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 2580e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 2581e7434821SGiuseppe CAVALLARO 2582e7434821SGiuseppe CAVALLARO return 0; 2583e7434821SGiuseppe CAVALLARO } 2584e7434821SGiuseppe CAVALLARO 2585e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 2586e7434821SGiuseppe CAVALLARO { 2587e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 2588e7434821SGiuseppe CAVALLARO } 2589e7434821SGiuseppe CAVALLARO 2590e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 2591e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 2592e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 2593e7434821SGiuseppe CAVALLARO .read = seq_read, 2594e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 259574863948SDjalal Harouni .release = single_release, 2596e7434821SGiuseppe CAVALLARO }; 2597e7434821SGiuseppe CAVALLARO 25987ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 25997ac29055SGiuseppe CAVALLARO { 26007ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 26017ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 26027ac29055SGiuseppe CAVALLARO 26037ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 26047ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 26057ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 26067ac29055SGiuseppe CAVALLARO 26077ac29055SGiuseppe CAVALLARO return -ENOMEM; 26087ac29055SGiuseppe CAVALLARO } 26097ac29055SGiuseppe CAVALLARO 26107ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 26117ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 26127ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 26137ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 26147ac29055SGiuseppe CAVALLARO 26157ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 26167ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 26177ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 26187ac29055SGiuseppe CAVALLARO 26197ac29055SGiuseppe CAVALLARO return -ENOMEM; 26207ac29055SGiuseppe CAVALLARO } 26217ac29055SGiuseppe CAVALLARO 2622e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 2623e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 2624e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 2625e7434821SGiuseppe CAVALLARO 2626e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 2627e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 2628e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2629e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 2630e7434821SGiuseppe CAVALLARO 2631e7434821SGiuseppe CAVALLARO return -ENOMEM; 2632e7434821SGiuseppe CAVALLARO } 2633e7434821SGiuseppe CAVALLARO 26347ac29055SGiuseppe CAVALLARO return 0; 26357ac29055SGiuseppe CAVALLARO } 26367ac29055SGiuseppe CAVALLARO 26377ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 26387ac29055SGiuseppe CAVALLARO { 26397ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2640e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 26417ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 26427ac29055SGiuseppe CAVALLARO } 26437ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 26447ac29055SGiuseppe CAVALLARO 26457ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 26467ac6653aSJeff Kirsher .ndo_open = stmmac_open, 26477ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 26487ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 26497ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 26507ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 2651d2afb5bdSGiuseppe CAVALLARO .ndo_set_features = stmmac_set_features, 265201789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 26537ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 26547ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 26557ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 26567ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 26577ac6653aSJeff Kirsher #endif 26587ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 26597ac6653aSJeff Kirsher }; 26607ac6653aSJeff Kirsher 26617ac6653aSJeff Kirsher /** 2662cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 266332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 2664cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 2665cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 2666cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 2667cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 2668cf3f047bSGiuseppe CAVALLARO * descriptor structure). 2669cf3f047bSGiuseppe CAVALLARO */ 2670cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 2671cf3f047bSGiuseppe CAVALLARO { 2672cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 2673cf3f047bSGiuseppe CAVALLARO 2674cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 267503f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 267603f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 26773b57de95SVince Bridgers mac = dwmac1000_setup(priv->ioaddr, 26783b57de95SVince Bridgers priv->plat->multicast_filter_bins, 26793b57de95SVince Bridgers priv->plat->unicast_filter_entries); 268003f2eecdSMarc Kleine-Budde } else { 2681cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 268203f2eecdSMarc Kleine-Budde } 2683cf3f047bSGiuseppe CAVALLARO if (!mac) 2684cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 2685cf3f047bSGiuseppe CAVALLARO 2686cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 2687cf3f047bSGiuseppe CAVALLARO 2688cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 2689cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 2690cf3f047bSGiuseppe CAVALLARO 26914a7d666aSGiuseppe CAVALLARO /* To use the chained or ring mode */ 26924a7d666aSGiuseppe CAVALLARO if (chain_mode) { 269329896a67SGiuseppe CAVALLARO priv->hw->mode = &chain_mode_ops; 26944a7d666aSGiuseppe CAVALLARO pr_info(" Chain mode enabled\n"); 26954a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_CHAIN_MODE; 26964a7d666aSGiuseppe CAVALLARO } else { 269729896a67SGiuseppe CAVALLARO priv->hw->mode = &ring_mode_ops; 26984a7d666aSGiuseppe CAVALLARO pr_info(" Ring mode enabled\n"); 26994a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_RING_MODE; 27004a7d666aSGiuseppe CAVALLARO } 27014a7d666aSGiuseppe CAVALLARO 2702cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 2703cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 2704cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 2705cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 2706cf3f047bSGiuseppe CAVALLARO 2707cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 2708cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 2709cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 2710cf3f047bSGiuseppe CAVALLARO * register (if supported). 2711cf3f047bSGiuseppe CAVALLARO */ 2712cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 2713cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 271438912bdbSDeepak SIKRI 271538912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 271638912bdbSDeepak SIKRI 271738912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 271838912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 271938912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 272038912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 272138912bdbSDeepak SIKRI 2722cf3f047bSGiuseppe CAVALLARO } else 2723cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 2724cf3f047bSGiuseppe CAVALLARO 272561369d02SByungho An /* To use alternate (extended) or normal descriptor structures */ 272661369d02SByungho An stmmac_selec_desc_mode(priv); 272761369d02SByungho An 2728d2afb5bdSGiuseppe CAVALLARO if (priv->plat->rx_coe) { 2729d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = priv->plat->rx_coe; 273038912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 273138912bdbSDeepak SIKRI priv->plat->rx_coe); 2732d2afb5bdSGiuseppe CAVALLARO } 2733cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 2734cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 2735cf3f047bSGiuseppe CAVALLARO 2736cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 2737cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 2738cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 2739cf3f047bSGiuseppe CAVALLARO } 2740cf3f047bSGiuseppe CAVALLARO 2741c24602efSGiuseppe CAVALLARO return 0; 2742cf3f047bSGiuseppe CAVALLARO } 2743cf3f047bSGiuseppe CAVALLARO 2744cf3f047bSGiuseppe CAVALLARO /** 2745bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 2746bfab27a1SGiuseppe CAVALLARO * @device: device pointer 2747ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 2748ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 2749bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 2750bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 27517ac6653aSJeff Kirsher */ 2752bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 2753cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 2754cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 27557ac6653aSJeff Kirsher { 27567ac6653aSJeff Kirsher int ret = 0; 2757bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 2758bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 27597ac6653aSJeff Kirsher 2760bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 276141de8d4cSJoe Perches if (!ndev) 2762bfab27a1SGiuseppe CAVALLARO return NULL; 27637ac6653aSJeff Kirsher 2764bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 27657ac6653aSJeff Kirsher 2766bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 2767bfab27a1SGiuseppe CAVALLARO priv->device = device; 2768bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 2769bfab27a1SGiuseppe CAVALLARO 2770bfab27a1SGiuseppe CAVALLARO stmmac_set_ethtool_ops(ndev); 2771cf3f047bSGiuseppe CAVALLARO priv->pause = pause; 2772cf3f047bSGiuseppe CAVALLARO priv->plat = plat_dat; 2773cf3f047bSGiuseppe CAVALLARO priv->ioaddr = addr; 2774cf3f047bSGiuseppe CAVALLARO priv->dev->base_addr = (unsigned long)addr; 2775bfab27a1SGiuseppe CAVALLARO 2776cf3f047bSGiuseppe CAVALLARO /* Verify driver arguments */ 2777cf3f047bSGiuseppe CAVALLARO stmmac_verify_args(); 2778cf3f047bSGiuseppe CAVALLARO 2779cf3f047bSGiuseppe CAVALLARO /* Override with kernel parameters if supplied XXX CRS XXX 2780ceb69499SGiuseppe CAVALLARO * this needs to have multiple instances 2781ceb69499SGiuseppe CAVALLARO */ 2782cf3f047bSGiuseppe CAVALLARO if ((phyaddr >= 0) && (phyaddr <= 31)) 2783cf3f047bSGiuseppe CAVALLARO priv->plat->phy_addr = phyaddr; 2784cf3f047bSGiuseppe CAVALLARO 278562866e98SChen-Yu Tsai priv->stmmac_clk = devm_clk_get(priv->device, STMMAC_RESOURCE_NAME); 278662866e98SChen-Yu Tsai if (IS_ERR(priv->stmmac_clk)) { 278762866e98SChen-Yu Tsai dev_warn(priv->device, "%s: warning: cannot get CSR clock\n", 278862866e98SChen-Yu Tsai __func__); 2789c5bb86c3SKweh, Hock Leong /* If failed to obtain stmmac_clk and specific clk_csr value 2790c5bb86c3SKweh, Hock Leong * is NOT passed from the platform, probe fail. 2791c5bb86c3SKweh, Hock Leong */ 2792c5bb86c3SKweh, Hock Leong if (!priv->plat->clk_csr) { 2793c5e4ddbdSChen-Yu Tsai ret = PTR_ERR(priv->stmmac_clk); 279462866e98SChen-Yu Tsai goto error_clk_get; 2795c5bb86c3SKweh, Hock Leong } else { 2796c5bb86c3SKweh, Hock Leong priv->stmmac_clk = NULL; 2797c5bb86c3SKweh, Hock Leong } 279862866e98SChen-Yu Tsai } 279962866e98SChen-Yu Tsai clk_prepare_enable(priv->stmmac_clk); 280062866e98SChen-Yu Tsai 2801c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = devm_reset_control_get(priv->device, 2802c5e4ddbdSChen-Yu Tsai STMMAC_RESOURCE_NAME); 2803c5e4ddbdSChen-Yu Tsai if (IS_ERR(priv->stmmac_rst)) { 2804c5e4ddbdSChen-Yu Tsai if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) { 2805c5e4ddbdSChen-Yu Tsai ret = -EPROBE_DEFER; 2806c5e4ddbdSChen-Yu Tsai goto error_hw_init; 2807c5e4ddbdSChen-Yu Tsai } 2808c5e4ddbdSChen-Yu Tsai dev_info(priv->device, "no reset control found\n"); 2809c5e4ddbdSChen-Yu Tsai priv->stmmac_rst = NULL; 2810c5e4ddbdSChen-Yu Tsai } 2811c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2812c5e4ddbdSChen-Yu Tsai reset_control_deassert(priv->stmmac_rst); 2813c5e4ddbdSChen-Yu Tsai 2814cf3f047bSGiuseppe CAVALLARO /* Init MAC and get the capabilities */ 2815c24602efSGiuseppe CAVALLARO ret = stmmac_hw_init(priv); 2816c24602efSGiuseppe CAVALLARO if (ret) 281762866e98SChen-Yu Tsai goto error_hw_init; 2818cf3f047bSGiuseppe CAVALLARO 2819cf3f047bSGiuseppe CAVALLARO ndev->netdev_ops = &stmmac_netdev_ops; 2820cf3f047bSGiuseppe CAVALLARO 2821cf3f047bSGiuseppe CAVALLARO ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 2822cf3f047bSGiuseppe CAVALLARO NETIF_F_RXCSUM; 2823bfab27a1SGiuseppe CAVALLARO ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; 2824bfab27a1SGiuseppe CAVALLARO ndev->watchdog_timeo = msecs_to_jiffies(watchdog); 28257ac6653aSJeff Kirsher #ifdef STMMAC_VLAN_TAG_USED 28267ac6653aSJeff Kirsher /* Both mac100 and gmac support receive VLAN tag detection */ 2827f646968fSPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; 28287ac6653aSJeff Kirsher #endif 28297ac6653aSJeff Kirsher priv->msg_enable = netif_msg_init(debug, default_msg_level); 28307ac6653aSJeff Kirsher 28317ac6653aSJeff Kirsher if (flow_ctrl) 28327ac6653aSJeff Kirsher priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 28337ac6653aSJeff Kirsher 283462a2ab93SGiuseppe CAVALLARO /* Rx Watchdog is available in the COREs newer than the 3.40. 283562a2ab93SGiuseppe CAVALLARO * In some case, for example on bugged HW this feature 283662a2ab93SGiuseppe CAVALLARO * has to be disable and this can be done by passing the 283762a2ab93SGiuseppe CAVALLARO * riwt_off field from the platform. 283862a2ab93SGiuseppe CAVALLARO */ 283962a2ab93SGiuseppe CAVALLARO if ((priv->synopsys_id >= DWMAC_CORE_3_50) && (!priv->plat->riwt_off)) { 284062a2ab93SGiuseppe CAVALLARO priv->use_riwt = 1; 284162a2ab93SGiuseppe CAVALLARO pr_info(" Enable RX Mitigation via HW Watchdog Timer\n"); 284262a2ab93SGiuseppe CAVALLARO } 284362a2ab93SGiuseppe CAVALLARO 2844bfab27a1SGiuseppe CAVALLARO netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); 28457ac6653aSJeff Kirsher 28467ac6653aSJeff Kirsher spin_lock_init(&priv->lock); 2847a9097a96SGiuseppe CAVALLARO spin_lock_init(&priv->tx_lock); 28487ac6653aSJeff Kirsher 2849bfab27a1SGiuseppe CAVALLARO ret = register_netdev(ndev); 28507ac6653aSJeff Kirsher if (ret) { 2851cf3f047bSGiuseppe CAVALLARO pr_err("%s: ERROR %i registering the device\n", __func__, ret); 28526a81c26fSViresh Kumar goto error_netdev_register; 28537ac6653aSJeff Kirsher } 28547ac6653aSJeff Kirsher 2855cd7201f4SGiuseppe CAVALLARO /* If a specific clk_csr value is passed from the platform 2856cd7201f4SGiuseppe CAVALLARO * this means that the CSR Clock Range selection cannot be 2857cd7201f4SGiuseppe CAVALLARO * changed at run-time and it is fixed. Viceversa the driver'll try to 2858cd7201f4SGiuseppe CAVALLARO * set the MDC clock dynamically according to the csr actual 2859cd7201f4SGiuseppe CAVALLARO * clock input. 2860cd7201f4SGiuseppe CAVALLARO */ 2861cd7201f4SGiuseppe CAVALLARO if (!priv->plat->clk_csr) 2862cd7201f4SGiuseppe CAVALLARO stmmac_clk_csr_set(priv); 2863cd7201f4SGiuseppe CAVALLARO else 2864cd7201f4SGiuseppe CAVALLARO priv->clk_csr = priv->plat->clk_csr; 2865cd7201f4SGiuseppe CAVALLARO 2866e58bb43fSGiuseppe CAVALLARO stmmac_check_pcs_mode(priv); 2867e58bb43fSGiuseppe CAVALLARO 28684d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 28694d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) { 28704bfcbd7aSFrancesco Virlinzi /* MDIO bus Registration */ 28714bfcbd7aSFrancesco Virlinzi ret = stmmac_mdio_register(ndev); 28724bfcbd7aSFrancesco Virlinzi if (ret < 0) { 28734bfcbd7aSFrancesco Virlinzi pr_debug("%s: MDIO bus (id: %d) registration failed", 28744bfcbd7aSFrancesco Virlinzi __func__, priv->plat->bus_id); 28756a81c26fSViresh Kumar goto error_mdio_register; 28764bfcbd7aSFrancesco Virlinzi } 2877e58bb43fSGiuseppe CAVALLARO } 28784bfcbd7aSFrancesco Virlinzi 2879bfab27a1SGiuseppe CAVALLARO return priv; 28807ac6653aSJeff Kirsher 28816a81c26fSViresh Kumar error_mdio_register: 28827ac6653aSJeff Kirsher unregister_netdev(ndev); 28836a81c26fSViresh Kumar error_netdev_register: 28846a81c26fSViresh Kumar netif_napi_del(&priv->napi); 288562866e98SChen-Yu Tsai error_hw_init: 288662866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 288762866e98SChen-Yu Tsai error_clk_get: 28887ac6653aSJeff Kirsher free_netdev(ndev); 28897ac6653aSJeff Kirsher 2890c5e4ddbdSChen-Yu Tsai return ERR_PTR(ret); 28917ac6653aSJeff Kirsher } 28927ac6653aSJeff Kirsher 28937ac6653aSJeff Kirsher /** 28947ac6653aSJeff Kirsher * stmmac_dvr_remove 2895bfab27a1SGiuseppe CAVALLARO * @ndev: net device pointer 28967ac6653aSJeff Kirsher * Description: this function resets the TX/RX processes, disables the MAC RX/TX 2897bfab27a1SGiuseppe CAVALLARO * changes the link status, releases the DMA descriptor rings. 28987ac6653aSJeff Kirsher */ 2899bfab27a1SGiuseppe CAVALLARO int stmmac_dvr_remove(struct net_device *ndev) 29007ac6653aSJeff Kirsher { 29017ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 29027ac6653aSJeff Kirsher 29037ac6653aSJeff Kirsher pr_info("%s:\n\tremoving driver", __func__); 29047ac6653aSJeff Kirsher 29057ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 29067ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 29077ac6653aSJeff Kirsher 2908bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 29094d8f0825SByungho An if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI && 29104d8f0825SByungho An priv->pcs != STMMAC_PCS_RTBI) 29114bfcbd7aSFrancesco Virlinzi stmmac_mdio_unregister(ndev); 29127ac6653aSJeff Kirsher netif_carrier_off(ndev); 29137ac6653aSJeff Kirsher unregister_netdev(ndev); 2914c5e4ddbdSChen-Yu Tsai if (priv->stmmac_rst) 2915c5e4ddbdSChen-Yu Tsai reset_control_assert(priv->stmmac_rst); 291662866e98SChen-Yu Tsai clk_disable_unprepare(priv->stmmac_clk); 29177ac6653aSJeff Kirsher free_netdev(ndev); 29187ac6653aSJeff Kirsher 29197ac6653aSJeff Kirsher return 0; 29207ac6653aSJeff Kirsher } 29217ac6653aSJeff Kirsher 29227ac6653aSJeff Kirsher #ifdef CONFIG_PM 2923bfab27a1SGiuseppe CAVALLARO int stmmac_suspend(struct net_device *ndev) 29247ac6653aSJeff Kirsher { 29257ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2926f8c5a875SGiuseppe CAVALLARO unsigned long flags; 29277ac6653aSJeff Kirsher 29287ac6653aSJeff Kirsher if (!ndev || !netif_running(ndev)) 29297ac6653aSJeff Kirsher return 0; 29307ac6653aSJeff Kirsher 2931102463b1SFrancesco Virlinzi if (priv->phydev) 2932102463b1SFrancesco Virlinzi phy_stop(priv->phydev); 2933102463b1SFrancesco Virlinzi 2934f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 29357ac6653aSJeff Kirsher 29367ac6653aSJeff Kirsher netif_device_detach(ndev); 29377ac6653aSJeff Kirsher netif_stop_queue(ndev); 29387ac6653aSJeff Kirsher 29397ac6653aSJeff Kirsher napi_disable(&priv->napi); 29407ac6653aSJeff Kirsher 29417ac6653aSJeff Kirsher /* Stop TX/RX DMA */ 29427ac6653aSJeff Kirsher priv->hw->dma->stop_tx(priv->ioaddr); 29437ac6653aSJeff Kirsher priv->hw->dma->stop_rx(priv->ioaddr); 2944c24602efSGiuseppe CAVALLARO 2945c24602efSGiuseppe CAVALLARO stmmac_clear_descriptors(priv); 29467ac6653aSJeff Kirsher 29477ac6653aSJeff Kirsher /* Enable Power down mode by programming the PMT regs */ 294889f7f2cfSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 29497ed24bbeSVince Bridgers priv->hw->mac->pmt(priv->hw, priv->wolopts); 295089f7f2cfSSrinivas Kandagatla priv->irq_wake = 1; 295189f7f2cfSSrinivas Kandagatla } else { 2952bfab27a1SGiuseppe CAVALLARO stmmac_set_mac(priv->ioaddr, false); 2953db88f10aSSrinivas Kandagatla pinctrl_pm_select_sleep_state(priv->device); 2954ba1377ffSGiuseppe CAVALLARO /* Disable clock in case of PWM is off */ 2955a630844dSStefan Roese clk_disable_unprepare(priv->stmmac_clk); 2956ba1377ffSGiuseppe CAVALLARO } 2957f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 29582d871aa0SVince Bridgers 29592d871aa0SVince Bridgers priv->oldlink = 0; 29602d871aa0SVince Bridgers priv->speed = 0; 29612d871aa0SVince Bridgers priv->oldduplex = -1; 29627ac6653aSJeff Kirsher return 0; 29637ac6653aSJeff Kirsher } 29647ac6653aSJeff Kirsher 2965bfab27a1SGiuseppe CAVALLARO int stmmac_resume(struct net_device *ndev) 29667ac6653aSJeff Kirsher { 29677ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(ndev); 2968f8c5a875SGiuseppe CAVALLARO unsigned long flags; 29697ac6653aSJeff Kirsher 29707ac6653aSJeff Kirsher if (!netif_running(ndev)) 29717ac6653aSJeff Kirsher return 0; 29727ac6653aSJeff Kirsher 2973f8c5a875SGiuseppe CAVALLARO spin_lock_irqsave(&priv->lock, flags); 29747ac6653aSJeff Kirsher 29757ac6653aSJeff Kirsher /* Power Down bit, into the PM register, is cleared 29767ac6653aSJeff Kirsher * automatically as soon as a magic packet or a Wake-up frame 29777ac6653aSJeff Kirsher * is received. Anyway, it's better to manually clear 29787ac6653aSJeff Kirsher * this bit because it can generate problems while resuming 2979ceb69499SGiuseppe CAVALLARO * from another devices (e.g. serial console). 2980ceb69499SGiuseppe CAVALLARO */ 2981623997fbSSrinivas Kandagatla if (device_may_wakeup(priv->device)) { 29827ed24bbeSVince Bridgers priv->hw->mac->pmt(priv->hw, 0); 298389f7f2cfSSrinivas Kandagatla priv->irq_wake = 0; 2984623997fbSSrinivas Kandagatla } else { 2985db88f10aSSrinivas Kandagatla pinctrl_pm_select_default_state(priv->device); 2986ba1377ffSGiuseppe CAVALLARO /* enable the clk prevously disabled */ 2987a630844dSStefan Roese clk_prepare_enable(priv->stmmac_clk); 2988623997fbSSrinivas Kandagatla /* reset the phy so that it's ready */ 2989623997fbSSrinivas Kandagatla if (priv->mii) 2990623997fbSSrinivas Kandagatla stmmac_mdio_reset(priv->mii); 2991623997fbSSrinivas Kandagatla } 29927ac6653aSJeff Kirsher 29937ac6653aSJeff Kirsher netif_device_attach(ndev); 29947ac6653aSJeff Kirsher 2995623997fbSSrinivas Kandagatla stmmac_hw_setup(ndev); 29967ac6653aSJeff Kirsher 29977ac6653aSJeff Kirsher napi_enable(&priv->napi); 29987ac6653aSJeff Kirsher 29997ac6653aSJeff Kirsher netif_start_queue(ndev); 30007ac6653aSJeff Kirsher 3001f8c5a875SGiuseppe CAVALLARO spin_unlock_irqrestore(&priv->lock, flags); 3002102463b1SFrancesco Virlinzi 3003102463b1SFrancesco Virlinzi if (priv->phydev) 3004102463b1SFrancesco Virlinzi phy_start(priv->phydev); 3005102463b1SFrancesco Virlinzi 30067ac6653aSJeff Kirsher return 0; 30077ac6653aSJeff Kirsher } 30087ac6653aSJeff Kirsher #endif /* CONFIG_PM */ 30097ac6653aSJeff Kirsher 301033d5e332SGiuseppe CAVALLARO /* Driver can be configured w/ and w/ both PCI and Platf drivers 301133d5e332SGiuseppe CAVALLARO * depending on the configuration selected. 301233d5e332SGiuseppe CAVALLARO */ 3013ba27ec66SGiuseppe CAVALLARO static int __init stmmac_init(void) 3014ba27ec66SGiuseppe CAVALLARO { 3015493682b8SKonstantin Khlebnikov int ret; 3016ba27ec66SGiuseppe CAVALLARO 3017493682b8SKonstantin Khlebnikov ret = stmmac_register_platform(); 3018493682b8SKonstantin Khlebnikov if (ret) 3019493682b8SKonstantin Khlebnikov goto err; 3020493682b8SKonstantin Khlebnikov ret = stmmac_register_pci(); 3021493682b8SKonstantin Khlebnikov if (ret) 3022493682b8SKonstantin Khlebnikov goto err_pci; 302333d5e332SGiuseppe CAVALLARO return 0; 3024493682b8SKonstantin Khlebnikov err_pci: 3025493682b8SKonstantin Khlebnikov stmmac_unregister_platform(); 3026493682b8SKonstantin Khlebnikov err: 3027493682b8SKonstantin Khlebnikov pr_err("stmmac: driver registration failed\n"); 3028493682b8SKonstantin Khlebnikov return ret; 3029ba27ec66SGiuseppe CAVALLARO } 3030ba27ec66SGiuseppe CAVALLARO 3031ba27ec66SGiuseppe CAVALLARO static void __exit stmmac_exit(void) 3032ba27ec66SGiuseppe CAVALLARO { 303333d5e332SGiuseppe CAVALLARO stmmac_unregister_platform(); 303433d5e332SGiuseppe CAVALLARO stmmac_unregister_pci(); 3035ba27ec66SGiuseppe CAVALLARO } 3036ba27ec66SGiuseppe CAVALLARO 3037ba27ec66SGiuseppe CAVALLARO module_init(stmmac_init); 3038ba27ec66SGiuseppe CAVALLARO module_exit(stmmac_exit); 3039ba27ec66SGiuseppe CAVALLARO 30407ac6653aSJeff Kirsher #ifndef MODULE 30417ac6653aSJeff Kirsher static int __init stmmac_cmdline_opt(char *str) 30427ac6653aSJeff Kirsher { 30437ac6653aSJeff Kirsher char *opt; 30447ac6653aSJeff Kirsher 30457ac6653aSJeff Kirsher if (!str || !*str) 30467ac6653aSJeff Kirsher return -EINVAL; 30477ac6653aSJeff Kirsher while ((opt = strsep(&str, ",")) != NULL) { 30487ac6653aSJeff Kirsher if (!strncmp(opt, "debug:", 6)) { 3049ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &debug)) 30507ac6653aSJeff Kirsher goto err; 30517ac6653aSJeff Kirsher } else if (!strncmp(opt, "phyaddr:", 8)) { 3052ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 8, 0, &phyaddr)) 30537ac6653aSJeff Kirsher goto err; 30547ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_txsize:", 11)) { 3055ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_txsize)) 30567ac6653aSJeff Kirsher goto err; 30577ac6653aSJeff Kirsher } else if (!strncmp(opt, "dma_rxsize:", 11)) { 3058ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &dma_rxsize)) 30597ac6653aSJeff Kirsher goto err; 30607ac6653aSJeff Kirsher } else if (!strncmp(opt, "buf_sz:", 7)) { 3061ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 7, 0, &buf_sz)) 30627ac6653aSJeff Kirsher goto err; 30637ac6653aSJeff Kirsher } else if (!strncmp(opt, "tc:", 3)) { 3064ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 3, 0, &tc)) 30657ac6653aSJeff Kirsher goto err; 30667ac6653aSJeff Kirsher } else if (!strncmp(opt, "watchdog:", 9)) { 3067ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 9, 0, &watchdog)) 30687ac6653aSJeff Kirsher goto err; 30697ac6653aSJeff Kirsher } else if (!strncmp(opt, "flow_ctrl:", 10)) { 3070ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &flow_ctrl)) 30717ac6653aSJeff Kirsher goto err; 30727ac6653aSJeff Kirsher } else if (!strncmp(opt, "pause:", 6)) { 3073ea2ab871SGiuseppe CAVALLARO if (kstrtoint(opt + 6, 0, &pause)) 30747ac6653aSJeff Kirsher goto err; 3075506f669cSGiuseppe CAVALLARO } else if (!strncmp(opt, "eee_timer:", 10)) { 3076d765955dSGiuseppe CAVALLARO if (kstrtoint(opt + 10, 0, &eee_timer)) 3077d765955dSGiuseppe CAVALLARO goto err; 30784a7d666aSGiuseppe CAVALLARO } else if (!strncmp(opt, "chain_mode:", 11)) { 30794a7d666aSGiuseppe CAVALLARO if (kstrtoint(opt + 11, 0, &chain_mode)) 30804a7d666aSGiuseppe CAVALLARO goto err; 30817ac6653aSJeff Kirsher } 30827ac6653aSJeff Kirsher } 30837ac6653aSJeff Kirsher return 0; 30847ac6653aSJeff Kirsher 30857ac6653aSJeff Kirsher err: 30867ac6653aSJeff Kirsher pr_err("%s: ERROR broken module parameter conversion", __func__); 30877ac6653aSJeff Kirsher return -EINVAL; 30887ac6653aSJeff Kirsher } 30897ac6653aSJeff Kirsher 30907ac6653aSJeff Kirsher __setup("stmmaceth=", stmmac_cmdline_opt); 3091ceb69499SGiuseppe CAVALLARO #endif /* MODULE */ 30926fc0d0f2SGiuseppe Cavallaro 30936fc0d0f2SGiuseppe Cavallaro MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver"); 30946fc0d0f2SGiuseppe Cavallaro MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>"); 30956fc0d0f2SGiuseppe Cavallaro MODULE_LICENSE("GPL"); 3096