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