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 18977ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { 18987ac6653aSJeff Kirsher if (!netif_queue_stopped(dev)) { 18997ac6653aSJeff Kirsher netif_stop_queue(dev); 19007ac6653aSJeff Kirsher /* This is a hard error, log it. */ 1901ceb69499SGiuseppe CAVALLARO pr_err("%s: Tx Ring full when queue awake\n", __func__); 19027ac6653aSJeff Kirsher } 19037ac6653aSJeff Kirsher return NETDEV_TX_BUSY; 19047ac6653aSJeff Kirsher } 19057ac6653aSJeff Kirsher 1906a9097a96SGiuseppe CAVALLARO spin_lock(&priv->tx_lock); 1907a9097a96SGiuseppe CAVALLARO 1908d765955dSGiuseppe CAVALLARO if (priv->tx_path_in_lpi_mode) 1909d765955dSGiuseppe CAVALLARO stmmac_disable_eee_mode(priv); 1910d765955dSGiuseppe CAVALLARO 19117ac6653aSJeff Kirsher entry = priv->cur_tx % txsize; 19127ac6653aSJeff Kirsher 19137ac6653aSJeff Kirsher csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); 19147ac6653aSJeff Kirsher 1915c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1916c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1917c24602efSGiuseppe CAVALLARO else 19187ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 1919c24602efSGiuseppe CAVALLARO 19207ac6653aSJeff Kirsher first = desc; 19217ac6653aSJeff Kirsher 19224a7d666aSGiuseppe CAVALLARO /* To program the descriptors according to the size of the frame */ 192329896a67SGiuseppe CAVALLARO if (enh_desc) 192429896a67SGiuseppe CAVALLARO is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc); 192529896a67SGiuseppe CAVALLARO 19264a7d666aSGiuseppe CAVALLARO if (likely(!is_jumbo)) { 19277ac6653aSJeff Kirsher desc->des2 = dma_map_single(priv->device, skb->data, 19287ac6653aSJeff Kirsher nopaged_len, DMA_TO_DEVICE); 1929362b37beSGiuseppe CAVALLARO if (dma_mapping_error(priv->device, desc->des2)) 1930362b37beSGiuseppe CAVALLARO goto dma_map_err; 1931362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf = desc->des2; 19327ac6653aSJeff Kirsher priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, 19334a7d666aSGiuseppe CAVALLARO csum_insertion, priv->mode); 193429896a67SGiuseppe CAVALLARO } else { 1935c24602efSGiuseppe CAVALLARO desc = first; 193629896a67SGiuseppe CAVALLARO entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); 1937362b37beSGiuseppe CAVALLARO if (unlikely(entry < 0)) 1938362b37beSGiuseppe CAVALLARO goto dma_map_err; 193929896a67SGiuseppe CAVALLARO } 19407ac6653aSJeff Kirsher 19417ac6653aSJeff Kirsher for (i = 0; i < nfrags; i++) { 19429e903e08SEric Dumazet const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 19439e903e08SEric Dumazet int len = skb_frag_size(frag); 19447ac6653aSJeff Kirsher 194575e4364fSdamuzi000 priv->tx_skbuff[entry] = NULL; 19467ac6653aSJeff Kirsher entry = (++priv->cur_tx) % txsize; 1947c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1948c24602efSGiuseppe CAVALLARO desc = (struct dma_desc *)(priv->dma_etx + entry); 1949c24602efSGiuseppe CAVALLARO else 19507ac6653aSJeff Kirsher desc = priv->dma_tx + entry; 19517ac6653aSJeff Kirsher 1952f722380dSIan Campbell desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len, 1953f722380dSIan Campbell DMA_TO_DEVICE); 1954362b37beSGiuseppe CAVALLARO if (dma_mapping_error(priv->device, desc->des2)) 1955362b37beSGiuseppe CAVALLARO goto dma_map_err; /* should reuse desc w/o issues */ 1956362b37beSGiuseppe CAVALLARO 1957362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].buf = desc->des2; 1958362b37beSGiuseppe CAVALLARO priv->tx_skbuff_dma[entry].map_as_page = true; 19594a7d666aSGiuseppe CAVALLARO priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion, 19604a7d666aSGiuseppe CAVALLARO priv->mode); 19617ac6653aSJeff Kirsher wmb(); 19627ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(desc); 19638e839891SDeepak Sikri wmb(); 19647ac6653aSJeff Kirsher } 19657ac6653aSJeff Kirsher 196675e4364fSdamuzi000 priv->tx_skbuff[entry] = skb; 196775e4364fSdamuzi000 19689125cdd1SGiuseppe CAVALLARO /* Finalize the latest segment. */ 19697ac6653aSJeff Kirsher priv->hw->desc->close_tx_desc(desc); 19707ac6653aSJeff Kirsher 19717ac6653aSJeff Kirsher wmb(); 19729125cdd1SGiuseppe CAVALLARO /* According to the coalesce parameter the IC bit for the latest 19739125cdd1SGiuseppe CAVALLARO * segment could be reset and the timer re-started to invoke the 19749125cdd1SGiuseppe CAVALLARO * stmmac_tx function. This approach takes care about the fragments. 19759125cdd1SGiuseppe CAVALLARO */ 19769125cdd1SGiuseppe CAVALLARO priv->tx_count_frames += nfrags + 1; 19779125cdd1SGiuseppe CAVALLARO if (priv->tx_coal_frames > priv->tx_count_frames) { 19789125cdd1SGiuseppe CAVALLARO priv->hw->desc->clear_tx_ic(desc); 19799125cdd1SGiuseppe CAVALLARO priv->xstats.tx_reset_ic_bit++; 19809125cdd1SGiuseppe CAVALLARO mod_timer(&priv->txtimer, 19819125cdd1SGiuseppe CAVALLARO STMMAC_COAL_TIMER(priv->tx_coal_timer)); 19829125cdd1SGiuseppe CAVALLARO } else 19839125cdd1SGiuseppe CAVALLARO priv->tx_count_frames = 0; 19847ac6653aSJeff Kirsher 19857ac6653aSJeff Kirsher /* To avoid raise condition */ 19867ac6653aSJeff Kirsher priv->hw->desc->set_tx_owner(first); 19878e839891SDeepak Sikri wmb(); 19887ac6653aSJeff Kirsher 19897ac6653aSJeff Kirsher priv->cur_tx++; 19907ac6653aSJeff Kirsher 19917ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 199283d7af64SGiuseppe CAVALLARO pr_debug("%s: curr %d dirty=%d entry=%d, first=%p, nfrags=%d", 1993ceb69499SGiuseppe CAVALLARO __func__, (priv->cur_tx % txsize), 1994ceb69499SGiuseppe CAVALLARO (priv->dirty_tx % txsize), entry, first, nfrags); 199583d7af64SGiuseppe CAVALLARO 1996c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 1997c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_etx, txsize, 1); 1998c24602efSGiuseppe CAVALLARO else 1999c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_tx, txsize, 0); 2000c24602efSGiuseppe CAVALLARO 200183d7af64SGiuseppe CAVALLARO pr_debug(">>> frame to be transmitted: "); 20027ac6653aSJeff Kirsher print_pkt(skb->data, skb->len); 20037ac6653aSJeff Kirsher } 20047ac6653aSJeff Kirsher if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) { 200583d7af64SGiuseppe CAVALLARO if (netif_msg_hw(priv)) 200683d7af64SGiuseppe CAVALLARO pr_debug("%s: stop transmitted packets\n", __func__); 20077ac6653aSJeff Kirsher netif_stop_queue(dev); 20087ac6653aSJeff Kirsher } 20097ac6653aSJeff Kirsher 20107ac6653aSJeff Kirsher dev->stats.tx_bytes += skb->len; 20117ac6653aSJeff Kirsher 2012891434b1SRayagond Kokatanur if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && 2013891434b1SRayagond Kokatanur priv->hwts_tx_en)) { 2014891434b1SRayagond Kokatanur /* declare that device is doing timestamping */ 2015891434b1SRayagond Kokatanur skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; 2016891434b1SRayagond Kokatanur priv->hw->desc->enable_tx_timestamp(first); 2017891434b1SRayagond Kokatanur } 2018891434b1SRayagond Kokatanur 2019891434b1SRayagond Kokatanur if (!priv->hwts_tx_en) 20207ac6653aSJeff Kirsher skb_tx_timestamp(skb); 20217ac6653aSJeff Kirsher 20227ac6653aSJeff Kirsher priv->hw->dma->enable_dma_transmission(priv->ioaddr); 20237ac6653aSJeff Kirsher 2024a9097a96SGiuseppe CAVALLARO spin_unlock(&priv->tx_lock); 2025362b37beSGiuseppe CAVALLARO return NETDEV_TX_OK; 2026a9097a96SGiuseppe CAVALLARO 2027362b37beSGiuseppe CAVALLARO dma_map_err: 2028362b37beSGiuseppe CAVALLARO dev_err(priv->device, "Tx dma map failed\n"); 2029362b37beSGiuseppe CAVALLARO dev_kfree_skb(skb); 2030362b37beSGiuseppe CAVALLARO priv->dev->stats.tx_dropped++; 20317ac6653aSJeff Kirsher return NETDEV_TX_OK; 20327ac6653aSJeff Kirsher } 20337ac6653aSJeff Kirsher 2034b9381985SVince Bridgers static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) 2035b9381985SVince Bridgers { 2036b9381985SVince Bridgers struct ethhdr *ehdr; 2037b9381985SVince Bridgers u16 vlanid; 2038b9381985SVince Bridgers 2039b9381985SVince Bridgers if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) == 2040b9381985SVince Bridgers NETIF_F_HW_VLAN_CTAG_RX && 2041b9381985SVince Bridgers !__vlan_get_tag(skb, &vlanid)) { 2042b9381985SVince Bridgers /* pop the vlan tag */ 2043b9381985SVince Bridgers ehdr = (struct ethhdr *)skb->data; 2044b9381985SVince Bridgers memmove(skb->data + VLAN_HLEN, ehdr, ETH_ALEN * 2); 2045b9381985SVince Bridgers skb_pull(skb, VLAN_HLEN); 2046b9381985SVince Bridgers __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlanid); 2047b9381985SVince Bridgers } 2048b9381985SVince Bridgers } 2049b9381985SVince Bridgers 2050b9381985SVince Bridgers 205132ceabcaSGiuseppe CAVALLARO /** 205232ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 205332ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 205432ceabcaSGiuseppe CAVALLARO * Description : this is to reallocate the skb for the reception process 205532ceabcaSGiuseppe CAVALLARO * that is based on zero-copy. 205632ceabcaSGiuseppe CAVALLARO */ 20577ac6653aSJeff Kirsher static inline void stmmac_rx_refill(struct stmmac_priv *priv) 20587ac6653aSJeff Kirsher { 20597ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 20607ac6653aSJeff Kirsher int bfsize = priv->dma_buf_sz; 20617ac6653aSJeff Kirsher 20627ac6653aSJeff Kirsher for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) { 20637ac6653aSJeff Kirsher unsigned int entry = priv->dirty_rx % rxsize; 2064c24602efSGiuseppe CAVALLARO struct dma_desc *p; 2065c24602efSGiuseppe CAVALLARO 2066c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2067c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2068c24602efSGiuseppe CAVALLARO else 2069c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2070c24602efSGiuseppe CAVALLARO 20717ac6653aSJeff Kirsher if (likely(priv->rx_skbuff[entry] == NULL)) { 20727ac6653aSJeff Kirsher struct sk_buff *skb; 20737ac6653aSJeff Kirsher 2074acb600deSEric Dumazet skb = netdev_alloc_skb_ip_align(priv->dev, bfsize); 20757ac6653aSJeff Kirsher 20767ac6653aSJeff Kirsher if (unlikely(skb == NULL)) 20777ac6653aSJeff Kirsher break; 20787ac6653aSJeff Kirsher 20797ac6653aSJeff Kirsher priv->rx_skbuff[entry] = skb; 20807ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry] = 20817ac6653aSJeff Kirsher dma_map_single(priv->device, skb->data, bfsize, 20827ac6653aSJeff Kirsher DMA_FROM_DEVICE); 2083362b37beSGiuseppe CAVALLARO if (dma_mapping_error(priv->device, 2084362b37beSGiuseppe CAVALLARO priv->rx_skbuff_dma[entry])) { 2085362b37beSGiuseppe CAVALLARO dev_err(priv->device, "Rx dma map failed\n"); 2086362b37beSGiuseppe CAVALLARO dev_kfree_skb(skb); 2087362b37beSGiuseppe CAVALLARO break; 2088362b37beSGiuseppe CAVALLARO } 2089c24602efSGiuseppe CAVALLARO p->des2 = priv->rx_skbuff_dma[entry]; 2090286a8372SGiuseppe CAVALLARO 209129896a67SGiuseppe CAVALLARO priv->hw->mode->refill_desc3(priv, p); 2092286a8372SGiuseppe CAVALLARO 209383d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) 209483d7af64SGiuseppe CAVALLARO pr_debug("\trefill entry #%d\n", entry); 20957ac6653aSJeff Kirsher } 20967ac6653aSJeff Kirsher wmb(); 2097c24602efSGiuseppe CAVALLARO priv->hw->desc->set_rx_owner(p); 20988e839891SDeepak Sikri wmb(); 20997ac6653aSJeff Kirsher } 21007ac6653aSJeff Kirsher } 21017ac6653aSJeff Kirsher 210232ceabcaSGiuseppe CAVALLARO /** 210332ceabcaSGiuseppe CAVALLARO * stmmac_rx_refill: refill used skb preallocated buffers 210432ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 210532ceabcaSGiuseppe CAVALLARO * @limit: napi bugget. 210632ceabcaSGiuseppe CAVALLARO * Description : this the function called by the napi poll method. 210732ceabcaSGiuseppe CAVALLARO * It gets all the frames inside the ring. 210832ceabcaSGiuseppe CAVALLARO */ 21097ac6653aSJeff Kirsher static int stmmac_rx(struct stmmac_priv *priv, int limit) 21107ac6653aSJeff Kirsher { 21117ac6653aSJeff Kirsher unsigned int rxsize = priv->dma_rx_size; 21127ac6653aSJeff Kirsher unsigned int entry = priv->cur_rx % rxsize; 21137ac6653aSJeff Kirsher unsigned int next_entry; 21147ac6653aSJeff Kirsher unsigned int count = 0; 2115d2afb5bdSGiuseppe CAVALLARO int coe = priv->hw->rx_csum; 21167ac6653aSJeff Kirsher 211783d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 211883d7af64SGiuseppe CAVALLARO pr_debug("%s: descriptor ring:\n", __func__); 2119c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2120c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_erx, rxsize, 1); 2121c24602efSGiuseppe CAVALLARO else 2122c24602efSGiuseppe CAVALLARO stmmac_display_ring((void *)priv->dma_rx, rxsize, 0); 21237ac6653aSJeff Kirsher } 2124c24602efSGiuseppe CAVALLARO while (count < limit) { 21257ac6653aSJeff Kirsher int status; 21269401bb5cSGiuseppe CAVALLARO struct dma_desc *p; 21277ac6653aSJeff Kirsher 2128c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 2129c24602efSGiuseppe CAVALLARO p = (struct dma_desc *)(priv->dma_erx + entry); 2130c24602efSGiuseppe CAVALLARO else 2131c24602efSGiuseppe CAVALLARO p = priv->dma_rx + entry; 2132c24602efSGiuseppe CAVALLARO 2133c24602efSGiuseppe CAVALLARO if (priv->hw->desc->get_rx_owner(p)) 21347ac6653aSJeff Kirsher break; 21357ac6653aSJeff Kirsher 21367ac6653aSJeff Kirsher count++; 21377ac6653aSJeff Kirsher 21387ac6653aSJeff Kirsher next_entry = (++priv->cur_rx) % rxsize; 2139c24602efSGiuseppe CAVALLARO if (priv->extend_desc) 21409401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_erx + next_entry); 2141c24602efSGiuseppe CAVALLARO else 21429401bb5cSGiuseppe CAVALLARO prefetch(priv->dma_rx + next_entry); 21437ac6653aSJeff Kirsher 21447ac6653aSJeff Kirsher /* read the status of the incoming frame */ 2145c24602efSGiuseppe CAVALLARO status = priv->hw->desc->rx_status(&priv->dev->stats, 2146c24602efSGiuseppe CAVALLARO &priv->xstats, p); 2147c24602efSGiuseppe CAVALLARO if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status)) 2148c24602efSGiuseppe CAVALLARO priv->hw->desc->rx_extended_status(&priv->dev->stats, 2149c24602efSGiuseppe CAVALLARO &priv->xstats, 2150c24602efSGiuseppe CAVALLARO priv->dma_erx + 2151c24602efSGiuseppe CAVALLARO entry); 2152891434b1SRayagond Kokatanur if (unlikely(status == discard_frame)) { 21537ac6653aSJeff Kirsher priv->dev->stats.rx_errors++; 2154891434b1SRayagond Kokatanur if (priv->hwts_rx_en && !priv->extend_desc) { 2155891434b1SRayagond Kokatanur /* DESC2 & DESC3 will be overwitten by device 2156891434b1SRayagond Kokatanur * with timestamp value, hence reinitialize 2157891434b1SRayagond Kokatanur * them in stmmac_rx_refill() function so that 2158891434b1SRayagond Kokatanur * device can reuse it. 2159891434b1SRayagond Kokatanur */ 2160891434b1SRayagond Kokatanur priv->rx_skbuff[entry] = NULL; 2161891434b1SRayagond Kokatanur dma_unmap_single(priv->device, 2162891434b1SRayagond Kokatanur priv->rx_skbuff_dma[entry], 2163ceb69499SGiuseppe CAVALLARO priv->dma_buf_sz, 2164ceb69499SGiuseppe CAVALLARO DMA_FROM_DEVICE); 2165891434b1SRayagond Kokatanur } 2166891434b1SRayagond Kokatanur } else { 21677ac6653aSJeff Kirsher struct sk_buff *skb; 21687ac6653aSJeff Kirsher int frame_len; 21697ac6653aSJeff Kirsher 2170ceb69499SGiuseppe CAVALLARO frame_len = priv->hw->desc->get_rx_frame_len(p, coe); 2171ceb69499SGiuseppe CAVALLARO 21727ac6653aSJeff Kirsher /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 2173ceb69499SGiuseppe CAVALLARO * Type frames (LLC/LLC-SNAP) 2174ceb69499SGiuseppe CAVALLARO */ 21757ac6653aSJeff Kirsher if (unlikely(status != llc_snap)) 21767ac6653aSJeff Kirsher frame_len -= ETH_FCS_LEN; 21777ac6653aSJeff Kirsher 217883d7af64SGiuseppe CAVALLARO if (netif_msg_rx_status(priv)) { 21797ac6653aSJeff Kirsher pr_debug("\tdesc: %p [entry %d] buff=0x%x\n", 21807ac6653aSJeff Kirsher p, entry, p->des2); 218183d7af64SGiuseppe CAVALLARO if (frame_len > ETH_FRAME_LEN) 218283d7af64SGiuseppe CAVALLARO pr_debug("\tframe size %d, COE: %d\n", 218383d7af64SGiuseppe CAVALLARO frame_len, status); 218483d7af64SGiuseppe CAVALLARO } 21857ac6653aSJeff Kirsher skb = priv->rx_skbuff[entry]; 21867ac6653aSJeff Kirsher if (unlikely(!skb)) { 21877ac6653aSJeff Kirsher pr_err("%s: Inconsistent Rx descriptor chain\n", 21887ac6653aSJeff Kirsher priv->dev->name); 21897ac6653aSJeff Kirsher priv->dev->stats.rx_dropped++; 21907ac6653aSJeff Kirsher break; 21917ac6653aSJeff Kirsher } 21927ac6653aSJeff Kirsher prefetch(skb->data - NET_IP_ALIGN); 21937ac6653aSJeff Kirsher priv->rx_skbuff[entry] = NULL; 21947ac6653aSJeff Kirsher 2195891434b1SRayagond Kokatanur stmmac_get_rx_hwtstamp(priv, entry, skb); 2196891434b1SRayagond Kokatanur 21977ac6653aSJeff Kirsher skb_put(skb, frame_len); 21987ac6653aSJeff Kirsher dma_unmap_single(priv->device, 21997ac6653aSJeff Kirsher priv->rx_skbuff_dma[entry], 22007ac6653aSJeff Kirsher priv->dma_buf_sz, DMA_FROM_DEVICE); 220183d7af64SGiuseppe CAVALLARO 22027ac6653aSJeff Kirsher if (netif_msg_pktdata(priv)) { 220383d7af64SGiuseppe CAVALLARO pr_debug("frame received (%dbytes)", frame_len); 22047ac6653aSJeff Kirsher print_pkt(skb->data, frame_len); 22057ac6653aSJeff Kirsher } 220683d7af64SGiuseppe CAVALLARO 2207b9381985SVince Bridgers stmmac_rx_vlan(priv->dev, skb); 2208b9381985SVince Bridgers 22097ac6653aSJeff Kirsher skb->protocol = eth_type_trans(skb, priv->dev); 22107ac6653aSJeff Kirsher 2211ceb69499SGiuseppe CAVALLARO if (unlikely(!coe)) 22127ac6653aSJeff Kirsher skb_checksum_none_assert(skb); 221362a2ab93SGiuseppe CAVALLARO else 22147ac6653aSJeff Kirsher skb->ip_summed = CHECKSUM_UNNECESSARY; 221562a2ab93SGiuseppe CAVALLARO 22167ac6653aSJeff Kirsher napi_gro_receive(&priv->napi, skb); 22177ac6653aSJeff Kirsher 22187ac6653aSJeff Kirsher priv->dev->stats.rx_packets++; 22197ac6653aSJeff Kirsher priv->dev->stats.rx_bytes += frame_len; 22207ac6653aSJeff Kirsher } 22217ac6653aSJeff Kirsher entry = next_entry; 22227ac6653aSJeff Kirsher } 22237ac6653aSJeff Kirsher 22247ac6653aSJeff Kirsher stmmac_rx_refill(priv); 22257ac6653aSJeff Kirsher 22267ac6653aSJeff Kirsher priv->xstats.rx_pkt_n += count; 22277ac6653aSJeff Kirsher 22287ac6653aSJeff Kirsher return count; 22297ac6653aSJeff Kirsher } 22307ac6653aSJeff Kirsher 22317ac6653aSJeff Kirsher /** 22327ac6653aSJeff Kirsher * stmmac_poll - stmmac poll method (NAPI) 22337ac6653aSJeff Kirsher * @napi : pointer to the napi structure. 22347ac6653aSJeff Kirsher * @budget : maximum number of packets that the current CPU can receive from 22357ac6653aSJeff Kirsher * all interfaces. 22367ac6653aSJeff Kirsher * Description : 22379125cdd1SGiuseppe CAVALLARO * To look at the incoming frames and clear the tx resources. 22387ac6653aSJeff Kirsher */ 22397ac6653aSJeff Kirsher static int stmmac_poll(struct napi_struct *napi, int budget) 22407ac6653aSJeff Kirsher { 22417ac6653aSJeff Kirsher struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi); 22427ac6653aSJeff Kirsher int work_done = 0; 22437ac6653aSJeff Kirsher 22449125cdd1SGiuseppe CAVALLARO priv->xstats.napi_poll++; 22459125cdd1SGiuseppe CAVALLARO stmmac_tx_clean(priv); 22467ac6653aSJeff Kirsher 22479125cdd1SGiuseppe CAVALLARO work_done = stmmac_rx(priv, budget); 22487ac6653aSJeff Kirsher if (work_done < budget) { 22497ac6653aSJeff Kirsher napi_complete(napi); 22509125cdd1SGiuseppe CAVALLARO stmmac_enable_dma_irq(priv); 22517ac6653aSJeff Kirsher } 22527ac6653aSJeff Kirsher return work_done; 22537ac6653aSJeff Kirsher } 22547ac6653aSJeff Kirsher 22557ac6653aSJeff Kirsher /** 22567ac6653aSJeff Kirsher * stmmac_tx_timeout 22577ac6653aSJeff Kirsher * @dev : Pointer to net device structure 22587ac6653aSJeff Kirsher * Description: this function is called when a packet transmission fails to 22597284a3f1SGiuseppe CAVALLARO * complete within a reasonable time. The driver will mark the error in the 22607ac6653aSJeff Kirsher * netdev structure and arrange for the device to be reset to a sane state 22617ac6653aSJeff Kirsher * in order to transmit a new packet. 22627ac6653aSJeff Kirsher */ 22637ac6653aSJeff Kirsher static void stmmac_tx_timeout(struct net_device *dev) 22647ac6653aSJeff Kirsher { 22657ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22667ac6653aSJeff Kirsher 22677ac6653aSJeff Kirsher /* Clear Tx resources and restart transmitting again */ 22687ac6653aSJeff Kirsher stmmac_tx_err(priv); 22697ac6653aSJeff Kirsher } 22707ac6653aSJeff Kirsher 22717ac6653aSJeff Kirsher /** 227201789349SJiri Pirko * stmmac_set_rx_mode - entry point for multicast addressing 22737ac6653aSJeff Kirsher * @dev : pointer to the device structure 22747ac6653aSJeff Kirsher * Description: 22757ac6653aSJeff Kirsher * This function is a driver entry point which gets called by the kernel 22767ac6653aSJeff Kirsher * whenever multicast addresses must be enabled/disabled. 22777ac6653aSJeff Kirsher * Return value: 22787ac6653aSJeff Kirsher * void. 22797ac6653aSJeff Kirsher */ 228001789349SJiri Pirko static void stmmac_set_rx_mode(struct net_device *dev) 22817ac6653aSJeff Kirsher { 22827ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 22837ac6653aSJeff Kirsher 22847ac6653aSJeff Kirsher spin_lock(&priv->lock); 22853b57de95SVince Bridgers priv->hw->mac->set_filter(priv->hw, dev); 22867ac6653aSJeff Kirsher spin_unlock(&priv->lock); 22877ac6653aSJeff Kirsher } 22887ac6653aSJeff Kirsher 22897ac6653aSJeff Kirsher /** 22907ac6653aSJeff Kirsher * stmmac_change_mtu - entry point to change MTU size for the device. 22917ac6653aSJeff Kirsher * @dev : device pointer. 22927ac6653aSJeff Kirsher * @new_mtu : the new MTU size for the device. 22937ac6653aSJeff Kirsher * Description: the Maximum Transfer Unit (MTU) is used by the network layer 22947ac6653aSJeff Kirsher * to drive packet transmission. Ethernet has an MTU of 1500 octets 22957ac6653aSJeff Kirsher * (ETH_DATA_LEN). This value can be changed with ifconfig. 22967ac6653aSJeff Kirsher * Return value: 22977ac6653aSJeff Kirsher * 0 on success and an appropriate (-)ve integer as defined in errno.h 22987ac6653aSJeff Kirsher * file on failure. 22997ac6653aSJeff Kirsher */ 23007ac6653aSJeff Kirsher static int stmmac_change_mtu(struct net_device *dev, int new_mtu) 23017ac6653aSJeff Kirsher { 23027ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23037ac6653aSJeff Kirsher int max_mtu; 23047ac6653aSJeff Kirsher 23057ac6653aSJeff Kirsher if (netif_running(dev)) { 23067ac6653aSJeff Kirsher pr_err("%s: must be stopped to change its MTU\n", dev->name); 23077ac6653aSJeff Kirsher return -EBUSY; 23087ac6653aSJeff Kirsher } 23097ac6653aSJeff Kirsher 231048febf7eSGiuseppe CAVALLARO if (priv->plat->enh_desc) 23117ac6653aSJeff Kirsher max_mtu = JUMBO_LEN; 23127ac6653aSJeff Kirsher else 231345db81e1SGiuseppe CAVALLARO max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); 23147ac6653aSJeff Kirsher 23152618abb7SVince Bridgers if (priv->plat->maxmtu < max_mtu) 23162618abb7SVince Bridgers max_mtu = priv->plat->maxmtu; 23172618abb7SVince Bridgers 23187ac6653aSJeff Kirsher if ((new_mtu < 46) || (new_mtu > max_mtu)) { 23197ac6653aSJeff Kirsher pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu); 23207ac6653aSJeff Kirsher return -EINVAL; 23217ac6653aSJeff Kirsher } 23227ac6653aSJeff Kirsher 23237ac6653aSJeff Kirsher dev->mtu = new_mtu; 23247ac6653aSJeff Kirsher netdev_update_features(dev); 23257ac6653aSJeff Kirsher 23267ac6653aSJeff Kirsher return 0; 23277ac6653aSJeff Kirsher } 23287ac6653aSJeff Kirsher 2329c8f44affSMichał Mirosław static netdev_features_t stmmac_fix_features(struct net_device *dev, 2330c8f44affSMichał Mirosław netdev_features_t features) 23317ac6653aSJeff Kirsher { 23327ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23337ac6653aSJeff Kirsher 233438912bdbSDeepak SIKRI if (priv->plat->rx_coe == STMMAC_RX_COE_NONE) 23357ac6653aSJeff Kirsher features &= ~NETIF_F_RXCSUM; 2336d2afb5bdSGiuseppe CAVALLARO 23377ac6653aSJeff Kirsher if (!priv->plat->tx_coe) 23387ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23397ac6653aSJeff Kirsher 23407ac6653aSJeff Kirsher /* Some GMAC devices have a bugged Jumbo frame support that 23417ac6653aSJeff Kirsher * needs to have the Tx COE disabled for oversized frames 23427ac6653aSJeff Kirsher * (due to limited buffer sizes). In this case we disable 2343ceb69499SGiuseppe CAVALLARO * the TX csum insertionin the TDES and not use SF. 2344ceb69499SGiuseppe CAVALLARO */ 23457ac6653aSJeff Kirsher if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) 23467ac6653aSJeff Kirsher features &= ~NETIF_F_ALL_CSUM; 23477ac6653aSJeff Kirsher 23487ac6653aSJeff Kirsher return features; 23497ac6653aSJeff Kirsher } 23507ac6653aSJeff Kirsher 2351d2afb5bdSGiuseppe CAVALLARO static int stmmac_set_features(struct net_device *netdev, 2352d2afb5bdSGiuseppe CAVALLARO netdev_features_t features) 2353d2afb5bdSGiuseppe CAVALLARO { 2354d2afb5bdSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(netdev); 2355d2afb5bdSGiuseppe CAVALLARO 2356d2afb5bdSGiuseppe CAVALLARO /* Keep the COE Type in case of csum is supporting */ 2357d2afb5bdSGiuseppe CAVALLARO if (features & NETIF_F_RXCSUM) 2358d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = priv->plat->rx_coe; 2359d2afb5bdSGiuseppe CAVALLARO else 2360d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = 0; 2361d2afb5bdSGiuseppe CAVALLARO /* No check needed because rx_coe has been set before and it will be 2362d2afb5bdSGiuseppe CAVALLARO * fixed in case of issue. 2363d2afb5bdSGiuseppe CAVALLARO */ 2364d2afb5bdSGiuseppe CAVALLARO priv->hw->mac->rx_ipc(priv->hw); 2365d2afb5bdSGiuseppe CAVALLARO 2366d2afb5bdSGiuseppe CAVALLARO return 0; 2367d2afb5bdSGiuseppe CAVALLARO } 2368d2afb5bdSGiuseppe CAVALLARO 236932ceabcaSGiuseppe CAVALLARO /** 237032ceabcaSGiuseppe CAVALLARO * stmmac_interrupt - main ISR 237132ceabcaSGiuseppe CAVALLARO * @irq: interrupt number. 237232ceabcaSGiuseppe CAVALLARO * @dev_id: to pass the net device pointer. 237332ceabcaSGiuseppe CAVALLARO * Description: this is the main driver interrupt service routine. 237432ceabcaSGiuseppe CAVALLARO * It calls the DMA ISR and also the core ISR to manage PMT, MMC, LPI 237532ceabcaSGiuseppe CAVALLARO * interrupts. 237632ceabcaSGiuseppe CAVALLARO */ 23777ac6653aSJeff Kirsher static irqreturn_t stmmac_interrupt(int irq, void *dev_id) 23787ac6653aSJeff Kirsher { 23797ac6653aSJeff Kirsher struct net_device *dev = (struct net_device *)dev_id; 23807ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 23817ac6653aSJeff Kirsher 238289f7f2cfSSrinivas Kandagatla if (priv->irq_wake) 238389f7f2cfSSrinivas Kandagatla pm_wakeup_event(priv->device, 0); 238489f7f2cfSSrinivas Kandagatla 23857ac6653aSJeff Kirsher if (unlikely(!dev)) { 23867ac6653aSJeff Kirsher pr_err("%s: invalid dev pointer\n", __func__); 23877ac6653aSJeff Kirsher return IRQ_NONE; 23887ac6653aSJeff Kirsher } 23897ac6653aSJeff Kirsher 23907ac6653aSJeff Kirsher /* To handle GMAC own interrupts */ 2391d765955dSGiuseppe CAVALLARO if (priv->plat->has_gmac) { 23927ed24bbeSVince Bridgers int status = priv->hw->mac->host_irq_status(priv->hw, 23930982a0f6SGiuseppe CAVALLARO &priv->xstats); 2394d765955dSGiuseppe CAVALLARO if (unlikely(status)) { 2395d765955dSGiuseppe CAVALLARO /* For LPI we need to save the tx status */ 23960982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_IN_LPI_MODE) 2397d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = true; 23980982a0f6SGiuseppe CAVALLARO if (status & CORE_IRQ_TX_PATH_EXIT_LPI_MODE) 2399d765955dSGiuseppe CAVALLARO priv->tx_path_in_lpi_mode = false; 2400d765955dSGiuseppe CAVALLARO } 2401d765955dSGiuseppe CAVALLARO } 2402d765955dSGiuseppe CAVALLARO 2403d765955dSGiuseppe CAVALLARO /* To handle DMA interrupts */ 24047ac6653aSJeff Kirsher stmmac_dma_interrupt(priv); 24057ac6653aSJeff Kirsher 24067ac6653aSJeff Kirsher return IRQ_HANDLED; 24077ac6653aSJeff Kirsher } 24087ac6653aSJeff Kirsher 24097ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 24107ac6653aSJeff Kirsher /* Polling receive - used by NETCONSOLE and other diagnostic tools 2411ceb69499SGiuseppe CAVALLARO * to allow network I/O with interrupts disabled. 2412ceb69499SGiuseppe CAVALLARO */ 24137ac6653aSJeff Kirsher static void stmmac_poll_controller(struct net_device *dev) 24147ac6653aSJeff Kirsher { 24157ac6653aSJeff Kirsher disable_irq(dev->irq); 24167ac6653aSJeff Kirsher stmmac_interrupt(dev->irq, dev); 24177ac6653aSJeff Kirsher enable_irq(dev->irq); 24187ac6653aSJeff Kirsher } 24197ac6653aSJeff Kirsher #endif 24207ac6653aSJeff Kirsher 24217ac6653aSJeff Kirsher /** 24227ac6653aSJeff Kirsher * stmmac_ioctl - Entry point for the Ioctl 24237ac6653aSJeff Kirsher * @dev: Device pointer. 24247ac6653aSJeff Kirsher * @rq: An IOCTL specefic structure, that can contain a pointer to 24257ac6653aSJeff Kirsher * a proprietary structure used to pass information to the driver. 24267ac6653aSJeff Kirsher * @cmd: IOCTL command 24277ac6653aSJeff Kirsher * Description: 242832ceabcaSGiuseppe CAVALLARO * Currently it supports the phy_mii_ioctl(...) and HW time stamping. 24297ac6653aSJeff Kirsher */ 24307ac6653aSJeff Kirsher static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 24317ac6653aSJeff Kirsher { 24327ac6653aSJeff Kirsher struct stmmac_priv *priv = netdev_priv(dev); 2433891434b1SRayagond Kokatanur int ret = -EOPNOTSUPP; 24347ac6653aSJeff Kirsher 24357ac6653aSJeff Kirsher if (!netif_running(dev)) 24367ac6653aSJeff Kirsher return -EINVAL; 24377ac6653aSJeff Kirsher 2438891434b1SRayagond Kokatanur switch (cmd) { 2439891434b1SRayagond Kokatanur case SIOCGMIIPHY: 2440891434b1SRayagond Kokatanur case SIOCGMIIREG: 2441891434b1SRayagond Kokatanur case SIOCSMIIREG: 24427ac6653aSJeff Kirsher if (!priv->phydev) 24437ac6653aSJeff Kirsher return -EINVAL; 24447ac6653aSJeff Kirsher ret = phy_mii_ioctl(priv->phydev, rq, cmd); 2445891434b1SRayagond Kokatanur break; 2446891434b1SRayagond Kokatanur case SIOCSHWTSTAMP: 2447891434b1SRayagond Kokatanur ret = stmmac_hwtstamp_ioctl(dev, rq); 2448891434b1SRayagond Kokatanur break; 2449891434b1SRayagond Kokatanur default: 2450891434b1SRayagond Kokatanur break; 2451891434b1SRayagond Kokatanur } 24527ac6653aSJeff Kirsher 24537ac6653aSJeff Kirsher return ret; 24547ac6653aSJeff Kirsher } 24557ac6653aSJeff Kirsher 24567ac29055SGiuseppe CAVALLARO #ifdef CONFIG_STMMAC_DEBUG_FS 24577ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_fs_dir; 24587ac29055SGiuseppe CAVALLARO static struct dentry *stmmac_rings_status; 2459e7434821SGiuseppe CAVALLARO static struct dentry *stmmac_dma_cap; 24607ac29055SGiuseppe CAVALLARO 2461c24602efSGiuseppe CAVALLARO static void sysfs_display_ring(void *head, int size, int extend_desc, 2462c24602efSGiuseppe CAVALLARO struct seq_file *seq) 24637ac29055SGiuseppe CAVALLARO { 24647ac29055SGiuseppe CAVALLARO int i; 2465c24602efSGiuseppe CAVALLARO struct dma_extended_desc *ep = (struct dma_extended_desc *)head; 2466c24602efSGiuseppe CAVALLARO struct dma_desc *p = (struct dma_desc *)head; 24677ac29055SGiuseppe CAVALLARO 2468c24602efSGiuseppe CAVALLARO for (i = 0; i < size; i++) { 2469c24602efSGiuseppe CAVALLARO u64 x; 2470c24602efSGiuseppe CAVALLARO if (extend_desc) { 2471c24602efSGiuseppe CAVALLARO x = *(u64 *) ep; 2472c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2473c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2474c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2475c24602efSGiuseppe CAVALLARO ep->basic.des2, ep->basic.des3); 2476c24602efSGiuseppe CAVALLARO ep++; 2477c24602efSGiuseppe CAVALLARO } else { 2478c24602efSGiuseppe CAVALLARO x = *(u64 *) p; 2479c24602efSGiuseppe CAVALLARO seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n", 2480c24602efSGiuseppe CAVALLARO i, (unsigned int)virt_to_phys(ep), 2481c24602efSGiuseppe CAVALLARO (unsigned int)x, (unsigned int)(x >> 32), 2482c24602efSGiuseppe CAVALLARO p->des2, p->des3); 2483c24602efSGiuseppe CAVALLARO p++; 2484c24602efSGiuseppe CAVALLARO } 24857ac29055SGiuseppe CAVALLARO seq_printf(seq, "\n"); 24867ac29055SGiuseppe CAVALLARO } 2487c24602efSGiuseppe CAVALLARO } 24887ac29055SGiuseppe CAVALLARO 2489c24602efSGiuseppe CAVALLARO static int stmmac_sysfs_ring_read(struct seq_file *seq, void *v) 2490c24602efSGiuseppe CAVALLARO { 2491c24602efSGiuseppe CAVALLARO struct net_device *dev = seq->private; 2492c24602efSGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2493c24602efSGiuseppe CAVALLARO unsigned int txsize = priv->dma_tx_size; 2494c24602efSGiuseppe CAVALLARO unsigned int rxsize = priv->dma_rx_size; 24957ac29055SGiuseppe CAVALLARO 2496c24602efSGiuseppe CAVALLARO if (priv->extend_desc) { 2497c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended RX descriptor ring:\n"); 2498c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_erx, rxsize, 1, seq); 2499c24602efSGiuseppe CAVALLARO seq_printf(seq, "Extended TX descriptor ring:\n"); 2500c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_etx, txsize, 1, seq); 2501c24602efSGiuseppe CAVALLARO } else { 2502c24602efSGiuseppe CAVALLARO seq_printf(seq, "RX descriptor ring:\n"); 2503c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_rx, rxsize, 0, seq); 2504c24602efSGiuseppe CAVALLARO seq_printf(seq, "TX descriptor ring:\n"); 2505c24602efSGiuseppe CAVALLARO sysfs_display_ring((void *)priv->dma_tx, txsize, 0, seq); 25067ac29055SGiuseppe CAVALLARO } 25077ac29055SGiuseppe CAVALLARO 25087ac29055SGiuseppe CAVALLARO return 0; 25097ac29055SGiuseppe CAVALLARO } 25107ac29055SGiuseppe CAVALLARO 25117ac29055SGiuseppe CAVALLARO static int stmmac_sysfs_ring_open(struct inode *inode, struct file *file) 25127ac29055SGiuseppe CAVALLARO { 25137ac29055SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_ring_read, inode->i_private); 25147ac29055SGiuseppe CAVALLARO } 25157ac29055SGiuseppe CAVALLARO 25167ac29055SGiuseppe CAVALLARO static const struct file_operations stmmac_rings_status_fops = { 25177ac29055SGiuseppe CAVALLARO .owner = THIS_MODULE, 25187ac29055SGiuseppe CAVALLARO .open = stmmac_sysfs_ring_open, 25197ac29055SGiuseppe CAVALLARO .read = seq_read, 25207ac29055SGiuseppe CAVALLARO .llseek = seq_lseek, 252174863948SDjalal Harouni .release = single_release, 25227ac29055SGiuseppe CAVALLARO }; 25237ac29055SGiuseppe CAVALLARO 2524e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v) 2525e7434821SGiuseppe CAVALLARO { 2526e7434821SGiuseppe CAVALLARO struct net_device *dev = seq->private; 2527e7434821SGiuseppe CAVALLARO struct stmmac_priv *priv = netdev_priv(dev); 2528e7434821SGiuseppe CAVALLARO 252919e30c14SGiuseppe CAVALLARO if (!priv->hw_cap_support) { 2530e7434821SGiuseppe CAVALLARO seq_printf(seq, "DMA HW features not supported\n"); 2531e7434821SGiuseppe CAVALLARO return 0; 2532e7434821SGiuseppe CAVALLARO } 2533e7434821SGiuseppe CAVALLARO 2534e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2535e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tDMA HW features\n"); 2536e7434821SGiuseppe CAVALLARO seq_printf(seq, "==============================\n"); 2537e7434821SGiuseppe CAVALLARO 2538e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t10/100 Mbps %s\n", 2539e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_10_100) ? "Y" : "N"); 2540e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t1000 Mbps %s\n", 2541e7434821SGiuseppe CAVALLARO (priv->dma_cap.mbps_1000) ? "Y" : "N"); 2542e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHalf duple %s\n", 2543e7434821SGiuseppe CAVALLARO (priv->dma_cap.half_duplex) ? "Y" : "N"); 2544e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tHash Filter: %s\n", 2545e7434821SGiuseppe CAVALLARO (priv->dma_cap.hash_filter) ? "Y" : "N"); 2546e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tMultiple MAC address registers: %s\n", 2547e7434821SGiuseppe CAVALLARO (priv->dma_cap.multi_addr) ? "Y" : "N"); 2548e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPCS (TBI/SGMII/RTBI PHY interfatces): %s\n", 2549e7434821SGiuseppe CAVALLARO (priv->dma_cap.pcs) ? "Y" : "N"); 2550e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tSMA (MDIO) Interface: %s\n", 2551e7434821SGiuseppe CAVALLARO (priv->dma_cap.sma_mdio) ? "Y" : "N"); 2552e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Remote wake up: %s\n", 2553e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_remote_wake_up) ? "Y" : "N"); 2554e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tPMT Magic Frame: %s\n", 2555e7434821SGiuseppe CAVALLARO (priv->dma_cap.pmt_magic_frame) ? "Y" : "N"); 2556e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRMON module: %s\n", 2557e7434821SGiuseppe CAVALLARO (priv->dma_cap.rmon) ? "Y" : "N"); 2558e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2002 Time Stamp: %s\n", 2559e7434821SGiuseppe CAVALLARO (priv->dma_cap.time_stamp) ? "Y" : "N"); 2560e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIEEE 1588-2008 Advanced Time Stamp:%s\n", 2561e7434821SGiuseppe CAVALLARO (priv->dma_cap.atime_stamp) ? "Y" : "N"); 2562e7434821SGiuseppe CAVALLARO seq_printf(seq, "\t802.3az - Energy-Efficient Ethernet (EEE) %s\n", 2563e7434821SGiuseppe CAVALLARO (priv->dma_cap.eee) ? "Y" : "N"); 2564e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tAV features: %s\n", (priv->dma_cap.av) ? "Y" : "N"); 2565e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tChecksum Offload in TX: %s\n", 2566e7434821SGiuseppe CAVALLARO (priv->dma_cap.tx_coe) ? "Y" : "N"); 2567e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type1) in RX: %s\n", 2568e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type1) ? "Y" : "N"); 2569e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tIP Checksum Offload (type2) in RX: %s\n", 2570e7434821SGiuseppe CAVALLARO (priv->dma_cap.rx_coe_type2) ? "Y" : "N"); 2571e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tRXFIFO > 2048bytes: %s\n", 2572e7434821SGiuseppe CAVALLARO (priv->dma_cap.rxfifo_over_2048) ? "Y" : "N"); 2573e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional RX channel: %d\n", 2574e7434821SGiuseppe CAVALLARO priv->dma_cap.number_rx_channel); 2575e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tNumber of Additional TX channel: %d\n", 2576e7434821SGiuseppe CAVALLARO priv->dma_cap.number_tx_channel); 2577e7434821SGiuseppe CAVALLARO seq_printf(seq, "\tEnhanced descriptors: %s\n", 2578e7434821SGiuseppe CAVALLARO (priv->dma_cap.enh_desc) ? "Y" : "N"); 2579e7434821SGiuseppe CAVALLARO 2580e7434821SGiuseppe CAVALLARO return 0; 2581e7434821SGiuseppe CAVALLARO } 2582e7434821SGiuseppe CAVALLARO 2583e7434821SGiuseppe CAVALLARO static int stmmac_sysfs_dma_cap_open(struct inode *inode, struct file *file) 2584e7434821SGiuseppe CAVALLARO { 2585e7434821SGiuseppe CAVALLARO return single_open(file, stmmac_sysfs_dma_cap_read, inode->i_private); 2586e7434821SGiuseppe CAVALLARO } 2587e7434821SGiuseppe CAVALLARO 2588e7434821SGiuseppe CAVALLARO static const struct file_operations stmmac_dma_cap_fops = { 2589e7434821SGiuseppe CAVALLARO .owner = THIS_MODULE, 2590e7434821SGiuseppe CAVALLARO .open = stmmac_sysfs_dma_cap_open, 2591e7434821SGiuseppe CAVALLARO .read = seq_read, 2592e7434821SGiuseppe CAVALLARO .llseek = seq_lseek, 259374863948SDjalal Harouni .release = single_release, 2594e7434821SGiuseppe CAVALLARO }; 2595e7434821SGiuseppe CAVALLARO 25967ac29055SGiuseppe CAVALLARO static int stmmac_init_fs(struct net_device *dev) 25977ac29055SGiuseppe CAVALLARO { 25987ac29055SGiuseppe CAVALLARO /* Create debugfs entries */ 25997ac29055SGiuseppe CAVALLARO stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); 26007ac29055SGiuseppe CAVALLARO 26017ac29055SGiuseppe CAVALLARO if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { 26027ac29055SGiuseppe CAVALLARO pr_err("ERROR %s, debugfs create directory failed\n", 26037ac29055SGiuseppe CAVALLARO STMMAC_RESOURCE_NAME); 26047ac29055SGiuseppe CAVALLARO 26057ac29055SGiuseppe CAVALLARO return -ENOMEM; 26067ac29055SGiuseppe CAVALLARO } 26077ac29055SGiuseppe CAVALLARO 26087ac29055SGiuseppe CAVALLARO /* Entry to report DMA RX/TX rings */ 26097ac29055SGiuseppe CAVALLARO stmmac_rings_status = debugfs_create_file("descriptors_status", 26107ac29055SGiuseppe CAVALLARO S_IRUGO, stmmac_fs_dir, dev, 26117ac29055SGiuseppe CAVALLARO &stmmac_rings_status_fops); 26127ac29055SGiuseppe CAVALLARO 26137ac29055SGiuseppe CAVALLARO if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { 26147ac29055SGiuseppe CAVALLARO pr_info("ERROR creating stmmac ring debugfs file\n"); 26157ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 26167ac29055SGiuseppe CAVALLARO 26177ac29055SGiuseppe CAVALLARO return -ENOMEM; 26187ac29055SGiuseppe CAVALLARO } 26197ac29055SGiuseppe CAVALLARO 2620e7434821SGiuseppe CAVALLARO /* Entry to report the DMA HW features */ 2621e7434821SGiuseppe CAVALLARO stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, 2622e7434821SGiuseppe CAVALLARO dev, &stmmac_dma_cap_fops); 2623e7434821SGiuseppe CAVALLARO 2624e7434821SGiuseppe CAVALLARO if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { 2625e7434821SGiuseppe CAVALLARO pr_info("ERROR creating stmmac MMC debugfs file\n"); 2626e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2627e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 2628e7434821SGiuseppe CAVALLARO 2629e7434821SGiuseppe CAVALLARO return -ENOMEM; 2630e7434821SGiuseppe CAVALLARO } 2631e7434821SGiuseppe CAVALLARO 26327ac29055SGiuseppe CAVALLARO return 0; 26337ac29055SGiuseppe CAVALLARO } 26347ac29055SGiuseppe CAVALLARO 26357ac29055SGiuseppe CAVALLARO static void stmmac_exit_fs(void) 26367ac29055SGiuseppe CAVALLARO { 26377ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_rings_status); 2638e7434821SGiuseppe CAVALLARO debugfs_remove(stmmac_dma_cap); 26397ac29055SGiuseppe CAVALLARO debugfs_remove(stmmac_fs_dir); 26407ac29055SGiuseppe CAVALLARO } 26417ac29055SGiuseppe CAVALLARO #endif /* CONFIG_STMMAC_DEBUG_FS */ 26427ac29055SGiuseppe CAVALLARO 26437ac6653aSJeff Kirsher static const struct net_device_ops stmmac_netdev_ops = { 26447ac6653aSJeff Kirsher .ndo_open = stmmac_open, 26457ac6653aSJeff Kirsher .ndo_start_xmit = stmmac_xmit, 26467ac6653aSJeff Kirsher .ndo_stop = stmmac_release, 26477ac6653aSJeff Kirsher .ndo_change_mtu = stmmac_change_mtu, 26487ac6653aSJeff Kirsher .ndo_fix_features = stmmac_fix_features, 2649d2afb5bdSGiuseppe CAVALLARO .ndo_set_features = stmmac_set_features, 265001789349SJiri Pirko .ndo_set_rx_mode = stmmac_set_rx_mode, 26517ac6653aSJeff Kirsher .ndo_tx_timeout = stmmac_tx_timeout, 26527ac6653aSJeff Kirsher .ndo_do_ioctl = stmmac_ioctl, 26537ac6653aSJeff Kirsher #ifdef CONFIG_NET_POLL_CONTROLLER 26547ac6653aSJeff Kirsher .ndo_poll_controller = stmmac_poll_controller, 26557ac6653aSJeff Kirsher #endif 26567ac6653aSJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 26577ac6653aSJeff Kirsher }; 26587ac6653aSJeff Kirsher 26597ac6653aSJeff Kirsher /** 2660cf3f047bSGiuseppe CAVALLARO * stmmac_hw_init - Init the MAC device 266132ceabcaSGiuseppe CAVALLARO * @priv: driver private structure 2662cf3f047bSGiuseppe CAVALLARO * Description: this function detects which MAC device 2663cf3f047bSGiuseppe CAVALLARO * (GMAC/MAC10-100) has to attached, checks the HW capability 2664cf3f047bSGiuseppe CAVALLARO * (if supported) and sets the driver's features (for example 2665cf3f047bSGiuseppe CAVALLARO * to use the ring or chaine mode or support the normal/enh 2666cf3f047bSGiuseppe CAVALLARO * descriptor structure). 2667cf3f047bSGiuseppe CAVALLARO */ 2668cf3f047bSGiuseppe CAVALLARO static int stmmac_hw_init(struct stmmac_priv *priv) 2669cf3f047bSGiuseppe CAVALLARO { 2670cf3f047bSGiuseppe CAVALLARO struct mac_device_info *mac; 2671cf3f047bSGiuseppe CAVALLARO 2672cf3f047bSGiuseppe CAVALLARO /* Identify the MAC HW device */ 267303f2eecdSMarc Kleine-Budde if (priv->plat->has_gmac) { 267403f2eecdSMarc Kleine-Budde priv->dev->priv_flags |= IFF_UNICAST_FLT; 26753b57de95SVince Bridgers mac = dwmac1000_setup(priv->ioaddr, 26763b57de95SVince Bridgers priv->plat->multicast_filter_bins, 26773b57de95SVince Bridgers priv->plat->unicast_filter_entries); 267803f2eecdSMarc Kleine-Budde } else { 2679cf3f047bSGiuseppe CAVALLARO mac = dwmac100_setup(priv->ioaddr); 268003f2eecdSMarc Kleine-Budde } 2681cf3f047bSGiuseppe CAVALLARO if (!mac) 2682cf3f047bSGiuseppe CAVALLARO return -ENOMEM; 2683cf3f047bSGiuseppe CAVALLARO 2684cf3f047bSGiuseppe CAVALLARO priv->hw = mac; 2685cf3f047bSGiuseppe CAVALLARO 2686cf3f047bSGiuseppe CAVALLARO /* Get and dump the chip ID */ 2687cffb13f4SGiuseppe CAVALLARO priv->synopsys_id = stmmac_get_synopsys_id(priv); 2688cf3f047bSGiuseppe CAVALLARO 26894a7d666aSGiuseppe CAVALLARO /* To use the chained or ring mode */ 26904a7d666aSGiuseppe CAVALLARO if (chain_mode) { 269129896a67SGiuseppe CAVALLARO priv->hw->mode = &chain_mode_ops; 26924a7d666aSGiuseppe CAVALLARO pr_info(" Chain mode enabled\n"); 26934a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_CHAIN_MODE; 26944a7d666aSGiuseppe CAVALLARO } else { 269529896a67SGiuseppe CAVALLARO priv->hw->mode = &ring_mode_ops; 26964a7d666aSGiuseppe CAVALLARO pr_info(" Ring mode enabled\n"); 26974a7d666aSGiuseppe CAVALLARO priv->mode = STMMAC_RING_MODE; 26984a7d666aSGiuseppe CAVALLARO } 26994a7d666aSGiuseppe CAVALLARO 2700cf3f047bSGiuseppe CAVALLARO /* Get the HW capability (new GMAC newer than 3.50a) */ 2701cf3f047bSGiuseppe CAVALLARO priv->hw_cap_support = stmmac_get_hw_features(priv); 2702cf3f047bSGiuseppe CAVALLARO if (priv->hw_cap_support) { 2703cf3f047bSGiuseppe CAVALLARO pr_info(" DMA HW capability register supported"); 2704cf3f047bSGiuseppe CAVALLARO 2705cf3f047bSGiuseppe CAVALLARO /* We can override some gmac/dma configuration fields: e.g. 2706cf3f047bSGiuseppe CAVALLARO * enh_desc, tx_coe (e.g. that are passed through the 2707cf3f047bSGiuseppe CAVALLARO * platform) with the values from the HW capability 2708cf3f047bSGiuseppe CAVALLARO * register (if supported). 2709cf3f047bSGiuseppe CAVALLARO */ 2710cf3f047bSGiuseppe CAVALLARO priv->plat->enh_desc = priv->dma_cap.enh_desc; 2711cf3f047bSGiuseppe CAVALLARO priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; 271238912bdbSDeepak SIKRI 271338912bdbSDeepak SIKRI priv->plat->tx_coe = priv->dma_cap.tx_coe; 271438912bdbSDeepak SIKRI 271538912bdbSDeepak SIKRI if (priv->dma_cap.rx_coe_type2) 271638912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE2; 271738912bdbSDeepak SIKRI else if (priv->dma_cap.rx_coe_type1) 271838912bdbSDeepak SIKRI priv->plat->rx_coe = STMMAC_RX_COE_TYPE1; 271938912bdbSDeepak SIKRI 2720cf3f047bSGiuseppe CAVALLARO } else 2721cf3f047bSGiuseppe CAVALLARO pr_info(" No HW DMA feature register supported"); 2722cf3f047bSGiuseppe CAVALLARO 272361369d02SByungho An /* To use alternate (extended) or normal descriptor structures */ 272461369d02SByungho An stmmac_selec_desc_mode(priv); 272561369d02SByungho An 2726d2afb5bdSGiuseppe CAVALLARO if (priv->plat->rx_coe) { 2727d2afb5bdSGiuseppe CAVALLARO priv->hw->rx_csum = priv->plat->rx_coe; 272838912bdbSDeepak SIKRI pr_info(" RX Checksum Offload Engine supported (type %d)\n", 272938912bdbSDeepak SIKRI priv->plat->rx_coe); 2730d2afb5bdSGiuseppe CAVALLARO } 2731cf3f047bSGiuseppe CAVALLARO if (priv->plat->tx_coe) 2732cf3f047bSGiuseppe CAVALLARO pr_info(" TX Checksum insertion supported\n"); 2733cf3f047bSGiuseppe CAVALLARO 2734cf3f047bSGiuseppe CAVALLARO if (priv->plat->pmt) { 2735cf3f047bSGiuseppe CAVALLARO pr_info(" Wake-Up On Lan supported\n"); 2736cf3f047bSGiuseppe CAVALLARO device_set_wakeup_capable(priv->device, 1); 2737cf3f047bSGiuseppe CAVALLARO } 2738cf3f047bSGiuseppe CAVALLARO 2739c24602efSGiuseppe CAVALLARO return 0; 2740cf3f047bSGiuseppe CAVALLARO } 2741cf3f047bSGiuseppe CAVALLARO 2742cf3f047bSGiuseppe CAVALLARO /** 2743bfab27a1SGiuseppe CAVALLARO * stmmac_dvr_probe 2744bfab27a1SGiuseppe CAVALLARO * @device: device pointer 2745ff3dd78cSGiuseppe CAVALLARO * @plat_dat: platform data pointer 2746ff3dd78cSGiuseppe CAVALLARO * @addr: iobase memory address 2747bfab27a1SGiuseppe CAVALLARO * Description: this is the main probe function used to 2748bfab27a1SGiuseppe CAVALLARO * call the alloc_etherdev, allocate the priv structure. 27497ac6653aSJeff Kirsher */ 2750bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *stmmac_dvr_probe(struct device *device, 2751cf3f047bSGiuseppe CAVALLARO struct plat_stmmacenet_data *plat_dat, 2752cf3f047bSGiuseppe CAVALLARO void __iomem *addr) 27537ac6653aSJeff Kirsher { 27547ac6653aSJeff Kirsher int ret = 0; 2755bfab27a1SGiuseppe CAVALLARO struct net_device *ndev = NULL; 2756bfab27a1SGiuseppe CAVALLARO struct stmmac_priv *priv; 27577ac6653aSJeff Kirsher 2758bfab27a1SGiuseppe CAVALLARO ndev = alloc_etherdev(sizeof(struct stmmac_priv)); 275941de8d4cSJoe Perches if (!ndev) 2760bfab27a1SGiuseppe CAVALLARO return NULL; 27617ac6653aSJeff Kirsher 2762bfab27a1SGiuseppe CAVALLARO SET_NETDEV_DEV(ndev, device); 27637ac6653aSJeff Kirsher 2764bfab27a1SGiuseppe CAVALLARO priv = netdev_priv(ndev); 2765bfab27a1SGiuseppe CAVALLARO priv->device = device; 2766bfab27a1SGiuseppe CAVALLARO priv->dev = ndev; 2767bfab27a1SGiuseppe CAVALLARO 2768bfab27a1SGiuseppe CAVALLARO ether_setup(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