1b83f1527SRafal Ozieblo /* 2b83f1527SRafal Ozieblo * Cadence MACB/GEM Ethernet Controller driver 3b83f1527SRafal Ozieblo * 4b83f1527SRafal Ozieblo * Copyright (C) 2004-2006 Atmel Corporation 5b83f1527SRafal Ozieblo * 6b83f1527SRafal Ozieblo * This program is free software; you can redistribute it and/or modify 7b83f1527SRafal Ozieblo * it under the terms of the GNU General Public License version 2 as 8b83f1527SRafal Ozieblo * published by the Free Software Foundation. 9b83f1527SRafal Ozieblo */ 10b83f1527SRafal Ozieblo 11b83f1527SRafal Ozieblo #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 12b83f1527SRafal Ozieblo #include <linux/clk.h> 13653e92a9SClaudiu Beznea #include <linux/crc32.h> 14b83f1527SRafal Ozieblo #include <linux/module.h> 15b83f1527SRafal Ozieblo #include <linux/moduleparam.h> 16b83f1527SRafal Ozieblo #include <linux/kernel.h> 17b83f1527SRafal Ozieblo #include <linux/types.h> 18b83f1527SRafal Ozieblo #include <linux/circ_buf.h> 19b83f1527SRafal Ozieblo #include <linux/slab.h> 20b83f1527SRafal Ozieblo #include <linux/init.h> 21b83f1527SRafal Ozieblo #include <linux/io.h> 22b83f1527SRafal Ozieblo #include <linux/gpio.h> 23b83f1527SRafal Ozieblo #include <linux/gpio/consumer.h> 24b83f1527SRafal Ozieblo #include <linux/interrupt.h> 25b83f1527SRafal Ozieblo #include <linux/netdevice.h> 26b83f1527SRafal Ozieblo #include <linux/etherdevice.h> 27b83f1527SRafal Ozieblo #include <linux/dma-mapping.h> 28b83f1527SRafal Ozieblo #include <linux/platform_data/macb.h> 29b83f1527SRafal Ozieblo #include <linux/platform_device.h> 30b83f1527SRafal Ozieblo #include <linux/phy.h> 31b83f1527SRafal Ozieblo #include <linux/of.h> 32b83f1527SRafal Ozieblo #include <linux/of_device.h> 33b83f1527SRafal Ozieblo #include <linux/of_gpio.h> 34b83f1527SRafal Ozieblo #include <linux/of_mdio.h> 35b83f1527SRafal Ozieblo #include <linux/of_net.h> 36b83f1527SRafal Ozieblo #include <linux/ip.h> 37b83f1527SRafal Ozieblo #include <linux/udp.h> 38b83f1527SRafal Ozieblo #include <linux/tcp.h> 398beb79b7SHarini Katakam #include <linux/iopoll.h> 40d54f89afSHarini Katakam #include <linux/pm_runtime.h> 41b83f1527SRafal Ozieblo #include "macb.h" 42b83f1527SRafal Ozieblo 43b83f1527SRafal Ozieblo #define MACB_RX_BUFFER_SIZE 128 44b83f1527SRafal Ozieblo #define RX_BUFFER_MULTIPLE 64 /* bytes */ 45b83f1527SRafal Ozieblo 46b83f1527SRafal Ozieblo #define DEFAULT_RX_RING_SIZE 512 /* must be power of 2 */ 47b83f1527SRafal Ozieblo #define MIN_RX_RING_SIZE 64 48b83f1527SRafal Ozieblo #define MAX_RX_RING_SIZE 8192 49b83f1527SRafal Ozieblo #define RX_RING_BYTES(bp) (macb_dma_desc_get_size(bp) \ 50b83f1527SRafal Ozieblo * (bp)->rx_ring_size) 51b83f1527SRafal Ozieblo 52b83f1527SRafal Ozieblo #define DEFAULT_TX_RING_SIZE 512 /* must be power of 2 */ 53b83f1527SRafal Ozieblo #define MIN_TX_RING_SIZE 64 54b83f1527SRafal Ozieblo #define MAX_TX_RING_SIZE 4096 55b83f1527SRafal Ozieblo #define TX_RING_BYTES(bp) (macb_dma_desc_get_size(bp) \ 56b83f1527SRafal Ozieblo * (bp)->tx_ring_size) 57b83f1527SRafal Ozieblo 58b83f1527SRafal Ozieblo /* level of occupied TX descriptors under which we wake up TX process */ 59b83f1527SRafal Ozieblo #define MACB_TX_WAKEUP_THRESH(bp) (3 * (bp)->tx_ring_size / 4) 60b83f1527SRafal Ozieblo 61e501070eSHarini Katakam #define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(ISR_ROVR)) 62b83f1527SRafal Ozieblo #define MACB_TX_ERR_FLAGS (MACB_BIT(ISR_TUND) \ 63b83f1527SRafal Ozieblo | MACB_BIT(ISR_RLE) \ 64b83f1527SRafal Ozieblo | MACB_BIT(TXERR)) 6542983885SClaudiu Beznea #define MACB_TX_INT_FLAGS (MACB_TX_ERR_FLAGS | MACB_BIT(TCOMP) \ 6642983885SClaudiu Beznea | MACB_BIT(TXUBR)) 67b83f1527SRafal Ozieblo 68b83f1527SRafal Ozieblo /* Max length of transmit frame must be a multiple of 8 bytes */ 69b83f1527SRafal Ozieblo #define MACB_TX_LEN_ALIGN 8 70b83f1527SRafal Ozieblo #define MACB_MAX_TX_LEN ((unsigned int)((1 << MACB_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1))) 71b83f1527SRafal Ozieblo #define GEM_MAX_TX_LEN ((unsigned int)((1 << GEM_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1))) 72b83f1527SRafal Ozieblo 73b83f1527SRafal Ozieblo #define GEM_MTU_MIN_SIZE ETH_MIN_MTU 74f9c45ae0SDavid S. Miller #define MACB_NETIF_LSO NETIF_F_TSO 75b83f1527SRafal Ozieblo 76b83f1527SRafal Ozieblo #define MACB_WOL_HAS_MAGIC_PACKET (0x1 << 0) 77b83f1527SRafal Ozieblo #define MACB_WOL_ENABLED (0x1 << 1) 78b83f1527SRafal Ozieblo 79b83f1527SRafal Ozieblo /* Graceful stop timeouts in us. We should allow up to 80b83f1527SRafal Ozieblo * 1 frame time (10 Mbits/s, full-duplex, ignoring collisions) 81b83f1527SRafal Ozieblo */ 82b83f1527SRafal Ozieblo #define MACB_HALT_TIMEOUT 1230 83b83f1527SRafal Ozieblo 84d54f89afSHarini Katakam #define MACB_PM_TIMEOUT 100 /* ms */ 85d54f89afSHarini Katakam 868beb79b7SHarini Katakam #define MACB_MDIO_TIMEOUT 1000000 /* in usecs */ 878beb79b7SHarini Katakam 88b83f1527SRafal Ozieblo /* DMA buffer descriptor might be different size 89b83f1527SRafal Ozieblo * depends on hardware configuration: 90b83f1527SRafal Ozieblo * 91b83f1527SRafal Ozieblo * 1. dma address width 32 bits: 92b83f1527SRafal Ozieblo * word 1: 32 bit address of Data Buffer 93b83f1527SRafal Ozieblo * word 2: control 94b83f1527SRafal Ozieblo * 95b83f1527SRafal Ozieblo * 2. dma address width 64 bits: 96b83f1527SRafal Ozieblo * word 1: 32 bit address of Data Buffer 97b83f1527SRafal Ozieblo * word 2: control 98b83f1527SRafal Ozieblo * word 3: upper 32 bit address of Data Buffer 99b83f1527SRafal Ozieblo * word 4: unused 100b83f1527SRafal Ozieblo * 101b83f1527SRafal Ozieblo * 3. dma address width 32 bits with hardware timestamping: 102b83f1527SRafal Ozieblo * word 1: 32 bit address of Data Buffer 103b83f1527SRafal Ozieblo * word 2: control 104b83f1527SRafal Ozieblo * word 3: timestamp word 1 105b83f1527SRafal Ozieblo * word 4: timestamp word 2 106b83f1527SRafal Ozieblo * 107b83f1527SRafal Ozieblo * 4. dma address width 64 bits with hardware timestamping: 108b83f1527SRafal Ozieblo * word 1: 32 bit address of Data Buffer 109b83f1527SRafal Ozieblo * word 2: control 110b83f1527SRafal Ozieblo * word 3: upper 32 bit address of Data Buffer 111b83f1527SRafal Ozieblo * word 4: unused 112b83f1527SRafal Ozieblo * word 5: timestamp word 1 113b83f1527SRafal Ozieblo * word 6: timestamp word 2 114b83f1527SRafal Ozieblo */ 115b83f1527SRafal Ozieblo static unsigned int macb_dma_desc_get_size(struct macb *bp) 116b83f1527SRafal Ozieblo { 117b83f1527SRafal Ozieblo #ifdef MACB_EXT_DESC 118b83f1527SRafal Ozieblo unsigned int desc_size; 119b83f1527SRafal Ozieblo 120b83f1527SRafal Ozieblo switch (bp->hw_dma_cap) { 121b83f1527SRafal Ozieblo case HW_DMA_CAP_64B: 122b83f1527SRafal Ozieblo desc_size = sizeof(struct macb_dma_desc) 123b83f1527SRafal Ozieblo + sizeof(struct macb_dma_desc_64); 124b83f1527SRafal Ozieblo break; 125b83f1527SRafal Ozieblo case HW_DMA_CAP_PTP: 126b83f1527SRafal Ozieblo desc_size = sizeof(struct macb_dma_desc) 127b83f1527SRafal Ozieblo + sizeof(struct macb_dma_desc_ptp); 128b83f1527SRafal Ozieblo break; 129b83f1527SRafal Ozieblo case HW_DMA_CAP_64B_PTP: 130b83f1527SRafal Ozieblo desc_size = sizeof(struct macb_dma_desc) 131b83f1527SRafal Ozieblo + sizeof(struct macb_dma_desc_64) 132b83f1527SRafal Ozieblo + sizeof(struct macb_dma_desc_ptp); 133b83f1527SRafal Ozieblo break; 134b83f1527SRafal Ozieblo default: 135b83f1527SRafal Ozieblo desc_size = sizeof(struct macb_dma_desc); 136b83f1527SRafal Ozieblo } 137b83f1527SRafal Ozieblo return desc_size; 138b83f1527SRafal Ozieblo #endif 139b83f1527SRafal Ozieblo return sizeof(struct macb_dma_desc); 140b83f1527SRafal Ozieblo } 141b83f1527SRafal Ozieblo 142b83f1527SRafal Ozieblo static unsigned int macb_adj_dma_desc_idx(struct macb *bp, unsigned int desc_idx) 143b83f1527SRafal Ozieblo { 144b83f1527SRafal Ozieblo #ifdef MACB_EXT_DESC 145b83f1527SRafal Ozieblo switch (bp->hw_dma_cap) { 146b83f1527SRafal Ozieblo case HW_DMA_CAP_64B: 147b83f1527SRafal Ozieblo case HW_DMA_CAP_PTP: 148b83f1527SRafal Ozieblo desc_idx <<= 1; 149b83f1527SRafal Ozieblo break; 150b83f1527SRafal Ozieblo case HW_DMA_CAP_64B_PTP: 151b83f1527SRafal Ozieblo desc_idx *= 3; 152b83f1527SRafal Ozieblo break; 153b83f1527SRafal Ozieblo default: 154b83f1527SRafal Ozieblo break; 155b83f1527SRafal Ozieblo } 156b83f1527SRafal Ozieblo #endif 157b83f1527SRafal Ozieblo return desc_idx; 158b83f1527SRafal Ozieblo } 159b83f1527SRafal Ozieblo 160b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 161b83f1527SRafal Ozieblo static struct macb_dma_desc_64 *macb_64b_desc(struct macb *bp, struct macb_dma_desc *desc) 162b83f1527SRafal Ozieblo { 163b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) 164b83f1527SRafal Ozieblo return (struct macb_dma_desc_64 *)((void *)desc + sizeof(struct macb_dma_desc)); 165b83f1527SRafal Ozieblo return NULL; 166b83f1527SRafal Ozieblo } 167b83f1527SRafal Ozieblo #endif 168b83f1527SRafal Ozieblo 169b83f1527SRafal Ozieblo /* Ring buffer accessors */ 170b83f1527SRafal Ozieblo static unsigned int macb_tx_ring_wrap(struct macb *bp, unsigned int index) 171b83f1527SRafal Ozieblo { 172b83f1527SRafal Ozieblo return index & (bp->tx_ring_size - 1); 173b83f1527SRafal Ozieblo } 174b83f1527SRafal Ozieblo 175b83f1527SRafal Ozieblo static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue, 176b83f1527SRafal Ozieblo unsigned int index) 177b83f1527SRafal Ozieblo { 178b83f1527SRafal Ozieblo index = macb_tx_ring_wrap(queue->bp, index); 179b83f1527SRafal Ozieblo index = macb_adj_dma_desc_idx(queue->bp, index); 180b83f1527SRafal Ozieblo return &queue->tx_ring[index]; 181b83f1527SRafal Ozieblo } 182b83f1527SRafal Ozieblo 183b83f1527SRafal Ozieblo static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue, 184b83f1527SRafal Ozieblo unsigned int index) 185b83f1527SRafal Ozieblo { 186b83f1527SRafal Ozieblo return &queue->tx_skb[macb_tx_ring_wrap(queue->bp, index)]; 187b83f1527SRafal Ozieblo } 188b83f1527SRafal Ozieblo 189b83f1527SRafal Ozieblo static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index) 190b83f1527SRafal Ozieblo { 191b83f1527SRafal Ozieblo dma_addr_t offset; 192b83f1527SRafal Ozieblo 193b83f1527SRafal Ozieblo offset = macb_tx_ring_wrap(queue->bp, index) * 194b83f1527SRafal Ozieblo macb_dma_desc_get_size(queue->bp); 195b83f1527SRafal Ozieblo 196b83f1527SRafal Ozieblo return queue->tx_ring_dma + offset; 197b83f1527SRafal Ozieblo } 198b83f1527SRafal Ozieblo 199b83f1527SRafal Ozieblo static unsigned int macb_rx_ring_wrap(struct macb *bp, unsigned int index) 200b83f1527SRafal Ozieblo { 201b83f1527SRafal Ozieblo return index & (bp->rx_ring_size - 1); 202b83f1527SRafal Ozieblo } 203b83f1527SRafal Ozieblo 204ae1f2a56SRafal Ozieblo static struct macb_dma_desc *macb_rx_desc(struct macb_queue *queue, unsigned int index) 205b83f1527SRafal Ozieblo { 206ae1f2a56SRafal Ozieblo index = macb_rx_ring_wrap(queue->bp, index); 207ae1f2a56SRafal Ozieblo index = macb_adj_dma_desc_idx(queue->bp, index); 208ae1f2a56SRafal Ozieblo return &queue->rx_ring[index]; 209b83f1527SRafal Ozieblo } 210b83f1527SRafal Ozieblo 211ae1f2a56SRafal Ozieblo static void *macb_rx_buffer(struct macb_queue *queue, unsigned int index) 212b83f1527SRafal Ozieblo { 213ae1f2a56SRafal Ozieblo return queue->rx_buffers + queue->bp->rx_buffer_size * 214ae1f2a56SRafal Ozieblo macb_rx_ring_wrap(queue->bp, index); 215b83f1527SRafal Ozieblo } 216b83f1527SRafal Ozieblo 217b83f1527SRafal Ozieblo /* I/O accessors */ 218b83f1527SRafal Ozieblo static u32 hw_readl_native(struct macb *bp, int offset) 219b83f1527SRafal Ozieblo { 220b83f1527SRafal Ozieblo return __raw_readl(bp->regs + offset); 221b83f1527SRafal Ozieblo } 222b83f1527SRafal Ozieblo 223b83f1527SRafal Ozieblo static void hw_writel_native(struct macb *bp, int offset, u32 value) 224b83f1527SRafal Ozieblo { 225b83f1527SRafal Ozieblo __raw_writel(value, bp->regs + offset); 226b83f1527SRafal Ozieblo } 227b83f1527SRafal Ozieblo 228b83f1527SRafal Ozieblo static u32 hw_readl(struct macb *bp, int offset) 229b83f1527SRafal Ozieblo { 230b83f1527SRafal Ozieblo return readl_relaxed(bp->regs + offset); 231b83f1527SRafal Ozieblo } 232b83f1527SRafal Ozieblo 233b83f1527SRafal Ozieblo static void hw_writel(struct macb *bp, int offset, u32 value) 234b83f1527SRafal Ozieblo { 235b83f1527SRafal Ozieblo writel_relaxed(value, bp->regs + offset); 236b83f1527SRafal Ozieblo } 237b83f1527SRafal Ozieblo 238b83f1527SRafal Ozieblo /* Find the CPU endianness by using the loopback bit of NCR register. When the 239b83f1527SRafal Ozieblo * CPU is in big endian we need to program swapped mode for management 240b83f1527SRafal Ozieblo * descriptor access. 241b83f1527SRafal Ozieblo */ 242b83f1527SRafal Ozieblo static bool hw_is_native_io(void __iomem *addr) 243b83f1527SRafal Ozieblo { 244b83f1527SRafal Ozieblo u32 value = MACB_BIT(LLB); 245b83f1527SRafal Ozieblo 246b83f1527SRafal Ozieblo __raw_writel(value, addr + MACB_NCR); 247b83f1527SRafal Ozieblo value = __raw_readl(addr + MACB_NCR); 248b83f1527SRafal Ozieblo 249b83f1527SRafal Ozieblo /* Write 0 back to disable everything */ 250b83f1527SRafal Ozieblo __raw_writel(0, addr + MACB_NCR); 251b83f1527SRafal Ozieblo 252b83f1527SRafal Ozieblo return value == MACB_BIT(LLB); 253b83f1527SRafal Ozieblo } 254b83f1527SRafal Ozieblo 255b83f1527SRafal Ozieblo static bool hw_is_gem(void __iomem *addr, bool native_io) 256b83f1527SRafal Ozieblo { 257b83f1527SRafal Ozieblo u32 id; 258b83f1527SRafal Ozieblo 259b83f1527SRafal Ozieblo if (native_io) 260b83f1527SRafal Ozieblo id = __raw_readl(addr + MACB_MID); 261b83f1527SRafal Ozieblo else 262b83f1527SRafal Ozieblo id = readl_relaxed(addr + MACB_MID); 263b83f1527SRafal Ozieblo 264b83f1527SRafal Ozieblo return MACB_BFEXT(IDNUM, id) >= 0x2; 265b83f1527SRafal Ozieblo } 266b83f1527SRafal Ozieblo 267b83f1527SRafal Ozieblo static void macb_set_hwaddr(struct macb *bp) 268b83f1527SRafal Ozieblo { 269b83f1527SRafal Ozieblo u32 bottom; 270b83f1527SRafal Ozieblo u16 top; 271b83f1527SRafal Ozieblo 272b83f1527SRafal Ozieblo bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr)); 273b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA1B, bottom); 274b83f1527SRafal Ozieblo top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); 275b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA1T, top); 276b83f1527SRafal Ozieblo 277b83f1527SRafal Ozieblo /* Clear unused address register sets */ 278b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA2B, 0); 279b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA2T, 0); 280b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA3B, 0); 281b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA3T, 0); 282b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA4B, 0); 283b83f1527SRafal Ozieblo macb_or_gem_writel(bp, SA4T, 0); 284b83f1527SRafal Ozieblo } 285b83f1527SRafal Ozieblo 286b83f1527SRafal Ozieblo static void macb_get_hwaddr(struct macb *bp) 287b83f1527SRafal Ozieblo { 288b83f1527SRafal Ozieblo u32 bottom; 289b83f1527SRafal Ozieblo u16 top; 290b83f1527SRafal Ozieblo u8 addr[6]; 291b83f1527SRafal Ozieblo int i; 292b83f1527SRafal Ozieblo 293b83f1527SRafal Ozieblo /* Check all 4 address register for valid address */ 294b83f1527SRafal Ozieblo for (i = 0; i < 4; i++) { 295b83f1527SRafal Ozieblo bottom = macb_or_gem_readl(bp, SA1B + i * 8); 296b83f1527SRafal Ozieblo top = macb_or_gem_readl(bp, SA1T + i * 8); 297b83f1527SRafal Ozieblo 298b83f1527SRafal Ozieblo addr[0] = bottom & 0xff; 299b83f1527SRafal Ozieblo addr[1] = (bottom >> 8) & 0xff; 300b83f1527SRafal Ozieblo addr[2] = (bottom >> 16) & 0xff; 301b83f1527SRafal Ozieblo addr[3] = (bottom >> 24) & 0xff; 302b83f1527SRafal Ozieblo addr[4] = top & 0xff; 303b83f1527SRafal Ozieblo addr[5] = (top >> 8) & 0xff; 304b83f1527SRafal Ozieblo 305b83f1527SRafal Ozieblo if (is_valid_ether_addr(addr)) { 306b83f1527SRafal Ozieblo memcpy(bp->dev->dev_addr, addr, sizeof(addr)); 307b83f1527SRafal Ozieblo return; 308b83f1527SRafal Ozieblo } 309b83f1527SRafal Ozieblo } 310b83f1527SRafal Ozieblo 311b83f1527SRafal Ozieblo dev_info(&bp->pdev->dev, "invalid hw address, using random\n"); 312b83f1527SRafal Ozieblo eth_hw_addr_random(bp->dev); 313b83f1527SRafal Ozieblo } 314b83f1527SRafal Ozieblo 3158beb79b7SHarini Katakam static int macb_mdio_wait_for_idle(struct macb *bp) 3168beb79b7SHarini Katakam { 3178beb79b7SHarini Katakam u32 val; 3188beb79b7SHarini Katakam 3198beb79b7SHarini Katakam return readx_poll_timeout(MACB_READ_NSR, bp, val, val & MACB_BIT(IDLE), 3208beb79b7SHarini Katakam 1, MACB_MDIO_TIMEOUT); 3218beb79b7SHarini Katakam } 3228beb79b7SHarini Katakam 323b83f1527SRafal Ozieblo static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 324b83f1527SRafal Ozieblo { 325b83f1527SRafal Ozieblo struct macb *bp = bus->priv; 326d54f89afSHarini Katakam int status; 3278beb79b7SHarini Katakam 328d54f89afSHarini Katakam status = pm_runtime_get_sync(&bp->pdev->dev); 329d54f89afSHarini Katakam if (status < 0) 330d54f89afSHarini Katakam goto mdio_pm_exit; 331d54f89afSHarini Katakam 332d54f89afSHarini Katakam status = macb_mdio_wait_for_idle(bp); 333d54f89afSHarini Katakam if (status < 0) 334d54f89afSHarini Katakam goto mdio_read_exit; 335b83f1527SRafal Ozieblo 336b83f1527SRafal Ozieblo macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) 337b83f1527SRafal Ozieblo | MACB_BF(RW, MACB_MAN_READ) 338b83f1527SRafal Ozieblo | MACB_BF(PHYA, mii_id) 339b83f1527SRafal Ozieblo | MACB_BF(REGA, regnum) 340b83f1527SRafal Ozieblo | MACB_BF(CODE, MACB_MAN_CODE))); 341b83f1527SRafal Ozieblo 342d54f89afSHarini Katakam status = macb_mdio_wait_for_idle(bp); 343d54f89afSHarini Katakam if (status < 0) 344d54f89afSHarini Katakam goto mdio_read_exit; 345b83f1527SRafal Ozieblo 346d54f89afSHarini Katakam status = MACB_BFEXT(DATA, macb_readl(bp, MAN)); 347b83f1527SRafal Ozieblo 348d54f89afSHarini Katakam mdio_read_exit: 349d54f89afSHarini Katakam pm_runtime_mark_last_busy(&bp->pdev->dev); 350d54f89afSHarini Katakam pm_runtime_put_autosuspend(&bp->pdev->dev); 351d54f89afSHarini Katakam mdio_pm_exit: 352d54f89afSHarini Katakam return status; 353b83f1527SRafal Ozieblo } 354b83f1527SRafal Ozieblo 355b83f1527SRafal Ozieblo static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, 356b83f1527SRafal Ozieblo u16 value) 357b83f1527SRafal Ozieblo { 358b83f1527SRafal Ozieblo struct macb *bp = bus->priv; 359d54f89afSHarini Katakam int status; 3608beb79b7SHarini Katakam 361d54f89afSHarini Katakam status = pm_runtime_get_sync(&bp->pdev->dev); 362d54f89afSHarini Katakam if (status < 0) 363d54f89afSHarini Katakam goto mdio_pm_exit; 364d54f89afSHarini Katakam 365d54f89afSHarini Katakam status = macb_mdio_wait_for_idle(bp); 366d54f89afSHarini Katakam if (status < 0) 367d54f89afSHarini Katakam goto mdio_write_exit; 368b83f1527SRafal Ozieblo 369b83f1527SRafal Ozieblo macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) 370b83f1527SRafal Ozieblo | MACB_BF(RW, MACB_MAN_WRITE) 371b83f1527SRafal Ozieblo | MACB_BF(PHYA, mii_id) 372b83f1527SRafal Ozieblo | MACB_BF(REGA, regnum) 373b83f1527SRafal Ozieblo | MACB_BF(CODE, MACB_MAN_CODE) 374b83f1527SRafal Ozieblo | MACB_BF(DATA, value))); 375b83f1527SRafal Ozieblo 376d54f89afSHarini Katakam status = macb_mdio_wait_for_idle(bp); 377d54f89afSHarini Katakam if (status < 0) 378d54f89afSHarini Katakam goto mdio_write_exit; 379b83f1527SRafal Ozieblo 380d54f89afSHarini Katakam mdio_write_exit: 381d54f89afSHarini Katakam pm_runtime_mark_last_busy(&bp->pdev->dev); 382d54f89afSHarini Katakam pm_runtime_put_autosuspend(&bp->pdev->dev); 383d54f89afSHarini Katakam mdio_pm_exit: 384d54f89afSHarini Katakam return status; 385b83f1527SRafal Ozieblo } 386b83f1527SRafal Ozieblo 387b83f1527SRafal Ozieblo /** 388b83f1527SRafal Ozieblo * macb_set_tx_clk() - Set a clock to a new frequency 389b83f1527SRafal Ozieblo * @clk Pointer to the clock to change 390b83f1527SRafal Ozieblo * @rate New frequency in Hz 391b83f1527SRafal Ozieblo * @dev Pointer to the struct net_device 392b83f1527SRafal Ozieblo */ 393b83f1527SRafal Ozieblo static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev) 394b83f1527SRafal Ozieblo { 395b83f1527SRafal Ozieblo long ferr, rate, rate_rounded; 396b83f1527SRafal Ozieblo 397b83f1527SRafal Ozieblo if (!clk) 398b83f1527SRafal Ozieblo return; 399b83f1527SRafal Ozieblo 400b83f1527SRafal Ozieblo switch (speed) { 401b83f1527SRafal Ozieblo case SPEED_10: 402b83f1527SRafal Ozieblo rate = 2500000; 403b83f1527SRafal Ozieblo break; 404b83f1527SRafal Ozieblo case SPEED_100: 405b83f1527SRafal Ozieblo rate = 25000000; 406b83f1527SRafal Ozieblo break; 407b83f1527SRafal Ozieblo case SPEED_1000: 408b83f1527SRafal Ozieblo rate = 125000000; 409b83f1527SRafal Ozieblo break; 410b83f1527SRafal Ozieblo default: 411b83f1527SRafal Ozieblo return; 412b83f1527SRafal Ozieblo } 413b83f1527SRafal Ozieblo 414b83f1527SRafal Ozieblo rate_rounded = clk_round_rate(clk, rate); 415b83f1527SRafal Ozieblo if (rate_rounded < 0) 416b83f1527SRafal Ozieblo return; 417b83f1527SRafal Ozieblo 418b83f1527SRafal Ozieblo /* RGMII allows 50 ppm frequency error. Test and warn if this limit 419b83f1527SRafal Ozieblo * is not satisfied. 420b83f1527SRafal Ozieblo */ 421b83f1527SRafal Ozieblo ferr = abs(rate_rounded - rate); 422b83f1527SRafal Ozieblo ferr = DIV_ROUND_UP(ferr, rate / 100000); 423b83f1527SRafal Ozieblo if (ferr > 5) 424b83f1527SRafal Ozieblo netdev_warn(dev, "unable to generate target frequency: %ld Hz\n", 425b83f1527SRafal Ozieblo rate); 426b83f1527SRafal Ozieblo 427b83f1527SRafal Ozieblo if (clk_set_rate(clk, rate_rounded)) 428b83f1527SRafal Ozieblo netdev_err(dev, "adjusting tx_clk failed.\n"); 429b83f1527SRafal Ozieblo } 430b83f1527SRafal Ozieblo 431b83f1527SRafal Ozieblo static void macb_handle_link_change(struct net_device *dev) 432b83f1527SRafal Ozieblo { 433b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 434b83f1527SRafal Ozieblo struct phy_device *phydev = dev->phydev; 435b83f1527SRafal Ozieblo unsigned long flags; 436b83f1527SRafal Ozieblo int status_change = 0; 437b83f1527SRafal Ozieblo 438b83f1527SRafal Ozieblo spin_lock_irqsave(&bp->lock, flags); 439b83f1527SRafal Ozieblo 440b83f1527SRafal Ozieblo if (phydev->link) { 441b83f1527SRafal Ozieblo if ((bp->speed != phydev->speed) || 442b83f1527SRafal Ozieblo (bp->duplex != phydev->duplex)) { 443b83f1527SRafal Ozieblo u32 reg; 444b83f1527SRafal Ozieblo 445b83f1527SRafal Ozieblo reg = macb_readl(bp, NCFGR); 446b83f1527SRafal Ozieblo reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); 447b83f1527SRafal Ozieblo if (macb_is_gem(bp)) 448b83f1527SRafal Ozieblo reg &= ~GEM_BIT(GBE); 449b83f1527SRafal Ozieblo 450b83f1527SRafal Ozieblo if (phydev->duplex) 451b83f1527SRafal Ozieblo reg |= MACB_BIT(FD); 452b83f1527SRafal Ozieblo if (phydev->speed == SPEED_100) 453b83f1527SRafal Ozieblo reg |= MACB_BIT(SPD); 454b83f1527SRafal Ozieblo if (phydev->speed == SPEED_1000 && 455b83f1527SRafal Ozieblo bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE) 456b83f1527SRafal Ozieblo reg |= GEM_BIT(GBE); 457b83f1527SRafal Ozieblo 458b83f1527SRafal Ozieblo macb_or_gem_writel(bp, NCFGR, reg); 459b83f1527SRafal Ozieblo 460b83f1527SRafal Ozieblo bp->speed = phydev->speed; 461b83f1527SRafal Ozieblo bp->duplex = phydev->duplex; 462b83f1527SRafal Ozieblo status_change = 1; 463b83f1527SRafal Ozieblo } 464b83f1527SRafal Ozieblo } 465b83f1527SRafal Ozieblo 466b83f1527SRafal Ozieblo if (phydev->link != bp->link) { 467b83f1527SRafal Ozieblo if (!phydev->link) { 468b83f1527SRafal Ozieblo bp->speed = 0; 469b83f1527SRafal Ozieblo bp->duplex = -1; 470b83f1527SRafal Ozieblo } 471b83f1527SRafal Ozieblo bp->link = phydev->link; 472b83f1527SRafal Ozieblo 473b83f1527SRafal Ozieblo status_change = 1; 474b83f1527SRafal Ozieblo } 475b83f1527SRafal Ozieblo 476b83f1527SRafal Ozieblo spin_unlock_irqrestore(&bp->lock, flags); 477b83f1527SRafal Ozieblo 478b83f1527SRafal Ozieblo if (status_change) { 479b83f1527SRafal Ozieblo if (phydev->link) { 480b83f1527SRafal Ozieblo /* Update the TX clock rate if and only if the link is 481b83f1527SRafal Ozieblo * up and there has been a link change. 482b83f1527SRafal Ozieblo */ 483b83f1527SRafal Ozieblo macb_set_tx_clk(bp->tx_clk, phydev->speed, dev); 484b83f1527SRafal Ozieblo 485b83f1527SRafal Ozieblo netif_carrier_on(dev); 486b83f1527SRafal Ozieblo netdev_info(dev, "link up (%d/%s)\n", 487b83f1527SRafal Ozieblo phydev->speed, 488b83f1527SRafal Ozieblo phydev->duplex == DUPLEX_FULL ? 489b83f1527SRafal Ozieblo "Full" : "Half"); 490b83f1527SRafal Ozieblo } else { 491b83f1527SRafal Ozieblo netif_carrier_off(dev); 492b83f1527SRafal Ozieblo netdev_info(dev, "link down\n"); 493b83f1527SRafal Ozieblo } 494b83f1527SRafal Ozieblo } 495b83f1527SRafal Ozieblo } 496b83f1527SRafal Ozieblo 497b83f1527SRafal Ozieblo /* based on au1000_eth. c*/ 498b83f1527SRafal Ozieblo static int macb_mii_probe(struct net_device *dev) 499b83f1527SRafal Ozieblo { 500b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 501b83f1527SRafal Ozieblo struct phy_device *phydev; 502739de9a1SBrad Mouring struct device_node *np; 503*8b952747SNicolas Ferre int ret, i; 504739de9a1SBrad Mouring 505739de9a1SBrad Mouring np = bp->pdev->dev.of_node; 506739de9a1SBrad Mouring ret = 0; 507739de9a1SBrad Mouring 508739de9a1SBrad Mouring if (np) { 509739de9a1SBrad Mouring if (of_phy_is_fixed_link(np)) { 510739de9a1SBrad Mouring bp->phy_node = of_node_get(np); 511739de9a1SBrad Mouring } else { 5122105a5d3SBrad Mouring bp->phy_node = of_parse_phandle(np, "phy-handle", 0); 5132105a5d3SBrad Mouring /* fallback to standard phy registration if no 5142105a5d3SBrad Mouring * phy-handle was found nor any phy found during 5152105a5d3SBrad Mouring * dt phy registration 516739de9a1SBrad Mouring */ 5172105a5d3SBrad Mouring if (!bp->phy_node && !phy_find_first(bp->mii_bus)) { 518739de9a1SBrad Mouring for (i = 0; i < PHY_MAX_ADDR; i++) { 519739de9a1SBrad Mouring phydev = mdiobus_scan(bp->mii_bus, i); 520739de9a1SBrad Mouring if (IS_ERR(phydev) && 521739de9a1SBrad Mouring PTR_ERR(phydev) != -ENODEV) { 522739de9a1SBrad Mouring ret = PTR_ERR(phydev); 523739de9a1SBrad Mouring break; 524739de9a1SBrad Mouring } 525739de9a1SBrad Mouring } 526739de9a1SBrad Mouring 527739de9a1SBrad Mouring if (ret) 528739de9a1SBrad Mouring return -ENODEV; 529739de9a1SBrad Mouring } 530739de9a1SBrad Mouring } 531739de9a1SBrad Mouring } 532b83f1527SRafal Ozieblo 533b83f1527SRafal Ozieblo if (bp->phy_node) { 534b83f1527SRafal Ozieblo phydev = of_phy_connect(dev, bp->phy_node, 535b83f1527SRafal Ozieblo &macb_handle_link_change, 0, 536b83f1527SRafal Ozieblo bp->phy_interface); 537b83f1527SRafal Ozieblo if (!phydev) 538b83f1527SRafal Ozieblo return -ENODEV; 539b83f1527SRafal Ozieblo } else { 540b83f1527SRafal Ozieblo phydev = phy_find_first(bp->mii_bus); 541b83f1527SRafal Ozieblo if (!phydev) { 542b83f1527SRafal Ozieblo netdev_err(dev, "no PHY found\n"); 543b83f1527SRafal Ozieblo return -ENXIO; 544b83f1527SRafal Ozieblo } 545b83f1527SRafal Ozieblo 546b83f1527SRafal Ozieblo /* attach the mac to the phy */ 547b83f1527SRafal Ozieblo ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 548b83f1527SRafal Ozieblo bp->phy_interface); 549b83f1527SRafal Ozieblo if (ret) { 550b83f1527SRafal Ozieblo netdev_err(dev, "Could not attach to PHY\n"); 551b83f1527SRafal Ozieblo return ret; 552b83f1527SRafal Ozieblo } 553b83f1527SRafal Ozieblo } 554b83f1527SRafal Ozieblo 555b83f1527SRafal Ozieblo /* mask with MAC supported features */ 556b83f1527SRafal Ozieblo if (macb_is_gem(bp) && bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE) 55758056c1eSAndrew Lunn phy_set_max_speed(phydev, SPEED_1000); 558b83f1527SRafal Ozieblo else 55958056c1eSAndrew Lunn phy_set_max_speed(phydev, SPEED_100); 560b83f1527SRafal Ozieblo 561b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_NO_GIGABIT_HALF) 56241124fa6SAndrew Lunn phy_remove_link_mode(phydev, 56341124fa6SAndrew Lunn ETHTOOL_LINK_MODE_1000baseT_Half_BIT); 564b83f1527SRafal Ozieblo 565b83f1527SRafal Ozieblo bp->link = 0; 566b83f1527SRafal Ozieblo bp->speed = 0; 567b83f1527SRafal Ozieblo bp->duplex = -1; 568b83f1527SRafal Ozieblo 569b83f1527SRafal Ozieblo return 0; 570b83f1527SRafal Ozieblo } 571b83f1527SRafal Ozieblo 572b83f1527SRafal Ozieblo static int macb_mii_init(struct macb *bp) 573b83f1527SRafal Ozieblo { 574b83f1527SRafal Ozieblo struct device_node *np; 575ab5f1105SAhmad Fatoum int err = -ENXIO; 576b83f1527SRafal Ozieblo 577b83f1527SRafal Ozieblo /* Enable management port */ 578b83f1527SRafal Ozieblo macb_writel(bp, NCR, MACB_BIT(MPE)); 579b83f1527SRafal Ozieblo 580b83f1527SRafal Ozieblo bp->mii_bus = mdiobus_alloc(); 581b83f1527SRafal Ozieblo if (!bp->mii_bus) { 582b83f1527SRafal Ozieblo err = -ENOMEM; 583b83f1527SRafal Ozieblo goto err_out; 584b83f1527SRafal Ozieblo } 585b83f1527SRafal Ozieblo 586b83f1527SRafal Ozieblo bp->mii_bus->name = "MACB_mii_bus"; 587b83f1527SRafal Ozieblo bp->mii_bus->read = &macb_mdio_read; 588b83f1527SRafal Ozieblo bp->mii_bus->write = &macb_mdio_write; 589b83f1527SRafal Ozieblo snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", 590b83f1527SRafal Ozieblo bp->pdev->name, bp->pdev->id); 591b83f1527SRafal Ozieblo bp->mii_bus->priv = bp; 592b83f1527SRafal Ozieblo bp->mii_bus->parent = &bp->pdev->dev; 593b83f1527SRafal Ozieblo 594b83f1527SRafal Ozieblo dev_set_drvdata(&bp->dev->dev, bp->mii_bus); 595b83f1527SRafal Ozieblo 596b83f1527SRafal Ozieblo np = bp->pdev->dev.of_node; 597ab5f1105SAhmad Fatoum if (np && of_phy_is_fixed_link(np)) { 598ab5f1105SAhmad Fatoum if (of_phy_register_fixed_link(np) < 0) { 599ab5f1105SAhmad Fatoum dev_err(&bp->pdev->dev, 600ab5f1105SAhmad Fatoum "broken fixed-link specification %pOF\n", np); 601ab5f1105SAhmad Fatoum goto err_out_free_mdiobus; 602ab5f1105SAhmad Fatoum } 603ab5f1105SAhmad Fatoum 604ab5f1105SAhmad Fatoum err = mdiobus_register(bp->mii_bus); 605ab5f1105SAhmad Fatoum } else { 60600e798c7SFlorian Fainelli err = of_mdiobus_register(bp->mii_bus, np); 607ab5f1105SAhmad Fatoum } 608ab5f1105SAhmad Fatoum 609b83f1527SRafal Ozieblo if (err) 610ab5f1105SAhmad Fatoum goto err_out_free_fixed_link; 611b83f1527SRafal Ozieblo 612b83f1527SRafal Ozieblo err = macb_mii_probe(bp->dev); 613b83f1527SRafal Ozieblo if (err) 614b83f1527SRafal Ozieblo goto err_out_unregister_bus; 615b83f1527SRafal Ozieblo 616b83f1527SRafal Ozieblo return 0; 617b83f1527SRafal Ozieblo 618b83f1527SRafal Ozieblo err_out_unregister_bus: 619b83f1527SRafal Ozieblo mdiobus_unregister(bp->mii_bus); 620ab5f1105SAhmad Fatoum err_out_free_fixed_link: 6219ce98140SMichael Grzeschik if (np && of_phy_is_fixed_link(np)) 6229ce98140SMichael Grzeschik of_phy_deregister_fixed_link(np); 623739de9a1SBrad Mouring err_out_free_mdiobus: 624739de9a1SBrad Mouring of_node_put(bp->phy_node); 625b83f1527SRafal Ozieblo mdiobus_free(bp->mii_bus); 626b83f1527SRafal Ozieblo err_out: 627b83f1527SRafal Ozieblo return err; 628b83f1527SRafal Ozieblo } 629b83f1527SRafal Ozieblo 630b83f1527SRafal Ozieblo static void macb_update_stats(struct macb *bp) 631b83f1527SRafal Ozieblo { 632b83f1527SRafal Ozieblo u32 *p = &bp->hw_stats.macb.rx_pause_frames; 633b83f1527SRafal Ozieblo u32 *end = &bp->hw_stats.macb.tx_pause_frames + 1; 634b83f1527SRafal Ozieblo int offset = MACB_PFR; 635b83f1527SRafal Ozieblo 636b83f1527SRafal Ozieblo WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); 637b83f1527SRafal Ozieblo 638b83f1527SRafal Ozieblo for (; p < end; p++, offset += 4) 639b83f1527SRafal Ozieblo *p += bp->macb_reg_readl(bp, offset); 640b83f1527SRafal Ozieblo } 641b83f1527SRafal Ozieblo 642b83f1527SRafal Ozieblo static int macb_halt_tx(struct macb *bp) 643b83f1527SRafal Ozieblo { 644b83f1527SRafal Ozieblo unsigned long halt_time, timeout; 645b83f1527SRafal Ozieblo u32 status; 646b83f1527SRafal Ozieblo 647b83f1527SRafal Ozieblo macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(THALT)); 648b83f1527SRafal Ozieblo 649b83f1527SRafal Ozieblo timeout = jiffies + usecs_to_jiffies(MACB_HALT_TIMEOUT); 650b83f1527SRafal Ozieblo do { 651b83f1527SRafal Ozieblo halt_time = jiffies; 652b83f1527SRafal Ozieblo status = macb_readl(bp, TSR); 653b83f1527SRafal Ozieblo if (!(status & MACB_BIT(TGO))) 654b83f1527SRafal Ozieblo return 0; 655b83f1527SRafal Ozieblo 65616fe10cfSJia-Ju Bai udelay(250); 657b83f1527SRafal Ozieblo } while (time_before(halt_time, timeout)); 658b83f1527SRafal Ozieblo 659b83f1527SRafal Ozieblo return -ETIMEDOUT; 660b83f1527SRafal Ozieblo } 661b83f1527SRafal Ozieblo 662b83f1527SRafal Ozieblo static void macb_tx_unmap(struct macb *bp, struct macb_tx_skb *tx_skb) 663b83f1527SRafal Ozieblo { 664b83f1527SRafal Ozieblo if (tx_skb->mapping) { 665b83f1527SRafal Ozieblo if (tx_skb->mapped_as_page) 666b83f1527SRafal Ozieblo dma_unmap_page(&bp->pdev->dev, tx_skb->mapping, 667b83f1527SRafal Ozieblo tx_skb->size, DMA_TO_DEVICE); 668b83f1527SRafal Ozieblo else 669b83f1527SRafal Ozieblo dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, 670b83f1527SRafal Ozieblo tx_skb->size, DMA_TO_DEVICE); 671b83f1527SRafal Ozieblo tx_skb->mapping = 0; 672b83f1527SRafal Ozieblo } 673b83f1527SRafal Ozieblo 674b83f1527SRafal Ozieblo if (tx_skb->skb) { 675b83f1527SRafal Ozieblo dev_kfree_skb_any(tx_skb->skb); 676b83f1527SRafal Ozieblo tx_skb->skb = NULL; 677b83f1527SRafal Ozieblo } 678b83f1527SRafal Ozieblo } 679b83f1527SRafal Ozieblo 680b83f1527SRafal Ozieblo static void macb_set_addr(struct macb *bp, struct macb_dma_desc *desc, dma_addr_t addr) 681b83f1527SRafal Ozieblo { 682b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 683b83f1527SRafal Ozieblo struct macb_dma_desc_64 *desc_64; 684b83f1527SRafal Ozieblo 685b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) { 686b83f1527SRafal Ozieblo desc_64 = macb_64b_desc(bp, desc); 687b83f1527SRafal Ozieblo desc_64->addrh = upper_32_bits(addr); 688e100a897SAnssi Hannula /* The low bits of RX address contain the RX_USED bit, clearing 689e100a897SAnssi Hannula * of which allows packet RX. Make sure the high bits are also 690e100a897SAnssi Hannula * visible to HW at that point. 691e100a897SAnssi Hannula */ 692e100a897SAnssi Hannula dma_wmb(); 693b83f1527SRafal Ozieblo } 694b83f1527SRafal Ozieblo #endif 695b83f1527SRafal Ozieblo desc->addr = lower_32_bits(addr); 696b83f1527SRafal Ozieblo } 697b83f1527SRafal Ozieblo 698b83f1527SRafal Ozieblo static dma_addr_t macb_get_addr(struct macb *bp, struct macb_dma_desc *desc) 699b83f1527SRafal Ozieblo { 700b83f1527SRafal Ozieblo dma_addr_t addr = 0; 701b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 702b83f1527SRafal Ozieblo struct macb_dma_desc_64 *desc_64; 703b83f1527SRafal Ozieblo 704b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) { 705b83f1527SRafal Ozieblo desc_64 = macb_64b_desc(bp, desc); 706b83f1527SRafal Ozieblo addr = ((u64)(desc_64->addrh) << 32); 707b83f1527SRafal Ozieblo } 708b83f1527SRafal Ozieblo #endif 709b83f1527SRafal Ozieblo addr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr)); 710b83f1527SRafal Ozieblo return addr; 711b83f1527SRafal Ozieblo } 712b83f1527SRafal Ozieblo 713b83f1527SRafal Ozieblo static void macb_tx_error_task(struct work_struct *work) 714b83f1527SRafal Ozieblo { 715b83f1527SRafal Ozieblo struct macb_queue *queue = container_of(work, struct macb_queue, 716b83f1527SRafal Ozieblo tx_error_task); 717b83f1527SRafal Ozieblo struct macb *bp = queue->bp; 718b83f1527SRafal Ozieblo struct macb_tx_skb *tx_skb; 719b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 720b83f1527SRafal Ozieblo struct sk_buff *skb; 721b83f1527SRafal Ozieblo unsigned int tail; 722b83f1527SRafal Ozieblo unsigned long flags; 723b83f1527SRafal Ozieblo 724b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "macb_tx_error_task: q = %u, t = %u, h = %u\n", 725b83f1527SRafal Ozieblo (unsigned int)(queue - bp->queues), 726b83f1527SRafal Ozieblo queue->tx_tail, queue->tx_head); 727b83f1527SRafal Ozieblo 728b83f1527SRafal Ozieblo /* Prevent the queue IRQ handlers from running: each of them may call 729b83f1527SRafal Ozieblo * macb_tx_interrupt(), which in turn may call netif_wake_subqueue(). 730b83f1527SRafal Ozieblo * As explained below, we have to halt the transmission before updating 731b83f1527SRafal Ozieblo * TBQP registers so we call netif_tx_stop_all_queues() to notify the 732b83f1527SRafal Ozieblo * network engine about the macb/gem being halted. 733b83f1527SRafal Ozieblo */ 734b83f1527SRafal Ozieblo spin_lock_irqsave(&bp->lock, flags); 735b83f1527SRafal Ozieblo 736b83f1527SRafal Ozieblo /* Make sure nobody is trying to queue up new packets */ 737b83f1527SRafal Ozieblo netif_tx_stop_all_queues(bp->dev); 738b83f1527SRafal Ozieblo 739b83f1527SRafal Ozieblo /* Stop transmission now 740b83f1527SRafal Ozieblo * (in case we have just queued new packets) 741b83f1527SRafal Ozieblo * macb/gem must be halted to write TBQP register 742b83f1527SRafal Ozieblo */ 743b83f1527SRafal Ozieblo if (macb_halt_tx(bp)) 744b83f1527SRafal Ozieblo /* Just complain for now, reinitializing TX path can be good */ 745b83f1527SRafal Ozieblo netdev_err(bp->dev, "BUG: halt tx timed out\n"); 746b83f1527SRafal Ozieblo 747b83f1527SRafal Ozieblo /* Treat frames in TX queue including the ones that caused the error. 748b83f1527SRafal Ozieblo * Free transmit buffers in upper layer. 749b83f1527SRafal Ozieblo */ 750b83f1527SRafal Ozieblo for (tail = queue->tx_tail; tail != queue->tx_head; tail++) { 751b83f1527SRafal Ozieblo u32 ctrl; 752b83f1527SRafal Ozieblo 753b83f1527SRafal Ozieblo desc = macb_tx_desc(queue, tail); 754b83f1527SRafal Ozieblo ctrl = desc->ctrl; 755b83f1527SRafal Ozieblo tx_skb = macb_tx_skb(queue, tail); 756b83f1527SRafal Ozieblo skb = tx_skb->skb; 757b83f1527SRafal Ozieblo 758b83f1527SRafal Ozieblo if (ctrl & MACB_BIT(TX_USED)) { 759b83f1527SRafal Ozieblo /* skb is set for the last buffer of the frame */ 760b83f1527SRafal Ozieblo while (!skb) { 761b83f1527SRafal Ozieblo macb_tx_unmap(bp, tx_skb); 762b83f1527SRafal Ozieblo tail++; 763b83f1527SRafal Ozieblo tx_skb = macb_tx_skb(queue, tail); 764b83f1527SRafal Ozieblo skb = tx_skb->skb; 765b83f1527SRafal Ozieblo } 766b83f1527SRafal Ozieblo 767b83f1527SRafal Ozieblo /* ctrl still refers to the first buffer descriptor 768b83f1527SRafal Ozieblo * since it's the only one written back by the hardware 769b83f1527SRafal Ozieblo */ 770b83f1527SRafal Ozieblo if (!(ctrl & MACB_BIT(TX_BUF_EXHAUSTED))) { 771b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n", 772b83f1527SRafal Ozieblo macb_tx_ring_wrap(bp, tail), 773b83f1527SRafal Ozieblo skb->data); 774b83f1527SRafal Ozieblo bp->dev->stats.tx_packets++; 775512286bbSRafal Ozieblo queue->stats.tx_packets++; 776b83f1527SRafal Ozieblo bp->dev->stats.tx_bytes += skb->len; 777512286bbSRafal Ozieblo queue->stats.tx_bytes += skb->len; 778b83f1527SRafal Ozieblo } 779b83f1527SRafal Ozieblo } else { 780b83f1527SRafal Ozieblo /* "Buffers exhausted mid-frame" errors may only happen 781b83f1527SRafal Ozieblo * if the driver is buggy, so complain loudly about 782b83f1527SRafal Ozieblo * those. Statistics are updated by hardware. 783b83f1527SRafal Ozieblo */ 784b83f1527SRafal Ozieblo if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED)) 785b83f1527SRafal Ozieblo netdev_err(bp->dev, 786b83f1527SRafal Ozieblo "BUG: TX buffers exhausted mid-frame\n"); 787b83f1527SRafal Ozieblo 788b83f1527SRafal Ozieblo desc->ctrl = ctrl | MACB_BIT(TX_USED); 789b83f1527SRafal Ozieblo } 790b83f1527SRafal Ozieblo 791b83f1527SRafal Ozieblo macb_tx_unmap(bp, tx_skb); 792b83f1527SRafal Ozieblo } 793b83f1527SRafal Ozieblo 794b83f1527SRafal Ozieblo /* Set end of TX queue */ 795b83f1527SRafal Ozieblo desc = macb_tx_desc(queue, 0); 796b83f1527SRafal Ozieblo macb_set_addr(bp, desc, 0); 797b83f1527SRafal Ozieblo desc->ctrl = MACB_BIT(TX_USED); 798b83f1527SRafal Ozieblo 799b83f1527SRafal Ozieblo /* Make descriptor updates visible to hardware */ 800b83f1527SRafal Ozieblo wmb(); 801b83f1527SRafal Ozieblo 802b83f1527SRafal Ozieblo /* Reinitialize the TX desc queue */ 803b83f1527SRafal Ozieblo queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma)); 804b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 805b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) 806b83f1527SRafal Ozieblo queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma)); 807b83f1527SRafal Ozieblo #endif 808b83f1527SRafal Ozieblo /* Make TX ring reflect state of hardware */ 809b83f1527SRafal Ozieblo queue->tx_head = 0; 810b83f1527SRafal Ozieblo queue->tx_tail = 0; 811b83f1527SRafal Ozieblo 812b83f1527SRafal Ozieblo /* Housework before enabling TX IRQ */ 813b83f1527SRafal Ozieblo macb_writel(bp, TSR, macb_readl(bp, TSR)); 814b83f1527SRafal Ozieblo queue_writel(queue, IER, MACB_TX_INT_FLAGS); 815b83f1527SRafal Ozieblo 816b83f1527SRafal Ozieblo /* Now we are ready to start transmission again */ 817b83f1527SRafal Ozieblo netif_tx_start_all_queues(bp->dev); 818b83f1527SRafal Ozieblo macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); 819b83f1527SRafal Ozieblo 820b83f1527SRafal Ozieblo spin_unlock_irqrestore(&bp->lock, flags); 821b83f1527SRafal Ozieblo } 822b83f1527SRafal Ozieblo 823b83f1527SRafal Ozieblo static void macb_tx_interrupt(struct macb_queue *queue) 824b83f1527SRafal Ozieblo { 825b83f1527SRafal Ozieblo unsigned int tail; 826b83f1527SRafal Ozieblo unsigned int head; 827b83f1527SRafal Ozieblo u32 status; 828b83f1527SRafal Ozieblo struct macb *bp = queue->bp; 829b83f1527SRafal Ozieblo u16 queue_index = queue - bp->queues; 830b83f1527SRafal Ozieblo 831b83f1527SRafal Ozieblo status = macb_readl(bp, TSR); 832b83f1527SRafal Ozieblo macb_writel(bp, TSR, status); 833b83f1527SRafal Ozieblo 834b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 835b83f1527SRafal Ozieblo queue_writel(queue, ISR, MACB_BIT(TCOMP)); 836b83f1527SRafal Ozieblo 837b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "macb_tx_interrupt status = 0x%03lx\n", 838b83f1527SRafal Ozieblo (unsigned long)status); 839b83f1527SRafal Ozieblo 840b83f1527SRafal Ozieblo head = queue->tx_head; 841b83f1527SRafal Ozieblo for (tail = queue->tx_tail; tail != head; tail++) { 842b83f1527SRafal Ozieblo struct macb_tx_skb *tx_skb; 843b83f1527SRafal Ozieblo struct sk_buff *skb; 844b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 845b83f1527SRafal Ozieblo u32 ctrl; 846b83f1527SRafal Ozieblo 847b83f1527SRafal Ozieblo desc = macb_tx_desc(queue, tail); 848b83f1527SRafal Ozieblo 849b83f1527SRafal Ozieblo /* Make hw descriptor updates visible to CPU */ 850b83f1527SRafal Ozieblo rmb(); 851b83f1527SRafal Ozieblo 852b83f1527SRafal Ozieblo ctrl = desc->ctrl; 853b83f1527SRafal Ozieblo 854b83f1527SRafal Ozieblo /* TX_USED bit is only set by hardware on the very first buffer 855b83f1527SRafal Ozieblo * descriptor of the transmitted frame. 856b83f1527SRafal Ozieblo */ 857b83f1527SRafal Ozieblo if (!(ctrl & MACB_BIT(TX_USED))) 858b83f1527SRafal Ozieblo break; 859b83f1527SRafal Ozieblo 860b83f1527SRafal Ozieblo /* Process all buffers of the current transmitted frame */ 861b83f1527SRafal Ozieblo for (;; tail++) { 862b83f1527SRafal Ozieblo tx_skb = macb_tx_skb(queue, tail); 863b83f1527SRafal Ozieblo skb = tx_skb->skb; 864b83f1527SRafal Ozieblo 865b83f1527SRafal Ozieblo /* First, update TX stats if needed */ 866b83f1527SRafal Ozieblo if (skb) { 867a6252047SPaul Thomas if (unlikely(skb_shinfo(skb)->tx_flags & 868a6252047SPaul Thomas SKBTX_HW_TSTAMP) && 869a6252047SPaul Thomas gem_ptp_do_txstamp(queue, skb, desc) == 0) { 870ab91f0a9SRafal Ozieblo /* skb now belongs to timestamp buffer 871ab91f0a9SRafal Ozieblo * and will be removed later 872ab91f0a9SRafal Ozieblo */ 873ab91f0a9SRafal Ozieblo tx_skb->skb = NULL; 874ab91f0a9SRafal Ozieblo } 875b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n", 876b83f1527SRafal Ozieblo macb_tx_ring_wrap(bp, tail), 877b83f1527SRafal Ozieblo skb->data); 878b83f1527SRafal Ozieblo bp->dev->stats.tx_packets++; 879512286bbSRafal Ozieblo queue->stats.tx_packets++; 880b83f1527SRafal Ozieblo bp->dev->stats.tx_bytes += skb->len; 881512286bbSRafal Ozieblo queue->stats.tx_bytes += skb->len; 882b83f1527SRafal Ozieblo } 883b83f1527SRafal Ozieblo 884b83f1527SRafal Ozieblo /* Now we can safely release resources */ 885b83f1527SRafal Ozieblo macb_tx_unmap(bp, tx_skb); 886b83f1527SRafal Ozieblo 887b83f1527SRafal Ozieblo /* skb is set only for the last buffer of the frame. 888b83f1527SRafal Ozieblo * WARNING: at this point skb has been freed by 889b83f1527SRafal Ozieblo * macb_tx_unmap(). 890b83f1527SRafal Ozieblo */ 891b83f1527SRafal Ozieblo if (skb) 892b83f1527SRafal Ozieblo break; 893b83f1527SRafal Ozieblo } 894b83f1527SRafal Ozieblo } 895b83f1527SRafal Ozieblo 896b83f1527SRafal Ozieblo queue->tx_tail = tail; 897b83f1527SRafal Ozieblo if (__netif_subqueue_stopped(bp->dev, queue_index) && 898b83f1527SRafal Ozieblo CIRC_CNT(queue->tx_head, queue->tx_tail, 899b83f1527SRafal Ozieblo bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp)) 900b83f1527SRafal Ozieblo netif_wake_subqueue(bp->dev, queue_index); 901b83f1527SRafal Ozieblo } 902b83f1527SRafal Ozieblo 903ae1f2a56SRafal Ozieblo static void gem_rx_refill(struct macb_queue *queue) 904b83f1527SRafal Ozieblo { 905b83f1527SRafal Ozieblo unsigned int entry; 906b83f1527SRafal Ozieblo struct sk_buff *skb; 907b83f1527SRafal Ozieblo dma_addr_t paddr; 908ae1f2a56SRafal Ozieblo struct macb *bp = queue->bp; 909b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 910b83f1527SRafal Ozieblo 911ae1f2a56SRafal Ozieblo while (CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail, 912b83f1527SRafal Ozieblo bp->rx_ring_size) > 0) { 913ae1f2a56SRafal Ozieblo entry = macb_rx_ring_wrap(bp, queue->rx_prepared_head); 914b83f1527SRafal Ozieblo 915b83f1527SRafal Ozieblo /* Make hw descriptor updates visible to CPU */ 916b83f1527SRafal Ozieblo rmb(); 917b83f1527SRafal Ozieblo 918ae1f2a56SRafal Ozieblo queue->rx_prepared_head++; 919ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, entry); 920b83f1527SRafal Ozieblo 921ae1f2a56SRafal Ozieblo if (!queue->rx_skbuff[entry]) { 922b83f1527SRafal Ozieblo /* allocate sk_buff for this free entry in ring */ 923b83f1527SRafal Ozieblo skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size); 924b83f1527SRafal Ozieblo if (unlikely(!skb)) { 925b83f1527SRafal Ozieblo netdev_err(bp->dev, 926b83f1527SRafal Ozieblo "Unable to allocate sk_buff\n"); 927b83f1527SRafal Ozieblo break; 928b83f1527SRafal Ozieblo } 929b83f1527SRafal Ozieblo 930b83f1527SRafal Ozieblo /* now fill corresponding descriptor entry */ 931b83f1527SRafal Ozieblo paddr = dma_map_single(&bp->pdev->dev, skb->data, 932b83f1527SRafal Ozieblo bp->rx_buffer_size, 933b83f1527SRafal Ozieblo DMA_FROM_DEVICE); 934b83f1527SRafal Ozieblo if (dma_mapping_error(&bp->pdev->dev, paddr)) { 935b83f1527SRafal Ozieblo dev_kfree_skb(skb); 936b83f1527SRafal Ozieblo break; 937b83f1527SRafal Ozieblo } 938b83f1527SRafal Ozieblo 939ae1f2a56SRafal Ozieblo queue->rx_skbuff[entry] = skb; 940b83f1527SRafal Ozieblo 941b83f1527SRafal Ozieblo if (entry == bp->rx_ring_size - 1) 942b83f1527SRafal Ozieblo paddr |= MACB_BIT(RX_WRAP); 943b83f1527SRafal Ozieblo desc->ctrl = 0; 9448159ecabSAnssi Hannula /* Setting addr clears RX_USED and allows reception, 9458159ecabSAnssi Hannula * make sure ctrl is cleared first to avoid a race. 9468159ecabSAnssi Hannula */ 9478159ecabSAnssi Hannula dma_wmb(); 9488159ecabSAnssi Hannula macb_set_addr(bp, desc, paddr); 949b83f1527SRafal Ozieblo 950b83f1527SRafal Ozieblo /* properly align Ethernet header */ 951b83f1527SRafal Ozieblo skb_reserve(skb, NET_IP_ALIGN); 952b83f1527SRafal Ozieblo } else { 953b83f1527SRafal Ozieblo desc->ctrl = 0; 9548159ecabSAnssi Hannula dma_wmb(); 9558159ecabSAnssi Hannula desc->addr &= ~MACB_BIT(RX_USED); 956b83f1527SRafal Ozieblo } 957b83f1527SRafal Ozieblo } 958b83f1527SRafal Ozieblo 959b83f1527SRafal Ozieblo /* Make descriptor updates visible to hardware */ 960b83f1527SRafal Ozieblo wmb(); 961b83f1527SRafal Ozieblo 962ae1f2a56SRafal Ozieblo netdev_vdbg(bp->dev, "rx ring: queue: %p, prepared head %d, tail %d\n", 963ae1f2a56SRafal Ozieblo queue, queue->rx_prepared_head, queue->rx_tail); 964b83f1527SRafal Ozieblo } 965b83f1527SRafal Ozieblo 966b83f1527SRafal Ozieblo /* Mark DMA descriptors from begin up to and not including end as unused */ 967ae1f2a56SRafal Ozieblo static void discard_partial_frame(struct macb_queue *queue, unsigned int begin, 968b83f1527SRafal Ozieblo unsigned int end) 969b83f1527SRafal Ozieblo { 970b83f1527SRafal Ozieblo unsigned int frag; 971b83f1527SRafal Ozieblo 972b83f1527SRafal Ozieblo for (frag = begin; frag != end; frag++) { 973ae1f2a56SRafal Ozieblo struct macb_dma_desc *desc = macb_rx_desc(queue, frag); 974b83f1527SRafal Ozieblo 975b83f1527SRafal Ozieblo desc->addr &= ~MACB_BIT(RX_USED); 976b83f1527SRafal Ozieblo } 977b83f1527SRafal Ozieblo 978b83f1527SRafal Ozieblo /* Make descriptor updates visible to hardware */ 979b83f1527SRafal Ozieblo wmb(); 980b83f1527SRafal Ozieblo 981b83f1527SRafal Ozieblo /* When this happens, the hardware stats registers for 982b83f1527SRafal Ozieblo * whatever caused this is updated, so we don't have to record 983b83f1527SRafal Ozieblo * anything. 984b83f1527SRafal Ozieblo */ 985b83f1527SRafal Ozieblo } 986b83f1527SRafal Ozieblo 987ae1f2a56SRafal Ozieblo static int gem_rx(struct macb_queue *queue, int budget) 988b83f1527SRafal Ozieblo { 989ae1f2a56SRafal Ozieblo struct macb *bp = queue->bp; 990b83f1527SRafal Ozieblo unsigned int len; 991b83f1527SRafal Ozieblo unsigned int entry; 992b83f1527SRafal Ozieblo struct sk_buff *skb; 993b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 994b83f1527SRafal Ozieblo int count = 0; 995b83f1527SRafal Ozieblo 996b83f1527SRafal Ozieblo while (count < budget) { 997b83f1527SRafal Ozieblo u32 ctrl; 998b83f1527SRafal Ozieblo dma_addr_t addr; 999b83f1527SRafal Ozieblo bool rxused; 1000b83f1527SRafal Ozieblo 1001ae1f2a56SRafal Ozieblo entry = macb_rx_ring_wrap(bp, queue->rx_tail); 1002ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, entry); 1003b83f1527SRafal Ozieblo 1004b83f1527SRafal Ozieblo /* Make hw descriptor updates visible to CPU */ 1005b83f1527SRafal Ozieblo rmb(); 1006b83f1527SRafal Ozieblo 1007b83f1527SRafal Ozieblo rxused = (desc->addr & MACB_BIT(RX_USED)) ? true : false; 1008b83f1527SRafal Ozieblo addr = macb_get_addr(bp, desc); 1009b83f1527SRafal Ozieblo 1010b83f1527SRafal Ozieblo if (!rxused) 1011b83f1527SRafal Ozieblo break; 1012b83f1527SRafal Ozieblo 10136e0af298SAnssi Hannula /* Ensure ctrl is at least as up-to-date as rxused */ 10146e0af298SAnssi Hannula dma_rmb(); 10156e0af298SAnssi Hannula 10166e0af298SAnssi Hannula ctrl = desc->ctrl; 10176e0af298SAnssi Hannula 1018ae1f2a56SRafal Ozieblo queue->rx_tail++; 1019b83f1527SRafal Ozieblo count++; 1020b83f1527SRafal Ozieblo 1021b83f1527SRafal Ozieblo if (!(ctrl & MACB_BIT(RX_SOF) && ctrl & MACB_BIT(RX_EOF))) { 1022b83f1527SRafal Ozieblo netdev_err(bp->dev, 1023b83f1527SRafal Ozieblo "not whole frame pointed by descriptor\n"); 1024b83f1527SRafal Ozieblo bp->dev->stats.rx_dropped++; 1025512286bbSRafal Ozieblo queue->stats.rx_dropped++; 1026b83f1527SRafal Ozieblo break; 1027b83f1527SRafal Ozieblo } 1028ae1f2a56SRafal Ozieblo skb = queue->rx_skbuff[entry]; 1029b83f1527SRafal Ozieblo if (unlikely(!skb)) { 1030b83f1527SRafal Ozieblo netdev_err(bp->dev, 1031b83f1527SRafal Ozieblo "inconsistent Rx descriptor chain\n"); 1032b83f1527SRafal Ozieblo bp->dev->stats.rx_dropped++; 1033512286bbSRafal Ozieblo queue->stats.rx_dropped++; 1034b83f1527SRafal Ozieblo break; 1035b83f1527SRafal Ozieblo } 1036b83f1527SRafal Ozieblo /* now everything is ready for receiving packet */ 1037ae1f2a56SRafal Ozieblo queue->rx_skbuff[entry] = NULL; 1038b83f1527SRafal Ozieblo len = ctrl & bp->rx_frm_len_mask; 1039b83f1527SRafal Ozieblo 1040b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "gem_rx %u (len %u)\n", entry, len); 1041b83f1527SRafal Ozieblo 1042b83f1527SRafal Ozieblo skb_put(skb, len); 1043b83f1527SRafal Ozieblo dma_unmap_single(&bp->pdev->dev, addr, 1044b83f1527SRafal Ozieblo bp->rx_buffer_size, DMA_FROM_DEVICE); 1045b83f1527SRafal Ozieblo 1046b83f1527SRafal Ozieblo skb->protocol = eth_type_trans(skb, bp->dev); 1047b83f1527SRafal Ozieblo skb_checksum_none_assert(skb); 1048b83f1527SRafal Ozieblo if (bp->dev->features & NETIF_F_RXCSUM && 1049b83f1527SRafal Ozieblo !(bp->dev->flags & IFF_PROMISC) && 1050b83f1527SRafal Ozieblo GEM_BFEXT(RX_CSUM, ctrl) & GEM_RX_CSUM_CHECKED_MASK) 1051b83f1527SRafal Ozieblo skb->ip_summed = CHECKSUM_UNNECESSARY; 1052b83f1527SRafal Ozieblo 1053b83f1527SRafal Ozieblo bp->dev->stats.rx_packets++; 1054512286bbSRafal Ozieblo queue->stats.rx_packets++; 1055b83f1527SRafal Ozieblo bp->dev->stats.rx_bytes += skb->len; 1056512286bbSRafal Ozieblo queue->stats.rx_bytes += skb->len; 1057b83f1527SRafal Ozieblo 1058ab91f0a9SRafal Ozieblo gem_ptp_do_rxstamp(bp, skb, desc); 1059ab91f0a9SRafal Ozieblo 1060b83f1527SRafal Ozieblo #if defined(DEBUG) && defined(VERBOSE_DEBUG) 1061b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n", 1062b83f1527SRafal Ozieblo skb->len, skb->csum); 1063b83f1527SRafal Ozieblo print_hex_dump(KERN_DEBUG, " mac: ", DUMP_PREFIX_ADDRESS, 16, 1, 1064b83f1527SRafal Ozieblo skb_mac_header(skb), 16, true); 1065b83f1527SRafal Ozieblo print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_ADDRESS, 16, 1, 1066b83f1527SRafal Ozieblo skb->data, 32, true); 1067b83f1527SRafal Ozieblo #endif 1068b83f1527SRafal Ozieblo 1069b83f1527SRafal Ozieblo netif_receive_skb(skb); 1070b83f1527SRafal Ozieblo } 1071b83f1527SRafal Ozieblo 1072ae1f2a56SRafal Ozieblo gem_rx_refill(queue); 1073b83f1527SRafal Ozieblo 1074b83f1527SRafal Ozieblo return count; 1075b83f1527SRafal Ozieblo } 1076b83f1527SRafal Ozieblo 1077ae1f2a56SRafal Ozieblo static int macb_rx_frame(struct macb_queue *queue, unsigned int first_frag, 1078b83f1527SRafal Ozieblo unsigned int last_frag) 1079b83f1527SRafal Ozieblo { 1080b83f1527SRafal Ozieblo unsigned int len; 1081b83f1527SRafal Ozieblo unsigned int frag; 1082b83f1527SRafal Ozieblo unsigned int offset; 1083b83f1527SRafal Ozieblo struct sk_buff *skb; 1084b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 1085ae1f2a56SRafal Ozieblo struct macb *bp = queue->bp; 1086b83f1527SRafal Ozieblo 1087ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, last_frag); 1088b83f1527SRafal Ozieblo len = desc->ctrl & bp->rx_frm_len_mask; 1089b83f1527SRafal Ozieblo 1090b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n", 1091b83f1527SRafal Ozieblo macb_rx_ring_wrap(bp, first_frag), 1092b83f1527SRafal Ozieblo macb_rx_ring_wrap(bp, last_frag), len); 1093b83f1527SRafal Ozieblo 1094b83f1527SRafal Ozieblo /* The ethernet header starts NET_IP_ALIGN bytes into the 1095b83f1527SRafal Ozieblo * first buffer. Since the header is 14 bytes, this makes the 1096b83f1527SRafal Ozieblo * payload word-aligned. 1097b83f1527SRafal Ozieblo * 1098b83f1527SRafal Ozieblo * Instead of calling skb_reserve(NET_IP_ALIGN), we just copy 1099b83f1527SRafal Ozieblo * the two padding bytes into the skb so that we avoid hitting 1100b83f1527SRafal Ozieblo * the slowpath in memcpy(), and pull them off afterwards. 1101b83f1527SRafal Ozieblo */ 1102b83f1527SRafal Ozieblo skb = netdev_alloc_skb(bp->dev, len + NET_IP_ALIGN); 1103b83f1527SRafal Ozieblo if (!skb) { 1104b83f1527SRafal Ozieblo bp->dev->stats.rx_dropped++; 1105b83f1527SRafal Ozieblo for (frag = first_frag; ; frag++) { 1106ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, frag); 1107b83f1527SRafal Ozieblo desc->addr &= ~MACB_BIT(RX_USED); 1108b83f1527SRafal Ozieblo if (frag == last_frag) 1109b83f1527SRafal Ozieblo break; 1110b83f1527SRafal Ozieblo } 1111b83f1527SRafal Ozieblo 1112b83f1527SRafal Ozieblo /* Make descriptor updates visible to hardware */ 1113b83f1527SRafal Ozieblo wmb(); 1114b83f1527SRafal Ozieblo 1115b83f1527SRafal Ozieblo return 1; 1116b83f1527SRafal Ozieblo } 1117b83f1527SRafal Ozieblo 1118b83f1527SRafal Ozieblo offset = 0; 1119b83f1527SRafal Ozieblo len += NET_IP_ALIGN; 1120b83f1527SRafal Ozieblo skb_checksum_none_assert(skb); 1121b83f1527SRafal Ozieblo skb_put(skb, len); 1122b83f1527SRafal Ozieblo 1123b83f1527SRafal Ozieblo for (frag = first_frag; ; frag++) { 1124b83f1527SRafal Ozieblo unsigned int frag_len = bp->rx_buffer_size; 1125b83f1527SRafal Ozieblo 1126b83f1527SRafal Ozieblo if (offset + frag_len > len) { 1127b83f1527SRafal Ozieblo if (unlikely(frag != last_frag)) { 1128b83f1527SRafal Ozieblo dev_kfree_skb_any(skb); 1129b83f1527SRafal Ozieblo return -1; 1130b83f1527SRafal Ozieblo } 1131b83f1527SRafal Ozieblo frag_len = len - offset; 1132b83f1527SRafal Ozieblo } 1133b83f1527SRafal Ozieblo skb_copy_to_linear_data_offset(skb, offset, 1134ae1f2a56SRafal Ozieblo macb_rx_buffer(queue, frag), 1135b83f1527SRafal Ozieblo frag_len); 1136b83f1527SRafal Ozieblo offset += bp->rx_buffer_size; 1137ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, frag); 1138b83f1527SRafal Ozieblo desc->addr &= ~MACB_BIT(RX_USED); 1139b83f1527SRafal Ozieblo 1140b83f1527SRafal Ozieblo if (frag == last_frag) 1141b83f1527SRafal Ozieblo break; 1142b83f1527SRafal Ozieblo } 1143b83f1527SRafal Ozieblo 1144b83f1527SRafal Ozieblo /* Make descriptor updates visible to hardware */ 1145b83f1527SRafal Ozieblo wmb(); 1146b83f1527SRafal Ozieblo 1147b83f1527SRafal Ozieblo __skb_pull(skb, NET_IP_ALIGN); 1148b83f1527SRafal Ozieblo skb->protocol = eth_type_trans(skb, bp->dev); 1149b83f1527SRafal Ozieblo 1150b83f1527SRafal Ozieblo bp->dev->stats.rx_packets++; 1151b83f1527SRafal Ozieblo bp->dev->stats.rx_bytes += skb->len; 1152b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n", 1153b83f1527SRafal Ozieblo skb->len, skb->csum); 1154b83f1527SRafal Ozieblo netif_receive_skb(skb); 1155b83f1527SRafal Ozieblo 1156b83f1527SRafal Ozieblo return 0; 1157b83f1527SRafal Ozieblo } 1158b83f1527SRafal Ozieblo 1159ae1f2a56SRafal Ozieblo static inline void macb_init_rx_ring(struct macb_queue *queue) 1160b83f1527SRafal Ozieblo { 1161ae1f2a56SRafal Ozieblo struct macb *bp = queue->bp; 1162b83f1527SRafal Ozieblo dma_addr_t addr; 1163b83f1527SRafal Ozieblo struct macb_dma_desc *desc = NULL; 1164b83f1527SRafal Ozieblo int i; 1165b83f1527SRafal Ozieblo 1166ae1f2a56SRafal Ozieblo addr = queue->rx_buffers_dma; 1167b83f1527SRafal Ozieblo for (i = 0; i < bp->rx_ring_size; i++) { 1168ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, i); 1169b83f1527SRafal Ozieblo macb_set_addr(bp, desc, addr); 1170b83f1527SRafal Ozieblo desc->ctrl = 0; 1171b83f1527SRafal Ozieblo addr += bp->rx_buffer_size; 1172b83f1527SRafal Ozieblo } 1173b83f1527SRafal Ozieblo desc->addr |= MACB_BIT(RX_WRAP); 1174ae1f2a56SRafal Ozieblo queue->rx_tail = 0; 1175b83f1527SRafal Ozieblo } 1176b83f1527SRafal Ozieblo 1177ae1f2a56SRafal Ozieblo static int macb_rx(struct macb_queue *queue, int budget) 1178b83f1527SRafal Ozieblo { 1179ae1f2a56SRafal Ozieblo struct macb *bp = queue->bp; 1180b83f1527SRafal Ozieblo bool reset_rx_queue = false; 1181b83f1527SRafal Ozieblo int received = 0; 1182b83f1527SRafal Ozieblo unsigned int tail; 1183b83f1527SRafal Ozieblo int first_frag = -1; 1184b83f1527SRafal Ozieblo 1185ae1f2a56SRafal Ozieblo for (tail = queue->rx_tail; budget > 0; tail++) { 1186ae1f2a56SRafal Ozieblo struct macb_dma_desc *desc = macb_rx_desc(queue, tail); 1187b83f1527SRafal Ozieblo u32 ctrl; 1188b83f1527SRafal Ozieblo 1189b83f1527SRafal Ozieblo /* Make hw descriptor updates visible to CPU */ 1190b83f1527SRafal Ozieblo rmb(); 1191b83f1527SRafal Ozieblo 1192b83f1527SRafal Ozieblo if (!(desc->addr & MACB_BIT(RX_USED))) 1193b83f1527SRafal Ozieblo break; 1194b83f1527SRafal Ozieblo 11956e0af298SAnssi Hannula /* Ensure ctrl is at least as up-to-date as addr */ 11966e0af298SAnssi Hannula dma_rmb(); 11976e0af298SAnssi Hannula 11986e0af298SAnssi Hannula ctrl = desc->ctrl; 11996e0af298SAnssi Hannula 1200b83f1527SRafal Ozieblo if (ctrl & MACB_BIT(RX_SOF)) { 1201b83f1527SRafal Ozieblo if (first_frag != -1) 1202ae1f2a56SRafal Ozieblo discard_partial_frame(queue, first_frag, tail); 1203b83f1527SRafal Ozieblo first_frag = tail; 1204b83f1527SRafal Ozieblo } 1205b83f1527SRafal Ozieblo 1206b83f1527SRafal Ozieblo if (ctrl & MACB_BIT(RX_EOF)) { 1207b83f1527SRafal Ozieblo int dropped; 1208b83f1527SRafal Ozieblo 1209b83f1527SRafal Ozieblo if (unlikely(first_frag == -1)) { 1210b83f1527SRafal Ozieblo reset_rx_queue = true; 1211b83f1527SRafal Ozieblo continue; 1212b83f1527SRafal Ozieblo } 1213b83f1527SRafal Ozieblo 1214ae1f2a56SRafal Ozieblo dropped = macb_rx_frame(queue, first_frag, tail); 1215b83f1527SRafal Ozieblo first_frag = -1; 1216b83f1527SRafal Ozieblo if (unlikely(dropped < 0)) { 1217b83f1527SRafal Ozieblo reset_rx_queue = true; 1218b83f1527SRafal Ozieblo continue; 1219b83f1527SRafal Ozieblo } 1220b83f1527SRafal Ozieblo if (!dropped) { 1221b83f1527SRafal Ozieblo received++; 1222b83f1527SRafal Ozieblo budget--; 1223b83f1527SRafal Ozieblo } 1224b83f1527SRafal Ozieblo } 1225b83f1527SRafal Ozieblo } 1226b83f1527SRafal Ozieblo 1227b83f1527SRafal Ozieblo if (unlikely(reset_rx_queue)) { 1228b83f1527SRafal Ozieblo unsigned long flags; 1229b83f1527SRafal Ozieblo u32 ctrl; 1230b83f1527SRafal Ozieblo 1231b83f1527SRafal Ozieblo netdev_err(bp->dev, "RX queue corruption: reset it\n"); 1232b83f1527SRafal Ozieblo 1233b83f1527SRafal Ozieblo spin_lock_irqsave(&bp->lock, flags); 1234b83f1527SRafal Ozieblo 1235b83f1527SRafal Ozieblo ctrl = macb_readl(bp, NCR); 1236b83f1527SRafal Ozieblo macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); 1237b83f1527SRafal Ozieblo 1238ae1f2a56SRafal Ozieblo macb_init_rx_ring(queue); 1239ae1f2a56SRafal Ozieblo queue_writel(queue, RBQP, queue->rx_ring_dma); 1240b83f1527SRafal Ozieblo 1241b83f1527SRafal Ozieblo macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); 1242b83f1527SRafal Ozieblo 1243b83f1527SRafal Ozieblo spin_unlock_irqrestore(&bp->lock, flags); 1244b83f1527SRafal Ozieblo return received; 1245b83f1527SRafal Ozieblo } 1246b83f1527SRafal Ozieblo 1247b83f1527SRafal Ozieblo if (first_frag != -1) 1248ae1f2a56SRafal Ozieblo queue->rx_tail = first_frag; 1249b83f1527SRafal Ozieblo else 1250ae1f2a56SRafal Ozieblo queue->rx_tail = tail; 1251b83f1527SRafal Ozieblo 1252b83f1527SRafal Ozieblo return received; 1253b83f1527SRafal Ozieblo } 1254b83f1527SRafal Ozieblo 1255b83f1527SRafal Ozieblo static int macb_poll(struct napi_struct *napi, int budget) 1256b83f1527SRafal Ozieblo { 1257ae1f2a56SRafal Ozieblo struct macb_queue *queue = container_of(napi, struct macb_queue, napi); 1258ae1f2a56SRafal Ozieblo struct macb *bp = queue->bp; 1259b83f1527SRafal Ozieblo int work_done; 1260b83f1527SRafal Ozieblo u32 status; 1261b83f1527SRafal Ozieblo 1262b83f1527SRafal Ozieblo status = macb_readl(bp, RSR); 1263b83f1527SRafal Ozieblo macb_writel(bp, RSR, status); 1264b83f1527SRafal Ozieblo 1265b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "poll: status = %08lx, budget = %d\n", 1266b83f1527SRafal Ozieblo (unsigned long)status, budget); 1267b83f1527SRafal Ozieblo 1268ae1f2a56SRafal Ozieblo work_done = bp->macbgem_ops.mog_rx(queue, budget); 1269b83f1527SRafal Ozieblo if (work_done < budget) { 1270b83f1527SRafal Ozieblo napi_complete_done(napi, work_done); 1271b83f1527SRafal Ozieblo 1272b83f1527SRafal Ozieblo /* Packets received while interrupts were disabled */ 1273b83f1527SRafal Ozieblo status = macb_readl(bp, RSR); 1274b83f1527SRafal Ozieblo if (status) { 1275b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1276ae1f2a56SRafal Ozieblo queue_writel(queue, ISR, MACB_BIT(RCOMP)); 1277b83f1527SRafal Ozieblo napi_reschedule(napi); 1278b83f1527SRafal Ozieblo } else { 1279e501070eSHarini Katakam queue_writel(queue, IER, bp->rx_intr_mask); 1280b83f1527SRafal Ozieblo } 1281b83f1527SRafal Ozieblo } 1282b83f1527SRafal Ozieblo 1283b83f1527SRafal Ozieblo /* TODO: Handle errors */ 1284b83f1527SRafal Ozieblo 1285b83f1527SRafal Ozieblo return work_done; 1286b83f1527SRafal Ozieblo } 1287b83f1527SRafal Ozieblo 1288032dc41bSHarini Katakam static void macb_hresp_error_task(unsigned long data) 1289032dc41bSHarini Katakam { 1290032dc41bSHarini Katakam struct macb *bp = (struct macb *)data; 1291032dc41bSHarini Katakam struct net_device *dev = bp->dev; 1292032dc41bSHarini Katakam struct macb_queue *queue = bp->queues; 1293032dc41bSHarini Katakam unsigned int q; 1294032dc41bSHarini Katakam u32 ctrl; 1295032dc41bSHarini Katakam 1296032dc41bSHarini Katakam for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 1297e501070eSHarini Katakam queue_writel(queue, IDR, bp->rx_intr_mask | 1298032dc41bSHarini Katakam MACB_TX_INT_FLAGS | 1299032dc41bSHarini Katakam MACB_BIT(HRESP)); 1300032dc41bSHarini Katakam } 1301032dc41bSHarini Katakam ctrl = macb_readl(bp, NCR); 1302032dc41bSHarini Katakam ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE)); 1303032dc41bSHarini Katakam macb_writel(bp, NCR, ctrl); 1304032dc41bSHarini Katakam 1305032dc41bSHarini Katakam netif_tx_stop_all_queues(dev); 1306032dc41bSHarini Katakam netif_carrier_off(dev); 1307032dc41bSHarini Katakam 1308032dc41bSHarini Katakam bp->macbgem_ops.mog_init_rings(bp); 1309032dc41bSHarini Katakam 1310032dc41bSHarini Katakam /* Initialize TX and RX buffers */ 1311032dc41bSHarini Katakam for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 1312032dc41bSHarini Katakam queue_writel(queue, RBQP, lower_32_bits(queue->rx_ring_dma)); 1313032dc41bSHarini Katakam #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 1314032dc41bSHarini Katakam if (bp->hw_dma_cap & HW_DMA_CAP_64B) 1315032dc41bSHarini Katakam queue_writel(queue, RBQPH, 1316032dc41bSHarini Katakam upper_32_bits(queue->rx_ring_dma)); 1317032dc41bSHarini Katakam #endif 1318032dc41bSHarini Katakam queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma)); 1319032dc41bSHarini Katakam #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 1320032dc41bSHarini Katakam if (bp->hw_dma_cap & HW_DMA_CAP_64B) 1321032dc41bSHarini Katakam queue_writel(queue, TBQPH, 1322032dc41bSHarini Katakam upper_32_bits(queue->tx_ring_dma)); 1323032dc41bSHarini Katakam #endif 1324032dc41bSHarini Katakam 1325032dc41bSHarini Katakam /* Enable interrupts */ 1326032dc41bSHarini Katakam queue_writel(queue, IER, 1327e501070eSHarini Katakam bp->rx_intr_mask | 1328032dc41bSHarini Katakam MACB_TX_INT_FLAGS | 1329032dc41bSHarini Katakam MACB_BIT(HRESP)); 1330032dc41bSHarini Katakam } 1331032dc41bSHarini Katakam 1332032dc41bSHarini Katakam ctrl |= MACB_BIT(RE) | MACB_BIT(TE); 1333032dc41bSHarini Katakam macb_writel(bp, NCR, ctrl); 1334032dc41bSHarini Katakam 1335032dc41bSHarini Katakam netif_carrier_on(dev); 1336032dc41bSHarini Katakam netif_tx_start_all_queues(dev); 1337032dc41bSHarini Katakam } 1338032dc41bSHarini Katakam 133942983885SClaudiu Beznea static void macb_tx_restart(struct macb_queue *queue) 134042983885SClaudiu Beznea { 134142983885SClaudiu Beznea unsigned int head = queue->tx_head; 134242983885SClaudiu Beznea unsigned int tail = queue->tx_tail; 134342983885SClaudiu Beznea struct macb *bp = queue->bp; 134442983885SClaudiu Beznea 134542983885SClaudiu Beznea if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 134642983885SClaudiu Beznea queue_writel(queue, ISR, MACB_BIT(TXUBR)); 134742983885SClaudiu Beznea 134842983885SClaudiu Beznea if (head == tail) 134942983885SClaudiu Beznea return; 135042983885SClaudiu Beznea 135142983885SClaudiu Beznea macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); 135242983885SClaudiu Beznea } 135342983885SClaudiu Beznea 1354b83f1527SRafal Ozieblo static irqreturn_t macb_interrupt(int irq, void *dev_id) 1355b83f1527SRafal Ozieblo { 1356b83f1527SRafal Ozieblo struct macb_queue *queue = dev_id; 1357b83f1527SRafal Ozieblo struct macb *bp = queue->bp; 1358b83f1527SRafal Ozieblo struct net_device *dev = bp->dev; 1359b83f1527SRafal Ozieblo u32 status, ctrl; 1360b83f1527SRafal Ozieblo 1361b83f1527SRafal Ozieblo status = queue_readl(queue, ISR); 1362b83f1527SRafal Ozieblo 1363b83f1527SRafal Ozieblo if (unlikely(!status)) 1364b83f1527SRafal Ozieblo return IRQ_NONE; 1365b83f1527SRafal Ozieblo 1366b83f1527SRafal Ozieblo spin_lock(&bp->lock); 1367b83f1527SRafal Ozieblo 1368b83f1527SRafal Ozieblo while (status) { 1369b83f1527SRafal Ozieblo /* close possible race with dev_close */ 1370b83f1527SRafal Ozieblo if (unlikely(!netif_running(dev))) { 1371b83f1527SRafal Ozieblo queue_writel(queue, IDR, -1); 1372b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1373b83f1527SRafal Ozieblo queue_writel(queue, ISR, -1); 1374b83f1527SRafal Ozieblo break; 1375b83f1527SRafal Ozieblo } 1376b83f1527SRafal Ozieblo 1377b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "queue = %u, isr = 0x%08lx\n", 1378b83f1527SRafal Ozieblo (unsigned int)(queue - bp->queues), 1379b83f1527SRafal Ozieblo (unsigned long)status); 1380b83f1527SRafal Ozieblo 1381e501070eSHarini Katakam if (status & bp->rx_intr_mask) { 1382b83f1527SRafal Ozieblo /* There's no point taking any more interrupts 1383b83f1527SRafal Ozieblo * until we have processed the buffers. The 1384b83f1527SRafal Ozieblo * scheduling call may fail if the poll routine 1385b83f1527SRafal Ozieblo * is already scheduled, so disable interrupts 1386b83f1527SRafal Ozieblo * now. 1387b83f1527SRafal Ozieblo */ 1388e501070eSHarini Katakam queue_writel(queue, IDR, bp->rx_intr_mask); 1389b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1390b83f1527SRafal Ozieblo queue_writel(queue, ISR, MACB_BIT(RCOMP)); 1391b83f1527SRafal Ozieblo 1392ae1f2a56SRafal Ozieblo if (napi_schedule_prep(&queue->napi)) { 1393b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, "scheduling RX softirq\n"); 1394ae1f2a56SRafal Ozieblo __napi_schedule(&queue->napi); 1395b83f1527SRafal Ozieblo } 1396b83f1527SRafal Ozieblo } 1397b83f1527SRafal Ozieblo 1398b83f1527SRafal Ozieblo if (unlikely(status & (MACB_TX_ERR_FLAGS))) { 1399b83f1527SRafal Ozieblo queue_writel(queue, IDR, MACB_TX_INT_FLAGS); 1400b83f1527SRafal Ozieblo schedule_work(&queue->tx_error_task); 1401b83f1527SRafal Ozieblo 1402b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1403b83f1527SRafal Ozieblo queue_writel(queue, ISR, MACB_TX_ERR_FLAGS); 1404b83f1527SRafal Ozieblo 1405b83f1527SRafal Ozieblo break; 1406b83f1527SRafal Ozieblo } 1407b83f1527SRafal Ozieblo 1408b83f1527SRafal Ozieblo if (status & MACB_BIT(TCOMP)) 1409b83f1527SRafal Ozieblo macb_tx_interrupt(queue); 1410b83f1527SRafal Ozieblo 141142983885SClaudiu Beznea if (status & MACB_BIT(TXUBR)) 141242983885SClaudiu Beznea macb_tx_restart(queue); 141342983885SClaudiu Beznea 1414b83f1527SRafal Ozieblo /* Link change detection isn't possible with RMII, so we'll 1415b83f1527SRafal Ozieblo * add that if/when we get our hands on a full-blown MII PHY. 1416b83f1527SRafal Ozieblo */ 1417b83f1527SRafal Ozieblo 1418b83f1527SRafal Ozieblo /* There is a hardware issue under heavy load where DMA can 1419b83f1527SRafal Ozieblo * stop, this causes endless "used buffer descriptor read" 1420b83f1527SRafal Ozieblo * interrupts but it can be cleared by re-enabling RX. See 1421e501070eSHarini Katakam * the at91rm9200 manual, section 41.3.1 or the Zynq manual 1422e501070eSHarini Katakam * section 16.7.4 for details. RXUBR is only enabled for 1423e501070eSHarini Katakam * these two versions. 1424b83f1527SRafal Ozieblo */ 1425b83f1527SRafal Ozieblo if (status & MACB_BIT(RXUBR)) { 1426b83f1527SRafal Ozieblo ctrl = macb_readl(bp, NCR); 1427b83f1527SRafal Ozieblo macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE)); 1428b83f1527SRafal Ozieblo wmb(); 1429b83f1527SRafal Ozieblo macb_writel(bp, NCR, ctrl | MACB_BIT(RE)); 1430b83f1527SRafal Ozieblo 1431b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1432b83f1527SRafal Ozieblo queue_writel(queue, ISR, MACB_BIT(RXUBR)); 1433b83f1527SRafal Ozieblo } 1434b83f1527SRafal Ozieblo 1435b83f1527SRafal Ozieblo if (status & MACB_BIT(ISR_ROVR)) { 1436b83f1527SRafal Ozieblo /* We missed at least one packet */ 1437b83f1527SRafal Ozieblo if (macb_is_gem(bp)) 1438b83f1527SRafal Ozieblo bp->hw_stats.gem.rx_overruns++; 1439b83f1527SRafal Ozieblo else 1440b83f1527SRafal Ozieblo bp->hw_stats.macb.rx_overruns++; 1441b83f1527SRafal Ozieblo 1442b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1443b83f1527SRafal Ozieblo queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); 1444b83f1527SRafal Ozieblo } 1445b83f1527SRafal Ozieblo 1446b83f1527SRafal Ozieblo if (status & MACB_BIT(HRESP)) { 1447032dc41bSHarini Katakam tasklet_schedule(&bp->hresp_err_tasklet); 1448b83f1527SRafal Ozieblo netdev_err(dev, "DMA bus error: HRESP not OK\n"); 1449b83f1527SRafal Ozieblo 1450b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 1451b83f1527SRafal Ozieblo queue_writel(queue, ISR, MACB_BIT(HRESP)); 1452b83f1527SRafal Ozieblo } 1453b83f1527SRafal Ozieblo status = queue_readl(queue, ISR); 1454b83f1527SRafal Ozieblo } 1455b83f1527SRafal Ozieblo 1456b83f1527SRafal Ozieblo spin_unlock(&bp->lock); 1457b83f1527SRafal Ozieblo 1458b83f1527SRafal Ozieblo return IRQ_HANDLED; 1459b83f1527SRafal Ozieblo } 1460b83f1527SRafal Ozieblo 1461b83f1527SRafal Ozieblo #ifdef CONFIG_NET_POLL_CONTROLLER 1462b83f1527SRafal Ozieblo /* Polling receive - used by netconsole and other diagnostic tools 1463b83f1527SRafal Ozieblo * to allow network i/o with interrupts disabled. 1464b83f1527SRafal Ozieblo */ 1465b83f1527SRafal Ozieblo static void macb_poll_controller(struct net_device *dev) 1466b83f1527SRafal Ozieblo { 1467b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 1468b83f1527SRafal Ozieblo struct macb_queue *queue; 1469b83f1527SRafal Ozieblo unsigned long flags; 1470b83f1527SRafal Ozieblo unsigned int q; 1471b83f1527SRafal Ozieblo 1472b83f1527SRafal Ozieblo local_irq_save(flags); 1473b83f1527SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) 1474b83f1527SRafal Ozieblo macb_interrupt(dev->irq, queue); 1475b83f1527SRafal Ozieblo local_irq_restore(flags); 1476b83f1527SRafal Ozieblo } 1477b83f1527SRafal Ozieblo #endif 1478b83f1527SRafal Ozieblo 1479b83f1527SRafal Ozieblo static unsigned int macb_tx_map(struct macb *bp, 1480b83f1527SRafal Ozieblo struct macb_queue *queue, 1481b83f1527SRafal Ozieblo struct sk_buff *skb, 1482b83f1527SRafal Ozieblo unsigned int hdrlen) 1483b83f1527SRafal Ozieblo { 1484b83f1527SRafal Ozieblo dma_addr_t mapping; 1485b83f1527SRafal Ozieblo unsigned int len, entry, i, tx_head = queue->tx_head; 1486b83f1527SRafal Ozieblo struct macb_tx_skb *tx_skb = NULL; 1487b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 1488b83f1527SRafal Ozieblo unsigned int offset, size, count = 0; 1489b83f1527SRafal Ozieblo unsigned int f, nr_frags = skb_shinfo(skb)->nr_frags; 1490b83f1527SRafal Ozieblo unsigned int eof = 1, mss_mfs = 0; 1491b83f1527SRafal Ozieblo u32 ctrl, lso_ctrl = 0, seq_ctrl = 0; 1492b83f1527SRafal Ozieblo 1493b83f1527SRafal Ozieblo /* LSO */ 1494b83f1527SRafal Ozieblo if (skb_shinfo(skb)->gso_size != 0) { 1495b83f1527SRafal Ozieblo if (ip_hdr(skb)->protocol == IPPROTO_UDP) 1496b83f1527SRafal Ozieblo /* UDP - UFO */ 1497b83f1527SRafal Ozieblo lso_ctrl = MACB_LSO_UFO_ENABLE; 1498b83f1527SRafal Ozieblo else 1499b83f1527SRafal Ozieblo /* TCP - TSO */ 1500b83f1527SRafal Ozieblo lso_ctrl = MACB_LSO_TSO_ENABLE; 1501b83f1527SRafal Ozieblo } 1502b83f1527SRafal Ozieblo 1503b83f1527SRafal Ozieblo /* First, map non-paged data */ 1504b83f1527SRafal Ozieblo len = skb_headlen(skb); 1505b83f1527SRafal Ozieblo 1506b83f1527SRafal Ozieblo /* first buffer length */ 1507b83f1527SRafal Ozieblo size = hdrlen; 1508b83f1527SRafal Ozieblo 1509b83f1527SRafal Ozieblo offset = 0; 1510b83f1527SRafal Ozieblo while (len) { 1511b83f1527SRafal Ozieblo entry = macb_tx_ring_wrap(bp, tx_head); 1512b83f1527SRafal Ozieblo tx_skb = &queue->tx_skb[entry]; 1513b83f1527SRafal Ozieblo 1514b83f1527SRafal Ozieblo mapping = dma_map_single(&bp->pdev->dev, 1515b83f1527SRafal Ozieblo skb->data + offset, 1516b83f1527SRafal Ozieblo size, DMA_TO_DEVICE); 1517b83f1527SRafal Ozieblo if (dma_mapping_error(&bp->pdev->dev, mapping)) 1518b83f1527SRafal Ozieblo goto dma_error; 1519b83f1527SRafal Ozieblo 1520b83f1527SRafal Ozieblo /* Save info to properly release resources */ 1521b83f1527SRafal Ozieblo tx_skb->skb = NULL; 1522b83f1527SRafal Ozieblo tx_skb->mapping = mapping; 1523b83f1527SRafal Ozieblo tx_skb->size = size; 1524b83f1527SRafal Ozieblo tx_skb->mapped_as_page = false; 1525b83f1527SRafal Ozieblo 1526b83f1527SRafal Ozieblo len -= size; 1527b83f1527SRafal Ozieblo offset += size; 1528b83f1527SRafal Ozieblo count++; 1529b83f1527SRafal Ozieblo tx_head++; 1530b83f1527SRafal Ozieblo 1531b83f1527SRafal Ozieblo size = min(len, bp->max_tx_length); 1532b83f1527SRafal Ozieblo } 1533b83f1527SRafal Ozieblo 1534b83f1527SRafal Ozieblo /* Then, map paged data from fragments */ 1535b83f1527SRafal Ozieblo for (f = 0; f < nr_frags; f++) { 1536b83f1527SRafal Ozieblo const skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; 1537b83f1527SRafal Ozieblo 1538b83f1527SRafal Ozieblo len = skb_frag_size(frag); 1539b83f1527SRafal Ozieblo offset = 0; 1540b83f1527SRafal Ozieblo while (len) { 1541b83f1527SRafal Ozieblo size = min(len, bp->max_tx_length); 1542b83f1527SRafal Ozieblo entry = macb_tx_ring_wrap(bp, tx_head); 1543b83f1527SRafal Ozieblo tx_skb = &queue->tx_skb[entry]; 1544b83f1527SRafal Ozieblo 1545b83f1527SRafal Ozieblo mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 1546b83f1527SRafal Ozieblo offset, size, DMA_TO_DEVICE); 1547b83f1527SRafal Ozieblo if (dma_mapping_error(&bp->pdev->dev, mapping)) 1548b83f1527SRafal Ozieblo goto dma_error; 1549b83f1527SRafal Ozieblo 1550b83f1527SRafal Ozieblo /* Save info to properly release resources */ 1551b83f1527SRafal Ozieblo tx_skb->skb = NULL; 1552b83f1527SRafal Ozieblo tx_skb->mapping = mapping; 1553b83f1527SRafal Ozieblo tx_skb->size = size; 1554b83f1527SRafal Ozieblo tx_skb->mapped_as_page = true; 1555b83f1527SRafal Ozieblo 1556b83f1527SRafal Ozieblo len -= size; 1557b83f1527SRafal Ozieblo offset += size; 1558b83f1527SRafal Ozieblo count++; 1559b83f1527SRafal Ozieblo tx_head++; 1560b83f1527SRafal Ozieblo } 1561b83f1527SRafal Ozieblo } 1562b83f1527SRafal Ozieblo 1563b83f1527SRafal Ozieblo /* Should never happen */ 1564b83f1527SRafal Ozieblo if (unlikely(!tx_skb)) { 1565b83f1527SRafal Ozieblo netdev_err(bp->dev, "BUG! empty skb!\n"); 1566b83f1527SRafal Ozieblo return 0; 1567b83f1527SRafal Ozieblo } 1568b83f1527SRafal Ozieblo 1569b83f1527SRafal Ozieblo /* This is the last buffer of the frame: save socket buffer */ 1570b83f1527SRafal Ozieblo tx_skb->skb = skb; 1571b83f1527SRafal Ozieblo 1572b83f1527SRafal Ozieblo /* Update TX ring: update buffer descriptors in reverse order 1573b83f1527SRafal Ozieblo * to avoid race condition 1574b83f1527SRafal Ozieblo */ 1575b83f1527SRafal Ozieblo 1576b83f1527SRafal Ozieblo /* Set 'TX_USED' bit in buffer descriptor at tx_head position 1577b83f1527SRafal Ozieblo * to set the end of TX queue 1578b83f1527SRafal Ozieblo */ 1579b83f1527SRafal Ozieblo i = tx_head; 1580b83f1527SRafal Ozieblo entry = macb_tx_ring_wrap(bp, i); 1581b83f1527SRafal Ozieblo ctrl = MACB_BIT(TX_USED); 1582b83f1527SRafal Ozieblo desc = macb_tx_desc(queue, entry); 1583b83f1527SRafal Ozieblo desc->ctrl = ctrl; 1584b83f1527SRafal Ozieblo 1585b83f1527SRafal Ozieblo if (lso_ctrl) { 1586b83f1527SRafal Ozieblo if (lso_ctrl == MACB_LSO_UFO_ENABLE) 1587b83f1527SRafal Ozieblo /* include header and FCS in value given to h/w */ 1588b83f1527SRafal Ozieblo mss_mfs = skb_shinfo(skb)->gso_size + 1589b83f1527SRafal Ozieblo skb_transport_offset(skb) + 1590b83f1527SRafal Ozieblo ETH_FCS_LEN; 1591b83f1527SRafal Ozieblo else /* TSO */ { 1592b83f1527SRafal Ozieblo mss_mfs = skb_shinfo(skb)->gso_size; 1593b83f1527SRafal Ozieblo /* TCP Sequence Number Source Select 1594b83f1527SRafal Ozieblo * can be set only for TSO 1595b83f1527SRafal Ozieblo */ 1596b83f1527SRafal Ozieblo seq_ctrl = 0; 1597b83f1527SRafal Ozieblo } 1598b83f1527SRafal Ozieblo } 1599b83f1527SRafal Ozieblo 1600b83f1527SRafal Ozieblo do { 1601b83f1527SRafal Ozieblo i--; 1602b83f1527SRafal Ozieblo entry = macb_tx_ring_wrap(bp, i); 1603b83f1527SRafal Ozieblo tx_skb = &queue->tx_skb[entry]; 1604b83f1527SRafal Ozieblo desc = macb_tx_desc(queue, entry); 1605b83f1527SRafal Ozieblo 1606b83f1527SRafal Ozieblo ctrl = (u32)tx_skb->size; 1607b83f1527SRafal Ozieblo if (eof) { 1608b83f1527SRafal Ozieblo ctrl |= MACB_BIT(TX_LAST); 1609b83f1527SRafal Ozieblo eof = 0; 1610b83f1527SRafal Ozieblo } 1611b83f1527SRafal Ozieblo if (unlikely(entry == (bp->tx_ring_size - 1))) 1612b83f1527SRafal Ozieblo ctrl |= MACB_BIT(TX_WRAP); 1613b83f1527SRafal Ozieblo 1614b83f1527SRafal Ozieblo /* First descriptor is header descriptor */ 1615b83f1527SRafal Ozieblo if (i == queue->tx_head) { 1616b83f1527SRafal Ozieblo ctrl |= MACB_BF(TX_LSO, lso_ctrl); 1617b83f1527SRafal Ozieblo ctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl); 1618653e92a9SClaudiu Beznea if ((bp->dev->features & NETIF_F_HW_CSUM) && 1619653e92a9SClaudiu Beznea skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl) 1620653e92a9SClaudiu Beznea ctrl |= MACB_BIT(TX_NOCRC); 1621b83f1527SRafal Ozieblo } else 1622b83f1527SRafal Ozieblo /* Only set MSS/MFS on payload descriptors 1623b83f1527SRafal Ozieblo * (second or later descriptor) 1624b83f1527SRafal Ozieblo */ 1625b83f1527SRafal Ozieblo ctrl |= MACB_BF(MSS_MFS, mss_mfs); 1626b83f1527SRafal Ozieblo 1627b83f1527SRafal Ozieblo /* Set TX buffer descriptor */ 1628b83f1527SRafal Ozieblo macb_set_addr(bp, desc, tx_skb->mapping); 1629b83f1527SRafal Ozieblo /* desc->addr must be visible to hardware before clearing 1630b83f1527SRafal Ozieblo * 'TX_USED' bit in desc->ctrl. 1631b83f1527SRafal Ozieblo */ 1632b83f1527SRafal Ozieblo wmb(); 1633b83f1527SRafal Ozieblo desc->ctrl = ctrl; 1634b83f1527SRafal Ozieblo } while (i != queue->tx_head); 1635b83f1527SRafal Ozieblo 1636b83f1527SRafal Ozieblo queue->tx_head = tx_head; 1637b83f1527SRafal Ozieblo 1638b83f1527SRafal Ozieblo return count; 1639b83f1527SRafal Ozieblo 1640b83f1527SRafal Ozieblo dma_error: 1641b83f1527SRafal Ozieblo netdev_err(bp->dev, "TX DMA map failed\n"); 1642b83f1527SRafal Ozieblo 1643b83f1527SRafal Ozieblo for (i = queue->tx_head; i != tx_head; i++) { 1644b83f1527SRafal Ozieblo tx_skb = macb_tx_skb(queue, i); 1645b83f1527SRafal Ozieblo 1646b83f1527SRafal Ozieblo macb_tx_unmap(bp, tx_skb); 1647b83f1527SRafal Ozieblo } 1648b83f1527SRafal Ozieblo 1649b83f1527SRafal Ozieblo return 0; 1650b83f1527SRafal Ozieblo } 1651b83f1527SRafal Ozieblo 1652b83f1527SRafal Ozieblo static netdev_features_t macb_features_check(struct sk_buff *skb, 1653b83f1527SRafal Ozieblo struct net_device *dev, 1654b83f1527SRafal Ozieblo netdev_features_t features) 1655b83f1527SRafal Ozieblo { 1656b83f1527SRafal Ozieblo unsigned int nr_frags, f; 1657b83f1527SRafal Ozieblo unsigned int hdrlen; 1658b83f1527SRafal Ozieblo 1659b83f1527SRafal Ozieblo /* Validate LSO compatibility */ 1660b83f1527SRafal Ozieblo 1661b83f1527SRafal Ozieblo /* there is only one buffer */ 1662b83f1527SRafal Ozieblo if (!skb_is_nonlinear(skb)) 1663b83f1527SRafal Ozieblo return features; 1664b83f1527SRafal Ozieblo 1665b83f1527SRafal Ozieblo /* length of header */ 1666b83f1527SRafal Ozieblo hdrlen = skb_transport_offset(skb); 1667b83f1527SRafal Ozieblo if (ip_hdr(skb)->protocol == IPPROTO_TCP) 1668b83f1527SRafal Ozieblo hdrlen += tcp_hdrlen(skb); 1669b83f1527SRafal Ozieblo 1670b83f1527SRafal Ozieblo /* For LSO: 1671b83f1527SRafal Ozieblo * When software supplies two or more payload buffers all payload buffers 1672b83f1527SRafal Ozieblo * apart from the last must be a multiple of 8 bytes in size. 1673b83f1527SRafal Ozieblo */ 1674b83f1527SRafal Ozieblo if (!IS_ALIGNED(skb_headlen(skb) - hdrlen, MACB_TX_LEN_ALIGN)) 1675b83f1527SRafal Ozieblo return features & ~MACB_NETIF_LSO; 1676b83f1527SRafal Ozieblo 1677b83f1527SRafal Ozieblo nr_frags = skb_shinfo(skb)->nr_frags; 1678b83f1527SRafal Ozieblo /* No need to check last fragment */ 1679b83f1527SRafal Ozieblo nr_frags--; 1680b83f1527SRafal Ozieblo for (f = 0; f < nr_frags; f++) { 1681b83f1527SRafal Ozieblo const skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; 1682b83f1527SRafal Ozieblo 1683b83f1527SRafal Ozieblo if (!IS_ALIGNED(skb_frag_size(frag), MACB_TX_LEN_ALIGN)) 1684b83f1527SRafal Ozieblo return features & ~MACB_NETIF_LSO; 1685b83f1527SRafal Ozieblo } 1686b83f1527SRafal Ozieblo return features; 1687b83f1527SRafal Ozieblo } 1688b83f1527SRafal Ozieblo 1689b83f1527SRafal Ozieblo static inline int macb_clear_csum(struct sk_buff *skb) 1690b83f1527SRafal Ozieblo { 1691b83f1527SRafal Ozieblo /* no change for packets without checksum offloading */ 1692b83f1527SRafal Ozieblo if (skb->ip_summed != CHECKSUM_PARTIAL) 1693b83f1527SRafal Ozieblo return 0; 1694b83f1527SRafal Ozieblo 1695b83f1527SRafal Ozieblo /* make sure we can modify the header */ 1696b83f1527SRafal Ozieblo if (unlikely(skb_cow_head(skb, 0))) 1697b83f1527SRafal Ozieblo return -1; 1698b83f1527SRafal Ozieblo 1699b83f1527SRafal Ozieblo /* initialize checksum field 1700b83f1527SRafal Ozieblo * This is required - at least for Zynq, which otherwise calculates 1701b83f1527SRafal Ozieblo * wrong UDP header checksums for UDP packets with UDP data len <=2 1702b83f1527SRafal Ozieblo */ 1703b83f1527SRafal Ozieblo *(__sum16 *)(skb_checksum_start(skb) + skb->csum_offset) = 0; 1704b83f1527SRafal Ozieblo return 0; 1705b83f1527SRafal Ozieblo } 1706b83f1527SRafal Ozieblo 1707653e92a9SClaudiu Beznea static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev) 1708653e92a9SClaudiu Beznea { 1709653e92a9SClaudiu Beznea bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb); 1710653e92a9SClaudiu Beznea int padlen = ETH_ZLEN - (*skb)->len; 1711653e92a9SClaudiu Beznea int headroom = skb_headroom(*skb); 1712653e92a9SClaudiu Beznea int tailroom = skb_tailroom(*skb); 1713653e92a9SClaudiu Beznea struct sk_buff *nskb; 1714653e92a9SClaudiu Beznea u32 fcs; 1715653e92a9SClaudiu Beznea 1716653e92a9SClaudiu Beznea if (!(ndev->features & NETIF_F_HW_CSUM) || 1717653e92a9SClaudiu Beznea !((*skb)->ip_summed != CHECKSUM_PARTIAL) || 1718653e92a9SClaudiu Beznea skb_shinfo(*skb)->gso_size) /* Not available for GSO */ 1719653e92a9SClaudiu Beznea return 0; 1720653e92a9SClaudiu Beznea 1721653e92a9SClaudiu Beznea if (padlen <= 0) { 1722653e92a9SClaudiu Beznea /* FCS could be appeded to tailroom. */ 1723653e92a9SClaudiu Beznea if (tailroom >= ETH_FCS_LEN) 1724653e92a9SClaudiu Beznea goto add_fcs; 1725653e92a9SClaudiu Beznea /* FCS could be appeded by moving data to headroom. */ 1726653e92a9SClaudiu Beznea else if (!cloned && headroom + tailroom >= ETH_FCS_LEN) 1727653e92a9SClaudiu Beznea padlen = 0; 1728653e92a9SClaudiu Beznea /* No room for FCS, need to reallocate skb. */ 1729653e92a9SClaudiu Beznea else 1730899ecaedSTristram Ha padlen = ETH_FCS_LEN; 1731653e92a9SClaudiu Beznea } else { 1732653e92a9SClaudiu Beznea /* Add room for FCS. */ 1733653e92a9SClaudiu Beznea padlen += ETH_FCS_LEN; 1734653e92a9SClaudiu Beznea } 1735653e92a9SClaudiu Beznea 1736653e92a9SClaudiu Beznea if (!cloned && headroom + tailroom >= padlen) { 1737653e92a9SClaudiu Beznea (*skb)->data = memmove((*skb)->head, (*skb)->data, (*skb)->len); 1738653e92a9SClaudiu Beznea skb_set_tail_pointer(*skb, (*skb)->len); 1739653e92a9SClaudiu Beznea } else { 1740653e92a9SClaudiu Beznea nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC); 1741653e92a9SClaudiu Beznea if (!nskb) 1742653e92a9SClaudiu Beznea return -ENOMEM; 1743653e92a9SClaudiu Beznea 1744f3e5c070SHuang Zijiang dev_consume_skb_any(*skb); 1745653e92a9SClaudiu Beznea *skb = nskb; 1746653e92a9SClaudiu Beznea } 1747653e92a9SClaudiu Beznea 1748ba3e1847SClaudiu Beznea if (padlen > ETH_FCS_LEN) 1749653e92a9SClaudiu Beznea skb_put_zero(*skb, padlen - ETH_FCS_LEN); 1750653e92a9SClaudiu Beznea 1751653e92a9SClaudiu Beznea add_fcs: 1752653e92a9SClaudiu Beznea /* set FCS to packet */ 1753653e92a9SClaudiu Beznea fcs = crc32_le(~0, (*skb)->data, (*skb)->len); 1754653e92a9SClaudiu Beznea fcs = ~fcs; 1755653e92a9SClaudiu Beznea 1756653e92a9SClaudiu Beznea skb_put_u8(*skb, fcs & 0xff); 1757653e92a9SClaudiu Beznea skb_put_u8(*skb, (fcs >> 8) & 0xff); 1758653e92a9SClaudiu Beznea skb_put_u8(*skb, (fcs >> 16) & 0xff); 1759653e92a9SClaudiu Beznea skb_put_u8(*skb, (fcs >> 24) & 0xff); 1760653e92a9SClaudiu Beznea 1761653e92a9SClaudiu Beznea return 0; 1762653e92a9SClaudiu Beznea } 1763653e92a9SClaudiu Beznea 1764d1c38957SClaudiu Beznea static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev) 1765b83f1527SRafal Ozieblo { 1766b83f1527SRafal Ozieblo u16 queue_index = skb_get_queue_mapping(skb); 1767b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 1768b83f1527SRafal Ozieblo struct macb_queue *queue = &bp->queues[queue_index]; 1769b83f1527SRafal Ozieblo unsigned long flags; 1770b83f1527SRafal Ozieblo unsigned int desc_cnt, nr_frags, frag_size, f; 1771b83f1527SRafal Ozieblo unsigned int hdrlen; 1772b83f1527SRafal Ozieblo bool is_lso, is_udp = 0; 1773d1c38957SClaudiu Beznea netdev_tx_t ret = NETDEV_TX_OK; 1774b83f1527SRafal Ozieblo 177533729f25SClaudiu Beznea if (macb_clear_csum(skb)) { 177633729f25SClaudiu Beznea dev_kfree_skb_any(skb); 177733729f25SClaudiu Beznea return ret; 177833729f25SClaudiu Beznea } 177933729f25SClaudiu Beznea 1780653e92a9SClaudiu Beznea if (macb_pad_and_fcs(&skb, dev)) { 1781653e92a9SClaudiu Beznea dev_kfree_skb_any(skb); 1782653e92a9SClaudiu Beznea return ret; 1783653e92a9SClaudiu Beznea } 1784653e92a9SClaudiu Beznea 1785b83f1527SRafal Ozieblo is_lso = (skb_shinfo(skb)->gso_size != 0); 1786b83f1527SRafal Ozieblo 1787b83f1527SRafal Ozieblo if (is_lso) { 1788b83f1527SRafal Ozieblo is_udp = !!(ip_hdr(skb)->protocol == IPPROTO_UDP); 1789b83f1527SRafal Ozieblo 1790b83f1527SRafal Ozieblo /* length of headers */ 1791b83f1527SRafal Ozieblo if (is_udp) 1792b83f1527SRafal Ozieblo /* only queue eth + ip headers separately for UDP */ 1793b83f1527SRafal Ozieblo hdrlen = skb_transport_offset(skb); 1794b83f1527SRafal Ozieblo else 1795b83f1527SRafal Ozieblo hdrlen = skb_transport_offset(skb) + tcp_hdrlen(skb); 1796b83f1527SRafal Ozieblo if (skb_headlen(skb) < hdrlen) { 1797b83f1527SRafal Ozieblo netdev_err(bp->dev, "Error - LSO headers fragmented!!!\n"); 1798b83f1527SRafal Ozieblo /* if this is required, would need to copy to single buffer */ 1799b83f1527SRafal Ozieblo return NETDEV_TX_BUSY; 1800b83f1527SRafal Ozieblo } 1801b83f1527SRafal Ozieblo } else 1802b83f1527SRafal Ozieblo hdrlen = min(skb_headlen(skb), bp->max_tx_length); 1803b83f1527SRafal Ozieblo 1804b83f1527SRafal Ozieblo #if defined(DEBUG) && defined(VERBOSE_DEBUG) 1805b83f1527SRafal Ozieblo netdev_vdbg(bp->dev, 1806b83f1527SRafal Ozieblo "start_xmit: queue %hu len %u head %p data %p tail %p end %p\n", 1807b83f1527SRafal Ozieblo queue_index, skb->len, skb->head, skb->data, 1808b83f1527SRafal Ozieblo skb_tail_pointer(skb), skb_end_pointer(skb)); 1809b83f1527SRafal Ozieblo print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1, 1810b83f1527SRafal Ozieblo skb->data, 16, true); 1811b83f1527SRafal Ozieblo #endif 1812b83f1527SRafal Ozieblo 1813b83f1527SRafal Ozieblo /* Count how many TX buffer descriptors are needed to send this 1814b83f1527SRafal Ozieblo * socket buffer: skb fragments of jumbo frames may need to be 1815b83f1527SRafal Ozieblo * split into many buffer descriptors. 1816b83f1527SRafal Ozieblo */ 1817b83f1527SRafal Ozieblo if (is_lso && (skb_headlen(skb) > hdrlen)) 1818b83f1527SRafal Ozieblo /* extra header descriptor if also payload in first buffer */ 1819b83f1527SRafal Ozieblo desc_cnt = DIV_ROUND_UP((skb_headlen(skb) - hdrlen), bp->max_tx_length) + 1; 1820b83f1527SRafal Ozieblo else 1821b83f1527SRafal Ozieblo desc_cnt = DIV_ROUND_UP(skb_headlen(skb), bp->max_tx_length); 1822b83f1527SRafal Ozieblo nr_frags = skb_shinfo(skb)->nr_frags; 1823b83f1527SRafal Ozieblo for (f = 0; f < nr_frags; f++) { 1824b83f1527SRafal Ozieblo frag_size = skb_frag_size(&skb_shinfo(skb)->frags[f]); 1825b83f1527SRafal Ozieblo desc_cnt += DIV_ROUND_UP(frag_size, bp->max_tx_length); 1826b83f1527SRafal Ozieblo } 1827b83f1527SRafal Ozieblo 1828b83f1527SRafal Ozieblo spin_lock_irqsave(&bp->lock, flags); 1829b83f1527SRafal Ozieblo 1830b83f1527SRafal Ozieblo /* This is a hard error, log it. */ 1831b83f1527SRafal Ozieblo if (CIRC_SPACE(queue->tx_head, queue->tx_tail, 1832b83f1527SRafal Ozieblo bp->tx_ring_size) < desc_cnt) { 1833b83f1527SRafal Ozieblo netif_stop_subqueue(dev, queue_index); 1834b83f1527SRafal Ozieblo spin_unlock_irqrestore(&bp->lock, flags); 1835b83f1527SRafal Ozieblo netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n", 1836b83f1527SRafal Ozieblo queue->tx_head, queue->tx_tail); 1837b83f1527SRafal Ozieblo return NETDEV_TX_BUSY; 1838b83f1527SRafal Ozieblo } 1839b83f1527SRafal Ozieblo 1840b83f1527SRafal Ozieblo /* Map socket buffer for DMA transfer */ 1841b83f1527SRafal Ozieblo if (!macb_tx_map(bp, queue, skb, hdrlen)) { 1842b83f1527SRafal Ozieblo dev_kfree_skb_any(skb); 1843b83f1527SRafal Ozieblo goto unlock; 1844b83f1527SRafal Ozieblo } 1845b83f1527SRafal Ozieblo 1846b83f1527SRafal Ozieblo /* Make newly initialized descriptor visible to hardware */ 1847b83f1527SRafal Ozieblo wmb(); 1848b83f1527SRafal Ozieblo skb_tx_timestamp(skb); 1849b83f1527SRafal Ozieblo 1850b83f1527SRafal Ozieblo macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); 1851b83f1527SRafal Ozieblo 1852b83f1527SRafal Ozieblo if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1) 1853b83f1527SRafal Ozieblo netif_stop_subqueue(dev, queue_index); 1854b83f1527SRafal Ozieblo 1855b83f1527SRafal Ozieblo unlock: 1856b83f1527SRafal Ozieblo spin_unlock_irqrestore(&bp->lock, flags); 1857b83f1527SRafal Ozieblo 1858d1c38957SClaudiu Beznea return ret; 1859b83f1527SRafal Ozieblo } 1860b83f1527SRafal Ozieblo 1861b83f1527SRafal Ozieblo static void macb_init_rx_buffer_size(struct macb *bp, size_t size) 1862b83f1527SRafal Ozieblo { 1863b83f1527SRafal Ozieblo if (!macb_is_gem(bp)) { 1864b83f1527SRafal Ozieblo bp->rx_buffer_size = MACB_RX_BUFFER_SIZE; 1865b83f1527SRafal Ozieblo } else { 1866b83f1527SRafal Ozieblo bp->rx_buffer_size = size; 1867b83f1527SRafal Ozieblo 1868b83f1527SRafal Ozieblo if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) { 1869b83f1527SRafal Ozieblo netdev_dbg(bp->dev, 1870b83f1527SRafal Ozieblo "RX buffer must be multiple of %d bytes, expanding\n", 1871b83f1527SRafal Ozieblo RX_BUFFER_MULTIPLE); 1872b83f1527SRafal Ozieblo bp->rx_buffer_size = 1873b83f1527SRafal Ozieblo roundup(bp->rx_buffer_size, RX_BUFFER_MULTIPLE); 1874b83f1527SRafal Ozieblo } 1875b83f1527SRafal Ozieblo } 1876b83f1527SRafal Ozieblo 1877b83f1527SRafal Ozieblo netdev_dbg(bp->dev, "mtu [%u] rx_buffer_size [%zu]\n", 1878b83f1527SRafal Ozieblo bp->dev->mtu, bp->rx_buffer_size); 1879b83f1527SRafal Ozieblo } 1880b83f1527SRafal Ozieblo 1881b83f1527SRafal Ozieblo static void gem_free_rx_buffers(struct macb *bp) 1882b83f1527SRafal Ozieblo { 1883b83f1527SRafal Ozieblo struct sk_buff *skb; 1884b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 1885ae1f2a56SRafal Ozieblo struct macb_queue *queue; 1886b83f1527SRafal Ozieblo dma_addr_t addr; 1887ae1f2a56SRafal Ozieblo unsigned int q; 1888b83f1527SRafal Ozieblo int i; 1889b83f1527SRafal Ozieblo 1890ae1f2a56SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 1891ae1f2a56SRafal Ozieblo if (!queue->rx_skbuff) 1892ae1f2a56SRafal Ozieblo continue; 1893b83f1527SRafal Ozieblo 1894b83f1527SRafal Ozieblo for (i = 0; i < bp->rx_ring_size; i++) { 1895ae1f2a56SRafal Ozieblo skb = queue->rx_skbuff[i]; 1896b83f1527SRafal Ozieblo 1897b83f1527SRafal Ozieblo if (!skb) 1898b83f1527SRafal Ozieblo continue; 1899b83f1527SRafal Ozieblo 1900ae1f2a56SRafal Ozieblo desc = macb_rx_desc(queue, i); 1901b83f1527SRafal Ozieblo addr = macb_get_addr(bp, desc); 1902b83f1527SRafal Ozieblo 1903b83f1527SRafal Ozieblo dma_unmap_single(&bp->pdev->dev, addr, bp->rx_buffer_size, 1904b83f1527SRafal Ozieblo DMA_FROM_DEVICE); 1905b83f1527SRafal Ozieblo dev_kfree_skb_any(skb); 1906b83f1527SRafal Ozieblo skb = NULL; 1907b83f1527SRafal Ozieblo } 1908b83f1527SRafal Ozieblo 1909ae1f2a56SRafal Ozieblo kfree(queue->rx_skbuff); 1910ae1f2a56SRafal Ozieblo queue->rx_skbuff = NULL; 1911ae1f2a56SRafal Ozieblo } 1912b83f1527SRafal Ozieblo } 1913b83f1527SRafal Ozieblo 1914b83f1527SRafal Ozieblo static void macb_free_rx_buffers(struct macb *bp) 1915b83f1527SRafal Ozieblo { 1916ae1f2a56SRafal Ozieblo struct macb_queue *queue = &bp->queues[0]; 1917ae1f2a56SRafal Ozieblo 1918ae1f2a56SRafal Ozieblo if (queue->rx_buffers) { 1919b83f1527SRafal Ozieblo dma_free_coherent(&bp->pdev->dev, 1920b83f1527SRafal Ozieblo bp->rx_ring_size * bp->rx_buffer_size, 1921ae1f2a56SRafal Ozieblo queue->rx_buffers, queue->rx_buffers_dma); 1922ae1f2a56SRafal Ozieblo queue->rx_buffers = NULL; 1923b83f1527SRafal Ozieblo } 1924b83f1527SRafal Ozieblo } 1925b83f1527SRafal Ozieblo 1926b83f1527SRafal Ozieblo static void macb_free_consistent(struct macb *bp) 1927b83f1527SRafal Ozieblo { 1928b83f1527SRafal Ozieblo struct macb_queue *queue; 1929b83f1527SRafal Ozieblo unsigned int q; 1930404cd086SHarini Katakam int size; 1931b83f1527SRafal Ozieblo 1932b83f1527SRafal Ozieblo bp->macbgem_ops.mog_free_rx_buffers(bp); 1933b83f1527SRafal Ozieblo 1934b83f1527SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 1935b83f1527SRafal Ozieblo kfree(queue->tx_skb); 1936b83f1527SRafal Ozieblo queue->tx_skb = NULL; 1937b83f1527SRafal Ozieblo if (queue->tx_ring) { 1938404cd086SHarini Katakam size = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch; 1939404cd086SHarini Katakam dma_free_coherent(&bp->pdev->dev, size, 1940b83f1527SRafal Ozieblo queue->tx_ring, queue->tx_ring_dma); 1941b83f1527SRafal Ozieblo queue->tx_ring = NULL; 1942b83f1527SRafal Ozieblo } 1943e50b770eSHarini Katakam if (queue->rx_ring) { 1944404cd086SHarini Katakam size = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch; 1945404cd086SHarini Katakam dma_free_coherent(&bp->pdev->dev, size, 1946e50b770eSHarini Katakam queue->rx_ring, queue->rx_ring_dma); 1947e50b770eSHarini Katakam queue->rx_ring = NULL; 1948e50b770eSHarini Katakam } 1949b83f1527SRafal Ozieblo } 1950b83f1527SRafal Ozieblo } 1951b83f1527SRafal Ozieblo 1952b83f1527SRafal Ozieblo static int gem_alloc_rx_buffers(struct macb *bp) 1953b83f1527SRafal Ozieblo { 1954ae1f2a56SRafal Ozieblo struct macb_queue *queue; 1955ae1f2a56SRafal Ozieblo unsigned int q; 1956b83f1527SRafal Ozieblo int size; 1957b83f1527SRafal Ozieblo 1958ae1f2a56SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 1959b83f1527SRafal Ozieblo size = bp->rx_ring_size * sizeof(struct sk_buff *); 1960ae1f2a56SRafal Ozieblo queue->rx_skbuff = kzalloc(size, GFP_KERNEL); 1961ae1f2a56SRafal Ozieblo if (!queue->rx_skbuff) 1962b83f1527SRafal Ozieblo return -ENOMEM; 1963b83f1527SRafal Ozieblo else 1964b83f1527SRafal Ozieblo netdev_dbg(bp->dev, 1965b83f1527SRafal Ozieblo "Allocated %d RX struct sk_buff entries at %p\n", 1966ae1f2a56SRafal Ozieblo bp->rx_ring_size, queue->rx_skbuff); 1967ae1f2a56SRafal Ozieblo } 1968b83f1527SRafal Ozieblo return 0; 1969b83f1527SRafal Ozieblo } 1970b83f1527SRafal Ozieblo 1971b83f1527SRafal Ozieblo static int macb_alloc_rx_buffers(struct macb *bp) 1972b83f1527SRafal Ozieblo { 1973ae1f2a56SRafal Ozieblo struct macb_queue *queue = &bp->queues[0]; 1974b83f1527SRafal Ozieblo int size; 1975b83f1527SRafal Ozieblo 1976b83f1527SRafal Ozieblo size = bp->rx_ring_size * bp->rx_buffer_size; 1977ae1f2a56SRafal Ozieblo queue->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size, 1978ae1f2a56SRafal Ozieblo &queue->rx_buffers_dma, GFP_KERNEL); 1979ae1f2a56SRafal Ozieblo if (!queue->rx_buffers) 1980b83f1527SRafal Ozieblo return -ENOMEM; 1981b83f1527SRafal Ozieblo 1982b83f1527SRafal Ozieblo netdev_dbg(bp->dev, 1983b83f1527SRafal Ozieblo "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n", 1984ae1f2a56SRafal Ozieblo size, (unsigned long)queue->rx_buffers_dma, queue->rx_buffers); 1985b83f1527SRafal Ozieblo return 0; 1986b83f1527SRafal Ozieblo } 1987b83f1527SRafal Ozieblo 1988b83f1527SRafal Ozieblo static int macb_alloc_consistent(struct macb *bp) 1989b83f1527SRafal Ozieblo { 1990b83f1527SRafal Ozieblo struct macb_queue *queue; 1991b83f1527SRafal Ozieblo unsigned int q; 1992b83f1527SRafal Ozieblo int size; 1993b83f1527SRafal Ozieblo 1994b83f1527SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 1995404cd086SHarini Katakam size = TX_RING_BYTES(bp) + bp->tx_bd_rd_prefetch; 1996b83f1527SRafal Ozieblo queue->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size, 1997b83f1527SRafal Ozieblo &queue->tx_ring_dma, 1998b83f1527SRafal Ozieblo GFP_KERNEL); 1999b83f1527SRafal Ozieblo if (!queue->tx_ring) 2000b83f1527SRafal Ozieblo goto out_err; 2001b83f1527SRafal Ozieblo netdev_dbg(bp->dev, 2002b83f1527SRafal Ozieblo "Allocated TX ring for queue %u of %d bytes at %08lx (mapped %p)\n", 2003b83f1527SRafal Ozieblo q, size, (unsigned long)queue->tx_ring_dma, 2004b83f1527SRafal Ozieblo queue->tx_ring); 2005b83f1527SRafal Ozieblo 2006b83f1527SRafal Ozieblo size = bp->tx_ring_size * sizeof(struct macb_tx_skb); 2007b83f1527SRafal Ozieblo queue->tx_skb = kmalloc(size, GFP_KERNEL); 2008b83f1527SRafal Ozieblo if (!queue->tx_skb) 2009b83f1527SRafal Ozieblo goto out_err; 2010b83f1527SRafal Ozieblo 2011404cd086SHarini Katakam size = RX_RING_BYTES(bp) + bp->rx_bd_rd_prefetch; 2012ae1f2a56SRafal Ozieblo queue->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size, 2013ae1f2a56SRafal Ozieblo &queue->rx_ring_dma, GFP_KERNEL); 2014ae1f2a56SRafal Ozieblo if (!queue->rx_ring) 2015b83f1527SRafal Ozieblo goto out_err; 2016b83f1527SRafal Ozieblo netdev_dbg(bp->dev, 2017b83f1527SRafal Ozieblo "Allocated RX ring of %d bytes at %08lx (mapped %p)\n", 2018ae1f2a56SRafal Ozieblo size, (unsigned long)queue->rx_ring_dma, queue->rx_ring); 2019ae1f2a56SRafal Ozieblo } 2020b83f1527SRafal Ozieblo if (bp->macbgem_ops.mog_alloc_rx_buffers(bp)) 2021b83f1527SRafal Ozieblo goto out_err; 2022b83f1527SRafal Ozieblo 2023b83f1527SRafal Ozieblo return 0; 2024b83f1527SRafal Ozieblo 2025b83f1527SRafal Ozieblo out_err: 2026b83f1527SRafal Ozieblo macb_free_consistent(bp); 2027b83f1527SRafal Ozieblo return -ENOMEM; 2028b83f1527SRafal Ozieblo } 2029b83f1527SRafal Ozieblo 2030b83f1527SRafal Ozieblo static void gem_init_rings(struct macb *bp) 2031b83f1527SRafal Ozieblo { 2032b83f1527SRafal Ozieblo struct macb_queue *queue; 2033b83f1527SRafal Ozieblo struct macb_dma_desc *desc = NULL; 2034b83f1527SRafal Ozieblo unsigned int q; 2035b83f1527SRafal Ozieblo int i; 2036b83f1527SRafal Ozieblo 2037b83f1527SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 2038b83f1527SRafal Ozieblo for (i = 0; i < bp->tx_ring_size; i++) { 2039b83f1527SRafal Ozieblo desc = macb_tx_desc(queue, i); 2040b83f1527SRafal Ozieblo macb_set_addr(bp, desc, 0); 2041b83f1527SRafal Ozieblo desc->ctrl = MACB_BIT(TX_USED); 2042b83f1527SRafal Ozieblo } 2043b83f1527SRafal Ozieblo desc->ctrl |= MACB_BIT(TX_WRAP); 2044b83f1527SRafal Ozieblo queue->tx_head = 0; 2045b83f1527SRafal Ozieblo queue->tx_tail = 0; 2046ae1f2a56SRafal Ozieblo 2047ae1f2a56SRafal Ozieblo queue->rx_tail = 0; 2048ae1f2a56SRafal Ozieblo queue->rx_prepared_head = 0; 2049ae1f2a56SRafal Ozieblo 2050ae1f2a56SRafal Ozieblo gem_rx_refill(queue); 2051b83f1527SRafal Ozieblo } 2052b83f1527SRafal Ozieblo 2053b83f1527SRafal Ozieblo } 2054b83f1527SRafal Ozieblo 2055b83f1527SRafal Ozieblo static void macb_init_rings(struct macb *bp) 2056b83f1527SRafal Ozieblo { 2057b83f1527SRafal Ozieblo int i; 2058b83f1527SRafal Ozieblo struct macb_dma_desc *desc = NULL; 2059b83f1527SRafal Ozieblo 2060ae1f2a56SRafal Ozieblo macb_init_rx_ring(&bp->queues[0]); 2061b83f1527SRafal Ozieblo 2062b83f1527SRafal Ozieblo for (i = 0; i < bp->tx_ring_size; i++) { 2063b83f1527SRafal Ozieblo desc = macb_tx_desc(&bp->queues[0], i); 2064b83f1527SRafal Ozieblo macb_set_addr(bp, desc, 0); 2065b83f1527SRafal Ozieblo desc->ctrl = MACB_BIT(TX_USED); 2066b83f1527SRafal Ozieblo } 2067b83f1527SRafal Ozieblo bp->queues[0].tx_head = 0; 2068b83f1527SRafal Ozieblo bp->queues[0].tx_tail = 0; 2069b83f1527SRafal Ozieblo desc->ctrl |= MACB_BIT(TX_WRAP); 2070b83f1527SRafal Ozieblo } 2071b83f1527SRafal Ozieblo 2072b83f1527SRafal Ozieblo static void macb_reset_hw(struct macb *bp) 2073b83f1527SRafal Ozieblo { 2074b83f1527SRafal Ozieblo struct macb_queue *queue; 2075b83f1527SRafal Ozieblo unsigned int q; 20760da70f80SAnssi Hannula u32 ctrl = macb_readl(bp, NCR); 2077b83f1527SRafal Ozieblo 2078b83f1527SRafal Ozieblo /* Disable RX and TX (XXX: Should we halt the transmission 2079b83f1527SRafal Ozieblo * more gracefully?) 2080b83f1527SRafal Ozieblo */ 20810da70f80SAnssi Hannula ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE)); 2082b83f1527SRafal Ozieblo 2083b83f1527SRafal Ozieblo /* Clear the stats registers (XXX: Update stats first?) */ 20840da70f80SAnssi Hannula ctrl |= MACB_BIT(CLRSTAT); 20850da70f80SAnssi Hannula 20860da70f80SAnssi Hannula macb_writel(bp, NCR, ctrl); 2087b83f1527SRafal Ozieblo 2088b83f1527SRafal Ozieblo /* Clear all status flags */ 2089b83f1527SRafal Ozieblo macb_writel(bp, TSR, -1); 2090b83f1527SRafal Ozieblo macb_writel(bp, RSR, -1); 2091b83f1527SRafal Ozieblo 2092b83f1527SRafal Ozieblo /* Disable all interrupts */ 2093b83f1527SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 2094b83f1527SRafal Ozieblo queue_writel(queue, IDR, -1); 2095b83f1527SRafal Ozieblo queue_readl(queue, ISR); 2096b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) 2097b83f1527SRafal Ozieblo queue_writel(queue, ISR, -1); 2098b83f1527SRafal Ozieblo } 2099b83f1527SRafal Ozieblo } 2100b83f1527SRafal Ozieblo 2101b83f1527SRafal Ozieblo static u32 gem_mdc_clk_div(struct macb *bp) 2102b83f1527SRafal Ozieblo { 2103b83f1527SRafal Ozieblo u32 config; 2104b83f1527SRafal Ozieblo unsigned long pclk_hz = clk_get_rate(bp->pclk); 2105b83f1527SRafal Ozieblo 2106b83f1527SRafal Ozieblo if (pclk_hz <= 20000000) 2107b83f1527SRafal Ozieblo config = GEM_BF(CLK, GEM_CLK_DIV8); 2108b83f1527SRafal Ozieblo else if (pclk_hz <= 40000000) 2109b83f1527SRafal Ozieblo config = GEM_BF(CLK, GEM_CLK_DIV16); 2110b83f1527SRafal Ozieblo else if (pclk_hz <= 80000000) 2111b83f1527SRafal Ozieblo config = GEM_BF(CLK, GEM_CLK_DIV32); 2112b83f1527SRafal Ozieblo else if (pclk_hz <= 120000000) 2113b83f1527SRafal Ozieblo config = GEM_BF(CLK, GEM_CLK_DIV48); 2114b83f1527SRafal Ozieblo else if (pclk_hz <= 160000000) 2115b83f1527SRafal Ozieblo config = GEM_BF(CLK, GEM_CLK_DIV64); 2116b83f1527SRafal Ozieblo else 2117b83f1527SRafal Ozieblo config = GEM_BF(CLK, GEM_CLK_DIV96); 2118b83f1527SRafal Ozieblo 2119b83f1527SRafal Ozieblo return config; 2120b83f1527SRafal Ozieblo } 2121b83f1527SRafal Ozieblo 2122b83f1527SRafal Ozieblo static u32 macb_mdc_clk_div(struct macb *bp) 2123b83f1527SRafal Ozieblo { 2124b83f1527SRafal Ozieblo u32 config; 2125b83f1527SRafal Ozieblo unsigned long pclk_hz; 2126b83f1527SRafal Ozieblo 2127b83f1527SRafal Ozieblo if (macb_is_gem(bp)) 2128b83f1527SRafal Ozieblo return gem_mdc_clk_div(bp); 2129b83f1527SRafal Ozieblo 2130b83f1527SRafal Ozieblo pclk_hz = clk_get_rate(bp->pclk); 2131b83f1527SRafal Ozieblo if (pclk_hz <= 20000000) 2132b83f1527SRafal Ozieblo config = MACB_BF(CLK, MACB_CLK_DIV8); 2133b83f1527SRafal Ozieblo else if (pclk_hz <= 40000000) 2134b83f1527SRafal Ozieblo config = MACB_BF(CLK, MACB_CLK_DIV16); 2135b83f1527SRafal Ozieblo else if (pclk_hz <= 80000000) 2136b83f1527SRafal Ozieblo config = MACB_BF(CLK, MACB_CLK_DIV32); 2137b83f1527SRafal Ozieblo else 2138b83f1527SRafal Ozieblo config = MACB_BF(CLK, MACB_CLK_DIV64); 2139b83f1527SRafal Ozieblo 2140b83f1527SRafal Ozieblo return config; 2141b83f1527SRafal Ozieblo } 2142b83f1527SRafal Ozieblo 2143b83f1527SRafal Ozieblo /* Get the DMA bus width field of the network configuration register that we 2144b83f1527SRafal Ozieblo * should program. We find the width from decoding the design configuration 2145b83f1527SRafal Ozieblo * register to find the maximum supported data bus width. 2146b83f1527SRafal Ozieblo */ 2147b83f1527SRafal Ozieblo static u32 macb_dbw(struct macb *bp) 2148b83f1527SRafal Ozieblo { 2149b83f1527SRafal Ozieblo if (!macb_is_gem(bp)) 2150b83f1527SRafal Ozieblo return 0; 2151b83f1527SRafal Ozieblo 2152b83f1527SRafal Ozieblo switch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) { 2153b83f1527SRafal Ozieblo case 4: 2154b83f1527SRafal Ozieblo return GEM_BF(DBW, GEM_DBW128); 2155b83f1527SRafal Ozieblo case 2: 2156b83f1527SRafal Ozieblo return GEM_BF(DBW, GEM_DBW64); 2157b83f1527SRafal Ozieblo case 1: 2158b83f1527SRafal Ozieblo default: 2159b83f1527SRafal Ozieblo return GEM_BF(DBW, GEM_DBW32); 2160b83f1527SRafal Ozieblo } 2161b83f1527SRafal Ozieblo } 2162b83f1527SRafal Ozieblo 2163b83f1527SRafal Ozieblo /* Configure the receive DMA engine 2164b83f1527SRafal Ozieblo * - use the correct receive buffer size 2165b83f1527SRafal Ozieblo * - set best burst length for DMA operations 2166b83f1527SRafal Ozieblo * (if not supported by FIFO, it will fallback to default) 2167b83f1527SRafal Ozieblo * - set both rx/tx packet buffers to full memory size 2168b83f1527SRafal Ozieblo * These are configurable parameters for GEM. 2169b83f1527SRafal Ozieblo */ 2170b83f1527SRafal Ozieblo static void macb_configure_dma(struct macb *bp) 2171b83f1527SRafal Ozieblo { 2172ae1f2a56SRafal Ozieblo struct macb_queue *queue; 2173ae1f2a56SRafal Ozieblo u32 buffer_size; 2174ae1f2a56SRafal Ozieblo unsigned int q; 2175b83f1527SRafal Ozieblo u32 dmacfg; 2176b83f1527SRafal Ozieblo 2177ae1f2a56SRafal Ozieblo buffer_size = bp->rx_buffer_size / RX_BUFFER_MULTIPLE; 2178b83f1527SRafal Ozieblo if (macb_is_gem(bp)) { 2179b83f1527SRafal Ozieblo dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L); 2180ae1f2a56SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 2181ae1f2a56SRafal Ozieblo if (q) 2182ae1f2a56SRafal Ozieblo queue_writel(queue, RBQS, buffer_size); 2183ae1f2a56SRafal Ozieblo else 2184ae1f2a56SRafal Ozieblo dmacfg |= GEM_BF(RXBS, buffer_size); 2185ae1f2a56SRafal Ozieblo } 2186b83f1527SRafal Ozieblo if (bp->dma_burst_length) 2187b83f1527SRafal Ozieblo dmacfg = GEM_BFINS(FBLDO, bp->dma_burst_length, dmacfg); 2188b83f1527SRafal Ozieblo dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L); 2189b83f1527SRafal Ozieblo dmacfg &= ~GEM_BIT(ENDIA_PKT); 2190b83f1527SRafal Ozieblo 2191b83f1527SRafal Ozieblo if (bp->native_io) 2192b83f1527SRafal Ozieblo dmacfg &= ~GEM_BIT(ENDIA_DESC); 2193b83f1527SRafal Ozieblo else 2194b83f1527SRafal Ozieblo dmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */ 2195b83f1527SRafal Ozieblo 2196b83f1527SRafal Ozieblo if (bp->dev->features & NETIF_F_HW_CSUM) 2197b83f1527SRafal Ozieblo dmacfg |= GEM_BIT(TXCOEN); 2198b83f1527SRafal Ozieblo else 2199b83f1527SRafal Ozieblo dmacfg &= ~GEM_BIT(TXCOEN); 2200b83f1527SRafal Ozieblo 2201bd620720SMichal Simek dmacfg &= ~GEM_BIT(ADDR64); 2202b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 2203b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) 2204b83f1527SRafal Ozieblo dmacfg |= GEM_BIT(ADDR64); 2205b83f1527SRafal Ozieblo #endif 2206b83f1527SRafal Ozieblo #ifdef CONFIG_MACB_USE_HWSTAMP 2207b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_PTP) 2208b83f1527SRafal Ozieblo dmacfg |= GEM_BIT(RXEXT) | GEM_BIT(TXEXT); 2209b83f1527SRafal Ozieblo #endif 2210b83f1527SRafal Ozieblo netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n", 2211b83f1527SRafal Ozieblo dmacfg); 2212b83f1527SRafal Ozieblo gem_writel(bp, DMACFG, dmacfg); 2213b83f1527SRafal Ozieblo } 2214b83f1527SRafal Ozieblo } 2215b83f1527SRafal Ozieblo 2216b83f1527SRafal Ozieblo static void macb_init_hw(struct macb *bp) 2217b83f1527SRafal Ozieblo { 2218b83f1527SRafal Ozieblo struct macb_queue *queue; 2219b83f1527SRafal Ozieblo unsigned int q; 2220b83f1527SRafal Ozieblo 2221b83f1527SRafal Ozieblo u32 config; 2222b83f1527SRafal Ozieblo 2223b83f1527SRafal Ozieblo macb_reset_hw(bp); 2224b83f1527SRafal Ozieblo macb_set_hwaddr(bp); 2225b83f1527SRafal Ozieblo 2226b83f1527SRafal Ozieblo config = macb_mdc_clk_div(bp); 2227b83f1527SRafal Ozieblo if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) 2228b83f1527SRafal Ozieblo config |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); 2229b83f1527SRafal Ozieblo config |= MACB_BF(RBOF, NET_IP_ALIGN); /* Make eth data aligned */ 2230b83f1527SRafal Ozieblo config |= MACB_BIT(PAE); /* PAuse Enable */ 2231b83f1527SRafal Ozieblo config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ 2232b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_JUMBO) 2233b83f1527SRafal Ozieblo config |= MACB_BIT(JFRAME); /* Enable jumbo frames */ 2234b83f1527SRafal Ozieblo else 2235b83f1527SRafal Ozieblo config |= MACB_BIT(BIG); /* Receive oversized frames */ 2236b83f1527SRafal Ozieblo if (bp->dev->flags & IFF_PROMISC) 2237b83f1527SRafal Ozieblo config |= MACB_BIT(CAF); /* Copy All Frames */ 2238b83f1527SRafal Ozieblo else if (macb_is_gem(bp) && bp->dev->features & NETIF_F_RXCSUM) 2239b83f1527SRafal Ozieblo config |= GEM_BIT(RXCOEN); 2240b83f1527SRafal Ozieblo if (!(bp->dev->flags & IFF_BROADCAST)) 2241b83f1527SRafal Ozieblo config |= MACB_BIT(NBC); /* No BroadCast */ 2242b83f1527SRafal Ozieblo config |= macb_dbw(bp); 2243b83f1527SRafal Ozieblo macb_writel(bp, NCFGR, config); 2244b83f1527SRafal Ozieblo if ((bp->caps & MACB_CAPS_JUMBO) && bp->jumbo_max_len) 2245b83f1527SRafal Ozieblo gem_writel(bp, JML, bp->jumbo_max_len); 2246b83f1527SRafal Ozieblo bp->speed = SPEED_10; 2247b83f1527SRafal Ozieblo bp->duplex = DUPLEX_HALF; 2248b83f1527SRafal Ozieblo bp->rx_frm_len_mask = MACB_RX_FRMLEN_MASK; 2249b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_JUMBO) 2250b83f1527SRafal Ozieblo bp->rx_frm_len_mask = MACB_RX_JFRMLEN_MASK; 2251b83f1527SRafal Ozieblo 2252b83f1527SRafal Ozieblo macb_configure_dma(bp); 2253b83f1527SRafal Ozieblo 2254b83f1527SRafal Ozieblo /* Initialize TX and RX buffers */ 2255ae1f2a56SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 2256ae1f2a56SRafal Ozieblo queue_writel(queue, RBQP, lower_32_bits(queue->rx_ring_dma)); 2257b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 2258b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) 2259ae1f2a56SRafal Ozieblo queue_writel(queue, RBQPH, upper_32_bits(queue->rx_ring_dma)); 2260b83f1527SRafal Ozieblo #endif 2261b83f1527SRafal Ozieblo queue_writel(queue, TBQP, lower_32_bits(queue->tx_ring_dma)); 2262b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 2263b83f1527SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) 2264b83f1527SRafal Ozieblo queue_writel(queue, TBQPH, upper_32_bits(queue->tx_ring_dma)); 2265b83f1527SRafal Ozieblo #endif 2266b83f1527SRafal Ozieblo 2267b83f1527SRafal Ozieblo /* Enable interrupts */ 2268b83f1527SRafal Ozieblo queue_writel(queue, IER, 2269e501070eSHarini Katakam bp->rx_intr_mask | 2270b83f1527SRafal Ozieblo MACB_TX_INT_FLAGS | 2271b83f1527SRafal Ozieblo MACB_BIT(HRESP)); 2272b83f1527SRafal Ozieblo } 2273b83f1527SRafal Ozieblo 2274b83f1527SRafal Ozieblo /* Enable TX and RX */ 22750da70f80SAnssi Hannula macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE)); 2276b83f1527SRafal Ozieblo } 2277b83f1527SRafal Ozieblo 2278b83f1527SRafal Ozieblo /* The hash address register is 64 bits long and takes up two 2279b83f1527SRafal Ozieblo * locations in the memory map. The least significant bits are stored 2280b83f1527SRafal Ozieblo * in EMAC_HSL and the most significant bits in EMAC_HSH. 2281b83f1527SRafal Ozieblo * 2282b83f1527SRafal Ozieblo * The unicast hash enable and the multicast hash enable bits in the 2283b83f1527SRafal Ozieblo * network configuration register enable the reception of hash matched 2284b83f1527SRafal Ozieblo * frames. The destination address is reduced to a 6 bit index into 2285b83f1527SRafal Ozieblo * the 64 bit hash register using the following hash function. The 2286b83f1527SRafal Ozieblo * hash function is an exclusive or of every sixth bit of the 2287b83f1527SRafal Ozieblo * destination address. 2288b83f1527SRafal Ozieblo * 2289b83f1527SRafal Ozieblo * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47] 2290b83f1527SRafal Ozieblo * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46] 2291b83f1527SRafal Ozieblo * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45] 2292b83f1527SRafal Ozieblo * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44] 2293b83f1527SRafal Ozieblo * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43] 2294b83f1527SRafal Ozieblo * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42] 2295b83f1527SRafal Ozieblo * 2296b83f1527SRafal Ozieblo * da[0] represents the least significant bit of the first byte 2297b83f1527SRafal Ozieblo * received, that is, the multicast/unicast indicator, and da[47] 2298b83f1527SRafal Ozieblo * represents the most significant bit of the last byte received. If 2299b83f1527SRafal Ozieblo * the hash index, hi[n], points to a bit that is set in the hash 2300b83f1527SRafal Ozieblo * register then the frame will be matched according to whether the 2301b83f1527SRafal Ozieblo * frame is multicast or unicast. A multicast match will be signalled 2302b83f1527SRafal Ozieblo * if the multicast hash enable bit is set, da[0] is 1 and the hash 2303b83f1527SRafal Ozieblo * index points to a bit set in the hash register. A unicast match 2304b83f1527SRafal Ozieblo * will be signalled if the unicast hash enable bit is set, da[0] is 0 2305b83f1527SRafal Ozieblo * and the hash index points to a bit set in the hash register. To 2306b83f1527SRafal Ozieblo * receive all multicast frames, the hash register should be set with 2307b83f1527SRafal Ozieblo * all ones and the multicast hash enable bit should be set in the 2308b83f1527SRafal Ozieblo * network configuration register. 2309b83f1527SRafal Ozieblo */ 2310b83f1527SRafal Ozieblo 2311b83f1527SRafal Ozieblo static inline int hash_bit_value(int bitnr, __u8 *addr) 2312b83f1527SRafal Ozieblo { 2313b83f1527SRafal Ozieblo if (addr[bitnr / 8] & (1 << (bitnr % 8))) 2314b83f1527SRafal Ozieblo return 1; 2315b83f1527SRafal Ozieblo return 0; 2316b83f1527SRafal Ozieblo } 2317b83f1527SRafal Ozieblo 2318b83f1527SRafal Ozieblo /* Return the hash index value for the specified address. */ 2319b83f1527SRafal Ozieblo static int hash_get_index(__u8 *addr) 2320b83f1527SRafal Ozieblo { 2321b83f1527SRafal Ozieblo int i, j, bitval; 2322b83f1527SRafal Ozieblo int hash_index = 0; 2323b83f1527SRafal Ozieblo 2324b83f1527SRafal Ozieblo for (j = 0; j < 6; j++) { 2325b83f1527SRafal Ozieblo for (i = 0, bitval = 0; i < 8; i++) 2326b83f1527SRafal Ozieblo bitval ^= hash_bit_value(i * 6 + j, addr); 2327b83f1527SRafal Ozieblo 2328b83f1527SRafal Ozieblo hash_index |= (bitval << j); 2329b83f1527SRafal Ozieblo } 2330b83f1527SRafal Ozieblo 2331b83f1527SRafal Ozieblo return hash_index; 2332b83f1527SRafal Ozieblo } 2333b83f1527SRafal Ozieblo 2334b83f1527SRafal Ozieblo /* Add multicast addresses to the internal multicast-hash table. */ 2335b83f1527SRafal Ozieblo static void macb_sethashtable(struct net_device *dev) 2336b83f1527SRafal Ozieblo { 2337b83f1527SRafal Ozieblo struct netdev_hw_addr *ha; 2338b83f1527SRafal Ozieblo unsigned long mc_filter[2]; 2339b83f1527SRafal Ozieblo unsigned int bitnr; 2340b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2341b83f1527SRafal Ozieblo 2342b83f1527SRafal Ozieblo mc_filter[0] = 0; 2343b83f1527SRafal Ozieblo mc_filter[1] = 0; 2344b83f1527SRafal Ozieblo 2345b83f1527SRafal Ozieblo netdev_for_each_mc_addr(ha, dev) { 2346b83f1527SRafal Ozieblo bitnr = hash_get_index(ha->addr); 2347b83f1527SRafal Ozieblo mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); 2348b83f1527SRafal Ozieblo } 2349b83f1527SRafal Ozieblo 2350b83f1527SRafal Ozieblo macb_or_gem_writel(bp, HRB, mc_filter[0]); 2351b83f1527SRafal Ozieblo macb_or_gem_writel(bp, HRT, mc_filter[1]); 2352b83f1527SRafal Ozieblo } 2353b83f1527SRafal Ozieblo 2354b83f1527SRafal Ozieblo /* Enable/Disable promiscuous and multicast modes. */ 2355b83f1527SRafal Ozieblo static void macb_set_rx_mode(struct net_device *dev) 2356b83f1527SRafal Ozieblo { 2357b83f1527SRafal Ozieblo unsigned long cfg; 2358b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2359b83f1527SRafal Ozieblo 2360b83f1527SRafal Ozieblo cfg = macb_readl(bp, NCFGR); 2361b83f1527SRafal Ozieblo 2362b83f1527SRafal Ozieblo if (dev->flags & IFF_PROMISC) { 2363b83f1527SRafal Ozieblo /* Enable promiscuous mode */ 2364b83f1527SRafal Ozieblo cfg |= MACB_BIT(CAF); 2365b83f1527SRafal Ozieblo 2366b83f1527SRafal Ozieblo /* Disable RX checksum offload */ 2367b83f1527SRafal Ozieblo if (macb_is_gem(bp)) 2368b83f1527SRafal Ozieblo cfg &= ~GEM_BIT(RXCOEN); 2369b83f1527SRafal Ozieblo } else { 2370b83f1527SRafal Ozieblo /* Disable promiscuous mode */ 2371b83f1527SRafal Ozieblo cfg &= ~MACB_BIT(CAF); 2372b83f1527SRafal Ozieblo 2373b83f1527SRafal Ozieblo /* Enable RX checksum offload only if requested */ 2374b83f1527SRafal Ozieblo if (macb_is_gem(bp) && dev->features & NETIF_F_RXCSUM) 2375b83f1527SRafal Ozieblo cfg |= GEM_BIT(RXCOEN); 2376b83f1527SRafal Ozieblo } 2377b83f1527SRafal Ozieblo 2378b83f1527SRafal Ozieblo if (dev->flags & IFF_ALLMULTI) { 2379b83f1527SRafal Ozieblo /* Enable all multicast mode */ 2380b83f1527SRafal Ozieblo macb_or_gem_writel(bp, HRB, -1); 2381b83f1527SRafal Ozieblo macb_or_gem_writel(bp, HRT, -1); 2382b83f1527SRafal Ozieblo cfg |= MACB_BIT(NCFGR_MTI); 2383b83f1527SRafal Ozieblo } else if (!netdev_mc_empty(dev)) { 2384b83f1527SRafal Ozieblo /* Enable specific multicasts */ 2385b83f1527SRafal Ozieblo macb_sethashtable(dev); 2386b83f1527SRafal Ozieblo cfg |= MACB_BIT(NCFGR_MTI); 2387b83f1527SRafal Ozieblo } else if (dev->flags & (~IFF_ALLMULTI)) { 2388b83f1527SRafal Ozieblo /* Disable all multicast mode */ 2389b83f1527SRafal Ozieblo macb_or_gem_writel(bp, HRB, 0); 2390b83f1527SRafal Ozieblo macb_or_gem_writel(bp, HRT, 0); 2391b83f1527SRafal Ozieblo cfg &= ~MACB_BIT(NCFGR_MTI); 2392b83f1527SRafal Ozieblo } 2393b83f1527SRafal Ozieblo 2394b83f1527SRafal Ozieblo macb_writel(bp, NCFGR, cfg); 2395b83f1527SRafal Ozieblo } 2396b83f1527SRafal Ozieblo 2397b83f1527SRafal Ozieblo static int macb_open(struct net_device *dev) 2398b83f1527SRafal Ozieblo { 2399b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2400b83f1527SRafal Ozieblo size_t bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN; 2401ae1f2a56SRafal Ozieblo struct macb_queue *queue; 2402ae1f2a56SRafal Ozieblo unsigned int q; 2403b83f1527SRafal Ozieblo int err; 2404b83f1527SRafal Ozieblo 2405b83f1527SRafal Ozieblo netdev_dbg(bp->dev, "open\n"); 2406b83f1527SRafal Ozieblo 2407d54f89afSHarini Katakam err = pm_runtime_get_sync(&bp->pdev->dev); 2408d54f89afSHarini Katakam if (err < 0) 2409d54f89afSHarini Katakam goto pm_exit; 2410d54f89afSHarini Katakam 2411b83f1527SRafal Ozieblo /* carrier starts down */ 2412b83f1527SRafal Ozieblo netif_carrier_off(dev); 2413b83f1527SRafal Ozieblo 2414b83f1527SRafal Ozieblo /* if the phy is not yet register, retry later*/ 2415d54f89afSHarini Katakam if (!dev->phydev) { 2416d54f89afSHarini Katakam err = -EAGAIN; 2417d54f89afSHarini Katakam goto pm_exit; 2418d54f89afSHarini Katakam } 2419b83f1527SRafal Ozieblo 2420b83f1527SRafal Ozieblo /* RX buffers initialization */ 2421b83f1527SRafal Ozieblo macb_init_rx_buffer_size(bp, bufsz); 2422b83f1527SRafal Ozieblo 2423b83f1527SRafal Ozieblo err = macb_alloc_consistent(bp); 2424b83f1527SRafal Ozieblo if (err) { 2425b83f1527SRafal Ozieblo netdev_err(dev, "Unable to allocate DMA memory (error %d)\n", 2426b83f1527SRafal Ozieblo err); 2427d54f89afSHarini Katakam goto pm_exit; 2428b83f1527SRafal Ozieblo } 2429b83f1527SRafal Ozieblo 2430b83f1527SRafal Ozieblo bp->macbgem_ops.mog_init_rings(bp); 2431b83f1527SRafal Ozieblo macb_init_hw(bp); 2432b83f1527SRafal Ozieblo 2433ae1f2a56SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) 2434ae1f2a56SRafal Ozieblo napi_enable(&queue->napi); 2435ae1f2a56SRafal Ozieblo 2436b83f1527SRafal Ozieblo /* schedule a link state check */ 2437b83f1527SRafal Ozieblo phy_start(dev->phydev); 2438b83f1527SRafal Ozieblo 2439b83f1527SRafal Ozieblo netif_tx_start_all_queues(dev); 2440b83f1527SRafal Ozieblo 2441b83f1527SRafal Ozieblo if (bp->ptp_info) 2442b83f1527SRafal Ozieblo bp->ptp_info->ptp_init(dev); 2443b83f1527SRafal Ozieblo 2444d54f89afSHarini Katakam pm_exit: 2445d54f89afSHarini Katakam if (err) { 2446d54f89afSHarini Katakam pm_runtime_put_sync(&bp->pdev->dev); 2447d54f89afSHarini Katakam return err; 2448d54f89afSHarini Katakam } 2449b83f1527SRafal Ozieblo return 0; 2450b83f1527SRafal Ozieblo } 2451b83f1527SRafal Ozieblo 2452b83f1527SRafal Ozieblo static int macb_close(struct net_device *dev) 2453b83f1527SRafal Ozieblo { 2454b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2455ae1f2a56SRafal Ozieblo struct macb_queue *queue; 2456b83f1527SRafal Ozieblo unsigned long flags; 2457ae1f2a56SRafal Ozieblo unsigned int q; 2458b83f1527SRafal Ozieblo 2459b83f1527SRafal Ozieblo netif_tx_stop_all_queues(dev); 2460ae1f2a56SRafal Ozieblo 2461ae1f2a56SRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) 2462ae1f2a56SRafal Ozieblo napi_disable(&queue->napi); 2463b83f1527SRafal Ozieblo 2464b83f1527SRafal Ozieblo if (dev->phydev) 2465b83f1527SRafal Ozieblo phy_stop(dev->phydev); 2466b83f1527SRafal Ozieblo 2467b83f1527SRafal Ozieblo spin_lock_irqsave(&bp->lock, flags); 2468b83f1527SRafal Ozieblo macb_reset_hw(bp); 2469b83f1527SRafal Ozieblo netif_carrier_off(dev); 2470b83f1527SRafal Ozieblo spin_unlock_irqrestore(&bp->lock, flags); 2471b83f1527SRafal Ozieblo 2472b83f1527SRafal Ozieblo macb_free_consistent(bp); 2473b83f1527SRafal Ozieblo 2474b83f1527SRafal Ozieblo if (bp->ptp_info) 2475b83f1527SRafal Ozieblo bp->ptp_info->ptp_remove(dev); 2476b83f1527SRafal Ozieblo 2477d54f89afSHarini Katakam pm_runtime_put(&bp->pdev->dev); 2478d54f89afSHarini Katakam 2479b83f1527SRafal Ozieblo return 0; 2480b83f1527SRafal Ozieblo } 2481b83f1527SRafal Ozieblo 2482b83f1527SRafal Ozieblo static int macb_change_mtu(struct net_device *dev, int new_mtu) 2483b83f1527SRafal Ozieblo { 2484b83f1527SRafal Ozieblo if (netif_running(dev)) 2485b83f1527SRafal Ozieblo return -EBUSY; 2486b83f1527SRafal Ozieblo 2487b83f1527SRafal Ozieblo dev->mtu = new_mtu; 2488b83f1527SRafal Ozieblo 2489b83f1527SRafal Ozieblo return 0; 2490b83f1527SRafal Ozieblo } 2491b83f1527SRafal Ozieblo 2492b83f1527SRafal Ozieblo static void gem_update_stats(struct macb *bp) 2493b83f1527SRafal Ozieblo { 2494512286bbSRafal Ozieblo struct macb_queue *queue; 2495512286bbSRafal Ozieblo unsigned int i, q, idx; 2496512286bbSRafal Ozieblo unsigned long *stat; 2497512286bbSRafal Ozieblo 2498b83f1527SRafal Ozieblo u32 *p = &bp->hw_stats.gem.tx_octets_31_0; 2499b83f1527SRafal Ozieblo 2500b83f1527SRafal Ozieblo for (i = 0; i < GEM_STATS_LEN; ++i, ++p) { 2501b83f1527SRafal Ozieblo u32 offset = gem_statistics[i].offset; 2502b83f1527SRafal Ozieblo u64 val = bp->macb_reg_readl(bp, offset); 2503b83f1527SRafal Ozieblo 2504b83f1527SRafal Ozieblo bp->ethtool_stats[i] += val; 2505b83f1527SRafal Ozieblo *p += val; 2506b83f1527SRafal Ozieblo 2507b83f1527SRafal Ozieblo if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) { 2508b83f1527SRafal Ozieblo /* Add GEM_OCTTXH, GEM_OCTRXH */ 2509b83f1527SRafal Ozieblo val = bp->macb_reg_readl(bp, offset + 4); 2510b83f1527SRafal Ozieblo bp->ethtool_stats[i] += ((u64)val) << 32; 2511b83f1527SRafal Ozieblo *(++p) += val; 2512b83f1527SRafal Ozieblo } 2513b83f1527SRafal Ozieblo } 2514512286bbSRafal Ozieblo 2515512286bbSRafal Ozieblo idx = GEM_STATS_LEN; 2516512286bbSRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) 2517512286bbSRafal Ozieblo for (i = 0, stat = &queue->stats.first; i < QUEUE_STATS_LEN; ++i, ++stat) 2518512286bbSRafal Ozieblo bp->ethtool_stats[idx++] = *stat; 2519b83f1527SRafal Ozieblo } 2520b83f1527SRafal Ozieblo 2521b83f1527SRafal Ozieblo static struct net_device_stats *gem_get_stats(struct macb *bp) 2522b83f1527SRafal Ozieblo { 2523b83f1527SRafal Ozieblo struct gem_stats *hwstat = &bp->hw_stats.gem; 2524b83f1527SRafal Ozieblo struct net_device_stats *nstat = &bp->dev->stats; 2525b83f1527SRafal Ozieblo 2526b83f1527SRafal Ozieblo gem_update_stats(bp); 2527b83f1527SRafal Ozieblo 2528b83f1527SRafal Ozieblo nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + 2529b83f1527SRafal Ozieblo hwstat->rx_alignment_errors + 2530b83f1527SRafal Ozieblo hwstat->rx_resource_errors + 2531b83f1527SRafal Ozieblo hwstat->rx_overruns + 2532b83f1527SRafal Ozieblo hwstat->rx_oversize_frames + 2533b83f1527SRafal Ozieblo hwstat->rx_jabbers + 2534b83f1527SRafal Ozieblo hwstat->rx_undersized_frames + 2535b83f1527SRafal Ozieblo hwstat->rx_length_field_frame_errors); 2536b83f1527SRafal Ozieblo nstat->tx_errors = (hwstat->tx_late_collisions + 2537b83f1527SRafal Ozieblo hwstat->tx_excessive_collisions + 2538b83f1527SRafal Ozieblo hwstat->tx_underrun + 2539b83f1527SRafal Ozieblo hwstat->tx_carrier_sense_errors); 2540b83f1527SRafal Ozieblo nstat->multicast = hwstat->rx_multicast_frames; 2541b83f1527SRafal Ozieblo nstat->collisions = (hwstat->tx_single_collision_frames + 2542b83f1527SRafal Ozieblo hwstat->tx_multiple_collision_frames + 2543b83f1527SRafal Ozieblo hwstat->tx_excessive_collisions); 2544b83f1527SRafal Ozieblo nstat->rx_length_errors = (hwstat->rx_oversize_frames + 2545b83f1527SRafal Ozieblo hwstat->rx_jabbers + 2546b83f1527SRafal Ozieblo hwstat->rx_undersized_frames + 2547b83f1527SRafal Ozieblo hwstat->rx_length_field_frame_errors); 2548b83f1527SRafal Ozieblo nstat->rx_over_errors = hwstat->rx_resource_errors; 2549b83f1527SRafal Ozieblo nstat->rx_crc_errors = hwstat->rx_frame_check_sequence_errors; 2550b83f1527SRafal Ozieblo nstat->rx_frame_errors = hwstat->rx_alignment_errors; 2551b83f1527SRafal Ozieblo nstat->rx_fifo_errors = hwstat->rx_overruns; 2552b83f1527SRafal Ozieblo nstat->tx_aborted_errors = hwstat->tx_excessive_collisions; 2553b83f1527SRafal Ozieblo nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors; 2554b83f1527SRafal Ozieblo nstat->tx_fifo_errors = hwstat->tx_underrun; 2555b83f1527SRafal Ozieblo 2556b83f1527SRafal Ozieblo return nstat; 2557b83f1527SRafal Ozieblo } 2558b83f1527SRafal Ozieblo 2559b83f1527SRafal Ozieblo static void gem_get_ethtool_stats(struct net_device *dev, 2560b83f1527SRafal Ozieblo struct ethtool_stats *stats, u64 *data) 2561b83f1527SRafal Ozieblo { 2562b83f1527SRafal Ozieblo struct macb *bp; 2563b83f1527SRafal Ozieblo 2564b83f1527SRafal Ozieblo bp = netdev_priv(dev); 2565b83f1527SRafal Ozieblo gem_update_stats(bp); 2566512286bbSRafal Ozieblo memcpy(data, &bp->ethtool_stats, sizeof(u64) 2567512286bbSRafal Ozieblo * (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES)); 2568b83f1527SRafal Ozieblo } 2569b83f1527SRafal Ozieblo 2570b83f1527SRafal Ozieblo static int gem_get_sset_count(struct net_device *dev, int sset) 2571b83f1527SRafal Ozieblo { 2572512286bbSRafal Ozieblo struct macb *bp = netdev_priv(dev); 2573512286bbSRafal Ozieblo 2574b83f1527SRafal Ozieblo switch (sset) { 2575b83f1527SRafal Ozieblo case ETH_SS_STATS: 2576512286bbSRafal Ozieblo return GEM_STATS_LEN + bp->num_queues * QUEUE_STATS_LEN; 2577b83f1527SRafal Ozieblo default: 2578b83f1527SRafal Ozieblo return -EOPNOTSUPP; 2579b83f1527SRafal Ozieblo } 2580b83f1527SRafal Ozieblo } 2581b83f1527SRafal Ozieblo 2582b83f1527SRafal Ozieblo static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p) 2583b83f1527SRafal Ozieblo { 2584512286bbSRafal Ozieblo char stat_string[ETH_GSTRING_LEN]; 2585512286bbSRafal Ozieblo struct macb *bp = netdev_priv(dev); 2586512286bbSRafal Ozieblo struct macb_queue *queue; 2587b83f1527SRafal Ozieblo unsigned int i; 2588512286bbSRafal Ozieblo unsigned int q; 2589b83f1527SRafal Ozieblo 2590b83f1527SRafal Ozieblo switch (sset) { 2591b83f1527SRafal Ozieblo case ETH_SS_STATS: 2592b83f1527SRafal Ozieblo for (i = 0; i < GEM_STATS_LEN; i++, p += ETH_GSTRING_LEN) 2593b83f1527SRafal Ozieblo memcpy(p, gem_statistics[i].stat_string, 2594b83f1527SRafal Ozieblo ETH_GSTRING_LEN); 2595512286bbSRafal Ozieblo 2596512286bbSRafal Ozieblo for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { 2597512286bbSRafal Ozieblo for (i = 0; i < QUEUE_STATS_LEN; i++, p += ETH_GSTRING_LEN) { 2598512286bbSRafal Ozieblo snprintf(stat_string, ETH_GSTRING_LEN, "q%d_%s", 2599512286bbSRafal Ozieblo q, queue_statistics[i].stat_string); 2600512286bbSRafal Ozieblo memcpy(p, stat_string, ETH_GSTRING_LEN); 2601512286bbSRafal Ozieblo } 2602512286bbSRafal Ozieblo } 2603b83f1527SRafal Ozieblo break; 2604b83f1527SRafal Ozieblo } 2605b83f1527SRafal Ozieblo } 2606b83f1527SRafal Ozieblo 2607b83f1527SRafal Ozieblo static struct net_device_stats *macb_get_stats(struct net_device *dev) 2608b83f1527SRafal Ozieblo { 2609b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2610b83f1527SRafal Ozieblo struct net_device_stats *nstat = &bp->dev->stats; 2611b83f1527SRafal Ozieblo struct macb_stats *hwstat = &bp->hw_stats.macb; 2612b83f1527SRafal Ozieblo 2613b83f1527SRafal Ozieblo if (macb_is_gem(bp)) 2614b83f1527SRafal Ozieblo return gem_get_stats(bp); 2615b83f1527SRafal Ozieblo 2616b83f1527SRafal Ozieblo /* read stats from hardware */ 2617b83f1527SRafal Ozieblo macb_update_stats(bp); 2618b83f1527SRafal Ozieblo 2619b83f1527SRafal Ozieblo /* Convert HW stats into netdevice stats */ 2620b83f1527SRafal Ozieblo nstat->rx_errors = (hwstat->rx_fcs_errors + 2621b83f1527SRafal Ozieblo hwstat->rx_align_errors + 2622b83f1527SRafal Ozieblo hwstat->rx_resource_errors + 2623b83f1527SRafal Ozieblo hwstat->rx_overruns + 2624b83f1527SRafal Ozieblo hwstat->rx_oversize_pkts + 2625b83f1527SRafal Ozieblo hwstat->rx_jabbers + 2626b83f1527SRafal Ozieblo hwstat->rx_undersize_pkts + 2627b83f1527SRafal Ozieblo hwstat->rx_length_mismatch); 2628b83f1527SRafal Ozieblo nstat->tx_errors = (hwstat->tx_late_cols + 2629b83f1527SRafal Ozieblo hwstat->tx_excessive_cols + 2630b83f1527SRafal Ozieblo hwstat->tx_underruns + 2631b83f1527SRafal Ozieblo hwstat->tx_carrier_errors + 2632b83f1527SRafal Ozieblo hwstat->sqe_test_errors); 2633b83f1527SRafal Ozieblo nstat->collisions = (hwstat->tx_single_cols + 2634b83f1527SRafal Ozieblo hwstat->tx_multiple_cols + 2635b83f1527SRafal Ozieblo hwstat->tx_excessive_cols); 2636b83f1527SRafal Ozieblo nstat->rx_length_errors = (hwstat->rx_oversize_pkts + 2637b83f1527SRafal Ozieblo hwstat->rx_jabbers + 2638b83f1527SRafal Ozieblo hwstat->rx_undersize_pkts + 2639b83f1527SRafal Ozieblo hwstat->rx_length_mismatch); 2640b83f1527SRafal Ozieblo nstat->rx_over_errors = hwstat->rx_resource_errors + 2641b83f1527SRafal Ozieblo hwstat->rx_overruns; 2642b83f1527SRafal Ozieblo nstat->rx_crc_errors = hwstat->rx_fcs_errors; 2643b83f1527SRafal Ozieblo nstat->rx_frame_errors = hwstat->rx_align_errors; 2644b83f1527SRafal Ozieblo nstat->rx_fifo_errors = hwstat->rx_overruns; 2645b83f1527SRafal Ozieblo /* XXX: What does "missed" mean? */ 2646b83f1527SRafal Ozieblo nstat->tx_aborted_errors = hwstat->tx_excessive_cols; 2647b83f1527SRafal Ozieblo nstat->tx_carrier_errors = hwstat->tx_carrier_errors; 2648b83f1527SRafal Ozieblo nstat->tx_fifo_errors = hwstat->tx_underruns; 2649b83f1527SRafal Ozieblo /* Don't know about heartbeat or window errors... */ 2650b83f1527SRafal Ozieblo 2651b83f1527SRafal Ozieblo return nstat; 2652b83f1527SRafal Ozieblo } 2653b83f1527SRafal Ozieblo 2654b83f1527SRafal Ozieblo static int macb_get_regs_len(struct net_device *netdev) 2655b83f1527SRafal Ozieblo { 2656b83f1527SRafal Ozieblo return MACB_GREGS_NBR * sizeof(u32); 2657b83f1527SRafal Ozieblo } 2658b83f1527SRafal Ozieblo 2659b83f1527SRafal Ozieblo static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs, 2660b83f1527SRafal Ozieblo void *p) 2661b83f1527SRafal Ozieblo { 2662b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2663b83f1527SRafal Ozieblo unsigned int tail, head; 2664b83f1527SRafal Ozieblo u32 *regs_buff = p; 2665b83f1527SRafal Ozieblo 2666b83f1527SRafal Ozieblo regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1)) 2667b83f1527SRafal Ozieblo | MACB_GREGS_VERSION; 2668b83f1527SRafal Ozieblo 2669b83f1527SRafal Ozieblo tail = macb_tx_ring_wrap(bp, bp->queues[0].tx_tail); 2670b83f1527SRafal Ozieblo head = macb_tx_ring_wrap(bp, bp->queues[0].tx_head); 2671b83f1527SRafal Ozieblo 2672b83f1527SRafal Ozieblo regs_buff[0] = macb_readl(bp, NCR); 2673b83f1527SRafal Ozieblo regs_buff[1] = macb_or_gem_readl(bp, NCFGR); 2674b83f1527SRafal Ozieblo regs_buff[2] = macb_readl(bp, NSR); 2675b83f1527SRafal Ozieblo regs_buff[3] = macb_readl(bp, TSR); 2676b83f1527SRafal Ozieblo regs_buff[4] = macb_readl(bp, RBQP); 2677b83f1527SRafal Ozieblo regs_buff[5] = macb_readl(bp, TBQP); 2678b83f1527SRafal Ozieblo regs_buff[6] = macb_readl(bp, RSR); 2679b83f1527SRafal Ozieblo regs_buff[7] = macb_readl(bp, IMR); 2680b83f1527SRafal Ozieblo 2681b83f1527SRafal Ozieblo regs_buff[8] = tail; 2682b83f1527SRafal Ozieblo regs_buff[9] = head; 2683b83f1527SRafal Ozieblo regs_buff[10] = macb_tx_dma(&bp->queues[0], tail); 2684b83f1527SRafal Ozieblo regs_buff[11] = macb_tx_dma(&bp->queues[0], head); 2685b83f1527SRafal Ozieblo 2686b83f1527SRafal Ozieblo if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) 2687b83f1527SRafal Ozieblo regs_buff[12] = macb_or_gem_readl(bp, USRIO); 2688b83f1527SRafal Ozieblo if (macb_is_gem(bp)) 2689b83f1527SRafal Ozieblo regs_buff[13] = gem_readl(bp, DMACFG); 2690b83f1527SRafal Ozieblo } 2691b83f1527SRafal Ozieblo 2692b83f1527SRafal Ozieblo static void macb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) 2693b83f1527SRafal Ozieblo { 2694b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 2695b83f1527SRafal Ozieblo 2696b83f1527SRafal Ozieblo wol->supported = 0; 2697b83f1527SRafal Ozieblo wol->wolopts = 0; 2698b83f1527SRafal Ozieblo 2699b83f1527SRafal Ozieblo if (bp->wol & MACB_WOL_HAS_MAGIC_PACKET) { 2700b83f1527SRafal Ozieblo wol->supported = WAKE_MAGIC; 2701b83f1527SRafal Ozieblo 2702b83f1527SRafal Ozieblo if (bp->wol & MACB_WOL_ENABLED) 2703b83f1527SRafal Ozieblo wol->wolopts |= WAKE_MAGIC; 2704b83f1527SRafal Ozieblo } 2705b83f1527SRafal Ozieblo } 2706b83f1527SRafal Ozieblo 2707b83f1527SRafal Ozieblo static int macb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) 2708b83f1527SRafal Ozieblo { 2709b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 2710b83f1527SRafal Ozieblo 2711b83f1527SRafal Ozieblo if (!(bp->wol & MACB_WOL_HAS_MAGIC_PACKET) || 2712b83f1527SRafal Ozieblo (wol->wolopts & ~WAKE_MAGIC)) 2713b83f1527SRafal Ozieblo return -EOPNOTSUPP; 2714b83f1527SRafal Ozieblo 2715b83f1527SRafal Ozieblo if (wol->wolopts & WAKE_MAGIC) 2716b83f1527SRafal Ozieblo bp->wol |= MACB_WOL_ENABLED; 2717b83f1527SRafal Ozieblo else 2718b83f1527SRafal Ozieblo bp->wol &= ~MACB_WOL_ENABLED; 2719b83f1527SRafal Ozieblo 2720b83f1527SRafal Ozieblo device_set_wakeup_enable(&bp->pdev->dev, bp->wol & MACB_WOL_ENABLED); 2721b83f1527SRafal Ozieblo 2722b83f1527SRafal Ozieblo return 0; 2723b83f1527SRafal Ozieblo } 2724b83f1527SRafal Ozieblo 2725b83f1527SRafal Ozieblo static void macb_get_ringparam(struct net_device *netdev, 2726b83f1527SRafal Ozieblo struct ethtool_ringparam *ring) 2727b83f1527SRafal Ozieblo { 2728b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 2729b83f1527SRafal Ozieblo 2730b83f1527SRafal Ozieblo ring->rx_max_pending = MAX_RX_RING_SIZE; 2731b83f1527SRafal Ozieblo ring->tx_max_pending = MAX_TX_RING_SIZE; 2732b83f1527SRafal Ozieblo 2733b83f1527SRafal Ozieblo ring->rx_pending = bp->rx_ring_size; 2734b83f1527SRafal Ozieblo ring->tx_pending = bp->tx_ring_size; 2735b83f1527SRafal Ozieblo } 2736b83f1527SRafal Ozieblo 2737b83f1527SRafal Ozieblo static int macb_set_ringparam(struct net_device *netdev, 2738b83f1527SRafal Ozieblo struct ethtool_ringparam *ring) 2739b83f1527SRafal Ozieblo { 2740b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 2741b83f1527SRafal Ozieblo u32 new_rx_size, new_tx_size; 2742b83f1527SRafal Ozieblo unsigned int reset = 0; 2743b83f1527SRafal Ozieblo 2744b83f1527SRafal Ozieblo if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 2745b83f1527SRafal Ozieblo return -EINVAL; 2746b83f1527SRafal Ozieblo 2747b83f1527SRafal Ozieblo new_rx_size = clamp_t(u32, ring->rx_pending, 2748b83f1527SRafal Ozieblo MIN_RX_RING_SIZE, MAX_RX_RING_SIZE); 2749b83f1527SRafal Ozieblo new_rx_size = roundup_pow_of_two(new_rx_size); 2750b83f1527SRafal Ozieblo 2751b83f1527SRafal Ozieblo new_tx_size = clamp_t(u32, ring->tx_pending, 2752b83f1527SRafal Ozieblo MIN_TX_RING_SIZE, MAX_TX_RING_SIZE); 2753b83f1527SRafal Ozieblo new_tx_size = roundup_pow_of_two(new_tx_size); 2754b83f1527SRafal Ozieblo 2755b83f1527SRafal Ozieblo if ((new_tx_size == bp->tx_ring_size) && 2756b83f1527SRafal Ozieblo (new_rx_size == bp->rx_ring_size)) { 2757b83f1527SRafal Ozieblo /* nothing to do */ 2758b83f1527SRafal Ozieblo return 0; 2759b83f1527SRafal Ozieblo } 2760b83f1527SRafal Ozieblo 2761b83f1527SRafal Ozieblo if (netif_running(bp->dev)) { 2762b83f1527SRafal Ozieblo reset = 1; 2763b83f1527SRafal Ozieblo macb_close(bp->dev); 2764b83f1527SRafal Ozieblo } 2765b83f1527SRafal Ozieblo 2766b83f1527SRafal Ozieblo bp->rx_ring_size = new_rx_size; 2767b83f1527SRafal Ozieblo bp->tx_ring_size = new_tx_size; 2768b83f1527SRafal Ozieblo 2769b83f1527SRafal Ozieblo if (reset) 2770b83f1527SRafal Ozieblo macb_open(bp->dev); 2771b83f1527SRafal Ozieblo 2772b83f1527SRafal Ozieblo return 0; 2773b83f1527SRafal Ozieblo } 2774b83f1527SRafal Ozieblo 2775ab91f0a9SRafal Ozieblo #ifdef CONFIG_MACB_USE_HWSTAMP 2776ab91f0a9SRafal Ozieblo static unsigned int gem_get_tsu_rate(struct macb *bp) 2777ab91f0a9SRafal Ozieblo { 2778ab91f0a9SRafal Ozieblo struct clk *tsu_clk; 2779ab91f0a9SRafal Ozieblo unsigned int tsu_rate; 2780ab91f0a9SRafal Ozieblo 2781ab91f0a9SRafal Ozieblo tsu_clk = devm_clk_get(&bp->pdev->dev, "tsu_clk"); 2782ab91f0a9SRafal Ozieblo if (!IS_ERR(tsu_clk)) 2783ab91f0a9SRafal Ozieblo tsu_rate = clk_get_rate(tsu_clk); 2784ab91f0a9SRafal Ozieblo /* try pclk instead */ 2785ab91f0a9SRafal Ozieblo else if (!IS_ERR(bp->pclk)) { 2786ab91f0a9SRafal Ozieblo tsu_clk = bp->pclk; 2787ab91f0a9SRafal Ozieblo tsu_rate = clk_get_rate(tsu_clk); 2788ab91f0a9SRafal Ozieblo } else 2789ab91f0a9SRafal Ozieblo return -ENOTSUPP; 2790ab91f0a9SRafal Ozieblo return tsu_rate; 2791ab91f0a9SRafal Ozieblo } 2792ab91f0a9SRafal Ozieblo 2793ab91f0a9SRafal Ozieblo static s32 gem_get_ptp_max_adj(void) 2794ab91f0a9SRafal Ozieblo { 2795ab91f0a9SRafal Ozieblo return 64000000; 2796ab91f0a9SRafal Ozieblo } 2797ab91f0a9SRafal Ozieblo 2798ab91f0a9SRafal Ozieblo static int gem_get_ts_info(struct net_device *dev, 2799ab91f0a9SRafal Ozieblo struct ethtool_ts_info *info) 2800ab91f0a9SRafal Ozieblo { 2801ab91f0a9SRafal Ozieblo struct macb *bp = netdev_priv(dev); 2802ab91f0a9SRafal Ozieblo 2803ab91f0a9SRafal Ozieblo if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) { 2804ab91f0a9SRafal Ozieblo ethtool_op_get_ts_info(dev, info); 2805ab91f0a9SRafal Ozieblo return 0; 2806ab91f0a9SRafal Ozieblo } 2807ab91f0a9SRafal Ozieblo 2808ab91f0a9SRafal Ozieblo info->so_timestamping = 2809ab91f0a9SRafal Ozieblo SOF_TIMESTAMPING_TX_SOFTWARE | 2810ab91f0a9SRafal Ozieblo SOF_TIMESTAMPING_RX_SOFTWARE | 2811ab91f0a9SRafal Ozieblo SOF_TIMESTAMPING_SOFTWARE | 2812ab91f0a9SRafal Ozieblo SOF_TIMESTAMPING_TX_HARDWARE | 2813ab91f0a9SRafal Ozieblo SOF_TIMESTAMPING_RX_HARDWARE | 2814ab91f0a9SRafal Ozieblo SOF_TIMESTAMPING_RAW_HARDWARE; 2815ab91f0a9SRafal Ozieblo info->tx_types = 2816ab91f0a9SRafal Ozieblo (1 << HWTSTAMP_TX_ONESTEP_SYNC) | 2817ab91f0a9SRafal Ozieblo (1 << HWTSTAMP_TX_OFF) | 2818ab91f0a9SRafal Ozieblo (1 << HWTSTAMP_TX_ON); 2819ab91f0a9SRafal Ozieblo info->rx_filters = 2820ab91f0a9SRafal Ozieblo (1 << HWTSTAMP_FILTER_NONE) | 2821ab91f0a9SRafal Ozieblo (1 << HWTSTAMP_FILTER_ALL); 2822ab91f0a9SRafal Ozieblo 2823ab91f0a9SRafal Ozieblo info->phc_index = bp->ptp_clock ? ptp_clock_index(bp->ptp_clock) : -1; 2824ab91f0a9SRafal Ozieblo 2825ab91f0a9SRafal Ozieblo return 0; 2826ab91f0a9SRafal Ozieblo } 2827ab91f0a9SRafal Ozieblo 2828ab91f0a9SRafal Ozieblo static struct macb_ptp_info gem_ptp_info = { 2829ab91f0a9SRafal Ozieblo .ptp_init = gem_ptp_init, 2830ab91f0a9SRafal Ozieblo .ptp_remove = gem_ptp_remove, 2831ab91f0a9SRafal Ozieblo .get_ptp_max_adj = gem_get_ptp_max_adj, 2832ab91f0a9SRafal Ozieblo .get_tsu_rate = gem_get_tsu_rate, 2833ab91f0a9SRafal Ozieblo .get_ts_info = gem_get_ts_info, 2834ab91f0a9SRafal Ozieblo .get_hwtst = gem_get_hwtst, 2835ab91f0a9SRafal Ozieblo .set_hwtst = gem_set_hwtst, 2836ab91f0a9SRafal Ozieblo }; 2837ab91f0a9SRafal Ozieblo #endif 2838ab91f0a9SRafal Ozieblo 2839b83f1527SRafal Ozieblo static int macb_get_ts_info(struct net_device *netdev, 2840b83f1527SRafal Ozieblo struct ethtool_ts_info *info) 2841b83f1527SRafal Ozieblo { 2842b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 2843b83f1527SRafal Ozieblo 2844b83f1527SRafal Ozieblo if (bp->ptp_info) 2845b83f1527SRafal Ozieblo return bp->ptp_info->get_ts_info(netdev, info); 2846b83f1527SRafal Ozieblo 2847b83f1527SRafal Ozieblo return ethtool_op_get_ts_info(netdev, info); 2848b83f1527SRafal Ozieblo } 2849b83f1527SRafal Ozieblo 2850ae8223deSRafal Ozieblo static void gem_enable_flow_filters(struct macb *bp, bool enable) 2851ae8223deSRafal Ozieblo { 2852ae8223deSRafal Ozieblo struct ethtool_rx_fs_item *item; 2853ae8223deSRafal Ozieblo u32 t2_scr; 2854ae8223deSRafal Ozieblo int num_t2_scr; 2855ae8223deSRafal Ozieblo 2856ae8223deSRafal Ozieblo num_t2_scr = GEM_BFEXT(T2SCR, gem_readl(bp, DCFG8)); 2857ae8223deSRafal Ozieblo 2858ae8223deSRafal Ozieblo list_for_each_entry(item, &bp->rx_fs_list.list, list) { 2859ae8223deSRafal Ozieblo struct ethtool_rx_flow_spec *fs = &item->fs; 2860ae8223deSRafal Ozieblo struct ethtool_tcpip4_spec *tp4sp_m; 2861ae8223deSRafal Ozieblo 2862ae8223deSRafal Ozieblo if (fs->location >= num_t2_scr) 2863ae8223deSRafal Ozieblo continue; 2864ae8223deSRafal Ozieblo 2865ae8223deSRafal Ozieblo t2_scr = gem_readl_n(bp, SCRT2, fs->location); 2866ae8223deSRafal Ozieblo 2867ae8223deSRafal Ozieblo /* enable/disable screener regs for the flow entry */ 2868ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(ETHTEN, enable, t2_scr); 2869ae8223deSRafal Ozieblo 2870ae8223deSRafal Ozieblo /* only enable fields with no masking */ 2871ae8223deSRafal Ozieblo tp4sp_m = &(fs->m_u.tcp_ip4_spec); 2872ae8223deSRafal Ozieblo 2873ae8223deSRafal Ozieblo if (enable && (tp4sp_m->ip4src == 0xFFFFFFFF)) 2874ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPAEN, 1, t2_scr); 2875ae8223deSRafal Ozieblo else 2876ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPAEN, 0, t2_scr); 2877ae8223deSRafal Ozieblo 2878ae8223deSRafal Ozieblo if (enable && (tp4sp_m->ip4dst == 0xFFFFFFFF)) 2879ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPBEN, 1, t2_scr); 2880ae8223deSRafal Ozieblo else 2881ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPBEN, 0, t2_scr); 2882ae8223deSRafal Ozieblo 2883ae8223deSRafal Ozieblo if (enable && ((tp4sp_m->psrc == 0xFFFF) || (tp4sp_m->pdst == 0xFFFF))) 2884ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPCEN, 1, t2_scr); 2885ae8223deSRafal Ozieblo else 2886ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPCEN, 0, t2_scr); 2887ae8223deSRafal Ozieblo 2888ae8223deSRafal Ozieblo gem_writel_n(bp, SCRT2, fs->location, t2_scr); 2889ae8223deSRafal Ozieblo } 2890ae8223deSRafal Ozieblo } 2891ae8223deSRafal Ozieblo 2892ae8223deSRafal Ozieblo static void gem_prog_cmp_regs(struct macb *bp, struct ethtool_rx_flow_spec *fs) 2893ae8223deSRafal Ozieblo { 2894ae8223deSRafal Ozieblo struct ethtool_tcpip4_spec *tp4sp_v, *tp4sp_m; 2895ae8223deSRafal Ozieblo uint16_t index = fs->location; 2896ae8223deSRafal Ozieblo u32 w0, w1, t2_scr; 2897ae8223deSRafal Ozieblo bool cmp_a = false; 2898ae8223deSRafal Ozieblo bool cmp_b = false; 2899ae8223deSRafal Ozieblo bool cmp_c = false; 2900ae8223deSRafal Ozieblo 2901ae8223deSRafal Ozieblo tp4sp_v = &(fs->h_u.tcp_ip4_spec); 2902ae8223deSRafal Ozieblo tp4sp_m = &(fs->m_u.tcp_ip4_spec); 2903ae8223deSRafal Ozieblo 2904ae8223deSRafal Ozieblo /* ignore field if any masking set */ 2905ae8223deSRafal Ozieblo if (tp4sp_m->ip4src == 0xFFFFFFFF) { 2906ae8223deSRafal Ozieblo /* 1st compare reg - IP source address */ 2907ae8223deSRafal Ozieblo w0 = 0; 2908ae8223deSRafal Ozieblo w1 = 0; 2909ae8223deSRafal Ozieblo w0 = tp4sp_v->ip4src; 2910ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2DISMSK, 1, w1); /* 32-bit compare */ 2911ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2CMPOFST, GEM_T2COMPOFST_ETYPE, w1); 2912ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2OFST, ETYPE_SRCIP_OFFSET, w1); 2913ae8223deSRafal Ozieblo gem_writel_n(bp, T2CMPW0, T2CMP_OFST(GEM_IP4SRC_CMP(index)), w0); 2914ae8223deSRafal Ozieblo gem_writel_n(bp, T2CMPW1, T2CMP_OFST(GEM_IP4SRC_CMP(index)), w1); 2915ae8223deSRafal Ozieblo cmp_a = true; 2916ae8223deSRafal Ozieblo } 2917ae8223deSRafal Ozieblo 2918ae8223deSRafal Ozieblo /* ignore field if any masking set */ 2919ae8223deSRafal Ozieblo if (tp4sp_m->ip4dst == 0xFFFFFFFF) { 2920ae8223deSRafal Ozieblo /* 2nd compare reg - IP destination address */ 2921ae8223deSRafal Ozieblo w0 = 0; 2922ae8223deSRafal Ozieblo w1 = 0; 2923ae8223deSRafal Ozieblo w0 = tp4sp_v->ip4dst; 2924ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2DISMSK, 1, w1); /* 32-bit compare */ 2925ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2CMPOFST, GEM_T2COMPOFST_ETYPE, w1); 2926ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2OFST, ETYPE_DSTIP_OFFSET, w1); 2927ae8223deSRafal Ozieblo gem_writel_n(bp, T2CMPW0, T2CMP_OFST(GEM_IP4DST_CMP(index)), w0); 2928ae8223deSRafal Ozieblo gem_writel_n(bp, T2CMPW1, T2CMP_OFST(GEM_IP4DST_CMP(index)), w1); 2929ae8223deSRafal Ozieblo cmp_b = true; 2930ae8223deSRafal Ozieblo } 2931ae8223deSRafal Ozieblo 2932ae8223deSRafal Ozieblo /* ignore both port fields if masking set in both */ 2933ae8223deSRafal Ozieblo if ((tp4sp_m->psrc == 0xFFFF) || (tp4sp_m->pdst == 0xFFFF)) { 2934ae8223deSRafal Ozieblo /* 3rd compare reg - source port, destination port */ 2935ae8223deSRafal Ozieblo w0 = 0; 2936ae8223deSRafal Ozieblo w1 = 0; 2937ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2CMPOFST, GEM_T2COMPOFST_IPHDR, w1); 2938ae8223deSRafal Ozieblo if (tp4sp_m->psrc == tp4sp_m->pdst) { 2939ae8223deSRafal Ozieblo w0 = GEM_BFINS(T2MASK, tp4sp_v->psrc, w0); 2940ae8223deSRafal Ozieblo w0 = GEM_BFINS(T2CMP, tp4sp_v->pdst, w0); 2941ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2DISMSK, 1, w1); /* 32-bit compare */ 2942ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2OFST, IPHDR_SRCPORT_OFFSET, w1); 2943ae8223deSRafal Ozieblo } else { 2944ae8223deSRafal Ozieblo /* only one port definition */ 2945ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2DISMSK, 0, w1); /* 16-bit compare */ 2946ae8223deSRafal Ozieblo w0 = GEM_BFINS(T2MASK, 0xFFFF, w0); 2947ae8223deSRafal Ozieblo if (tp4sp_m->psrc == 0xFFFF) { /* src port */ 2948ae8223deSRafal Ozieblo w0 = GEM_BFINS(T2CMP, tp4sp_v->psrc, w0); 2949ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2OFST, IPHDR_SRCPORT_OFFSET, w1); 2950ae8223deSRafal Ozieblo } else { /* dst port */ 2951ae8223deSRafal Ozieblo w0 = GEM_BFINS(T2CMP, tp4sp_v->pdst, w0); 2952ae8223deSRafal Ozieblo w1 = GEM_BFINS(T2OFST, IPHDR_DSTPORT_OFFSET, w1); 2953ae8223deSRafal Ozieblo } 2954ae8223deSRafal Ozieblo } 2955ae8223deSRafal Ozieblo gem_writel_n(bp, T2CMPW0, T2CMP_OFST(GEM_PORT_CMP(index)), w0); 2956ae8223deSRafal Ozieblo gem_writel_n(bp, T2CMPW1, T2CMP_OFST(GEM_PORT_CMP(index)), w1); 2957ae8223deSRafal Ozieblo cmp_c = true; 2958ae8223deSRafal Ozieblo } 2959ae8223deSRafal Ozieblo 2960ae8223deSRafal Ozieblo t2_scr = 0; 2961ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(QUEUE, (fs->ring_cookie) & 0xFF, t2_scr); 2962ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(ETHT2IDX, SCRT2_ETHT, t2_scr); 2963ae8223deSRafal Ozieblo if (cmp_a) 2964ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPA, GEM_IP4SRC_CMP(index), t2_scr); 2965ae8223deSRafal Ozieblo if (cmp_b) 2966ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPB, GEM_IP4DST_CMP(index), t2_scr); 2967ae8223deSRafal Ozieblo if (cmp_c) 2968ae8223deSRafal Ozieblo t2_scr = GEM_BFINS(CMPC, GEM_PORT_CMP(index), t2_scr); 2969ae8223deSRafal Ozieblo gem_writel_n(bp, SCRT2, index, t2_scr); 2970ae8223deSRafal Ozieblo } 2971ae8223deSRafal Ozieblo 2972ae8223deSRafal Ozieblo static int gem_add_flow_filter(struct net_device *netdev, 2973ae8223deSRafal Ozieblo struct ethtool_rxnfc *cmd) 2974ae8223deSRafal Ozieblo { 2975ae8223deSRafal Ozieblo struct macb *bp = netdev_priv(netdev); 2976ae8223deSRafal Ozieblo struct ethtool_rx_flow_spec *fs = &cmd->fs; 2977ae8223deSRafal Ozieblo struct ethtool_rx_fs_item *item, *newfs; 29787038cdb7SJulia Cartwright unsigned long flags; 2979ae8223deSRafal Ozieblo int ret = -EINVAL; 2980ae8223deSRafal Ozieblo bool added = false; 2981ae8223deSRafal Ozieblo 2982cc1674eeSJulia Cartwright newfs = kmalloc(sizeof(*newfs), GFP_KERNEL); 2983ae8223deSRafal Ozieblo if (newfs == NULL) 2984ae8223deSRafal Ozieblo return -ENOMEM; 2985ae8223deSRafal Ozieblo memcpy(&newfs->fs, fs, sizeof(newfs->fs)); 2986ae8223deSRafal Ozieblo 2987ae8223deSRafal Ozieblo netdev_dbg(netdev, 2988ae8223deSRafal Ozieblo "Adding flow filter entry,type=%u,queue=%u,loc=%u,src=%08X,dst=%08X,ps=%u,pd=%u\n", 2989ae8223deSRafal Ozieblo fs->flow_type, (int)fs->ring_cookie, fs->location, 2990ae8223deSRafal Ozieblo htonl(fs->h_u.tcp_ip4_spec.ip4src), 2991ae8223deSRafal Ozieblo htonl(fs->h_u.tcp_ip4_spec.ip4dst), 2992ae8223deSRafal Ozieblo htons(fs->h_u.tcp_ip4_spec.psrc), htons(fs->h_u.tcp_ip4_spec.pdst)); 2993ae8223deSRafal Ozieblo 29947038cdb7SJulia Cartwright spin_lock_irqsave(&bp->rx_fs_lock, flags); 29957038cdb7SJulia Cartwright 2996ae8223deSRafal Ozieblo /* find correct place to add in list */ 2997ae8223deSRafal Ozieblo list_for_each_entry(item, &bp->rx_fs_list.list, list) { 2998ae8223deSRafal Ozieblo if (item->fs.location > newfs->fs.location) { 2999ae8223deSRafal Ozieblo list_add_tail(&newfs->list, &item->list); 3000ae8223deSRafal Ozieblo added = true; 3001ae8223deSRafal Ozieblo break; 3002ae8223deSRafal Ozieblo } else if (item->fs.location == fs->location) { 3003ae8223deSRafal Ozieblo netdev_err(netdev, "Rule not added: location %d not free!\n", 3004ae8223deSRafal Ozieblo fs->location); 3005ae8223deSRafal Ozieblo ret = -EBUSY; 3006ae8223deSRafal Ozieblo goto err; 3007ae8223deSRafal Ozieblo } 3008ae8223deSRafal Ozieblo } 3009ae8223deSRafal Ozieblo if (!added) 3010ae8223deSRafal Ozieblo list_add_tail(&newfs->list, &bp->rx_fs_list.list); 3011ae8223deSRafal Ozieblo 3012ae8223deSRafal Ozieblo gem_prog_cmp_regs(bp, fs); 3013ae8223deSRafal Ozieblo bp->rx_fs_list.count++; 3014ae8223deSRafal Ozieblo /* enable filtering if NTUPLE on */ 3015ae8223deSRafal Ozieblo if (netdev->features & NETIF_F_NTUPLE) 3016ae8223deSRafal Ozieblo gem_enable_flow_filters(bp, 1); 3017ae8223deSRafal Ozieblo 30187038cdb7SJulia Cartwright spin_unlock_irqrestore(&bp->rx_fs_lock, flags); 3019ae8223deSRafal Ozieblo return 0; 3020ae8223deSRafal Ozieblo 3021ae8223deSRafal Ozieblo err: 30227038cdb7SJulia Cartwright spin_unlock_irqrestore(&bp->rx_fs_lock, flags); 3023ae8223deSRafal Ozieblo kfree(newfs); 3024ae8223deSRafal Ozieblo return ret; 3025ae8223deSRafal Ozieblo } 3026ae8223deSRafal Ozieblo 3027ae8223deSRafal Ozieblo static int gem_del_flow_filter(struct net_device *netdev, 3028ae8223deSRafal Ozieblo struct ethtool_rxnfc *cmd) 3029ae8223deSRafal Ozieblo { 3030ae8223deSRafal Ozieblo struct macb *bp = netdev_priv(netdev); 3031ae8223deSRafal Ozieblo struct ethtool_rx_fs_item *item; 3032ae8223deSRafal Ozieblo struct ethtool_rx_flow_spec *fs; 30337038cdb7SJulia Cartwright unsigned long flags; 30347038cdb7SJulia Cartwright 30357038cdb7SJulia Cartwright spin_lock_irqsave(&bp->rx_fs_lock, flags); 3036ae8223deSRafal Ozieblo 3037ae8223deSRafal Ozieblo list_for_each_entry(item, &bp->rx_fs_list.list, list) { 3038ae8223deSRafal Ozieblo if (item->fs.location == cmd->fs.location) { 3039ae8223deSRafal Ozieblo /* disable screener regs for the flow entry */ 3040ae8223deSRafal Ozieblo fs = &(item->fs); 3041ae8223deSRafal Ozieblo netdev_dbg(netdev, 3042ae8223deSRafal Ozieblo "Deleting flow filter entry,type=%u,queue=%u,loc=%u,src=%08X,dst=%08X,ps=%u,pd=%u\n", 3043ae8223deSRafal Ozieblo fs->flow_type, (int)fs->ring_cookie, fs->location, 3044ae8223deSRafal Ozieblo htonl(fs->h_u.tcp_ip4_spec.ip4src), 3045ae8223deSRafal Ozieblo htonl(fs->h_u.tcp_ip4_spec.ip4dst), 3046ae8223deSRafal Ozieblo htons(fs->h_u.tcp_ip4_spec.psrc), 3047ae8223deSRafal Ozieblo htons(fs->h_u.tcp_ip4_spec.pdst)); 3048ae8223deSRafal Ozieblo 3049ae8223deSRafal Ozieblo gem_writel_n(bp, SCRT2, fs->location, 0); 3050ae8223deSRafal Ozieblo 3051ae8223deSRafal Ozieblo list_del(&item->list); 3052ae8223deSRafal Ozieblo bp->rx_fs_list.count--; 30537038cdb7SJulia Cartwright spin_unlock_irqrestore(&bp->rx_fs_lock, flags); 30547038cdb7SJulia Cartwright kfree(item); 3055ae8223deSRafal Ozieblo return 0; 3056ae8223deSRafal Ozieblo } 3057ae8223deSRafal Ozieblo } 3058ae8223deSRafal Ozieblo 30597038cdb7SJulia Cartwright spin_unlock_irqrestore(&bp->rx_fs_lock, flags); 3060ae8223deSRafal Ozieblo return -EINVAL; 3061ae8223deSRafal Ozieblo } 3062ae8223deSRafal Ozieblo 3063ae8223deSRafal Ozieblo static int gem_get_flow_entry(struct net_device *netdev, 3064ae8223deSRafal Ozieblo struct ethtool_rxnfc *cmd) 3065ae8223deSRafal Ozieblo { 3066ae8223deSRafal Ozieblo struct macb *bp = netdev_priv(netdev); 3067ae8223deSRafal Ozieblo struct ethtool_rx_fs_item *item; 3068ae8223deSRafal Ozieblo 3069ae8223deSRafal Ozieblo list_for_each_entry(item, &bp->rx_fs_list.list, list) { 3070ae8223deSRafal Ozieblo if (item->fs.location == cmd->fs.location) { 3071ae8223deSRafal Ozieblo memcpy(&cmd->fs, &item->fs, sizeof(cmd->fs)); 3072ae8223deSRafal Ozieblo return 0; 3073ae8223deSRafal Ozieblo } 3074ae8223deSRafal Ozieblo } 3075ae8223deSRafal Ozieblo return -EINVAL; 3076ae8223deSRafal Ozieblo } 3077ae8223deSRafal Ozieblo 3078ae8223deSRafal Ozieblo static int gem_get_all_flow_entries(struct net_device *netdev, 3079ae8223deSRafal Ozieblo struct ethtool_rxnfc *cmd, u32 *rule_locs) 3080ae8223deSRafal Ozieblo { 3081ae8223deSRafal Ozieblo struct macb *bp = netdev_priv(netdev); 3082ae8223deSRafal Ozieblo struct ethtool_rx_fs_item *item; 3083ae8223deSRafal Ozieblo uint32_t cnt = 0; 3084ae8223deSRafal Ozieblo 3085ae8223deSRafal Ozieblo list_for_each_entry(item, &bp->rx_fs_list.list, list) { 3086ae8223deSRafal Ozieblo if (cnt == cmd->rule_cnt) 3087ae8223deSRafal Ozieblo return -EMSGSIZE; 3088ae8223deSRafal Ozieblo rule_locs[cnt] = item->fs.location; 3089ae8223deSRafal Ozieblo cnt++; 3090ae8223deSRafal Ozieblo } 3091ae8223deSRafal Ozieblo cmd->data = bp->max_tuples; 3092ae8223deSRafal Ozieblo cmd->rule_cnt = cnt; 3093ae8223deSRafal Ozieblo 3094ae8223deSRafal Ozieblo return 0; 3095ae8223deSRafal Ozieblo } 3096ae8223deSRafal Ozieblo 3097ae8223deSRafal Ozieblo static int gem_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, 3098ae8223deSRafal Ozieblo u32 *rule_locs) 3099ae8223deSRafal Ozieblo { 3100ae8223deSRafal Ozieblo struct macb *bp = netdev_priv(netdev); 3101ae8223deSRafal Ozieblo int ret = 0; 3102ae8223deSRafal Ozieblo 3103ae8223deSRafal Ozieblo switch (cmd->cmd) { 3104ae8223deSRafal Ozieblo case ETHTOOL_GRXRINGS: 3105ae8223deSRafal Ozieblo cmd->data = bp->num_queues; 3106ae8223deSRafal Ozieblo break; 3107ae8223deSRafal Ozieblo case ETHTOOL_GRXCLSRLCNT: 3108ae8223deSRafal Ozieblo cmd->rule_cnt = bp->rx_fs_list.count; 3109ae8223deSRafal Ozieblo break; 3110ae8223deSRafal Ozieblo case ETHTOOL_GRXCLSRULE: 3111ae8223deSRafal Ozieblo ret = gem_get_flow_entry(netdev, cmd); 3112ae8223deSRafal Ozieblo break; 3113ae8223deSRafal Ozieblo case ETHTOOL_GRXCLSRLALL: 3114ae8223deSRafal Ozieblo ret = gem_get_all_flow_entries(netdev, cmd, rule_locs); 3115ae8223deSRafal Ozieblo break; 3116ae8223deSRafal Ozieblo default: 3117ae8223deSRafal Ozieblo netdev_err(netdev, 3118ae8223deSRafal Ozieblo "Command parameter %d is not supported\n", cmd->cmd); 3119ae8223deSRafal Ozieblo ret = -EOPNOTSUPP; 3120ae8223deSRafal Ozieblo } 3121ae8223deSRafal Ozieblo 3122ae8223deSRafal Ozieblo return ret; 3123ae8223deSRafal Ozieblo } 3124ae8223deSRafal Ozieblo 3125ae8223deSRafal Ozieblo static int gem_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) 3126ae8223deSRafal Ozieblo { 3127ae8223deSRafal Ozieblo struct macb *bp = netdev_priv(netdev); 3128ae8223deSRafal Ozieblo int ret; 3129ae8223deSRafal Ozieblo 3130ae8223deSRafal Ozieblo switch (cmd->cmd) { 3131ae8223deSRafal Ozieblo case ETHTOOL_SRXCLSRLINS: 3132ae8223deSRafal Ozieblo if ((cmd->fs.location >= bp->max_tuples) 3133ae8223deSRafal Ozieblo || (cmd->fs.ring_cookie >= bp->num_queues)) { 3134ae8223deSRafal Ozieblo ret = -EINVAL; 3135ae8223deSRafal Ozieblo break; 3136ae8223deSRafal Ozieblo } 3137ae8223deSRafal Ozieblo ret = gem_add_flow_filter(netdev, cmd); 3138ae8223deSRafal Ozieblo break; 3139ae8223deSRafal Ozieblo case ETHTOOL_SRXCLSRLDEL: 3140ae8223deSRafal Ozieblo ret = gem_del_flow_filter(netdev, cmd); 3141ae8223deSRafal Ozieblo break; 3142ae8223deSRafal Ozieblo default: 3143ae8223deSRafal Ozieblo netdev_err(netdev, 3144ae8223deSRafal Ozieblo "Command parameter %d is not supported\n", cmd->cmd); 3145ae8223deSRafal Ozieblo ret = -EOPNOTSUPP; 3146ae8223deSRafal Ozieblo } 3147ae8223deSRafal Ozieblo 3148ae8223deSRafal Ozieblo return ret; 3149ae8223deSRafal Ozieblo } 3150ae8223deSRafal Ozieblo 3151b83f1527SRafal Ozieblo static const struct ethtool_ops macb_ethtool_ops = { 3152b83f1527SRafal Ozieblo .get_regs_len = macb_get_regs_len, 3153b83f1527SRafal Ozieblo .get_regs = macb_get_regs, 3154b83f1527SRafal Ozieblo .get_link = ethtool_op_get_link, 3155b83f1527SRafal Ozieblo .get_ts_info = ethtool_op_get_ts_info, 3156b83f1527SRafal Ozieblo .get_wol = macb_get_wol, 3157b83f1527SRafal Ozieblo .set_wol = macb_set_wol, 3158b83f1527SRafal Ozieblo .get_link_ksettings = phy_ethtool_get_link_ksettings, 3159b83f1527SRafal Ozieblo .set_link_ksettings = phy_ethtool_set_link_ksettings, 3160b83f1527SRafal Ozieblo .get_ringparam = macb_get_ringparam, 3161b83f1527SRafal Ozieblo .set_ringparam = macb_set_ringparam, 3162b83f1527SRafal Ozieblo }; 3163b83f1527SRafal Ozieblo 3164b83f1527SRafal Ozieblo static const struct ethtool_ops gem_ethtool_ops = { 3165b83f1527SRafal Ozieblo .get_regs_len = macb_get_regs_len, 3166b83f1527SRafal Ozieblo .get_regs = macb_get_regs, 3167b83f1527SRafal Ozieblo .get_link = ethtool_op_get_link, 3168b83f1527SRafal Ozieblo .get_ts_info = macb_get_ts_info, 3169b83f1527SRafal Ozieblo .get_ethtool_stats = gem_get_ethtool_stats, 3170b83f1527SRafal Ozieblo .get_strings = gem_get_ethtool_strings, 3171b83f1527SRafal Ozieblo .get_sset_count = gem_get_sset_count, 3172b83f1527SRafal Ozieblo .get_link_ksettings = phy_ethtool_get_link_ksettings, 3173b83f1527SRafal Ozieblo .set_link_ksettings = phy_ethtool_set_link_ksettings, 3174b83f1527SRafal Ozieblo .get_ringparam = macb_get_ringparam, 3175b83f1527SRafal Ozieblo .set_ringparam = macb_set_ringparam, 3176ae8223deSRafal Ozieblo .get_rxnfc = gem_get_rxnfc, 3177ae8223deSRafal Ozieblo .set_rxnfc = gem_set_rxnfc, 3178b83f1527SRafal Ozieblo }; 3179b83f1527SRafal Ozieblo 3180b83f1527SRafal Ozieblo static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 3181b83f1527SRafal Ozieblo { 3182b83f1527SRafal Ozieblo struct phy_device *phydev = dev->phydev; 3183b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 3184b83f1527SRafal Ozieblo 3185b83f1527SRafal Ozieblo if (!netif_running(dev)) 3186b83f1527SRafal Ozieblo return -EINVAL; 3187b83f1527SRafal Ozieblo 3188b83f1527SRafal Ozieblo if (!phydev) 3189b83f1527SRafal Ozieblo return -ENODEV; 3190b83f1527SRafal Ozieblo 3191b83f1527SRafal Ozieblo if (!bp->ptp_info) 3192b83f1527SRafal Ozieblo return phy_mii_ioctl(phydev, rq, cmd); 3193b83f1527SRafal Ozieblo 3194b83f1527SRafal Ozieblo switch (cmd) { 3195b83f1527SRafal Ozieblo case SIOCSHWTSTAMP: 3196b83f1527SRafal Ozieblo return bp->ptp_info->set_hwtst(dev, rq, cmd); 3197b83f1527SRafal Ozieblo case SIOCGHWTSTAMP: 3198b83f1527SRafal Ozieblo return bp->ptp_info->get_hwtst(dev, rq); 3199b83f1527SRafal Ozieblo default: 3200b83f1527SRafal Ozieblo return phy_mii_ioctl(phydev, rq, cmd); 3201b83f1527SRafal Ozieblo } 3202b83f1527SRafal Ozieblo } 3203b83f1527SRafal Ozieblo 3204b83f1527SRafal Ozieblo static int macb_set_features(struct net_device *netdev, 3205b83f1527SRafal Ozieblo netdev_features_t features) 3206b83f1527SRafal Ozieblo { 3207b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 3208b83f1527SRafal Ozieblo netdev_features_t changed = features ^ netdev->features; 3209b83f1527SRafal Ozieblo 3210b83f1527SRafal Ozieblo /* TX checksum offload */ 3211b83f1527SRafal Ozieblo if ((changed & NETIF_F_HW_CSUM) && macb_is_gem(bp)) { 3212b83f1527SRafal Ozieblo u32 dmacfg; 3213b83f1527SRafal Ozieblo 3214b83f1527SRafal Ozieblo dmacfg = gem_readl(bp, DMACFG); 3215b83f1527SRafal Ozieblo if (features & NETIF_F_HW_CSUM) 3216b83f1527SRafal Ozieblo dmacfg |= GEM_BIT(TXCOEN); 3217b83f1527SRafal Ozieblo else 3218b83f1527SRafal Ozieblo dmacfg &= ~GEM_BIT(TXCOEN); 3219b83f1527SRafal Ozieblo gem_writel(bp, DMACFG, dmacfg); 3220b83f1527SRafal Ozieblo } 3221b83f1527SRafal Ozieblo 3222b83f1527SRafal Ozieblo /* RX checksum offload */ 3223b83f1527SRafal Ozieblo if ((changed & NETIF_F_RXCSUM) && macb_is_gem(bp)) { 3224b83f1527SRafal Ozieblo u32 netcfg; 3225b83f1527SRafal Ozieblo 3226b83f1527SRafal Ozieblo netcfg = gem_readl(bp, NCFGR); 3227b83f1527SRafal Ozieblo if (features & NETIF_F_RXCSUM && 3228b83f1527SRafal Ozieblo !(netdev->flags & IFF_PROMISC)) 3229b83f1527SRafal Ozieblo netcfg |= GEM_BIT(RXCOEN); 3230b83f1527SRafal Ozieblo else 3231b83f1527SRafal Ozieblo netcfg &= ~GEM_BIT(RXCOEN); 3232b83f1527SRafal Ozieblo gem_writel(bp, NCFGR, netcfg); 3233b83f1527SRafal Ozieblo } 3234b83f1527SRafal Ozieblo 3235ae8223deSRafal Ozieblo /* RX Flow Filters */ 3236ae8223deSRafal Ozieblo if ((changed & NETIF_F_NTUPLE) && macb_is_gem(bp)) { 3237ae8223deSRafal Ozieblo bool turn_on = features & NETIF_F_NTUPLE; 3238ae8223deSRafal Ozieblo 3239ae8223deSRafal Ozieblo gem_enable_flow_filters(bp, turn_on); 3240ae8223deSRafal Ozieblo } 3241b83f1527SRafal Ozieblo return 0; 3242b83f1527SRafal Ozieblo } 3243b83f1527SRafal Ozieblo 3244b83f1527SRafal Ozieblo static const struct net_device_ops macb_netdev_ops = { 3245b83f1527SRafal Ozieblo .ndo_open = macb_open, 3246b83f1527SRafal Ozieblo .ndo_stop = macb_close, 3247b83f1527SRafal Ozieblo .ndo_start_xmit = macb_start_xmit, 3248b83f1527SRafal Ozieblo .ndo_set_rx_mode = macb_set_rx_mode, 3249b83f1527SRafal Ozieblo .ndo_get_stats = macb_get_stats, 3250b83f1527SRafal Ozieblo .ndo_do_ioctl = macb_ioctl, 3251b83f1527SRafal Ozieblo .ndo_validate_addr = eth_validate_addr, 3252b83f1527SRafal Ozieblo .ndo_change_mtu = macb_change_mtu, 3253b83f1527SRafal Ozieblo .ndo_set_mac_address = eth_mac_addr, 3254b83f1527SRafal Ozieblo #ifdef CONFIG_NET_POLL_CONTROLLER 3255b83f1527SRafal Ozieblo .ndo_poll_controller = macb_poll_controller, 3256b83f1527SRafal Ozieblo #endif 3257b83f1527SRafal Ozieblo .ndo_set_features = macb_set_features, 3258b83f1527SRafal Ozieblo .ndo_features_check = macb_features_check, 3259b83f1527SRafal Ozieblo }; 3260b83f1527SRafal Ozieblo 3261b83f1527SRafal Ozieblo /* Configure peripheral capabilities according to device tree 3262b83f1527SRafal Ozieblo * and integration options used 3263b83f1527SRafal Ozieblo */ 3264b83f1527SRafal Ozieblo static void macb_configure_caps(struct macb *bp, 3265b83f1527SRafal Ozieblo const struct macb_config *dt_conf) 3266b83f1527SRafal Ozieblo { 3267b83f1527SRafal Ozieblo u32 dcfg; 3268b83f1527SRafal Ozieblo 3269b83f1527SRafal Ozieblo if (dt_conf) 3270b83f1527SRafal Ozieblo bp->caps = dt_conf->caps; 3271b83f1527SRafal Ozieblo 3272b83f1527SRafal Ozieblo if (hw_is_gem(bp->regs, bp->native_io)) { 3273b83f1527SRafal Ozieblo bp->caps |= MACB_CAPS_MACB_IS_GEM; 3274b83f1527SRafal Ozieblo 3275b83f1527SRafal Ozieblo dcfg = gem_readl(bp, DCFG1); 3276b83f1527SRafal Ozieblo if (GEM_BFEXT(IRQCOR, dcfg) == 0) 3277b83f1527SRafal Ozieblo bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE; 3278b83f1527SRafal Ozieblo dcfg = gem_readl(bp, DCFG2); 3279b83f1527SRafal Ozieblo if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0) 3280b83f1527SRafal Ozieblo bp->caps |= MACB_CAPS_FIFO_MODE; 3281ab91f0a9SRafal Ozieblo #ifdef CONFIG_MACB_USE_HWSTAMP 3282ab91f0a9SRafal Ozieblo if (gem_has_ptp(bp)) { 3283b83f1527SRafal Ozieblo if (!GEM_BFEXT(TSU, gem_readl(bp, DCFG5))) 3284b83f1527SRafal Ozieblo pr_err("GEM doesn't support hardware ptp.\n"); 3285ab91f0a9SRafal Ozieblo else { 3286b83f1527SRafal Ozieblo bp->hw_dma_cap |= HW_DMA_CAP_PTP; 3287ab91f0a9SRafal Ozieblo bp->ptp_info = &gem_ptp_info; 3288b83f1527SRafal Ozieblo } 3289b83f1527SRafal Ozieblo } 3290ab91f0a9SRafal Ozieblo #endif 3291ab91f0a9SRafal Ozieblo } 3292b83f1527SRafal Ozieblo 3293b83f1527SRafal Ozieblo dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps); 3294b83f1527SRafal Ozieblo } 3295b83f1527SRafal Ozieblo 3296b83f1527SRafal Ozieblo static void macb_probe_queues(void __iomem *mem, 3297b83f1527SRafal Ozieblo bool native_io, 3298b83f1527SRafal Ozieblo unsigned int *queue_mask, 3299b83f1527SRafal Ozieblo unsigned int *num_queues) 3300b83f1527SRafal Ozieblo { 3301b83f1527SRafal Ozieblo unsigned int hw_q; 3302b83f1527SRafal Ozieblo 3303b83f1527SRafal Ozieblo *queue_mask = 0x1; 3304b83f1527SRafal Ozieblo *num_queues = 1; 3305b83f1527SRafal Ozieblo 3306b83f1527SRafal Ozieblo /* is it macb or gem ? 3307b83f1527SRafal Ozieblo * 3308b83f1527SRafal Ozieblo * We need to read directly from the hardware here because 3309b83f1527SRafal Ozieblo * we are early in the probe process and don't have the 3310b83f1527SRafal Ozieblo * MACB_CAPS_MACB_IS_GEM flag positioned 3311b83f1527SRafal Ozieblo */ 3312b83f1527SRafal Ozieblo if (!hw_is_gem(mem, native_io)) 3313b83f1527SRafal Ozieblo return; 3314b83f1527SRafal Ozieblo 3315b83f1527SRafal Ozieblo /* bit 0 is never set but queue 0 always exists */ 3316b83f1527SRafal Ozieblo *queue_mask = readl_relaxed(mem + GEM_DCFG6) & 0xff; 3317b83f1527SRafal Ozieblo 3318b83f1527SRafal Ozieblo *queue_mask |= 0x1; 3319b83f1527SRafal Ozieblo 3320b83f1527SRafal Ozieblo for (hw_q = 1; hw_q < MACB_MAX_QUEUES; ++hw_q) 3321b83f1527SRafal Ozieblo if (*queue_mask & (1 << hw_q)) 3322b83f1527SRafal Ozieblo (*num_queues)++; 3323b83f1527SRafal Ozieblo } 3324b83f1527SRafal Ozieblo 3325b83f1527SRafal Ozieblo static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, 3326b83f1527SRafal Ozieblo struct clk **hclk, struct clk **tx_clk, 3327f5473d1dSHarini Katakam struct clk **rx_clk, struct clk **tsu_clk) 3328b83f1527SRafal Ozieblo { 3329b83f1527SRafal Ozieblo struct macb_platform_data *pdata; 3330b83f1527SRafal Ozieblo int err; 3331b83f1527SRafal Ozieblo 3332b83f1527SRafal Ozieblo pdata = dev_get_platdata(&pdev->dev); 3333b83f1527SRafal Ozieblo if (pdata) { 3334b83f1527SRafal Ozieblo *pclk = pdata->pclk; 3335b83f1527SRafal Ozieblo *hclk = pdata->hclk; 3336b83f1527SRafal Ozieblo } else { 3337b83f1527SRafal Ozieblo *pclk = devm_clk_get(&pdev->dev, "pclk"); 3338b83f1527SRafal Ozieblo *hclk = devm_clk_get(&pdev->dev, "hclk"); 3339b83f1527SRafal Ozieblo } 3340b83f1527SRafal Ozieblo 3341cd5afa91SHarini Katakam if (IS_ERR_OR_NULL(*pclk)) { 3342b83f1527SRafal Ozieblo err = PTR_ERR(*pclk); 3343cd5afa91SHarini Katakam if (!err) 3344cd5afa91SHarini Katakam err = -ENODEV; 3345cd5afa91SHarini Katakam 3346b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err); 3347b83f1527SRafal Ozieblo return err; 3348b83f1527SRafal Ozieblo } 3349b83f1527SRafal Ozieblo 3350cd5afa91SHarini Katakam if (IS_ERR_OR_NULL(*hclk)) { 3351b83f1527SRafal Ozieblo err = PTR_ERR(*hclk); 3352cd5afa91SHarini Katakam if (!err) 3353cd5afa91SHarini Katakam err = -ENODEV; 3354cd5afa91SHarini Katakam 3355b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to get hclk (%u)\n", err); 3356b83f1527SRafal Ozieblo return err; 3357b83f1527SRafal Ozieblo } 3358b83f1527SRafal Ozieblo 3359b83f1527SRafal Ozieblo *tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); 3360b83f1527SRafal Ozieblo if (IS_ERR(*tx_clk)) 3361b83f1527SRafal Ozieblo *tx_clk = NULL; 3362b83f1527SRafal Ozieblo 3363b83f1527SRafal Ozieblo *rx_clk = devm_clk_get(&pdev->dev, "rx_clk"); 3364b83f1527SRafal Ozieblo if (IS_ERR(*rx_clk)) 3365b83f1527SRafal Ozieblo *rx_clk = NULL; 3366b83f1527SRafal Ozieblo 3367f5473d1dSHarini Katakam *tsu_clk = devm_clk_get(&pdev->dev, "tsu_clk"); 3368f5473d1dSHarini Katakam if (IS_ERR(*tsu_clk)) 3369f5473d1dSHarini Katakam *tsu_clk = NULL; 3370f5473d1dSHarini Katakam 3371b83f1527SRafal Ozieblo err = clk_prepare_enable(*pclk); 3372b83f1527SRafal Ozieblo if (err) { 3373b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); 3374b83f1527SRafal Ozieblo return err; 3375b83f1527SRafal Ozieblo } 3376b83f1527SRafal Ozieblo 3377b83f1527SRafal Ozieblo err = clk_prepare_enable(*hclk); 3378b83f1527SRafal Ozieblo if (err) { 3379b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err); 3380b83f1527SRafal Ozieblo goto err_disable_pclk; 3381b83f1527SRafal Ozieblo } 3382b83f1527SRafal Ozieblo 3383b83f1527SRafal Ozieblo err = clk_prepare_enable(*tx_clk); 3384b83f1527SRafal Ozieblo if (err) { 3385b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err); 3386b83f1527SRafal Ozieblo goto err_disable_hclk; 3387b83f1527SRafal Ozieblo } 3388b83f1527SRafal Ozieblo 3389b83f1527SRafal Ozieblo err = clk_prepare_enable(*rx_clk); 3390b83f1527SRafal Ozieblo if (err) { 3391b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to enable rx_clk (%u)\n", err); 3392b83f1527SRafal Ozieblo goto err_disable_txclk; 3393b83f1527SRafal Ozieblo } 3394b83f1527SRafal Ozieblo 3395f5473d1dSHarini Katakam err = clk_prepare_enable(*tsu_clk); 3396f5473d1dSHarini Katakam if (err) { 3397f5473d1dSHarini Katakam dev_err(&pdev->dev, "failed to enable tsu_clk (%u)\n", err); 3398f5473d1dSHarini Katakam goto err_disable_rxclk; 3399f5473d1dSHarini Katakam } 3400f5473d1dSHarini Katakam 3401b83f1527SRafal Ozieblo return 0; 3402b83f1527SRafal Ozieblo 3403f5473d1dSHarini Katakam err_disable_rxclk: 3404f5473d1dSHarini Katakam clk_disable_unprepare(*rx_clk); 3405f5473d1dSHarini Katakam 3406b83f1527SRafal Ozieblo err_disable_txclk: 3407b83f1527SRafal Ozieblo clk_disable_unprepare(*tx_clk); 3408b83f1527SRafal Ozieblo 3409b83f1527SRafal Ozieblo err_disable_hclk: 3410b83f1527SRafal Ozieblo clk_disable_unprepare(*hclk); 3411b83f1527SRafal Ozieblo 3412b83f1527SRafal Ozieblo err_disable_pclk: 3413b83f1527SRafal Ozieblo clk_disable_unprepare(*pclk); 3414b83f1527SRafal Ozieblo 3415b83f1527SRafal Ozieblo return err; 3416b83f1527SRafal Ozieblo } 3417b83f1527SRafal Ozieblo 3418b83f1527SRafal Ozieblo static int macb_init(struct platform_device *pdev) 3419b83f1527SRafal Ozieblo { 3420b83f1527SRafal Ozieblo struct net_device *dev = platform_get_drvdata(pdev); 3421b83f1527SRafal Ozieblo unsigned int hw_q, q; 3422b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 3423b83f1527SRafal Ozieblo struct macb_queue *queue; 3424b83f1527SRafal Ozieblo int err; 3425ae8223deSRafal Ozieblo u32 val, reg; 3426b83f1527SRafal Ozieblo 3427b83f1527SRafal Ozieblo bp->tx_ring_size = DEFAULT_TX_RING_SIZE; 3428b83f1527SRafal Ozieblo bp->rx_ring_size = DEFAULT_RX_RING_SIZE; 3429b83f1527SRafal Ozieblo 3430b83f1527SRafal Ozieblo /* set the queue register mapping once for all: queue0 has a special 3431b83f1527SRafal Ozieblo * register mapping but we don't want to test the queue index then 3432b83f1527SRafal Ozieblo * compute the corresponding register offset at run time. 3433b83f1527SRafal Ozieblo */ 3434b83f1527SRafal Ozieblo for (hw_q = 0, q = 0; hw_q < MACB_MAX_QUEUES; ++hw_q) { 3435b83f1527SRafal Ozieblo if (!(bp->queue_mask & (1 << hw_q))) 3436b83f1527SRafal Ozieblo continue; 3437b83f1527SRafal Ozieblo 3438b83f1527SRafal Ozieblo queue = &bp->queues[q]; 3439b83f1527SRafal Ozieblo queue->bp = bp; 3440ae1f2a56SRafal Ozieblo netif_napi_add(dev, &queue->napi, macb_poll, 64); 3441b83f1527SRafal Ozieblo if (hw_q) { 3442b83f1527SRafal Ozieblo queue->ISR = GEM_ISR(hw_q - 1); 3443b83f1527SRafal Ozieblo queue->IER = GEM_IER(hw_q - 1); 3444b83f1527SRafal Ozieblo queue->IDR = GEM_IDR(hw_q - 1); 3445b83f1527SRafal Ozieblo queue->IMR = GEM_IMR(hw_q - 1); 3446b83f1527SRafal Ozieblo queue->TBQP = GEM_TBQP(hw_q - 1); 3447ae1f2a56SRafal Ozieblo queue->RBQP = GEM_RBQP(hw_q - 1); 3448ae1f2a56SRafal Ozieblo queue->RBQS = GEM_RBQS(hw_q - 1); 3449b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 3450ae1f2a56SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) { 3451b83f1527SRafal Ozieblo queue->TBQPH = GEM_TBQPH(hw_q - 1); 3452ae1f2a56SRafal Ozieblo queue->RBQPH = GEM_RBQPH(hw_q - 1); 3453ae1f2a56SRafal Ozieblo } 3454b83f1527SRafal Ozieblo #endif 3455b83f1527SRafal Ozieblo } else { 3456b83f1527SRafal Ozieblo /* queue0 uses legacy registers */ 3457b83f1527SRafal Ozieblo queue->ISR = MACB_ISR; 3458b83f1527SRafal Ozieblo queue->IER = MACB_IER; 3459b83f1527SRafal Ozieblo queue->IDR = MACB_IDR; 3460b83f1527SRafal Ozieblo queue->IMR = MACB_IMR; 3461b83f1527SRafal Ozieblo queue->TBQP = MACB_TBQP; 3462ae1f2a56SRafal Ozieblo queue->RBQP = MACB_RBQP; 3463b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 3464ae1f2a56SRafal Ozieblo if (bp->hw_dma_cap & HW_DMA_CAP_64B) { 3465b83f1527SRafal Ozieblo queue->TBQPH = MACB_TBQPH; 3466ae1f2a56SRafal Ozieblo queue->RBQPH = MACB_RBQPH; 3467ae1f2a56SRafal Ozieblo } 3468b83f1527SRafal Ozieblo #endif 3469b83f1527SRafal Ozieblo } 3470b83f1527SRafal Ozieblo 3471b83f1527SRafal Ozieblo /* get irq: here we use the linux queue index, not the hardware 3472b83f1527SRafal Ozieblo * queue index. the queue irq definitions in the device tree 3473b83f1527SRafal Ozieblo * must remove the optional gaps that could exist in the 3474b83f1527SRafal Ozieblo * hardware queue mask. 3475b83f1527SRafal Ozieblo */ 3476b83f1527SRafal Ozieblo queue->irq = platform_get_irq(pdev, q); 3477b83f1527SRafal Ozieblo err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt, 3478b83f1527SRafal Ozieblo IRQF_SHARED, dev->name, queue); 3479b83f1527SRafal Ozieblo if (err) { 3480b83f1527SRafal Ozieblo dev_err(&pdev->dev, 3481b83f1527SRafal Ozieblo "Unable to request IRQ %d (error %d)\n", 3482b83f1527SRafal Ozieblo queue->irq, err); 3483b83f1527SRafal Ozieblo return err; 3484b83f1527SRafal Ozieblo } 3485b83f1527SRafal Ozieblo 3486b83f1527SRafal Ozieblo INIT_WORK(&queue->tx_error_task, macb_tx_error_task); 3487b83f1527SRafal Ozieblo q++; 3488b83f1527SRafal Ozieblo } 3489b83f1527SRafal Ozieblo 3490b83f1527SRafal Ozieblo dev->netdev_ops = &macb_netdev_ops; 3491b83f1527SRafal Ozieblo 3492b83f1527SRafal Ozieblo /* setup appropriated routines according to adapter type */ 3493b83f1527SRafal Ozieblo if (macb_is_gem(bp)) { 3494b83f1527SRafal Ozieblo bp->max_tx_length = GEM_MAX_TX_LEN; 3495b83f1527SRafal Ozieblo bp->macbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers; 3496b83f1527SRafal Ozieblo bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers; 3497b83f1527SRafal Ozieblo bp->macbgem_ops.mog_init_rings = gem_init_rings; 3498b83f1527SRafal Ozieblo bp->macbgem_ops.mog_rx = gem_rx; 3499b83f1527SRafal Ozieblo dev->ethtool_ops = &gem_ethtool_ops; 3500b83f1527SRafal Ozieblo } else { 3501b83f1527SRafal Ozieblo bp->max_tx_length = MACB_MAX_TX_LEN; 3502b83f1527SRafal Ozieblo bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers; 3503b83f1527SRafal Ozieblo bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers; 3504b83f1527SRafal Ozieblo bp->macbgem_ops.mog_init_rings = macb_init_rings; 3505b83f1527SRafal Ozieblo bp->macbgem_ops.mog_rx = macb_rx; 3506b83f1527SRafal Ozieblo dev->ethtool_ops = &macb_ethtool_ops; 3507b83f1527SRafal Ozieblo } 3508b83f1527SRafal Ozieblo 3509b83f1527SRafal Ozieblo /* Set features */ 3510b83f1527SRafal Ozieblo dev->hw_features = NETIF_F_SG; 3511b83f1527SRafal Ozieblo 3512b83f1527SRafal Ozieblo /* Check LSO capability */ 3513b83f1527SRafal Ozieblo if (GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6))) 3514b83f1527SRafal Ozieblo dev->hw_features |= MACB_NETIF_LSO; 3515b83f1527SRafal Ozieblo 3516b83f1527SRafal Ozieblo /* Checksum offload is only available on gem with packet buffer */ 3517b83f1527SRafal Ozieblo if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE)) 3518b83f1527SRafal Ozieblo dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; 3519b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_SG_DISABLED) 3520b83f1527SRafal Ozieblo dev->hw_features &= ~NETIF_F_SG; 3521b83f1527SRafal Ozieblo dev->features = dev->hw_features; 3522b83f1527SRafal Ozieblo 3523ae8223deSRafal Ozieblo /* Check RX Flow Filters support. 3524ae8223deSRafal Ozieblo * Max Rx flows set by availability of screeners & compare regs: 3525ae8223deSRafal Ozieblo * each 4-tuple define requires 1 T2 screener reg + 3 compare regs 3526ae8223deSRafal Ozieblo */ 3527ae8223deSRafal Ozieblo reg = gem_readl(bp, DCFG8); 3528ae8223deSRafal Ozieblo bp->max_tuples = min((GEM_BFEXT(SCR2CMP, reg) / 3), 3529ae8223deSRafal Ozieblo GEM_BFEXT(T2SCR, reg)); 3530ae8223deSRafal Ozieblo if (bp->max_tuples > 0) { 3531ae8223deSRafal Ozieblo /* also needs one ethtype match to check IPv4 */ 3532ae8223deSRafal Ozieblo if (GEM_BFEXT(SCR2ETH, reg) > 0) { 3533ae8223deSRafal Ozieblo /* program this reg now */ 3534ae8223deSRafal Ozieblo reg = 0; 3535ae8223deSRafal Ozieblo reg = GEM_BFINS(ETHTCMP, (uint16_t)ETH_P_IP, reg); 3536ae8223deSRafal Ozieblo gem_writel_n(bp, ETHT, SCRT2_ETHT, reg); 3537ae8223deSRafal Ozieblo /* Filtering is supported in hw but don't enable it in kernel now */ 3538ae8223deSRafal Ozieblo dev->hw_features |= NETIF_F_NTUPLE; 3539ae8223deSRafal Ozieblo /* init Rx flow definitions */ 3540ae8223deSRafal Ozieblo INIT_LIST_HEAD(&bp->rx_fs_list.list); 3541ae8223deSRafal Ozieblo bp->rx_fs_list.count = 0; 3542ae8223deSRafal Ozieblo spin_lock_init(&bp->rx_fs_lock); 3543ae8223deSRafal Ozieblo } else 3544ae8223deSRafal Ozieblo bp->max_tuples = 0; 3545ae8223deSRafal Ozieblo } 3546ae8223deSRafal Ozieblo 3547b83f1527SRafal Ozieblo if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) { 3548b83f1527SRafal Ozieblo val = 0; 3549b83f1527SRafal Ozieblo if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII) 3550b83f1527SRafal Ozieblo val = GEM_BIT(RGMII); 3551b83f1527SRafal Ozieblo else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && 3552b83f1527SRafal Ozieblo (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII)) 3553b83f1527SRafal Ozieblo val = MACB_BIT(RMII); 3554b83f1527SRafal Ozieblo else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII)) 3555b83f1527SRafal Ozieblo val = MACB_BIT(MII); 3556b83f1527SRafal Ozieblo 3557b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN) 3558b83f1527SRafal Ozieblo val |= MACB_BIT(CLKEN); 3559b83f1527SRafal Ozieblo 3560b83f1527SRafal Ozieblo macb_or_gem_writel(bp, USRIO, val); 3561b83f1527SRafal Ozieblo } 3562b83f1527SRafal Ozieblo 3563b83f1527SRafal Ozieblo /* Set MII management clock divider */ 3564b83f1527SRafal Ozieblo val = macb_mdc_clk_div(bp); 3565b83f1527SRafal Ozieblo val |= macb_dbw(bp); 3566b83f1527SRafal Ozieblo if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) 3567b83f1527SRafal Ozieblo val |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL); 3568b83f1527SRafal Ozieblo macb_writel(bp, NCFGR, val); 3569b83f1527SRafal Ozieblo 3570b83f1527SRafal Ozieblo return 0; 3571b83f1527SRafal Ozieblo } 3572b83f1527SRafal Ozieblo 3573b83f1527SRafal Ozieblo #if defined(CONFIG_OF) 3574b83f1527SRafal Ozieblo /* 1518 rounded up */ 3575b83f1527SRafal Ozieblo #define AT91ETHER_MAX_RBUFF_SZ 0x600 3576b83f1527SRafal Ozieblo /* max number of receive buffers */ 3577b83f1527SRafal Ozieblo #define AT91ETHER_MAX_RX_DESCR 9 3578b83f1527SRafal Ozieblo 3579b83f1527SRafal Ozieblo /* Initialize and start the Receiver and Transmit subsystems */ 3580b83f1527SRafal Ozieblo static int at91ether_start(struct net_device *dev) 3581b83f1527SRafal Ozieblo { 3582b83f1527SRafal Ozieblo struct macb *lp = netdev_priv(dev); 3583ae1f2a56SRafal Ozieblo struct macb_queue *q = &lp->queues[0]; 3584b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 3585b83f1527SRafal Ozieblo dma_addr_t addr; 3586b83f1527SRafal Ozieblo u32 ctl; 3587b83f1527SRafal Ozieblo int i; 3588b83f1527SRafal Ozieblo 3589ae1f2a56SRafal Ozieblo q->rx_ring = dma_alloc_coherent(&lp->pdev->dev, 3590b83f1527SRafal Ozieblo (AT91ETHER_MAX_RX_DESCR * 3591b83f1527SRafal Ozieblo macb_dma_desc_get_size(lp)), 3592ae1f2a56SRafal Ozieblo &q->rx_ring_dma, GFP_KERNEL); 3593ae1f2a56SRafal Ozieblo if (!q->rx_ring) 3594b83f1527SRafal Ozieblo return -ENOMEM; 3595b83f1527SRafal Ozieblo 3596ae1f2a56SRafal Ozieblo q->rx_buffers = dma_alloc_coherent(&lp->pdev->dev, 3597b83f1527SRafal Ozieblo AT91ETHER_MAX_RX_DESCR * 3598b83f1527SRafal Ozieblo AT91ETHER_MAX_RBUFF_SZ, 3599ae1f2a56SRafal Ozieblo &q->rx_buffers_dma, GFP_KERNEL); 3600ae1f2a56SRafal Ozieblo if (!q->rx_buffers) { 3601b83f1527SRafal Ozieblo dma_free_coherent(&lp->pdev->dev, 3602b83f1527SRafal Ozieblo AT91ETHER_MAX_RX_DESCR * 3603b83f1527SRafal Ozieblo macb_dma_desc_get_size(lp), 3604ae1f2a56SRafal Ozieblo q->rx_ring, q->rx_ring_dma); 3605ae1f2a56SRafal Ozieblo q->rx_ring = NULL; 3606b83f1527SRafal Ozieblo return -ENOMEM; 3607b83f1527SRafal Ozieblo } 3608b83f1527SRafal Ozieblo 3609ae1f2a56SRafal Ozieblo addr = q->rx_buffers_dma; 3610b83f1527SRafal Ozieblo for (i = 0; i < AT91ETHER_MAX_RX_DESCR; i++) { 3611ae1f2a56SRafal Ozieblo desc = macb_rx_desc(q, i); 3612b83f1527SRafal Ozieblo macb_set_addr(lp, desc, addr); 3613b83f1527SRafal Ozieblo desc->ctrl = 0; 3614b83f1527SRafal Ozieblo addr += AT91ETHER_MAX_RBUFF_SZ; 3615b83f1527SRafal Ozieblo } 3616b83f1527SRafal Ozieblo 3617b83f1527SRafal Ozieblo /* Set the Wrap bit on the last descriptor */ 3618b83f1527SRafal Ozieblo desc->addr |= MACB_BIT(RX_WRAP); 3619b83f1527SRafal Ozieblo 3620b83f1527SRafal Ozieblo /* Reset buffer index */ 3621ae1f2a56SRafal Ozieblo q->rx_tail = 0; 3622b83f1527SRafal Ozieblo 3623b83f1527SRafal Ozieblo /* Program address of descriptor list in Rx Buffer Queue register */ 3624ae1f2a56SRafal Ozieblo macb_writel(lp, RBQP, q->rx_ring_dma); 3625b83f1527SRafal Ozieblo 3626b83f1527SRafal Ozieblo /* Enable Receive and Transmit */ 3627b83f1527SRafal Ozieblo ctl = macb_readl(lp, NCR); 3628b83f1527SRafal Ozieblo macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE)); 3629b83f1527SRafal Ozieblo 3630b83f1527SRafal Ozieblo return 0; 3631b83f1527SRafal Ozieblo } 3632b83f1527SRafal Ozieblo 3633b83f1527SRafal Ozieblo /* Open the ethernet interface */ 3634b83f1527SRafal Ozieblo static int at91ether_open(struct net_device *dev) 3635b83f1527SRafal Ozieblo { 3636b83f1527SRafal Ozieblo struct macb *lp = netdev_priv(dev); 3637b83f1527SRafal Ozieblo u32 ctl; 3638b83f1527SRafal Ozieblo int ret; 3639b83f1527SRafal Ozieblo 3640b83f1527SRafal Ozieblo /* Clear internal statistics */ 3641b83f1527SRafal Ozieblo ctl = macb_readl(lp, NCR); 3642b83f1527SRafal Ozieblo macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); 3643b83f1527SRafal Ozieblo 3644b83f1527SRafal Ozieblo macb_set_hwaddr(lp); 3645b83f1527SRafal Ozieblo 3646b83f1527SRafal Ozieblo ret = at91ether_start(dev); 3647b83f1527SRafal Ozieblo if (ret) 3648b83f1527SRafal Ozieblo return ret; 3649b83f1527SRafal Ozieblo 3650b83f1527SRafal Ozieblo /* Enable MAC interrupts */ 3651b83f1527SRafal Ozieblo macb_writel(lp, IER, MACB_BIT(RCOMP) | 3652b83f1527SRafal Ozieblo MACB_BIT(RXUBR) | 3653b83f1527SRafal Ozieblo MACB_BIT(ISR_TUND) | 3654b83f1527SRafal Ozieblo MACB_BIT(ISR_RLE) | 3655b83f1527SRafal Ozieblo MACB_BIT(TCOMP) | 3656b83f1527SRafal Ozieblo MACB_BIT(ISR_ROVR) | 3657b83f1527SRafal Ozieblo MACB_BIT(HRESP)); 3658b83f1527SRafal Ozieblo 3659b83f1527SRafal Ozieblo /* schedule a link state check */ 3660b83f1527SRafal Ozieblo phy_start(dev->phydev); 3661b83f1527SRafal Ozieblo 3662b83f1527SRafal Ozieblo netif_start_queue(dev); 3663b83f1527SRafal Ozieblo 3664b83f1527SRafal Ozieblo return 0; 3665b83f1527SRafal Ozieblo } 3666b83f1527SRafal Ozieblo 3667b83f1527SRafal Ozieblo /* Close the interface */ 3668b83f1527SRafal Ozieblo static int at91ether_close(struct net_device *dev) 3669b83f1527SRafal Ozieblo { 3670b83f1527SRafal Ozieblo struct macb *lp = netdev_priv(dev); 3671ae1f2a56SRafal Ozieblo struct macb_queue *q = &lp->queues[0]; 3672b83f1527SRafal Ozieblo u32 ctl; 3673b83f1527SRafal Ozieblo 3674b83f1527SRafal Ozieblo /* Disable Receiver and Transmitter */ 3675b83f1527SRafal Ozieblo ctl = macb_readl(lp, NCR); 3676b83f1527SRafal Ozieblo macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); 3677b83f1527SRafal Ozieblo 3678b83f1527SRafal Ozieblo /* Disable MAC interrupts */ 3679b83f1527SRafal Ozieblo macb_writel(lp, IDR, MACB_BIT(RCOMP) | 3680b83f1527SRafal Ozieblo MACB_BIT(RXUBR) | 3681b83f1527SRafal Ozieblo MACB_BIT(ISR_TUND) | 3682b83f1527SRafal Ozieblo MACB_BIT(ISR_RLE) | 3683b83f1527SRafal Ozieblo MACB_BIT(TCOMP) | 3684b83f1527SRafal Ozieblo MACB_BIT(ISR_ROVR) | 3685b83f1527SRafal Ozieblo MACB_BIT(HRESP)); 3686b83f1527SRafal Ozieblo 3687b83f1527SRafal Ozieblo netif_stop_queue(dev); 3688b83f1527SRafal Ozieblo 3689b83f1527SRafal Ozieblo dma_free_coherent(&lp->pdev->dev, 3690b83f1527SRafal Ozieblo AT91ETHER_MAX_RX_DESCR * 3691b83f1527SRafal Ozieblo macb_dma_desc_get_size(lp), 3692ae1f2a56SRafal Ozieblo q->rx_ring, q->rx_ring_dma); 3693ae1f2a56SRafal Ozieblo q->rx_ring = NULL; 3694b83f1527SRafal Ozieblo 3695b83f1527SRafal Ozieblo dma_free_coherent(&lp->pdev->dev, 3696b83f1527SRafal Ozieblo AT91ETHER_MAX_RX_DESCR * AT91ETHER_MAX_RBUFF_SZ, 3697ae1f2a56SRafal Ozieblo q->rx_buffers, q->rx_buffers_dma); 3698ae1f2a56SRafal Ozieblo q->rx_buffers = NULL; 3699b83f1527SRafal Ozieblo 3700b83f1527SRafal Ozieblo return 0; 3701b83f1527SRafal Ozieblo } 3702b83f1527SRafal Ozieblo 3703b83f1527SRafal Ozieblo /* Transmit packet */ 3704d1c38957SClaudiu Beznea static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb, 3705d1c38957SClaudiu Beznea struct net_device *dev) 3706b83f1527SRafal Ozieblo { 3707b83f1527SRafal Ozieblo struct macb *lp = netdev_priv(dev); 3708b83f1527SRafal Ozieblo 3709b83f1527SRafal Ozieblo if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) { 3710b83f1527SRafal Ozieblo netif_stop_queue(dev); 3711b83f1527SRafal Ozieblo 3712b83f1527SRafal Ozieblo /* Store packet information (to free when Tx completed) */ 3713b83f1527SRafal Ozieblo lp->skb = skb; 3714b83f1527SRafal Ozieblo lp->skb_length = skb->len; 3715564923e4SChristoph Hellwig lp->skb_physaddr = dma_map_single(&lp->pdev->dev, skb->data, 3716564923e4SChristoph Hellwig skb->len, DMA_TO_DEVICE); 3717564923e4SChristoph Hellwig if (dma_mapping_error(&lp->pdev->dev, lp->skb_physaddr)) { 3718b83f1527SRafal Ozieblo dev_kfree_skb_any(skb); 3719b83f1527SRafal Ozieblo dev->stats.tx_dropped++; 3720b83f1527SRafal Ozieblo netdev_err(dev, "%s: DMA mapping error\n", __func__); 3721b83f1527SRafal Ozieblo return NETDEV_TX_OK; 3722b83f1527SRafal Ozieblo } 3723b83f1527SRafal Ozieblo 3724b83f1527SRafal Ozieblo /* Set address of the data in the Transmit Address register */ 3725b83f1527SRafal Ozieblo macb_writel(lp, TAR, lp->skb_physaddr); 3726b83f1527SRafal Ozieblo /* Set length of the packet in the Transmit Control register */ 3727b83f1527SRafal Ozieblo macb_writel(lp, TCR, skb->len); 3728b83f1527SRafal Ozieblo 3729b83f1527SRafal Ozieblo } else { 3730b83f1527SRafal Ozieblo netdev_err(dev, "%s called, but device is busy!\n", __func__); 3731b83f1527SRafal Ozieblo return NETDEV_TX_BUSY; 3732b83f1527SRafal Ozieblo } 3733b83f1527SRafal Ozieblo 3734b83f1527SRafal Ozieblo return NETDEV_TX_OK; 3735b83f1527SRafal Ozieblo } 3736b83f1527SRafal Ozieblo 3737b83f1527SRafal Ozieblo /* Extract received frame from buffer descriptors and sent to upper layers. 3738b83f1527SRafal Ozieblo * (Called from interrupt context) 3739b83f1527SRafal Ozieblo */ 3740b83f1527SRafal Ozieblo static void at91ether_rx(struct net_device *dev) 3741b83f1527SRafal Ozieblo { 3742b83f1527SRafal Ozieblo struct macb *lp = netdev_priv(dev); 3743ae1f2a56SRafal Ozieblo struct macb_queue *q = &lp->queues[0]; 3744b83f1527SRafal Ozieblo struct macb_dma_desc *desc; 3745b83f1527SRafal Ozieblo unsigned char *p_recv; 3746b83f1527SRafal Ozieblo struct sk_buff *skb; 3747b83f1527SRafal Ozieblo unsigned int pktlen; 3748b83f1527SRafal Ozieblo 3749ae1f2a56SRafal Ozieblo desc = macb_rx_desc(q, q->rx_tail); 3750b83f1527SRafal Ozieblo while (desc->addr & MACB_BIT(RX_USED)) { 3751ae1f2a56SRafal Ozieblo p_recv = q->rx_buffers + q->rx_tail * AT91ETHER_MAX_RBUFF_SZ; 3752b83f1527SRafal Ozieblo pktlen = MACB_BF(RX_FRMLEN, desc->ctrl); 3753b83f1527SRafal Ozieblo skb = netdev_alloc_skb(dev, pktlen + 2); 3754b83f1527SRafal Ozieblo if (skb) { 3755b83f1527SRafal Ozieblo skb_reserve(skb, 2); 3756b83f1527SRafal Ozieblo skb_put_data(skb, p_recv, pktlen); 3757b83f1527SRafal Ozieblo 3758b83f1527SRafal Ozieblo skb->protocol = eth_type_trans(skb, dev); 3759b83f1527SRafal Ozieblo dev->stats.rx_packets++; 3760b83f1527SRafal Ozieblo dev->stats.rx_bytes += pktlen; 3761b83f1527SRafal Ozieblo netif_rx(skb); 3762b83f1527SRafal Ozieblo } else { 3763b83f1527SRafal Ozieblo dev->stats.rx_dropped++; 3764b83f1527SRafal Ozieblo } 3765b83f1527SRafal Ozieblo 3766b83f1527SRafal Ozieblo if (desc->ctrl & MACB_BIT(RX_MHASH_MATCH)) 3767b83f1527SRafal Ozieblo dev->stats.multicast++; 3768b83f1527SRafal Ozieblo 3769b83f1527SRafal Ozieblo /* reset ownership bit */ 3770b83f1527SRafal Ozieblo desc->addr &= ~MACB_BIT(RX_USED); 3771b83f1527SRafal Ozieblo 3772b83f1527SRafal Ozieblo /* wrap after last buffer */ 3773ae1f2a56SRafal Ozieblo if (q->rx_tail == AT91ETHER_MAX_RX_DESCR - 1) 3774ae1f2a56SRafal Ozieblo q->rx_tail = 0; 3775b83f1527SRafal Ozieblo else 3776ae1f2a56SRafal Ozieblo q->rx_tail++; 3777b83f1527SRafal Ozieblo 3778ae1f2a56SRafal Ozieblo desc = macb_rx_desc(q, q->rx_tail); 3779b83f1527SRafal Ozieblo } 3780b83f1527SRafal Ozieblo } 3781b83f1527SRafal Ozieblo 3782b83f1527SRafal Ozieblo /* MAC interrupt handler */ 3783b83f1527SRafal Ozieblo static irqreturn_t at91ether_interrupt(int irq, void *dev_id) 3784b83f1527SRafal Ozieblo { 3785b83f1527SRafal Ozieblo struct net_device *dev = dev_id; 3786b83f1527SRafal Ozieblo struct macb *lp = netdev_priv(dev); 3787b83f1527SRafal Ozieblo u32 intstatus, ctl; 3788b83f1527SRafal Ozieblo 3789b83f1527SRafal Ozieblo /* MAC Interrupt Status register indicates what interrupts are pending. 3790b83f1527SRafal Ozieblo * It is automatically cleared once read. 3791b83f1527SRafal Ozieblo */ 3792b83f1527SRafal Ozieblo intstatus = macb_readl(lp, ISR); 3793b83f1527SRafal Ozieblo 3794b83f1527SRafal Ozieblo /* Receive complete */ 3795b83f1527SRafal Ozieblo if (intstatus & MACB_BIT(RCOMP)) 3796b83f1527SRafal Ozieblo at91ether_rx(dev); 3797b83f1527SRafal Ozieblo 3798b83f1527SRafal Ozieblo /* Transmit complete */ 3799b83f1527SRafal Ozieblo if (intstatus & MACB_BIT(TCOMP)) { 3800b83f1527SRafal Ozieblo /* The TCOM bit is set even if the transmission failed */ 3801b83f1527SRafal Ozieblo if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE))) 3802b83f1527SRafal Ozieblo dev->stats.tx_errors++; 3803b83f1527SRafal Ozieblo 3804b83f1527SRafal Ozieblo if (lp->skb) { 3805b9560a22SYang Wei dev_consume_skb_irq(lp->skb); 3806b83f1527SRafal Ozieblo lp->skb = NULL; 3807564923e4SChristoph Hellwig dma_unmap_single(&lp->pdev->dev, lp->skb_physaddr, 3808b83f1527SRafal Ozieblo lp->skb_length, DMA_TO_DEVICE); 3809b83f1527SRafal Ozieblo dev->stats.tx_packets++; 3810b83f1527SRafal Ozieblo dev->stats.tx_bytes += lp->skb_length; 3811b83f1527SRafal Ozieblo } 3812b83f1527SRafal Ozieblo netif_wake_queue(dev); 3813b83f1527SRafal Ozieblo } 3814b83f1527SRafal Ozieblo 3815b83f1527SRafal Ozieblo /* Work-around for EMAC Errata section 41.3.1 */ 3816b83f1527SRafal Ozieblo if (intstatus & MACB_BIT(RXUBR)) { 3817b83f1527SRafal Ozieblo ctl = macb_readl(lp, NCR); 3818b83f1527SRafal Ozieblo macb_writel(lp, NCR, ctl & ~MACB_BIT(RE)); 3819b83f1527SRafal Ozieblo wmb(); 3820b83f1527SRafal Ozieblo macb_writel(lp, NCR, ctl | MACB_BIT(RE)); 3821b83f1527SRafal Ozieblo } 3822b83f1527SRafal Ozieblo 3823b83f1527SRafal Ozieblo if (intstatus & MACB_BIT(ISR_ROVR)) 3824b83f1527SRafal Ozieblo netdev_err(dev, "ROVR error\n"); 3825b83f1527SRafal Ozieblo 3826b83f1527SRafal Ozieblo return IRQ_HANDLED; 3827b83f1527SRafal Ozieblo } 3828b83f1527SRafal Ozieblo 3829b83f1527SRafal Ozieblo #ifdef CONFIG_NET_POLL_CONTROLLER 3830b83f1527SRafal Ozieblo static void at91ether_poll_controller(struct net_device *dev) 3831b83f1527SRafal Ozieblo { 3832b83f1527SRafal Ozieblo unsigned long flags; 3833b83f1527SRafal Ozieblo 3834b83f1527SRafal Ozieblo local_irq_save(flags); 3835b83f1527SRafal Ozieblo at91ether_interrupt(dev->irq, dev); 3836b83f1527SRafal Ozieblo local_irq_restore(flags); 3837b83f1527SRafal Ozieblo } 3838b83f1527SRafal Ozieblo #endif 3839b83f1527SRafal Ozieblo 3840b83f1527SRafal Ozieblo static const struct net_device_ops at91ether_netdev_ops = { 3841b83f1527SRafal Ozieblo .ndo_open = at91ether_open, 3842b83f1527SRafal Ozieblo .ndo_stop = at91ether_close, 3843b83f1527SRafal Ozieblo .ndo_start_xmit = at91ether_start_xmit, 3844b83f1527SRafal Ozieblo .ndo_get_stats = macb_get_stats, 3845b83f1527SRafal Ozieblo .ndo_set_rx_mode = macb_set_rx_mode, 3846b83f1527SRafal Ozieblo .ndo_set_mac_address = eth_mac_addr, 3847b83f1527SRafal Ozieblo .ndo_do_ioctl = macb_ioctl, 3848b83f1527SRafal Ozieblo .ndo_validate_addr = eth_validate_addr, 3849b83f1527SRafal Ozieblo #ifdef CONFIG_NET_POLL_CONTROLLER 3850b83f1527SRafal Ozieblo .ndo_poll_controller = at91ether_poll_controller, 3851b83f1527SRafal Ozieblo #endif 3852b83f1527SRafal Ozieblo }; 3853b83f1527SRafal Ozieblo 3854b83f1527SRafal Ozieblo static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk, 3855b83f1527SRafal Ozieblo struct clk **hclk, struct clk **tx_clk, 3856f5473d1dSHarini Katakam struct clk **rx_clk, struct clk **tsu_clk) 3857b83f1527SRafal Ozieblo { 3858b83f1527SRafal Ozieblo int err; 3859b83f1527SRafal Ozieblo 3860b83f1527SRafal Ozieblo *hclk = NULL; 3861b83f1527SRafal Ozieblo *tx_clk = NULL; 3862b83f1527SRafal Ozieblo *rx_clk = NULL; 3863f5473d1dSHarini Katakam *tsu_clk = NULL; 3864b83f1527SRafal Ozieblo 3865b83f1527SRafal Ozieblo *pclk = devm_clk_get(&pdev->dev, "ether_clk"); 3866b83f1527SRafal Ozieblo if (IS_ERR(*pclk)) 3867b83f1527SRafal Ozieblo return PTR_ERR(*pclk); 3868b83f1527SRafal Ozieblo 3869b83f1527SRafal Ozieblo err = clk_prepare_enable(*pclk); 3870b83f1527SRafal Ozieblo if (err) { 3871b83f1527SRafal Ozieblo dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); 3872b83f1527SRafal Ozieblo return err; 3873b83f1527SRafal Ozieblo } 3874b83f1527SRafal Ozieblo 3875b83f1527SRafal Ozieblo return 0; 3876b83f1527SRafal Ozieblo } 3877b83f1527SRafal Ozieblo 3878b83f1527SRafal Ozieblo static int at91ether_init(struct platform_device *pdev) 3879b83f1527SRafal Ozieblo { 3880b83f1527SRafal Ozieblo struct net_device *dev = platform_get_drvdata(pdev); 3881b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(dev); 3882b83f1527SRafal Ozieblo int err; 3883b83f1527SRafal Ozieblo u32 reg; 3884b83f1527SRafal Ozieblo 3885fec9d3b1SAlexandre Belloni bp->queues[0].bp = bp; 3886fec9d3b1SAlexandre Belloni 3887b83f1527SRafal Ozieblo dev->netdev_ops = &at91ether_netdev_ops; 3888b83f1527SRafal Ozieblo dev->ethtool_ops = &macb_ethtool_ops; 3889b83f1527SRafal Ozieblo 3890b83f1527SRafal Ozieblo err = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, 3891b83f1527SRafal Ozieblo 0, dev->name, dev); 3892b83f1527SRafal Ozieblo if (err) 3893b83f1527SRafal Ozieblo return err; 3894b83f1527SRafal Ozieblo 3895b83f1527SRafal Ozieblo macb_writel(bp, NCR, 0); 3896b83f1527SRafal Ozieblo 3897b83f1527SRafal Ozieblo reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); 3898b83f1527SRafal Ozieblo if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) 3899b83f1527SRafal Ozieblo reg |= MACB_BIT(RM9200_RMII); 3900b83f1527SRafal Ozieblo 3901b83f1527SRafal Ozieblo macb_writel(bp, NCFGR, reg); 3902b83f1527SRafal Ozieblo 3903b83f1527SRafal Ozieblo return 0; 3904b83f1527SRafal Ozieblo } 3905b83f1527SRafal Ozieblo 3906b83f1527SRafal Ozieblo static const struct macb_config at91sam9260_config = { 3907b83f1527SRafal Ozieblo .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, 3908b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3909b83f1527SRafal Ozieblo .init = macb_init, 3910b83f1527SRafal Ozieblo }; 3911b83f1527SRafal Ozieblo 3912eb4ed8e2SNicolas Ferre static const struct macb_config sama5d3macb_config = { 3913eb4ed8e2SNicolas Ferre .caps = MACB_CAPS_SG_DISABLED 3914eb4ed8e2SNicolas Ferre | MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, 3915eb4ed8e2SNicolas Ferre .clk_init = macb_clk_init, 3916eb4ed8e2SNicolas Ferre .init = macb_init, 3917eb4ed8e2SNicolas Ferre }; 3918eb4ed8e2SNicolas Ferre 3919b83f1527SRafal Ozieblo static const struct macb_config pc302gem_config = { 3920b83f1527SRafal Ozieblo .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE, 3921b83f1527SRafal Ozieblo .dma_burst_length = 16, 3922b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3923b83f1527SRafal Ozieblo .init = macb_init, 3924b83f1527SRafal Ozieblo }; 3925b83f1527SRafal Ozieblo 3926b83f1527SRafal Ozieblo static const struct macb_config sama5d2_config = { 3927b83f1527SRafal Ozieblo .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, 3928b83f1527SRafal Ozieblo .dma_burst_length = 16, 3929b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3930b83f1527SRafal Ozieblo .init = macb_init, 3931b83f1527SRafal Ozieblo }; 3932b83f1527SRafal Ozieblo 3933b83f1527SRafal Ozieblo static const struct macb_config sama5d3_config = { 3934b83f1527SRafal Ozieblo .caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE 3935233a1587Svishnuvardhan | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_JUMBO, 3936b83f1527SRafal Ozieblo .dma_burst_length = 16, 3937b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3938b83f1527SRafal Ozieblo .init = macb_init, 3939233a1587Svishnuvardhan .jumbo_max_len = 10240, 3940b83f1527SRafal Ozieblo }; 3941b83f1527SRafal Ozieblo 3942b83f1527SRafal Ozieblo static const struct macb_config sama5d4_config = { 3943b83f1527SRafal Ozieblo .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, 3944b83f1527SRafal Ozieblo .dma_burst_length = 4, 3945b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3946b83f1527SRafal Ozieblo .init = macb_init, 3947b83f1527SRafal Ozieblo }; 3948b83f1527SRafal Ozieblo 3949b83f1527SRafal Ozieblo static const struct macb_config emac_config = { 3950e501070eSHarini Katakam .caps = MACB_CAPS_NEEDS_RSTONUBR, 3951b83f1527SRafal Ozieblo .clk_init = at91ether_clk_init, 3952b83f1527SRafal Ozieblo .init = at91ether_init, 3953b83f1527SRafal Ozieblo }; 3954b83f1527SRafal Ozieblo 3955b83f1527SRafal Ozieblo static const struct macb_config np4_config = { 3956b83f1527SRafal Ozieblo .caps = MACB_CAPS_USRIO_DISABLED, 3957b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3958b83f1527SRafal Ozieblo .init = macb_init, 3959b83f1527SRafal Ozieblo }; 3960b83f1527SRafal Ozieblo 3961b83f1527SRafal Ozieblo static const struct macb_config zynqmp_config = { 3962ab91f0a9SRafal Ozieblo .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | 3963ab91f0a9SRafal Ozieblo MACB_CAPS_JUMBO | 3964404cd086SHarini Katakam MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH, 3965b83f1527SRafal Ozieblo .dma_burst_length = 16, 3966b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3967b83f1527SRafal Ozieblo .init = macb_init, 3968b83f1527SRafal Ozieblo .jumbo_max_len = 10240, 3969b83f1527SRafal Ozieblo }; 3970b83f1527SRafal Ozieblo 3971b83f1527SRafal Ozieblo static const struct macb_config zynq_config = { 3972e501070eSHarini Katakam .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_NO_GIGABIT_HALF | 3973e501070eSHarini Katakam MACB_CAPS_NEEDS_RSTONUBR, 3974b83f1527SRafal Ozieblo .dma_burst_length = 16, 3975b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 3976b83f1527SRafal Ozieblo .init = macb_init, 3977b83f1527SRafal Ozieblo }; 3978b83f1527SRafal Ozieblo 3979b83f1527SRafal Ozieblo static const struct of_device_id macb_dt_ids[] = { 3980b83f1527SRafal Ozieblo { .compatible = "cdns,at32ap7000-macb" }, 3981b83f1527SRafal Ozieblo { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, 3982b83f1527SRafal Ozieblo { .compatible = "cdns,macb" }, 3983b83f1527SRafal Ozieblo { .compatible = "cdns,np4-macb", .data = &np4_config }, 3984b83f1527SRafal Ozieblo { .compatible = "cdns,pc302-gem", .data = &pc302gem_config }, 3985b83f1527SRafal Ozieblo { .compatible = "cdns,gem", .data = &pc302gem_config }, 39863e3e0cdfSNicolas Ferre { .compatible = "cdns,sam9x60-macb", .data = &at91sam9260_config }, 3987b83f1527SRafal Ozieblo { .compatible = "atmel,sama5d2-gem", .data = &sama5d2_config }, 3988b83f1527SRafal Ozieblo { .compatible = "atmel,sama5d3-gem", .data = &sama5d3_config }, 3989eb4ed8e2SNicolas Ferre { .compatible = "atmel,sama5d3-macb", .data = &sama5d3macb_config }, 3990b83f1527SRafal Ozieblo { .compatible = "atmel,sama5d4-gem", .data = &sama5d4_config }, 3991b83f1527SRafal Ozieblo { .compatible = "cdns,at91rm9200-emac", .data = &emac_config }, 3992b83f1527SRafal Ozieblo { .compatible = "cdns,emac", .data = &emac_config }, 3993b83f1527SRafal Ozieblo { .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config}, 3994b83f1527SRafal Ozieblo { .compatible = "cdns,zynq-gem", .data = &zynq_config }, 3995b83f1527SRafal Ozieblo { /* sentinel */ } 3996b83f1527SRafal Ozieblo }; 3997b83f1527SRafal Ozieblo MODULE_DEVICE_TABLE(of, macb_dt_ids); 3998b83f1527SRafal Ozieblo #endif /* CONFIG_OF */ 3999b83f1527SRafal Ozieblo 4000b83f1527SRafal Ozieblo static const struct macb_config default_gem_config = { 4001ab91f0a9SRafal Ozieblo .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | 4002ab91f0a9SRafal Ozieblo MACB_CAPS_JUMBO | 4003ab91f0a9SRafal Ozieblo MACB_CAPS_GEM_HAS_PTP, 4004b83f1527SRafal Ozieblo .dma_burst_length = 16, 4005b83f1527SRafal Ozieblo .clk_init = macb_clk_init, 4006b83f1527SRafal Ozieblo .init = macb_init, 4007b83f1527SRafal Ozieblo .jumbo_max_len = 10240, 4008b83f1527SRafal Ozieblo }; 4009b83f1527SRafal Ozieblo 4010b83f1527SRafal Ozieblo static int macb_probe(struct platform_device *pdev) 4011b83f1527SRafal Ozieblo { 4012b83f1527SRafal Ozieblo const struct macb_config *macb_config = &default_gem_config; 4013b83f1527SRafal Ozieblo int (*clk_init)(struct platform_device *, struct clk **, 4014f5473d1dSHarini Katakam struct clk **, struct clk **, struct clk **, 4015f5473d1dSHarini Katakam struct clk **) = macb_config->clk_init; 4016b83f1527SRafal Ozieblo int (*init)(struct platform_device *) = macb_config->init; 4017b83f1527SRafal Ozieblo struct device_node *np = pdev->dev.of_node; 4018b83f1527SRafal Ozieblo struct clk *pclk, *hclk = NULL, *tx_clk = NULL, *rx_clk = NULL; 4019f5473d1dSHarini Katakam struct clk *tsu_clk = NULL; 4020b83f1527SRafal Ozieblo unsigned int queue_mask, num_queues; 4021b83f1527SRafal Ozieblo bool native_io; 4022b83f1527SRafal Ozieblo struct phy_device *phydev; 4023b83f1527SRafal Ozieblo struct net_device *dev; 4024b83f1527SRafal Ozieblo struct resource *regs; 4025b83f1527SRafal Ozieblo void __iomem *mem; 4026b83f1527SRafal Ozieblo const char *mac; 4027b83f1527SRafal Ozieblo struct macb *bp; 4028404cd086SHarini Katakam int err, val; 4029b83f1527SRafal Ozieblo 4030b83f1527SRafal Ozieblo regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 4031b83f1527SRafal Ozieblo mem = devm_ioremap_resource(&pdev->dev, regs); 4032b83f1527SRafal Ozieblo if (IS_ERR(mem)) 4033b83f1527SRafal Ozieblo return PTR_ERR(mem); 4034b83f1527SRafal Ozieblo 4035b83f1527SRafal Ozieblo if (np) { 4036b83f1527SRafal Ozieblo const struct of_device_id *match; 4037b83f1527SRafal Ozieblo 4038b83f1527SRafal Ozieblo match = of_match_node(macb_dt_ids, np); 4039b83f1527SRafal Ozieblo if (match && match->data) { 4040b83f1527SRafal Ozieblo macb_config = match->data; 4041b83f1527SRafal Ozieblo clk_init = macb_config->clk_init; 4042b83f1527SRafal Ozieblo init = macb_config->init; 4043b83f1527SRafal Ozieblo } 4044b83f1527SRafal Ozieblo } 4045b83f1527SRafal Ozieblo 4046f5473d1dSHarini Katakam err = clk_init(pdev, &pclk, &hclk, &tx_clk, &rx_clk, &tsu_clk); 4047b83f1527SRafal Ozieblo if (err) 4048b83f1527SRafal Ozieblo return err; 4049b83f1527SRafal Ozieblo 4050d54f89afSHarini Katakam pm_runtime_set_autosuspend_delay(&pdev->dev, MACB_PM_TIMEOUT); 4051d54f89afSHarini Katakam pm_runtime_use_autosuspend(&pdev->dev); 4052d54f89afSHarini Katakam pm_runtime_get_noresume(&pdev->dev); 4053d54f89afSHarini Katakam pm_runtime_set_active(&pdev->dev); 4054d54f89afSHarini Katakam pm_runtime_enable(&pdev->dev); 4055b83f1527SRafal Ozieblo native_io = hw_is_native_io(mem); 4056b83f1527SRafal Ozieblo 4057b83f1527SRafal Ozieblo macb_probe_queues(mem, native_io, &queue_mask, &num_queues); 4058b83f1527SRafal Ozieblo dev = alloc_etherdev_mq(sizeof(*bp), num_queues); 4059b83f1527SRafal Ozieblo if (!dev) { 4060b83f1527SRafal Ozieblo err = -ENOMEM; 4061b83f1527SRafal Ozieblo goto err_disable_clocks; 4062b83f1527SRafal Ozieblo } 4063b83f1527SRafal Ozieblo 4064b83f1527SRafal Ozieblo dev->base_addr = regs->start; 4065b83f1527SRafal Ozieblo 4066b83f1527SRafal Ozieblo SET_NETDEV_DEV(dev, &pdev->dev); 4067b83f1527SRafal Ozieblo 4068b83f1527SRafal Ozieblo bp = netdev_priv(dev); 4069b83f1527SRafal Ozieblo bp->pdev = pdev; 4070b83f1527SRafal Ozieblo bp->dev = dev; 4071b83f1527SRafal Ozieblo bp->regs = mem; 4072b83f1527SRafal Ozieblo bp->native_io = native_io; 4073b83f1527SRafal Ozieblo if (native_io) { 4074b83f1527SRafal Ozieblo bp->macb_reg_readl = hw_readl_native; 4075b83f1527SRafal Ozieblo bp->macb_reg_writel = hw_writel_native; 4076b83f1527SRafal Ozieblo } else { 4077b83f1527SRafal Ozieblo bp->macb_reg_readl = hw_readl; 4078b83f1527SRafal Ozieblo bp->macb_reg_writel = hw_writel; 4079b83f1527SRafal Ozieblo } 4080b83f1527SRafal Ozieblo bp->num_queues = num_queues; 4081b83f1527SRafal Ozieblo bp->queue_mask = queue_mask; 4082b83f1527SRafal Ozieblo if (macb_config) 4083b83f1527SRafal Ozieblo bp->dma_burst_length = macb_config->dma_burst_length; 4084b83f1527SRafal Ozieblo bp->pclk = pclk; 4085b83f1527SRafal Ozieblo bp->hclk = hclk; 4086b83f1527SRafal Ozieblo bp->tx_clk = tx_clk; 4087b83f1527SRafal Ozieblo bp->rx_clk = rx_clk; 4088f5473d1dSHarini Katakam bp->tsu_clk = tsu_clk; 4089b83f1527SRafal Ozieblo if (macb_config) 4090b83f1527SRafal Ozieblo bp->jumbo_max_len = macb_config->jumbo_max_len; 4091b83f1527SRafal Ozieblo 4092b83f1527SRafal Ozieblo bp->wol = 0; 4093b83f1527SRafal Ozieblo if (of_get_property(np, "magic-packet", NULL)) 4094b83f1527SRafal Ozieblo bp->wol |= MACB_WOL_HAS_MAGIC_PACKET; 4095b83f1527SRafal Ozieblo device_init_wakeup(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET); 4096b83f1527SRafal Ozieblo 4097b83f1527SRafal Ozieblo spin_lock_init(&bp->lock); 4098b83f1527SRafal Ozieblo 4099b83f1527SRafal Ozieblo /* setup capabilities */ 4100b83f1527SRafal Ozieblo macb_configure_caps(bp, macb_config); 4101b83f1527SRafal Ozieblo 4102b83f1527SRafal Ozieblo #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 4103b83f1527SRafal Ozieblo if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) { 4104b83f1527SRafal Ozieblo dma_set_mask(&pdev->dev, DMA_BIT_MASK(44)); 4105b83f1527SRafal Ozieblo bp->hw_dma_cap |= HW_DMA_CAP_64B; 4106b83f1527SRafal Ozieblo } 4107b83f1527SRafal Ozieblo #endif 4108b83f1527SRafal Ozieblo platform_set_drvdata(pdev, dev); 4109b83f1527SRafal Ozieblo 4110b83f1527SRafal Ozieblo dev->irq = platform_get_irq(pdev, 0); 4111b83f1527SRafal Ozieblo if (dev->irq < 0) { 4112b83f1527SRafal Ozieblo err = dev->irq; 4113b83f1527SRafal Ozieblo goto err_out_free_netdev; 4114b83f1527SRafal Ozieblo } 4115b83f1527SRafal Ozieblo 4116b83f1527SRafal Ozieblo /* MTU range: 68 - 1500 or 10240 */ 4117b83f1527SRafal Ozieblo dev->min_mtu = GEM_MTU_MIN_SIZE; 4118b83f1527SRafal Ozieblo if (bp->caps & MACB_CAPS_JUMBO) 4119b83f1527SRafal Ozieblo dev->max_mtu = gem_readl(bp, JML) - ETH_HLEN - ETH_FCS_LEN; 4120b83f1527SRafal Ozieblo else 4121b83f1527SRafal Ozieblo dev->max_mtu = ETH_DATA_LEN; 4122b83f1527SRafal Ozieblo 4123404cd086SHarini Katakam if (bp->caps & MACB_CAPS_BD_RD_PREFETCH) { 4124404cd086SHarini Katakam val = GEM_BFEXT(RXBD_RDBUFF, gem_readl(bp, DCFG10)); 4125404cd086SHarini Katakam if (val) 4126404cd086SHarini Katakam bp->rx_bd_rd_prefetch = (2 << (val - 1)) * 4127404cd086SHarini Katakam macb_dma_desc_get_size(bp); 4128404cd086SHarini Katakam 4129404cd086SHarini Katakam val = GEM_BFEXT(TXBD_RDBUFF, gem_readl(bp, DCFG10)); 4130404cd086SHarini Katakam if (val) 4131404cd086SHarini Katakam bp->tx_bd_rd_prefetch = (2 << (val - 1)) * 4132404cd086SHarini Katakam macb_dma_desc_get_size(bp); 4133404cd086SHarini Katakam } 4134404cd086SHarini Katakam 4135e501070eSHarini Katakam bp->rx_intr_mask = MACB_RX_INT_FLAGS; 4136e501070eSHarini Katakam if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR) 4137e501070eSHarini Katakam bp->rx_intr_mask |= MACB_BIT(RXUBR); 4138e501070eSHarini Katakam 4139b83f1527SRafal Ozieblo mac = of_get_mac_address(np); 4140aa076e3dSMike Looijmans if (mac) { 4141b83f1527SRafal Ozieblo ether_addr_copy(bp->dev->dev_addr, mac); 4142aa076e3dSMike Looijmans } else { 4143cce41b8fSBartosz Golaszewski err = nvmem_get_mac_address(&pdev->dev, bp->dev->dev_addr); 4144aa076e3dSMike Looijmans if (err) { 4145aa076e3dSMike Looijmans if (err == -EPROBE_DEFER) 4146aa076e3dSMike Looijmans goto err_out_free_netdev; 4147b83f1527SRafal Ozieblo macb_get_hwaddr(bp); 4148aa076e3dSMike Looijmans } 4149aa076e3dSMike Looijmans } 4150b83f1527SRafal Ozieblo 4151b83f1527SRafal Ozieblo err = of_get_phy_mode(np); 4152*8b952747SNicolas Ferre if (err < 0) 4153*8b952747SNicolas Ferre /* not found in DT, MII by default */ 4154b83f1527SRafal Ozieblo bp->phy_interface = PHY_INTERFACE_MODE_MII; 4155*8b952747SNicolas Ferre else 4156b83f1527SRafal Ozieblo bp->phy_interface = err; 4157b83f1527SRafal Ozieblo 4158b83f1527SRafal Ozieblo /* IP specific init */ 4159b83f1527SRafal Ozieblo err = init(pdev); 4160b83f1527SRafal Ozieblo if (err) 4161b83f1527SRafal Ozieblo goto err_out_free_netdev; 4162b83f1527SRafal Ozieblo 4163b83f1527SRafal Ozieblo err = macb_mii_init(bp); 4164b83f1527SRafal Ozieblo if (err) 4165b83f1527SRafal Ozieblo goto err_out_free_netdev; 4166b83f1527SRafal Ozieblo 4167b83f1527SRafal Ozieblo phydev = dev->phydev; 4168b83f1527SRafal Ozieblo 4169b83f1527SRafal Ozieblo netif_carrier_off(dev); 4170b83f1527SRafal Ozieblo 4171b83f1527SRafal Ozieblo err = register_netdev(dev); 4172b83f1527SRafal Ozieblo if (err) { 4173b83f1527SRafal Ozieblo dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); 4174b83f1527SRafal Ozieblo goto err_out_unregister_mdio; 4175b83f1527SRafal Ozieblo } 4176b83f1527SRafal Ozieblo 4177032dc41bSHarini Katakam tasklet_init(&bp->hresp_err_tasklet, macb_hresp_error_task, 4178032dc41bSHarini Katakam (unsigned long)bp); 4179032dc41bSHarini Katakam 4180b83f1527SRafal Ozieblo phy_attached_info(phydev); 4181b83f1527SRafal Ozieblo 4182b83f1527SRafal Ozieblo netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n", 4183b83f1527SRafal Ozieblo macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID), 4184b83f1527SRafal Ozieblo dev->base_addr, dev->irq, dev->dev_addr); 4185b83f1527SRafal Ozieblo 4186d54f89afSHarini Katakam pm_runtime_mark_last_busy(&bp->pdev->dev); 4187d54f89afSHarini Katakam pm_runtime_put_autosuspend(&bp->pdev->dev); 4188d54f89afSHarini Katakam 4189b83f1527SRafal Ozieblo return 0; 4190b83f1527SRafal Ozieblo 4191b83f1527SRafal Ozieblo err_out_unregister_mdio: 4192b83f1527SRafal Ozieblo phy_disconnect(dev->phydev); 4193b83f1527SRafal Ozieblo mdiobus_unregister(bp->mii_bus); 419466ee6a06SMichael Grzeschik of_node_put(bp->phy_node); 41959ce98140SMichael Grzeschik if (np && of_phy_is_fixed_link(np)) 41969ce98140SMichael Grzeschik of_phy_deregister_fixed_link(np); 4197b83f1527SRafal Ozieblo mdiobus_free(bp->mii_bus); 4198b83f1527SRafal Ozieblo 4199b83f1527SRafal Ozieblo err_out_free_netdev: 4200b83f1527SRafal Ozieblo free_netdev(dev); 4201b83f1527SRafal Ozieblo 4202b83f1527SRafal Ozieblo err_disable_clocks: 4203b83f1527SRafal Ozieblo clk_disable_unprepare(tx_clk); 4204b83f1527SRafal Ozieblo clk_disable_unprepare(hclk); 4205b83f1527SRafal Ozieblo clk_disable_unprepare(pclk); 4206b83f1527SRafal Ozieblo clk_disable_unprepare(rx_clk); 4207f5473d1dSHarini Katakam clk_disable_unprepare(tsu_clk); 4208d54f89afSHarini Katakam pm_runtime_disable(&pdev->dev); 4209d54f89afSHarini Katakam pm_runtime_set_suspended(&pdev->dev); 4210d54f89afSHarini Katakam pm_runtime_dont_use_autosuspend(&pdev->dev); 4211b83f1527SRafal Ozieblo 4212b83f1527SRafal Ozieblo return err; 4213b83f1527SRafal Ozieblo } 4214b83f1527SRafal Ozieblo 4215b83f1527SRafal Ozieblo static int macb_remove(struct platform_device *pdev) 4216b83f1527SRafal Ozieblo { 4217b83f1527SRafal Ozieblo struct net_device *dev; 4218b83f1527SRafal Ozieblo struct macb *bp; 42199ce98140SMichael Grzeschik struct device_node *np = pdev->dev.of_node; 4220b83f1527SRafal Ozieblo 4221b83f1527SRafal Ozieblo dev = platform_get_drvdata(pdev); 4222b83f1527SRafal Ozieblo 4223b83f1527SRafal Ozieblo if (dev) { 4224b83f1527SRafal Ozieblo bp = netdev_priv(dev); 4225b83f1527SRafal Ozieblo if (dev->phydev) 4226b83f1527SRafal Ozieblo phy_disconnect(dev->phydev); 4227b83f1527SRafal Ozieblo mdiobus_unregister(bp->mii_bus); 42289ce98140SMichael Grzeschik if (np && of_phy_is_fixed_link(np)) 42299ce98140SMichael Grzeschik of_phy_deregister_fixed_link(np); 4230b83f1527SRafal Ozieblo dev->phydev = NULL; 4231b83f1527SRafal Ozieblo mdiobus_free(bp->mii_bus); 4232b83f1527SRafal Ozieblo 4233b83f1527SRafal Ozieblo unregister_netdev(dev); 4234d54f89afSHarini Katakam pm_runtime_disable(&pdev->dev); 4235d54f89afSHarini Katakam pm_runtime_dont_use_autosuspend(&pdev->dev); 4236d54f89afSHarini Katakam if (!pm_runtime_suspended(&pdev->dev)) { 4237b83f1527SRafal Ozieblo clk_disable_unprepare(bp->tx_clk); 4238b83f1527SRafal Ozieblo clk_disable_unprepare(bp->hclk); 4239b83f1527SRafal Ozieblo clk_disable_unprepare(bp->pclk); 4240b83f1527SRafal Ozieblo clk_disable_unprepare(bp->rx_clk); 4241f5473d1dSHarini Katakam clk_disable_unprepare(bp->tsu_clk); 4242d54f89afSHarini Katakam pm_runtime_set_suspended(&pdev->dev); 4243d54f89afSHarini Katakam } 4244b83f1527SRafal Ozieblo of_node_put(bp->phy_node); 4245b83f1527SRafal Ozieblo free_netdev(dev); 4246b83f1527SRafal Ozieblo } 4247b83f1527SRafal Ozieblo 4248b83f1527SRafal Ozieblo return 0; 4249b83f1527SRafal Ozieblo } 4250b83f1527SRafal Ozieblo 4251b83f1527SRafal Ozieblo static int __maybe_unused macb_suspend(struct device *dev) 4252b83f1527SRafal Ozieblo { 4253ce886a47SWolfram Sang struct net_device *netdev = dev_get_drvdata(dev); 4254b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 4255de991c58SHarini Katakam struct macb_queue *queue = bp->queues; 4256de991c58SHarini Katakam unsigned long flags; 4257de991c58SHarini Katakam unsigned int q; 4258b83f1527SRafal Ozieblo 4259de991c58SHarini Katakam if (!netif_running(netdev)) 4260de991c58SHarini Katakam return 0; 4261de991c58SHarini Katakam 4262b83f1527SRafal Ozieblo 4263b83f1527SRafal Ozieblo if (bp->wol & MACB_WOL_ENABLED) { 4264b83f1527SRafal Ozieblo macb_writel(bp, IER, MACB_BIT(WOL)); 4265b83f1527SRafal Ozieblo macb_writel(bp, WOL, MACB_BIT(MAG)); 4266b83f1527SRafal Ozieblo enable_irq_wake(bp->queues[0].irq); 4267de991c58SHarini Katakam netif_device_detach(netdev); 4268de991c58SHarini Katakam } else { 4269de991c58SHarini Katakam netif_device_detach(netdev); 4270de991c58SHarini Katakam for (q = 0, queue = bp->queues; q < bp->num_queues; 4271de991c58SHarini Katakam ++q, ++queue) 4272de991c58SHarini Katakam napi_disable(&queue->napi); 4273de991c58SHarini Katakam phy_stop(netdev->phydev); 4274de991c58SHarini Katakam phy_suspend(netdev->phydev); 4275de991c58SHarini Katakam spin_lock_irqsave(&bp->lock, flags); 4276de991c58SHarini Katakam macb_reset_hw(bp); 4277de991c58SHarini Katakam spin_unlock_irqrestore(&bp->lock, flags); 4278d54f89afSHarini Katakam } 4279d54f89afSHarini Katakam 4280de991c58SHarini Katakam netif_carrier_off(netdev); 4281de991c58SHarini Katakam if (bp->ptp_info) 4282de991c58SHarini Katakam bp->ptp_info->ptp_remove(netdev); 4283d54f89afSHarini Katakam pm_runtime_force_suspend(dev); 4284d54f89afSHarini Katakam 4285d54f89afSHarini Katakam return 0; 4286d54f89afSHarini Katakam } 4287d54f89afSHarini Katakam 4288d54f89afSHarini Katakam static int __maybe_unused macb_resume(struct device *dev) 4289d54f89afSHarini Katakam { 4290d54f89afSHarini Katakam struct net_device *netdev = dev_get_drvdata(dev); 4291d54f89afSHarini Katakam struct macb *bp = netdev_priv(netdev); 4292de991c58SHarini Katakam struct macb_queue *queue = bp->queues; 4293de991c58SHarini Katakam unsigned int q; 4294de991c58SHarini Katakam 4295de991c58SHarini Katakam if (!netif_running(netdev)) 4296de991c58SHarini Katakam return 0; 4297d54f89afSHarini Katakam 4298d54f89afSHarini Katakam pm_runtime_force_resume(dev); 4299d54f89afSHarini Katakam 4300d54f89afSHarini Katakam if (bp->wol & MACB_WOL_ENABLED) { 4301d54f89afSHarini Katakam macb_writel(bp, IDR, MACB_BIT(WOL)); 4302d54f89afSHarini Katakam macb_writel(bp, WOL, 0); 4303d54f89afSHarini Katakam disable_irq_wake(bp->queues[0].irq); 4304de991c58SHarini Katakam } else { 4305de991c58SHarini Katakam macb_writel(bp, NCR, MACB_BIT(MPE)); 4306de991c58SHarini Katakam for (q = 0, queue = bp->queues; q < bp->num_queues; 4307de991c58SHarini Katakam ++q, ++queue) 4308de991c58SHarini Katakam napi_enable(&queue->napi); 4309de991c58SHarini Katakam phy_resume(netdev->phydev); 4310de991c58SHarini Katakam phy_init_hw(netdev->phydev); 4311de991c58SHarini Katakam phy_start(netdev->phydev); 4312d54f89afSHarini Katakam } 4313d54f89afSHarini Katakam 4314de991c58SHarini Katakam bp->macbgem_ops.mog_init_rings(bp); 4315de991c58SHarini Katakam macb_init_hw(bp); 4316de991c58SHarini Katakam macb_set_rx_mode(netdev); 4317d54f89afSHarini Katakam netif_device_attach(netdev); 4318de991c58SHarini Katakam if (bp->ptp_info) 4319de991c58SHarini Katakam bp->ptp_info->ptp_init(netdev); 4320d54f89afSHarini Katakam 4321d54f89afSHarini Katakam return 0; 4322d54f89afSHarini Katakam } 4323d54f89afSHarini Katakam 4324d54f89afSHarini Katakam static int __maybe_unused macb_runtime_suspend(struct device *dev) 4325d54f89afSHarini Katakam { 4326f9cb7597SWolfram Sang struct net_device *netdev = dev_get_drvdata(dev); 4327d54f89afSHarini Katakam struct macb *bp = netdev_priv(netdev); 4328d54f89afSHarini Katakam 4329d54f89afSHarini Katakam if (!(device_may_wakeup(&bp->dev->dev))) { 4330b83f1527SRafal Ozieblo clk_disable_unprepare(bp->tx_clk); 4331b83f1527SRafal Ozieblo clk_disable_unprepare(bp->hclk); 4332b83f1527SRafal Ozieblo clk_disable_unprepare(bp->pclk); 4333b83f1527SRafal Ozieblo clk_disable_unprepare(bp->rx_clk); 4334b83f1527SRafal Ozieblo } 4335f5473d1dSHarini Katakam clk_disable_unprepare(bp->tsu_clk); 4336b83f1527SRafal Ozieblo 4337b83f1527SRafal Ozieblo return 0; 4338b83f1527SRafal Ozieblo } 4339b83f1527SRafal Ozieblo 4340d54f89afSHarini Katakam static int __maybe_unused macb_runtime_resume(struct device *dev) 4341b83f1527SRafal Ozieblo { 4342f9cb7597SWolfram Sang struct net_device *netdev = dev_get_drvdata(dev); 4343b83f1527SRafal Ozieblo struct macb *bp = netdev_priv(netdev); 4344b83f1527SRafal Ozieblo 4345d54f89afSHarini Katakam if (!(device_may_wakeup(&bp->dev->dev))) { 4346b83f1527SRafal Ozieblo clk_prepare_enable(bp->pclk); 4347b83f1527SRafal Ozieblo clk_prepare_enable(bp->hclk); 4348b83f1527SRafal Ozieblo clk_prepare_enable(bp->tx_clk); 4349b83f1527SRafal Ozieblo clk_prepare_enable(bp->rx_clk); 4350b83f1527SRafal Ozieblo } 4351f5473d1dSHarini Katakam clk_prepare_enable(bp->tsu_clk); 4352b83f1527SRafal Ozieblo 4353b83f1527SRafal Ozieblo return 0; 4354b83f1527SRafal Ozieblo } 4355b83f1527SRafal Ozieblo 4356d54f89afSHarini Katakam static const struct dev_pm_ops macb_pm_ops = { 4357d54f89afSHarini Katakam SET_SYSTEM_SLEEP_PM_OPS(macb_suspend, macb_resume) 4358d54f89afSHarini Katakam SET_RUNTIME_PM_OPS(macb_runtime_suspend, macb_runtime_resume, NULL) 4359d54f89afSHarini Katakam }; 4360b83f1527SRafal Ozieblo 4361b83f1527SRafal Ozieblo static struct platform_driver macb_driver = { 4362b83f1527SRafal Ozieblo .probe = macb_probe, 4363b83f1527SRafal Ozieblo .remove = macb_remove, 4364b83f1527SRafal Ozieblo .driver = { 4365b83f1527SRafal Ozieblo .name = "macb", 4366b83f1527SRafal Ozieblo .of_match_table = of_match_ptr(macb_dt_ids), 4367b83f1527SRafal Ozieblo .pm = &macb_pm_ops, 4368b83f1527SRafal Ozieblo }, 4369b83f1527SRafal Ozieblo }; 4370b83f1527SRafal Ozieblo 4371b83f1527SRafal Ozieblo module_platform_driver(macb_driver); 4372b83f1527SRafal Ozieblo 4373b83f1527SRafal Ozieblo MODULE_LICENSE("GPL"); 4374b83f1527SRafal Ozieblo MODULE_DESCRIPTION("Cadence MACB/GEM Ethernet driver"); 4375b83f1527SRafal Ozieblo MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); 4376b83f1527SRafal Ozieblo MODULE_ALIAS("platform:macb"); 4377