ll_temac_main.c revision 8513fbd880093f00a47e85a552f14ca2de8d84d6
192744989533cbe85e8057935d230e128810168ceGrant Likely/* 292744989533cbe85e8057935d230e128810168ceGrant Likely * Driver for Xilinx TEMAC Ethernet device 392744989533cbe85e8057935d230e128810168ceGrant Likely * 492744989533cbe85e8057935d230e128810168ceGrant Likely * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi 592744989533cbe85e8057935d230e128810168ceGrant Likely * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. <dhlii@dlasys.net> 692744989533cbe85e8057935d230e128810168ceGrant Likely * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. 792744989533cbe85e8057935d230e128810168ceGrant Likely * 892744989533cbe85e8057935d230e128810168ceGrant Likely * This is a driver for the Xilinx ll_temac ipcore which is often used 992744989533cbe85e8057935d230e128810168ceGrant Likely * in the Virtex and Spartan series of chips. 1092744989533cbe85e8057935d230e128810168ceGrant Likely * 1192744989533cbe85e8057935d230e128810168ceGrant Likely * Notes: 1292744989533cbe85e8057935d230e128810168ceGrant Likely * - The ll_temac hardware uses indirect access for many of the TEMAC 1392744989533cbe85e8057935d230e128810168ceGrant Likely * registers, include the MDIO bus. However, indirect access to MDIO 1492744989533cbe85e8057935d230e128810168ceGrant Likely * registers take considerably more clock cycles than to TEMAC registers. 1592744989533cbe85e8057935d230e128810168ceGrant Likely * MDIO accesses are long, so threads doing them should probably sleep 1692744989533cbe85e8057935d230e128810168ceGrant Likely * rather than busywait. However, since only one indirect access can be 1792744989533cbe85e8057935d230e128810168ceGrant Likely * in progress at any given time, that means that *all* indirect accesses 1892744989533cbe85e8057935d230e128810168ceGrant Likely * could end up sleeping (to wait for an MDIO access to complete). 1992744989533cbe85e8057935d230e128810168ceGrant Likely * Fortunately none of the indirect accesses are on the 'hot' path for tx 2092744989533cbe85e8057935d230e128810168ceGrant Likely * or rx, so this should be okay. 2192744989533cbe85e8057935d230e128810168ceGrant Likely * 2292744989533cbe85e8057935d230e128810168ceGrant Likely * TODO: 2392744989533cbe85e8057935d230e128810168ceGrant Likely * - Factor out locallink DMA code into separate driver 2492744989533cbe85e8057935d230e128810168ceGrant Likely * - Fix multicast assignment. 2592744989533cbe85e8057935d230e128810168ceGrant Likely * - Fix support for hardware checksumming. 2692744989533cbe85e8057935d230e128810168ceGrant Likely * - Testing. Lots and lots of testing. 2792744989533cbe85e8057935d230e128810168ceGrant Likely * 2892744989533cbe85e8057935d230e128810168ceGrant Likely */ 2992744989533cbe85e8057935d230e128810168ceGrant Likely 3092744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/delay.h> 3192744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/etherdevice.h> 3292744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/init.h> 3392744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/mii.h> 3492744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/module.h> 3592744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/mutex.h> 3692744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/netdevice.h> 3792744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of.h> 3892744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_device.h> 3992744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_mdio.h> 4092744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_platform.h> 419f1a1fca35066117353994bff80a5115cddad7a2Michal Simek#include <linux/of_address.h> 4292744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/skbuff.h> 4392744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/spinlock.h> 4492744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/tcp.h> /* needed for sizeof(tcphdr) */ 4592744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/udp.h> /* needed for sizeof(udphdr) */ 4692744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/phy.h> 4792744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/in.h> 4892744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/io.h> 4992744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/ip.h> 505a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 51ffbc03bc75b39c7bd412e7cc6d2185c11b0ffeddStephen Rothwell#include <linux/interrupt.h> 5284cac3989a0fa009fff63c315759006560c91c13Stephen Rothwell#include <linux/dma-mapping.h> 5392744989533cbe85e8057935d230e128810168ceGrant Likely 5492744989533cbe85e8057935d230e128810168ceGrant Likely#include "ll_temac.h" 5592744989533cbe85e8057935d230e128810168ceGrant Likely 5692744989533cbe85e8057935d230e128810168ceGrant Likely#define TX_BD_NUM 64 5792744989533cbe85e8057935d230e128810168ceGrant Likely#define RX_BD_NUM 128 5892744989533cbe85e8057935d230e128810168ceGrant Likely 5992744989533cbe85e8057935d230e128810168ceGrant Likely/* --------------------------------------------------------------------- 6092744989533cbe85e8057935d230e128810168ceGrant Likely * Low level register access functions 6192744989533cbe85e8057935d230e128810168ceGrant Likely */ 6292744989533cbe85e8057935d230e128810168ceGrant Likely 6392744989533cbe85e8057935d230e128810168ceGrant Likelyu32 temac_ior(struct temac_local *lp, int offset) 6492744989533cbe85e8057935d230e128810168ceGrant Likely{ 6592744989533cbe85e8057935d230e128810168ceGrant Likely return in_be32((u32 *)(lp->regs + offset)); 6692744989533cbe85e8057935d230e128810168ceGrant Likely} 6792744989533cbe85e8057935d230e128810168ceGrant Likely 6892744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_iow(struct temac_local *lp, int offset, u32 value) 6992744989533cbe85e8057935d230e128810168ceGrant Likely{ 7092744989533cbe85e8057935d230e128810168ceGrant Likely out_be32((u32 *) (lp->regs + offset), value); 7192744989533cbe85e8057935d230e128810168ceGrant Likely} 7292744989533cbe85e8057935d230e128810168ceGrant Likely 7392744989533cbe85e8057935d230e128810168ceGrant Likelyint temac_indirect_busywait(struct temac_local *lp) 7492744989533cbe85e8057935d230e128810168ceGrant Likely{ 7592744989533cbe85e8057935d230e128810168ceGrant Likely long end = jiffies + 2; 7692744989533cbe85e8057935d230e128810168ceGrant Likely 7792744989533cbe85e8057935d230e128810168ceGrant Likely while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { 7892744989533cbe85e8057935d230e128810168ceGrant Likely if (end - jiffies <= 0) { 7992744989533cbe85e8057935d230e128810168ceGrant Likely WARN_ON(1); 8092744989533cbe85e8057935d230e128810168ceGrant Likely return -ETIMEDOUT; 8192744989533cbe85e8057935d230e128810168ceGrant Likely } 8292744989533cbe85e8057935d230e128810168ceGrant Likely msleep(1); 8392744989533cbe85e8057935d230e128810168ceGrant Likely } 8492744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 8592744989533cbe85e8057935d230e128810168ceGrant Likely} 8692744989533cbe85e8057935d230e128810168ceGrant Likely 8792744989533cbe85e8057935d230e128810168ceGrant Likely/** 8892744989533cbe85e8057935d230e128810168ceGrant Likely * temac_indirect_in32 8992744989533cbe85e8057935d230e128810168ceGrant Likely * 9092744989533cbe85e8057935d230e128810168ceGrant Likely * lp->indirect_mutex must be held when calling this function 9192744989533cbe85e8057935d230e128810168ceGrant Likely */ 9292744989533cbe85e8057935d230e128810168ceGrant Likelyu32 temac_indirect_in32(struct temac_local *lp, int reg) 9392744989533cbe85e8057935d230e128810168ceGrant Likely{ 9492744989533cbe85e8057935d230e128810168ceGrant Likely u32 val; 9592744989533cbe85e8057935d230e128810168ceGrant Likely 9692744989533cbe85e8057935d230e128810168ceGrant Likely if (temac_indirect_busywait(lp)) 9792744989533cbe85e8057935d230e128810168ceGrant Likely return -ETIMEDOUT; 9892744989533cbe85e8057935d230e128810168ceGrant Likely temac_iow(lp, XTE_CTL0_OFFSET, reg); 9992744989533cbe85e8057935d230e128810168ceGrant Likely if (temac_indirect_busywait(lp)) 10092744989533cbe85e8057935d230e128810168ceGrant Likely return -ETIMEDOUT; 10192744989533cbe85e8057935d230e128810168ceGrant Likely val = temac_ior(lp, XTE_LSW0_OFFSET); 10292744989533cbe85e8057935d230e128810168ceGrant Likely 10392744989533cbe85e8057935d230e128810168ceGrant Likely return val; 10492744989533cbe85e8057935d230e128810168ceGrant Likely} 10592744989533cbe85e8057935d230e128810168ceGrant Likely 10692744989533cbe85e8057935d230e128810168ceGrant Likely/** 10792744989533cbe85e8057935d230e128810168ceGrant Likely * temac_indirect_out32 10892744989533cbe85e8057935d230e128810168ceGrant Likely * 10992744989533cbe85e8057935d230e128810168ceGrant Likely * lp->indirect_mutex must be held when calling this function 11092744989533cbe85e8057935d230e128810168ceGrant Likely */ 11192744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_indirect_out32(struct temac_local *lp, int reg, u32 value) 11292744989533cbe85e8057935d230e128810168ceGrant Likely{ 11392744989533cbe85e8057935d230e128810168ceGrant Likely if (temac_indirect_busywait(lp)) 11492744989533cbe85e8057935d230e128810168ceGrant Likely return; 11592744989533cbe85e8057935d230e128810168ceGrant Likely temac_iow(lp, XTE_LSW0_OFFSET, value); 11692744989533cbe85e8057935d230e128810168ceGrant Likely temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); 117f79d7e6f6ae397caf219cef1392ca39b3ff10833Ricardo Ribalda temac_indirect_busywait(lp); 11892744989533cbe85e8057935d230e128810168ceGrant Likely} 11992744989533cbe85e8057935d230e128810168ceGrant Likely 120e44171f115de3dedf34064646206deb91549865fJohn Linn/** 121e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_in32 - Memory mapped DMA read, this function expects a 122e44171f115de3dedf34064646206deb91549865fJohn Linn * register input that is based on DCR word addresses which 123e44171f115de3dedf34064646206deb91549865fJohn Linn * are then converted to memory mapped byte addresses 124e44171f115de3dedf34064646206deb91549865fJohn Linn */ 12592744989533cbe85e8057935d230e128810168ceGrant Likelystatic u32 temac_dma_in32(struct temac_local *lp, int reg) 12692744989533cbe85e8057935d230e128810168ceGrant Likely{ 127e44171f115de3dedf34064646206deb91549865fJohn Linn return in_be32((u32 *)(lp->sdma_regs + (reg << 2))); 12892744989533cbe85e8057935d230e128810168ceGrant Likely} 12992744989533cbe85e8057935d230e128810168ceGrant Likely 130e44171f115de3dedf34064646206deb91549865fJohn Linn/** 131e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_out32 - Memory mapped DMA read, this function expects a 132e44171f115de3dedf34064646206deb91549865fJohn Linn * register input that is based on DCR word addresses which 133e44171f115de3dedf34064646206deb91549865fJohn Linn * are then converted to memory mapped byte addresses 134e44171f115de3dedf34064646206deb91549865fJohn Linn */ 13592744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_dma_out32(struct temac_local *lp, int reg, u32 value) 13692744989533cbe85e8057935d230e128810168ceGrant Likely{ 137e44171f115de3dedf34064646206deb91549865fJohn Linn out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value); 138e44171f115de3dedf34064646206deb91549865fJohn Linn} 139e44171f115de3dedf34064646206deb91549865fJohn Linn 140e44171f115de3dedf34064646206deb91549865fJohn Linn/* DMA register access functions can be DCR based or memory mapped. 141e44171f115de3dedf34064646206deb91549865fJohn Linn * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both 142e44171f115de3dedf34064646206deb91549865fJohn Linn * memory mapped. 143e44171f115de3dedf34064646206deb91549865fJohn Linn */ 144e44171f115de3dedf34064646206deb91549865fJohn Linn#ifdef CONFIG_PPC_DCR 145e44171f115de3dedf34064646206deb91549865fJohn Linn 146e44171f115de3dedf34064646206deb91549865fJohn Linn/** 147e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_dcr_in32 - DCR based DMA read 148e44171f115de3dedf34064646206deb91549865fJohn Linn */ 149e44171f115de3dedf34064646206deb91549865fJohn Linnstatic u32 temac_dma_dcr_in(struct temac_local *lp, int reg) 150e44171f115de3dedf34064646206deb91549865fJohn Linn{ 151e44171f115de3dedf34064646206deb91549865fJohn Linn return dcr_read(lp->sdma_dcrs, reg); 152e44171f115de3dedf34064646206deb91549865fJohn Linn} 153e44171f115de3dedf34064646206deb91549865fJohn Linn 154e44171f115de3dedf34064646206deb91549865fJohn Linn/** 155e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_dcr_out32 - DCR based DMA write 156e44171f115de3dedf34064646206deb91549865fJohn Linn */ 157e44171f115de3dedf34064646206deb91549865fJohn Linnstatic void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) 158e44171f115de3dedf34064646206deb91549865fJohn Linn{ 15992744989533cbe85e8057935d230e128810168ceGrant Likely dcr_write(lp->sdma_dcrs, reg, value); 16092744989533cbe85e8057935d230e128810168ceGrant Likely} 16192744989533cbe85e8057935d230e128810168ceGrant Likely 16292744989533cbe85e8057935d230e128810168ceGrant Likely/** 163e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dcr_setup - If the DMA is DCR based, then setup the address and 164e44171f115de3dedf34064646206deb91549865fJohn Linn * I/O functions 165e44171f115de3dedf34064646206deb91549865fJohn Linn */ 1662dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int temac_dcr_setup(struct temac_local *lp, struct platform_device *op, 167e44171f115de3dedf34064646206deb91549865fJohn Linn struct device_node *np) 168e44171f115de3dedf34064646206deb91549865fJohn Linn{ 169e44171f115de3dedf34064646206deb91549865fJohn Linn unsigned int dcrs; 170e44171f115de3dedf34064646206deb91549865fJohn Linn 171e44171f115de3dedf34064646206deb91549865fJohn Linn /* setup the dcr address mapping if it's in the device tree */ 172e44171f115de3dedf34064646206deb91549865fJohn Linn 173e44171f115de3dedf34064646206deb91549865fJohn Linn dcrs = dcr_resource_start(np, 0); 174e44171f115de3dedf34064646206deb91549865fJohn Linn if (dcrs != 0) { 175e44171f115de3dedf34064646206deb91549865fJohn Linn lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); 176e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_in = temac_dma_dcr_in; 177e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out = temac_dma_dcr_out; 178e44171f115de3dedf34064646206deb91549865fJohn Linn dev_dbg(&op->dev, "DCR base: %x\n", dcrs); 179e44171f115de3dedf34064646206deb91549865fJohn Linn return 0; 180e44171f115de3dedf34064646206deb91549865fJohn Linn } 181e44171f115de3dedf34064646206deb91549865fJohn Linn /* no DCR in the device tree, indicate a failure */ 182e44171f115de3dedf34064646206deb91549865fJohn Linn return -1; 183e44171f115de3dedf34064646206deb91549865fJohn Linn} 184e44171f115de3dedf34064646206deb91549865fJohn Linn 185e44171f115de3dedf34064646206deb91549865fJohn Linn#else 186e44171f115de3dedf34064646206deb91549865fJohn Linn 187e44171f115de3dedf34064646206deb91549865fJohn Linn/* 188e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dcr_setup - This is a stub for when DCR is not supported, 189e44171f115de3dedf34064646206deb91549865fJohn Linn * such as with MicroBlaze 190e44171f115de3dedf34064646206deb91549865fJohn Linn */ 1912dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int temac_dcr_setup(struct temac_local *lp, struct platform_device *op, 192e44171f115de3dedf34064646206deb91549865fJohn Linn struct device_node *np) 193e44171f115de3dedf34064646206deb91549865fJohn Linn{ 194e44171f115de3dedf34064646206deb91549865fJohn Linn return -1; 195e44171f115de3dedf34064646206deb91549865fJohn Linn} 196e44171f115de3dedf34064646206deb91549865fJohn Linn 197e44171f115de3dedf34064646206deb91549865fJohn Linn#endif 198e44171f115de3dedf34064646206deb91549865fJohn Linn 199e44171f115de3dedf34064646206deb91549865fJohn Linn/** 20049ce9c2cda18f62b13055dc715e7b514157c2da8Ben Hutchings * temac_dma_bd_release - Release buffer descriptor rings 201301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov */ 202301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanovstatic void temac_dma_bd_release(struct net_device *ndev) 203301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov{ 204301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov struct temac_local *lp = netdev_priv(ndev); 205301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov int i; 206301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov 20750ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda /* Reset Local Link (DMA) */ 20850ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); 20950ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda 210301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov for (i = 0; i < RX_BD_NUM; i++) { 211301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov if (!lp->rx_skb[i]) 212301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov break; 213301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov else { 214301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys, 215301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); 216301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov dev_kfree_skb(lp->rx_skb[i]); 217301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov } 218301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov } 219301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov if (lp->rx_bd_v) 220301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov dma_free_coherent(ndev->dev.parent, 221301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov sizeof(*lp->rx_bd_v) * RX_BD_NUM, 222301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov lp->rx_bd_v, lp->rx_bd_p); 223301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov if (lp->tx_bd_v) 224301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov dma_free_coherent(ndev->dev.parent, 225301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov sizeof(*lp->tx_bd_v) * TX_BD_NUM, 226301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov lp->tx_bd_v, lp->tx_bd_p); 227301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov if (lp->rx_skb) 228301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov kfree(lp->rx_skb); 229301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov} 230301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov 231301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov/** 23292744989533cbe85e8057935d230e128810168ceGrant Likely * temac_dma_bd_init - Setup buffer descriptor rings 23392744989533cbe85e8057935d230e128810168ceGrant Likely */ 23492744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_dma_bd_init(struct net_device *ndev) 23592744989533cbe85e8057935d230e128810168ceGrant Likely{ 23692744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 23792744989533cbe85e8057935d230e128810168ceGrant Likely struct sk_buff *skb; 23892744989533cbe85e8057935d230e128810168ceGrant Likely int i; 23992744989533cbe85e8057935d230e128810168ceGrant Likely 240ddf98e6d30a966dbd6e675c90e2caa5b9486e519Thomas Meyer lp->rx_skb = kcalloc(RX_BD_NUM, sizeof(*lp->rx_skb), GFP_KERNEL); 241b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches if (!lp->rx_skb) 242fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov goto out; 243b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches 24492744989533cbe85e8057935d230e128810168ceGrant Likely /* allocate the tx and rx ring buffer descriptors. */ 245b595076a180a56d1bb170e6eceda6eb9d76f4cd3Uwe Kleine-König /* returns a virtual address and a physical address. */ 24692744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, 24792744989533cbe85e8057935d230e128810168ceGrant Likely sizeof(*lp->tx_bd_v) * TX_BD_NUM, 2481f9061d27d3d2028805549c4a306324a48209057Joe Perches &lp->tx_bd_p, GFP_KERNEL | __GFP_ZERO); 249d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches if (!lp->tx_bd_v) 250fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov goto out; 251d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches 25292744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, 25392744989533cbe85e8057935d230e128810168ceGrant Likely sizeof(*lp->rx_bd_v) * RX_BD_NUM, 2541f9061d27d3d2028805549c4a306324a48209057Joe Perches &lp->rx_bd_p, GFP_KERNEL | __GFP_ZERO); 255d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches if (!lp->rx_bd_v) 256fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov goto out; 25792744989533cbe85e8057935d230e128810168ceGrant Likely 25892744989533cbe85e8057935d230e128810168ceGrant Likely for (i = 0; i < TX_BD_NUM; i++) { 25992744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_v[i].next = lp->tx_bd_p + 26092744989533cbe85e8057935d230e128810168ceGrant Likely sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM); 26192744989533cbe85e8057935d230e128810168ceGrant Likely } 26292744989533cbe85e8057935d230e128810168ceGrant Likely 26392744989533cbe85e8057935d230e128810168ceGrant Likely for (i = 0; i < RX_BD_NUM; i++) { 26492744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_v[i].next = lp->rx_bd_p + 26592744989533cbe85e8057935d230e128810168ceGrant Likely sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); 26692744989533cbe85e8057935d230e128810168ceGrant Likely 267e44171f115de3dedf34064646206deb91549865fJohn Linn skb = netdev_alloc_skb_ip_align(ndev, 268e44171f115de3dedf34064646206deb91549865fJohn Linn XTE_MAX_JUMBO_FRAME_SIZE); 269720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches if (!skb) 270fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov goto out; 271720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches 27292744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_skb[i] = skb; 27392744989533cbe85e8057935d230e128810168ceGrant Likely /* returns physical address of skb->data */ 27492744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, 27592744989533cbe85e8057935d230e128810168ceGrant Likely skb->data, 27692744989533cbe85e8057935d230e128810168ceGrant Likely XTE_MAX_JUMBO_FRAME_SIZE, 27792744989533cbe85e8057935d230e128810168ceGrant Likely DMA_FROM_DEVICE); 27892744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE; 27992744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; 28092744989533cbe85e8057935d230e128810168ceGrant Likely } 28192744989533cbe85e8057935d230e128810168ceGrant Likely 282e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 | 28392744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_EN | 28492744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_DLY_EN | 28592744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_COAL_EN); 28692744989533cbe85e8057935d230e128810168ceGrant Likely /* 0x10220483 */ 28792744989533cbe85e8057935d230e128810168ceGrant Likely /* 0x00100483 */ 28823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 | 28992744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_EN | 29092744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_DLY_EN | 29192744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_COAL_EN | 29292744989533cbe85e8057935d230e128810168ceGrant Likely CHNL_CTRL_IRQ_IOE); 29392744989533cbe85e8057935d230e128810168ceGrant Likely /* 0xff010283 */ 29492744989533cbe85e8057935d230e128810168ceGrant Likely 295e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); 296e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, RX_TAILDESC_PTR, 29792744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); 298e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); 29992744989533cbe85e8057935d230e128810168ceGrant Likely 30092744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 301fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov 302fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanovout: 303301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov temac_dma_bd_release(ndev); 304fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov return -ENOMEM; 30592744989533cbe85e8057935d230e128810168ceGrant Likely} 30692744989533cbe85e8057935d230e128810168ceGrant Likely 30792744989533cbe85e8057935d230e128810168ceGrant Likely/* --------------------------------------------------------------------- 30892744989533cbe85e8057935d230e128810168ceGrant Likely * net_device_ops 30992744989533cbe85e8057935d230e128810168ceGrant Likely */ 31092744989533cbe85e8057935d230e128810168ceGrant Likely 31104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic void temac_do_set_mac_address(struct net_device *ndev) 31292744989533cbe85e8057935d230e128810168ceGrant Likely{ 31392744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 31492744989533cbe85e8057935d230e128810168ceGrant Likely 31592744989533cbe85e8057935d230e128810168ceGrant Likely /* set up unicast MAC address filter set its mac address */ 31692744989533cbe85e8057935d230e128810168ceGrant Likely mutex_lock(&lp->indirect_mutex); 31792744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_UAW0_OFFSET, 31892744989533cbe85e8057935d230e128810168ceGrant Likely (ndev->dev_addr[0]) | 31992744989533cbe85e8057935d230e128810168ceGrant Likely (ndev->dev_addr[1] << 8) | 32092744989533cbe85e8057935d230e128810168ceGrant Likely (ndev->dev_addr[2] << 16) | 32192744989533cbe85e8057935d230e128810168ceGrant Likely (ndev->dev_addr[3] << 24)); 32292744989533cbe85e8057935d230e128810168ceGrant Likely /* There are reserved bits in EUAW1 32392744989533cbe85e8057935d230e128810168ceGrant Likely * so don't affect them Set MAC bits [47:32] in EUAW1 */ 32492744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_UAW1_OFFSET, 32592744989533cbe85e8057935d230e128810168ceGrant Likely (ndev->dev_addr[4] & 0x000000ff) | 32692744989533cbe85e8057935d230e128810168ceGrant Likely (ndev->dev_addr[5] << 8)); 32792744989533cbe85e8057935d230e128810168ceGrant Likely mutex_unlock(&lp->indirect_mutex); 32804e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko} 32992744989533cbe85e8057935d230e128810168ceGrant Likely 33004e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic int temac_init_mac_address(struct net_device *ndev, void *address) 33104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko{ 33204e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko memcpy(ndev->dev_addr, address, ETH_ALEN); 33304e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko if (!is_valid_ether_addr(ndev->dev_addr)) 33404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko eth_hw_addr_random(ndev); 33504e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko temac_do_set_mac_address(ndev); 33692744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 33792744989533cbe85e8057935d230e128810168ceGrant Likely} 33892744989533cbe85e8057935d230e128810168ceGrant Likely 33904e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic int temac_set_mac_address(struct net_device *ndev, void *p) 3408ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani{ 3418ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani struct sockaddr *addr = p; 3428ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani 34304e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko if (!is_valid_ether_addr(addr->sa_data)) 34404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko return -EADDRNOTAVAIL; 34504e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko memcpy(ndev->dev_addr, addr->sa_data, ETH_ALEN); 34604e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko temac_do_set_mac_address(ndev); 34704e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko return 0; 3488ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani} 3498ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani 35092744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_set_multicast_list(struct net_device *ndev) 35192744989533cbe85e8057935d230e128810168ceGrant Likely{ 35292744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 35392744989533cbe85e8057935d230e128810168ceGrant Likely u32 multi_addr_msw, multi_addr_lsw, val; 35492744989533cbe85e8057935d230e128810168ceGrant Likely int i; 35592744989533cbe85e8057935d230e128810168ceGrant Likely 35692744989533cbe85e8057935d230e128810168ceGrant Likely mutex_lock(&lp->indirect_mutex); 3578e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) || 3584cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) { 35992744989533cbe85e8057935d230e128810168ceGrant Likely /* 36092744989533cbe85e8057935d230e128810168ceGrant Likely * We must make the kernel realise we had to move 36192744989533cbe85e8057935d230e128810168ceGrant Likely * into promisc mode or we start all out war on 36292744989533cbe85e8057935d230e128810168ceGrant Likely * the cable. If it was a promisc request the 36392744989533cbe85e8057935d230e128810168ceGrant Likely * flag is already set. If not we assert it. 36492744989533cbe85e8057935d230e128810168ceGrant Likely */ 36592744989533cbe85e8057935d230e128810168ceGrant Likely ndev->flags |= IFF_PROMISC; 36692744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK); 36792744989533cbe85e8057935d230e128810168ceGrant Likely dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); 3684cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko } else if (!netdev_mc_empty(ndev)) { 36922bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko struct netdev_hw_addr *ha; 37092744989533cbe85e8057935d230e128810168ceGrant Likely 371f9dcbcc9e338d08c0f7de7eba4eaafbbb7f81249Jiri Pirko i = 0; 37222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko netdev_for_each_mc_addr(ha, ndev) { 37392744989533cbe85e8057935d230e128810168ceGrant Likely if (i >= MULTICAST_CAM_TABLE_NUM) 37492744989533cbe85e8057935d230e128810168ceGrant Likely break; 37522bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko multi_addr_msw = ((ha->addr[3] << 24) | 37622bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko (ha->addr[2] << 16) | 37722bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko (ha->addr[1] << 8) | 37822bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko (ha->addr[0])); 37992744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_MAW0_OFFSET, 38092744989533cbe85e8057935d230e128810168ceGrant Likely multi_addr_msw); 38122bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko multi_addr_lsw = ((ha->addr[5] << 8) | 38222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko (ha->addr[4]) | (i << 16)); 38392744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_MAW1_OFFSET, 38492744989533cbe85e8057935d230e128810168ceGrant Likely multi_addr_lsw); 385f9dcbcc9e338d08c0f7de7eba4eaafbbb7f81249Jiri Pirko i++; 38692744989533cbe85e8057935d230e128810168ceGrant Likely } 38792744989533cbe85e8057935d230e128810168ceGrant Likely } else { 38892744989533cbe85e8057935d230e128810168ceGrant Likely val = temac_indirect_in32(lp, XTE_AFM_OFFSET); 38992744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_AFM_OFFSET, 39092744989533cbe85e8057935d230e128810168ceGrant Likely val & ~XTE_AFM_EPPRM_MASK); 39192744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0); 39292744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0); 39392744989533cbe85e8057935d230e128810168ceGrant Likely dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); 39492744989533cbe85e8057935d230e128810168ceGrant Likely } 39592744989533cbe85e8057935d230e128810168ceGrant Likely mutex_unlock(&lp->indirect_mutex); 39692744989533cbe85e8057935d230e128810168ceGrant Likely} 39792744989533cbe85e8057935d230e128810168ceGrant Likely 39892744989533cbe85e8057935d230e128810168ceGrant Likelystruct temac_option { 39992744989533cbe85e8057935d230e128810168ceGrant Likely int flg; 40092744989533cbe85e8057935d230e128810168ceGrant Likely u32 opt; 40192744989533cbe85e8057935d230e128810168ceGrant Likely u32 reg; 40292744989533cbe85e8057935d230e128810168ceGrant Likely u32 m_or; 40392744989533cbe85e8057935d230e128810168ceGrant Likely u32 m_and; 40492744989533cbe85e8057935d230e128810168ceGrant Likely} temac_options[] = { 40592744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on jumbo packet support for both Rx and Tx */ 40692744989533cbe85e8057935d230e128810168ceGrant Likely { 40792744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_JUMBO, 40892744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_TXC_OFFSET, 40992744989533cbe85e8057935d230e128810168ceGrant Likely .m_or = XTE_TXC_TXJMBO_MASK, 41092744989533cbe85e8057935d230e128810168ceGrant Likely }, 41192744989533cbe85e8057935d230e128810168ceGrant Likely { 41292744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_JUMBO, 41392744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_RXC1_OFFSET, 41492744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_RXC1_RXJMBO_MASK, 41592744989533cbe85e8057935d230e128810168ceGrant Likely }, 41692744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on VLAN packet support for both Rx and Tx */ 41792744989533cbe85e8057935d230e128810168ceGrant Likely { 41892744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_VLAN, 41992744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_TXC_OFFSET, 42092744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_TXC_TXVLAN_MASK, 42192744989533cbe85e8057935d230e128810168ceGrant Likely }, 42292744989533cbe85e8057935d230e128810168ceGrant Likely { 42392744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_VLAN, 42492744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_RXC1_OFFSET, 42592744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_RXC1_RXVLAN_MASK, 42692744989533cbe85e8057935d230e128810168ceGrant Likely }, 42792744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on FCS stripping on receive packets */ 42892744989533cbe85e8057935d230e128810168ceGrant Likely { 42992744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_FCS_STRIP, 43092744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_RXC1_OFFSET, 43192744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_RXC1_RXFCS_MASK, 43292744989533cbe85e8057935d230e128810168ceGrant Likely }, 43392744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on FCS insertion on transmit packets */ 43492744989533cbe85e8057935d230e128810168ceGrant Likely { 43592744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_FCS_INSERT, 43692744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_TXC_OFFSET, 43792744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_TXC_TXFCS_MASK, 43892744989533cbe85e8057935d230e128810168ceGrant Likely }, 43992744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on length/type field checking on receive packets */ 44092744989533cbe85e8057935d230e128810168ceGrant Likely { 44192744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_LENTYPE_ERR, 44292744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_RXC1_OFFSET, 44392744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_RXC1_RXLT_MASK, 44492744989533cbe85e8057935d230e128810168ceGrant Likely }, 44592744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on flow control */ 44692744989533cbe85e8057935d230e128810168ceGrant Likely { 44792744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_FLOW_CONTROL, 44892744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_FCC_OFFSET, 44992744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_FCC_RXFLO_MASK, 45092744989533cbe85e8057935d230e128810168ceGrant Likely }, 45192744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on flow control */ 45292744989533cbe85e8057935d230e128810168ceGrant Likely { 45392744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_FLOW_CONTROL, 45492744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_FCC_OFFSET, 45592744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_FCC_TXFLO_MASK, 45692744989533cbe85e8057935d230e128810168ceGrant Likely }, 45792744989533cbe85e8057935d230e128810168ceGrant Likely /* Turn on promiscuous frame filtering (all frames are received ) */ 45892744989533cbe85e8057935d230e128810168ceGrant Likely { 45992744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_PROMISC, 46092744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_AFM_OFFSET, 46192744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_AFM_EPPRM_MASK, 46292744989533cbe85e8057935d230e128810168ceGrant Likely }, 46392744989533cbe85e8057935d230e128810168ceGrant Likely /* Enable transmitter if not already enabled */ 46492744989533cbe85e8057935d230e128810168ceGrant Likely { 46592744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_TXEN, 46692744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_TXC_OFFSET, 46792744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_TXC_TXEN_MASK, 46892744989533cbe85e8057935d230e128810168ceGrant Likely }, 46992744989533cbe85e8057935d230e128810168ceGrant Likely /* Enable receiver? */ 47092744989533cbe85e8057935d230e128810168ceGrant Likely { 47192744989533cbe85e8057935d230e128810168ceGrant Likely .opt = XTE_OPTION_RXEN, 47292744989533cbe85e8057935d230e128810168ceGrant Likely .reg = XTE_RXC1_OFFSET, 47392744989533cbe85e8057935d230e128810168ceGrant Likely .m_or =XTE_RXC1_RXEN_MASK, 47492744989533cbe85e8057935d230e128810168ceGrant Likely }, 47592744989533cbe85e8057935d230e128810168ceGrant Likely {} 47692744989533cbe85e8057935d230e128810168ceGrant Likely}; 47792744989533cbe85e8057935d230e128810168ceGrant Likely 47892744989533cbe85e8057935d230e128810168ceGrant Likely/** 47992744989533cbe85e8057935d230e128810168ceGrant Likely * temac_setoptions 48092744989533cbe85e8057935d230e128810168ceGrant Likely */ 48192744989533cbe85e8057935d230e128810168ceGrant Likelystatic u32 temac_setoptions(struct net_device *ndev, u32 options) 48292744989533cbe85e8057935d230e128810168ceGrant Likely{ 48392744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 48492744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_option *tp = &temac_options[0]; 48592744989533cbe85e8057935d230e128810168ceGrant Likely int reg; 48692744989533cbe85e8057935d230e128810168ceGrant Likely 48792744989533cbe85e8057935d230e128810168ceGrant Likely mutex_lock(&lp->indirect_mutex); 48892744989533cbe85e8057935d230e128810168ceGrant Likely while (tp->opt) { 48992744989533cbe85e8057935d230e128810168ceGrant Likely reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or; 49092744989533cbe85e8057935d230e128810168ceGrant Likely if (options & tp->opt) 49192744989533cbe85e8057935d230e128810168ceGrant Likely reg |= tp->m_or; 49292744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, tp->reg, reg); 49392744989533cbe85e8057935d230e128810168ceGrant Likely tp++; 49492744989533cbe85e8057935d230e128810168ceGrant Likely } 49592744989533cbe85e8057935d230e128810168ceGrant Likely lp->options |= options; 49692744989533cbe85e8057935d230e128810168ceGrant Likely mutex_unlock(&lp->indirect_mutex); 49792744989533cbe85e8057935d230e128810168ceGrant Likely 498807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return 0; 49992744989533cbe85e8057935d230e128810168ceGrant Likely} 50092744989533cbe85e8057935d230e128810168ceGrant Likely 501421f91d21ad6f799dc7b489bb33cc560ccc56f98Uwe Kleine-König/* Initialize temac */ 50292744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_device_reset(struct net_device *ndev) 50392744989533cbe85e8057935d230e128810168ceGrant Likely{ 50492744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 50592744989533cbe85e8057935d230e128810168ceGrant Likely u32 timeout; 50692744989533cbe85e8057935d230e128810168ceGrant Likely u32 val; 50792744989533cbe85e8057935d230e128810168ceGrant Likely 50892744989533cbe85e8057935d230e128810168ceGrant Likely /* Perform a software reset */ 50992744989533cbe85e8057935d230e128810168ceGrant Likely 51092744989533cbe85e8057935d230e128810168ceGrant Likely /* 0x300 host enable bit ? */ 51192744989533cbe85e8057935d230e128810168ceGrant Likely /* reset PHY through control register ?:1 */ 51292744989533cbe85e8057935d230e128810168ceGrant Likely 51392744989533cbe85e8057935d230e128810168ceGrant Likely dev_dbg(&ndev->dev, "%s()\n", __func__); 51492744989533cbe85e8057935d230e128810168ceGrant Likely 51592744989533cbe85e8057935d230e128810168ceGrant Likely mutex_lock(&lp->indirect_mutex); 51692744989533cbe85e8057935d230e128810168ceGrant Likely /* Reset the receiver and wait for it to finish reset */ 51792744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK); 51892744989533cbe85e8057935d230e128810168ceGrant Likely timeout = 1000; 51992744989533cbe85e8057935d230e128810168ceGrant Likely while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) { 52092744989533cbe85e8057935d230e128810168ceGrant Likely udelay(1); 52192744989533cbe85e8057935d230e128810168ceGrant Likely if (--timeout == 0) { 52292744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&ndev->dev, 52392744989533cbe85e8057935d230e128810168ceGrant Likely "temac_device_reset RX reset timeout!!\n"); 52492744989533cbe85e8057935d230e128810168ceGrant Likely break; 52592744989533cbe85e8057935d230e128810168ceGrant Likely } 52692744989533cbe85e8057935d230e128810168ceGrant Likely } 52792744989533cbe85e8057935d230e128810168ceGrant Likely 52892744989533cbe85e8057935d230e128810168ceGrant Likely /* Reset the transmitter and wait for it to finish reset */ 52992744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK); 53092744989533cbe85e8057935d230e128810168ceGrant Likely timeout = 1000; 53192744989533cbe85e8057935d230e128810168ceGrant Likely while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) { 53292744989533cbe85e8057935d230e128810168ceGrant Likely udelay(1); 53392744989533cbe85e8057935d230e128810168ceGrant Likely if (--timeout == 0) { 53492744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&ndev->dev, 53592744989533cbe85e8057935d230e128810168ceGrant Likely "temac_device_reset TX reset timeout!!\n"); 53692744989533cbe85e8057935d230e128810168ceGrant Likely break; 53792744989533cbe85e8057935d230e128810168ceGrant Likely } 53892744989533cbe85e8057935d230e128810168ceGrant Likely } 53992744989533cbe85e8057935d230e128810168ceGrant Likely 54092744989533cbe85e8057935d230e128810168ceGrant Likely /* Disable the receiver */ 54192744989533cbe85e8057935d230e128810168ceGrant Likely val = temac_indirect_in32(lp, XTE_RXC1_OFFSET); 54292744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); 54392744989533cbe85e8057935d230e128810168ceGrant Likely 54492744989533cbe85e8057935d230e128810168ceGrant Likely /* Reset Local Link (DMA) */ 545e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); 54692744989533cbe85e8057935d230e128810168ceGrant Likely timeout = 1000; 547e44171f115de3dedf34064646206deb91549865fJohn Linn while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { 54892744989533cbe85e8057935d230e128810168ceGrant Likely udelay(1); 54992744989533cbe85e8057935d230e128810168ceGrant Likely if (--timeout == 0) { 55092744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&ndev->dev, 55192744989533cbe85e8057935d230e128810168ceGrant Likely "temac_device_reset DMA reset timeout!!\n"); 55292744989533cbe85e8057935d230e128810168ceGrant Likely break; 55392744989533cbe85e8057935d230e128810168ceGrant Likely } 55492744989533cbe85e8057935d230e128810168ceGrant Likely } 555e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); 55692744989533cbe85e8057935d230e128810168ceGrant Likely 557fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov if (temac_dma_bd_init(ndev)) { 558fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov dev_err(&ndev->dev, 559fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov "temac_device_reset descriptor allocation failed\n"); 560fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov } 56192744989533cbe85e8057935d230e128810168ceGrant Likely 56292744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0); 56392744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0); 56492744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_TXC_OFFSET, 0); 56592744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK); 56692744989533cbe85e8057935d230e128810168ceGrant Likely 56792744989533cbe85e8057935d230e128810168ceGrant Likely mutex_unlock(&lp->indirect_mutex); 56892744989533cbe85e8057935d230e128810168ceGrant Likely 56992744989533cbe85e8057935d230e128810168ceGrant Likely /* Sync default options with HW 57092744989533cbe85e8057935d230e128810168ceGrant Likely * but leave receiver and transmitter disabled. */ 57192744989533cbe85e8057935d230e128810168ceGrant Likely temac_setoptions(ndev, 57292744989533cbe85e8057935d230e128810168ceGrant Likely lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN)); 57392744989533cbe85e8057935d230e128810168ceGrant Likely 57404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko temac_do_set_mac_address(ndev); 57592744989533cbe85e8057935d230e128810168ceGrant Likely 57692744989533cbe85e8057935d230e128810168ceGrant Likely /* Set address filter table */ 57792744989533cbe85e8057935d230e128810168ceGrant Likely temac_set_multicast_list(ndev); 57892744989533cbe85e8057935d230e128810168ceGrant Likely if (temac_setoptions(ndev, lp->options)) 57992744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&ndev->dev, "Error setting TEMAC options\n"); 58092744989533cbe85e8057935d230e128810168ceGrant Likely 58192744989533cbe85e8057935d230e128810168ceGrant Likely /* Init Driver variable */ 5821ae5dc342ac78d7a42965fd1f323815f6f5ef2c1Eric Dumazet ndev->trans_start = jiffies; /* prevent tx timeout */ 58392744989533cbe85e8057935d230e128810168ceGrant Likely} 58492744989533cbe85e8057935d230e128810168ceGrant Likely 58592744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_adjust_link(struct net_device *ndev) 58692744989533cbe85e8057935d230e128810168ceGrant Likely{ 58792744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 58892744989533cbe85e8057935d230e128810168ceGrant Likely struct phy_device *phy = lp->phy_dev; 58992744989533cbe85e8057935d230e128810168ceGrant Likely u32 mii_speed; 59092744989533cbe85e8057935d230e128810168ceGrant Likely int link_state; 59192744989533cbe85e8057935d230e128810168ceGrant Likely 59292744989533cbe85e8057935d230e128810168ceGrant Likely /* hash together the state values to decide if something has changed */ 59392744989533cbe85e8057935d230e128810168ceGrant Likely link_state = phy->speed | (phy->duplex << 1) | phy->link; 59492744989533cbe85e8057935d230e128810168ceGrant Likely 59592744989533cbe85e8057935d230e128810168ceGrant Likely mutex_lock(&lp->indirect_mutex); 59692744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->last_link != link_state) { 59792744989533cbe85e8057935d230e128810168ceGrant Likely mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET); 59892744989533cbe85e8057935d230e128810168ceGrant Likely mii_speed &= ~XTE_EMCFG_LINKSPD_MASK; 59992744989533cbe85e8057935d230e128810168ceGrant Likely 60092744989533cbe85e8057935d230e128810168ceGrant Likely switch (phy->speed) { 60192744989533cbe85e8057935d230e128810168ceGrant Likely case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break; 60292744989533cbe85e8057935d230e128810168ceGrant Likely case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break; 60392744989533cbe85e8057935d230e128810168ceGrant Likely case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break; 60492744989533cbe85e8057935d230e128810168ceGrant Likely } 60592744989533cbe85e8057935d230e128810168ceGrant Likely 60692744989533cbe85e8057935d230e128810168ceGrant Likely /* Write new speed setting out to TEMAC */ 60792744989533cbe85e8057935d230e128810168ceGrant Likely temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed); 60892744989533cbe85e8057935d230e128810168ceGrant Likely lp->last_link = link_state; 60992744989533cbe85e8057935d230e128810168ceGrant Likely phy_print_status(phy); 61092744989533cbe85e8057935d230e128810168ceGrant Likely } 61192744989533cbe85e8057935d230e128810168ceGrant Likely mutex_unlock(&lp->indirect_mutex); 61292744989533cbe85e8057935d230e128810168ceGrant Likely} 61392744989533cbe85e8057935d230e128810168ceGrant Likely 61492744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_start_xmit_done(struct net_device *ndev) 61592744989533cbe85e8057935d230e128810168ceGrant Likely{ 61692744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 61792744989533cbe85e8057935d230e128810168ceGrant Likely struct cdmac_bd *cur_p; 61892744989533cbe85e8057935d230e128810168ceGrant Likely unsigned int stat = 0; 61992744989533cbe85e8057935d230e128810168ceGrant Likely 62092744989533cbe85e8057935d230e128810168ceGrant Likely cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; 62192744989533cbe85e8057935d230e128810168ceGrant Likely stat = cur_p->app0; 62292744989533cbe85e8057935d230e128810168ceGrant Likely 62392744989533cbe85e8057935d230e128810168ceGrant Likely while (stat & STS_CTRL_APP0_CMPLT) { 62492744989533cbe85e8057935d230e128810168ceGrant Likely dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len, 62592744989533cbe85e8057935d230e128810168ceGrant Likely DMA_TO_DEVICE); 62692744989533cbe85e8057935d230e128810168ceGrant Likely if (cur_p->app4) 62792744989533cbe85e8057935d230e128810168ceGrant Likely dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); 62892744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app0 = 0; 62923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app1 = 0; 63023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app2 = 0; 63123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app3 = 0; 63223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app4 = 0; 63392744989533cbe85e8057935d230e128810168ceGrant Likely 63492744989533cbe85e8057935d230e128810168ceGrant Likely ndev->stats.tx_packets++; 63592744989533cbe85e8057935d230e128810168ceGrant Likely ndev->stats.tx_bytes += cur_p->len; 63692744989533cbe85e8057935d230e128810168ceGrant Likely 63792744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_ci++; 63892744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->tx_bd_ci >= TX_BD_NUM) 63992744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_ci = 0; 64092744989533cbe85e8057935d230e128810168ceGrant Likely 64192744989533cbe85e8057935d230e128810168ceGrant Likely cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; 64292744989533cbe85e8057935d230e128810168ceGrant Likely stat = cur_p->app0; 64392744989533cbe85e8057935d230e128810168ceGrant Likely } 64492744989533cbe85e8057935d230e128810168ceGrant Likely 64592744989533cbe85e8057935d230e128810168ceGrant Likely netif_wake_queue(ndev); 64692744989533cbe85e8057935d230e128810168ceGrant Likely} 64792744989533cbe85e8057935d230e128810168ceGrant Likely 64823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hillstatic inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) 64923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill{ 65023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill struct cdmac_bd *cur_p; 65123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill int tail; 65223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 65323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill tail = lp->tx_bd_tail; 65423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p = &lp->tx_bd_v[tail]; 65523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 65623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill do { 65723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill if (cur_p->app0) 65823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill return NETDEV_TX_BUSY; 65923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 66023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill tail++; 66123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill if (tail >= TX_BD_NUM) 66223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill tail = 0; 66323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 66423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p = &lp->tx_bd_v[tail]; 66523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill num_frag--; 66623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill } while (num_frag >= 0); 66723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 66823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill return 0; 66923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill} 67023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 67192744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) 67292744989533cbe85e8057935d230e128810168ceGrant Likely{ 67392744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 67492744989533cbe85e8057935d230e128810168ceGrant Likely struct cdmac_bd *cur_p; 67592744989533cbe85e8057935d230e128810168ceGrant Likely dma_addr_t start_p, tail_p; 67692744989533cbe85e8057935d230e128810168ceGrant Likely int ii; 67792744989533cbe85e8057935d230e128810168ceGrant Likely unsigned long num_frag; 67892744989533cbe85e8057935d230e128810168ceGrant Likely skb_frag_t *frag; 67992744989533cbe85e8057935d230e128810168ceGrant Likely 68092744989533cbe85e8057935d230e128810168ceGrant Likely num_frag = skb_shinfo(skb)->nr_frags; 68192744989533cbe85e8057935d230e128810168ceGrant Likely frag = &skb_shinfo(skb)->frags[0]; 68292744989533cbe85e8057935d230e128810168ceGrant Likely start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; 68392744989533cbe85e8057935d230e128810168ceGrant Likely cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; 68492744989533cbe85e8057935d230e128810168ceGrant Likely 68523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill if (temac_check_tx_bd_space(lp, num_frag)) { 68692744989533cbe85e8057935d230e128810168ceGrant Likely if (!netif_queue_stopped(ndev)) { 68792744989533cbe85e8057935d230e128810168ceGrant Likely netif_stop_queue(ndev); 68892744989533cbe85e8057935d230e128810168ceGrant Likely return NETDEV_TX_BUSY; 68992744989533cbe85e8057935d230e128810168ceGrant Likely } 69092744989533cbe85e8057935d230e128810168ceGrant Likely return NETDEV_TX_BUSY; 69192744989533cbe85e8057935d230e128810168ceGrant Likely } 69292744989533cbe85e8057935d230e128810168ceGrant Likely 69392744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app0 = 0; 69492744989533cbe85e8057935d230e128810168ceGrant Likely if (skb->ip_summed == CHECKSUM_PARTIAL) { 6950d0b16727f24f8258eeb33818347ca0f4557f982Michał Mirosław unsigned int csum_start_off = skb_checksum_start_offset(skb); 69623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill unsigned int csum_index_off = csum_start_off + skb->csum_offset; 69723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 69823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app0 |= 1; /* TX Checksum Enabled */ 69923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app1 = (csum_start_off << 16) | csum_index_off; 70023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill cur_p->app2 = 0; /* initial checksum seed */ 70192744989533cbe85e8057935d230e128810168ceGrant Likely } 70223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 70392744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app0 |= STS_CTRL_APP0_SOP; 70492744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->len = skb_headlen(skb); 70592744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, 70692744989533cbe85e8057935d230e128810168ceGrant Likely DMA_TO_DEVICE); 70792744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app4 = (unsigned long)skb; 70892744989533cbe85e8057935d230e128810168ceGrant Likely 70992744989533cbe85e8057935d230e128810168ceGrant Likely for (ii = 0; ii < num_frag; ii++) { 71092744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_tail++; 71192744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->tx_bd_tail >= TX_BD_NUM) 71292744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_tail = 0; 71392744989533cbe85e8057935d230e128810168ceGrant Likely 71492744989533cbe85e8057935d230e128810168ceGrant Likely cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; 71592744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->phys = dma_map_single(ndev->dev.parent, 7163ed6f6958c0ac21958285d8648f14d34da4bbcb3Ian Campbell skb_frag_address(frag), 7172edcd4ca43df3c1d1d392753531cc73a53e709baStephen Rothwell skb_frag_size(frag), DMA_TO_DEVICE); 7182edcd4ca43df3c1d1d392753531cc73a53e709baStephen Rothwell cur_p->len = skb_frag_size(frag); 71992744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app0 = 0; 72092744989533cbe85e8057935d230e128810168ceGrant Likely frag++; 72192744989533cbe85e8057935d230e128810168ceGrant Likely } 72292744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app0 |= STS_CTRL_APP0_EOP; 72392744989533cbe85e8057935d230e128810168ceGrant Likely 72492744989533cbe85e8057935d230e128810168ceGrant Likely tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; 72592744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_tail++; 72692744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->tx_bd_tail >= TX_BD_NUM) 72792744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_bd_tail = 0; 72892744989533cbe85e8057935d230e128810168ceGrant Likely 72993e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran skb_tx_timestamp(skb); 73093e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran 73192744989533cbe85e8057935d230e128810168ceGrant Likely /* Kick off the transfer */ 732e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ 73392744989533cbe85e8057935d230e128810168ceGrant Likely 7346ed106549d17474ca17a16057f4c0ed4eba5a7caPatrick McHardy return NETDEV_TX_OK; 73592744989533cbe85e8057935d230e128810168ceGrant Likely} 73692744989533cbe85e8057935d230e128810168ceGrant Likely 73792744989533cbe85e8057935d230e128810168ceGrant Likely 73892744989533cbe85e8057935d230e128810168ceGrant Likelystatic void ll_temac_recv(struct net_device *ndev) 73992744989533cbe85e8057935d230e128810168ceGrant Likely{ 74092744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 74192744989533cbe85e8057935d230e128810168ceGrant Likely struct sk_buff *skb, *new_skb; 74292744989533cbe85e8057935d230e128810168ceGrant Likely unsigned int bdstat; 74392744989533cbe85e8057935d230e128810168ceGrant Likely struct cdmac_bd *cur_p; 74492744989533cbe85e8057935d230e128810168ceGrant Likely dma_addr_t tail_p; 74592744989533cbe85e8057935d230e128810168ceGrant Likely int length; 74692744989533cbe85e8057935d230e128810168ceGrant Likely unsigned long flags; 74792744989533cbe85e8057935d230e128810168ceGrant Likely 74892744989533cbe85e8057935d230e128810168ceGrant Likely spin_lock_irqsave(&lp->rx_lock, flags); 74992744989533cbe85e8057935d230e128810168ceGrant Likely 75092744989533cbe85e8057935d230e128810168ceGrant Likely tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; 75192744989533cbe85e8057935d230e128810168ceGrant Likely cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; 75292744989533cbe85e8057935d230e128810168ceGrant Likely 75392744989533cbe85e8057935d230e128810168ceGrant Likely bdstat = cur_p->app0; 75492744989533cbe85e8057935d230e128810168ceGrant Likely while ((bdstat & STS_CTRL_APP0_CMPLT)) { 75592744989533cbe85e8057935d230e128810168ceGrant Likely 75692744989533cbe85e8057935d230e128810168ceGrant Likely skb = lp->rx_skb[lp->rx_bd_ci]; 757c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani length = cur_p->app4 & 0x3FFF; 75892744989533cbe85e8057935d230e128810168ceGrant Likely 75933646d7ff5f47225cbbf3a06597ded649bf34e8dJohn Linn dma_unmap_single(ndev->dev.parent, cur_p->phys, length, 76092744989533cbe85e8057935d230e128810168ceGrant Likely DMA_FROM_DEVICE); 76192744989533cbe85e8057935d230e128810168ceGrant Likely 76292744989533cbe85e8057935d230e128810168ceGrant Likely skb_put(skb, length); 76392744989533cbe85e8057935d230e128810168ceGrant Likely skb->protocol = eth_type_trans(skb, ndev); 764bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet skb_checksum_none_assert(skb); 76592744989533cbe85e8057935d230e128810168ceGrant Likely 76623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill /* if we're doing rx csum offload, set it up */ 76723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && 76823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill (skb->protocol == __constant_htons(ETH_P_IP)) && 76923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill (skb->len > 64)) { 77023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 77123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill skb->csum = cur_p->app3 & 0xFFFF; 77223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill skb->ip_summed = CHECKSUM_COMPLETE; 77323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill } 77423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 77593e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran if (!skb_defer_rx_timestamp(skb)) 77693e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran netif_rx(skb); 77792744989533cbe85e8057935d230e128810168ceGrant Likely 77892744989533cbe85e8057935d230e128810168ceGrant Likely ndev->stats.rx_packets++; 77992744989533cbe85e8057935d230e128810168ceGrant Likely ndev->stats.rx_bytes += length; 78092744989533cbe85e8057935d230e128810168ceGrant Likely 781e44171f115de3dedf34064646206deb91549865fJohn Linn new_skb = netdev_alloc_skb_ip_align(ndev, 782e44171f115de3dedf34064646206deb91549865fJohn Linn XTE_MAX_JUMBO_FRAME_SIZE); 783720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches if (!new_skb) { 78492744989533cbe85e8057935d230e128810168ceGrant Likely spin_unlock_irqrestore(&lp->rx_lock, flags); 78592744989533cbe85e8057935d230e128810168ceGrant Likely return; 78692744989533cbe85e8057935d230e128810168ceGrant Likely } 78792744989533cbe85e8057935d230e128810168ceGrant Likely 78892744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->app0 = STS_CTRL_APP0_IRQONEND; 78992744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, 79092744989533cbe85e8057935d230e128810168ceGrant Likely XTE_MAX_JUMBO_FRAME_SIZE, 79192744989533cbe85e8057935d230e128810168ceGrant Likely DMA_FROM_DEVICE); 79292744989533cbe85e8057935d230e128810168ceGrant Likely cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE; 79392744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_skb[lp->rx_bd_ci] = new_skb; 79492744989533cbe85e8057935d230e128810168ceGrant Likely 79592744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_ci++; 79692744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->rx_bd_ci >= RX_BD_NUM) 79792744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_bd_ci = 0; 79892744989533cbe85e8057935d230e128810168ceGrant Likely 79992744989533cbe85e8057935d230e128810168ceGrant Likely cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; 80092744989533cbe85e8057935d230e128810168ceGrant Likely bdstat = cur_p->app0; 80192744989533cbe85e8057935d230e128810168ceGrant Likely } 802e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); 80392744989533cbe85e8057935d230e128810168ceGrant Likely 80492744989533cbe85e8057935d230e128810168ceGrant Likely spin_unlock_irqrestore(&lp->rx_lock, flags); 80592744989533cbe85e8057935d230e128810168ceGrant Likely} 80692744989533cbe85e8057935d230e128810168ceGrant Likely 80792744989533cbe85e8057935d230e128810168ceGrant Likelystatic irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) 80892744989533cbe85e8057935d230e128810168ceGrant Likely{ 80992744989533cbe85e8057935d230e128810168ceGrant Likely struct net_device *ndev = _ndev; 81092744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 81192744989533cbe85e8057935d230e128810168ceGrant Likely unsigned int status; 81292744989533cbe85e8057935d230e128810168ceGrant Likely 813e44171f115de3dedf34064646206deb91549865fJohn Linn status = lp->dma_in(lp, TX_IRQ_REG); 814e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, TX_IRQ_REG, status); 81592744989533cbe85e8057935d230e128810168ceGrant Likely 81692744989533cbe85e8057935d230e128810168ceGrant Likely if (status & (IRQ_COAL | IRQ_DLY)) 81792744989533cbe85e8057935d230e128810168ceGrant Likely temac_start_xmit_done(lp->ndev); 81892744989533cbe85e8057935d230e128810168ceGrant Likely if (status & 0x080) 81992744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&ndev->dev, "DMA error 0x%x\n", status); 82092744989533cbe85e8057935d230e128810168ceGrant Likely 82192744989533cbe85e8057935d230e128810168ceGrant Likely return IRQ_HANDLED; 82292744989533cbe85e8057935d230e128810168ceGrant Likely} 82392744989533cbe85e8057935d230e128810168ceGrant Likely 82492744989533cbe85e8057935d230e128810168ceGrant Likelystatic irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) 82592744989533cbe85e8057935d230e128810168ceGrant Likely{ 82692744989533cbe85e8057935d230e128810168ceGrant Likely struct net_device *ndev = _ndev; 82792744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 82892744989533cbe85e8057935d230e128810168ceGrant Likely unsigned int status; 82992744989533cbe85e8057935d230e128810168ceGrant Likely 83092744989533cbe85e8057935d230e128810168ceGrant Likely /* Read and clear the status registers */ 831e44171f115de3dedf34064646206deb91549865fJohn Linn status = lp->dma_in(lp, RX_IRQ_REG); 832e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out(lp, RX_IRQ_REG, status); 83392744989533cbe85e8057935d230e128810168ceGrant Likely 83492744989533cbe85e8057935d230e128810168ceGrant Likely if (status & (IRQ_COAL | IRQ_DLY)) 83592744989533cbe85e8057935d230e128810168ceGrant Likely ll_temac_recv(lp->ndev); 83692744989533cbe85e8057935d230e128810168ceGrant Likely 83792744989533cbe85e8057935d230e128810168ceGrant Likely return IRQ_HANDLED; 83892744989533cbe85e8057935d230e128810168ceGrant Likely} 83992744989533cbe85e8057935d230e128810168ceGrant Likely 84092744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_open(struct net_device *ndev) 84192744989533cbe85e8057935d230e128810168ceGrant Likely{ 84292744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 84392744989533cbe85e8057935d230e128810168ceGrant Likely int rc; 84492744989533cbe85e8057935d230e128810168ceGrant Likely 84592744989533cbe85e8057935d230e128810168ceGrant Likely dev_dbg(&ndev->dev, "temac_open()\n"); 84692744989533cbe85e8057935d230e128810168ceGrant Likely 84792744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->phy_node) { 84892744989533cbe85e8057935d230e128810168ceGrant Likely lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, 84992744989533cbe85e8057935d230e128810168ceGrant Likely temac_adjust_link, 0, 0); 85092744989533cbe85e8057935d230e128810168ceGrant Likely if (!lp->phy_dev) { 85192744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(lp->dev, "of_phy_connect() failed\n"); 85292744989533cbe85e8057935d230e128810168ceGrant Likely return -ENODEV; 85392744989533cbe85e8057935d230e128810168ceGrant Likely } 85492744989533cbe85e8057935d230e128810168ceGrant Likely 85592744989533cbe85e8057935d230e128810168ceGrant Likely phy_start(lp->phy_dev); 85692744989533cbe85e8057935d230e128810168ceGrant Likely } 85792744989533cbe85e8057935d230e128810168ceGrant Likely 85850ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda temac_device_reset(ndev); 85950ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda 86092744989533cbe85e8057935d230e128810168ceGrant Likely rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); 86192744989533cbe85e8057935d230e128810168ceGrant Likely if (rc) 86292744989533cbe85e8057935d230e128810168ceGrant Likely goto err_tx_irq; 86392744989533cbe85e8057935d230e128810168ceGrant Likely rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev); 86492744989533cbe85e8057935d230e128810168ceGrant Likely if (rc) 86592744989533cbe85e8057935d230e128810168ceGrant Likely goto err_rx_irq; 86692744989533cbe85e8057935d230e128810168ceGrant Likely 86792744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 86892744989533cbe85e8057935d230e128810168ceGrant Likely 86992744989533cbe85e8057935d230e128810168ceGrant Likely err_rx_irq: 87092744989533cbe85e8057935d230e128810168ceGrant Likely free_irq(lp->tx_irq, ndev); 87192744989533cbe85e8057935d230e128810168ceGrant Likely err_tx_irq: 87292744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->phy_dev) 87392744989533cbe85e8057935d230e128810168ceGrant Likely phy_disconnect(lp->phy_dev); 87492744989533cbe85e8057935d230e128810168ceGrant Likely lp->phy_dev = NULL; 87592744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(lp->dev, "request_irq() failed\n"); 87692744989533cbe85e8057935d230e128810168ceGrant Likely return rc; 87792744989533cbe85e8057935d230e128810168ceGrant Likely} 87892744989533cbe85e8057935d230e128810168ceGrant Likely 87992744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_stop(struct net_device *ndev) 88092744989533cbe85e8057935d230e128810168ceGrant Likely{ 88192744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 88292744989533cbe85e8057935d230e128810168ceGrant Likely 88392744989533cbe85e8057935d230e128810168ceGrant Likely dev_dbg(&ndev->dev, "temac_close()\n"); 88492744989533cbe85e8057935d230e128810168ceGrant Likely 88592744989533cbe85e8057935d230e128810168ceGrant Likely free_irq(lp->tx_irq, ndev); 88692744989533cbe85e8057935d230e128810168ceGrant Likely free_irq(lp->rx_irq, ndev); 88792744989533cbe85e8057935d230e128810168ceGrant Likely 88892744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->phy_dev) 88992744989533cbe85e8057935d230e128810168ceGrant Likely phy_disconnect(lp->phy_dev); 89092744989533cbe85e8057935d230e128810168ceGrant Likely lp->phy_dev = NULL; 89192744989533cbe85e8057935d230e128810168ceGrant Likely 892301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov temac_dma_bd_release(ndev); 893301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov 89492744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 89592744989533cbe85e8057935d230e128810168ceGrant Likely} 89692744989533cbe85e8057935d230e128810168ceGrant Likely 89792744989533cbe85e8057935d230e128810168ceGrant Likely#ifdef CONFIG_NET_POLL_CONTROLLER 89892744989533cbe85e8057935d230e128810168ceGrant Likelystatic void 89992744989533cbe85e8057935d230e128810168ceGrant Likelytemac_poll_controller(struct net_device *ndev) 90092744989533cbe85e8057935d230e128810168ceGrant Likely{ 90192744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 90292744989533cbe85e8057935d230e128810168ceGrant Likely 90392744989533cbe85e8057935d230e128810168ceGrant Likely disable_irq(lp->tx_irq); 90492744989533cbe85e8057935d230e128810168ceGrant Likely disable_irq(lp->rx_irq); 90592744989533cbe85e8057935d230e128810168ceGrant Likely 9068539992f6091eb8206c781421312157d0c282e6eMichal Simek ll_temac_rx_irq(lp->tx_irq, ndev); 9078539992f6091eb8206c781421312157d0c282e6eMichal Simek ll_temac_tx_irq(lp->rx_irq, ndev); 90892744989533cbe85e8057935d230e128810168ceGrant Likely 90992744989533cbe85e8057935d230e128810168ceGrant Likely enable_irq(lp->tx_irq); 91092744989533cbe85e8057935d230e128810168ceGrant Likely enable_irq(lp->rx_irq); 91192744989533cbe85e8057935d230e128810168ceGrant Likely} 91292744989533cbe85e8057935d230e128810168ceGrant Likely#endif 91392744989533cbe85e8057935d230e128810168ceGrant Likely 9148d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribaldastatic int temac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) 9158d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda{ 9168d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda struct temac_local *lp = netdev_priv(ndev); 9178d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda 9188d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda if (!netif_running(ndev)) 9198d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda return -EINVAL; 9208d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda 9218d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda if (!lp->phy_dev) 9228d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda return -EINVAL; 9238d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda 9248d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda return phy_mii_ioctl(lp->phy_dev, rq, cmd); 9258d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda} 9268d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda 92792744989533cbe85e8057935d230e128810168ceGrant Likelystatic const struct net_device_ops temac_netdev_ops = { 92892744989533cbe85e8057935d230e128810168ceGrant Likely .ndo_open = temac_open, 92992744989533cbe85e8057935d230e128810168ceGrant Likely .ndo_stop = temac_stop, 93092744989533cbe85e8057935d230e128810168ceGrant Likely .ndo_start_xmit = temac_start_xmit, 93104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko .ndo_set_mac_address = temac_set_mac_address, 93260eb5fd11d1c6050c45a5aab141f42dd396e2a7fDenis Kirjanov .ndo_validate_addr = eth_validate_addr, 9338d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda .ndo_do_ioctl = temac_ioctl, 93492744989533cbe85e8057935d230e128810168ceGrant Likely#ifdef CONFIG_NET_POLL_CONTROLLER 93592744989533cbe85e8057935d230e128810168ceGrant Likely .ndo_poll_controller = temac_poll_controller, 93692744989533cbe85e8057935d230e128810168ceGrant Likely#endif 93792744989533cbe85e8057935d230e128810168ceGrant Likely}; 93892744989533cbe85e8057935d230e128810168ceGrant Likely 93992744989533cbe85e8057935d230e128810168ceGrant Likely/* --------------------------------------------------------------------- 94092744989533cbe85e8057935d230e128810168ceGrant Likely * SYSFS device attributes 94192744989533cbe85e8057935d230e128810168ceGrant Likely */ 94292744989533cbe85e8057935d230e128810168ceGrant Likelystatic ssize_t temac_show_llink_regs(struct device *dev, 94392744989533cbe85e8057935d230e128810168ceGrant Likely struct device_attribute *attr, char *buf) 94492744989533cbe85e8057935d230e128810168ceGrant Likely{ 94592744989533cbe85e8057935d230e128810168ceGrant Likely struct net_device *ndev = dev_get_drvdata(dev); 94692744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 94792744989533cbe85e8057935d230e128810168ceGrant Likely int i, len = 0; 94892744989533cbe85e8057935d230e128810168ceGrant Likely 94992744989533cbe85e8057935d230e128810168ceGrant Likely for (i = 0; i < 0x11; i++) 950e44171f115de3dedf34064646206deb91549865fJohn Linn len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i), 95192744989533cbe85e8057935d230e128810168ceGrant Likely (i % 8) == 7 ? "\n" : " "); 95292744989533cbe85e8057935d230e128810168ceGrant Likely len += sprintf(buf + len, "\n"); 95392744989533cbe85e8057935d230e128810168ceGrant Likely 95492744989533cbe85e8057935d230e128810168ceGrant Likely return len; 95592744989533cbe85e8057935d230e128810168ceGrant Likely} 95692744989533cbe85e8057935d230e128810168ceGrant Likely 95792744989533cbe85e8057935d230e128810168ceGrant Likelystatic DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL); 95892744989533cbe85e8057935d230e128810168ceGrant Likely 95992744989533cbe85e8057935d230e128810168ceGrant Likelystatic struct attribute *temac_device_attrs[] = { 96092744989533cbe85e8057935d230e128810168ceGrant Likely &dev_attr_llink_regs.attr, 96192744989533cbe85e8057935d230e128810168ceGrant Likely NULL, 96292744989533cbe85e8057935d230e128810168ceGrant Likely}; 96392744989533cbe85e8057935d230e128810168ceGrant Likely 96492744989533cbe85e8057935d230e128810168ceGrant Likelystatic const struct attribute_group temac_attr_group = { 96592744989533cbe85e8057935d230e128810168ceGrant Likely .attrs = temac_device_attrs, 96692744989533cbe85e8057935d230e128810168ceGrant Likely}; 96792744989533cbe85e8057935d230e128810168ceGrant Likely 9689eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo/* ethtool support */ 9699eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 9709eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{ 9719eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo struct temac_local *lp = netdev_priv(ndev); 9729eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo return phy_ethtool_gset(lp->phy_dev, cmd); 9739eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo} 9749eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo 9759eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) 9769eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{ 9779eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo struct temac_local *lp = netdev_priv(ndev); 9789eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo return phy_ethtool_sset(lp->phy_dev, cmd); 9799eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo} 9809eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo 9819eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_nway_reset(struct net_device *ndev) 9829eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{ 9839eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo struct temac_local *lp = netdev_priv(ndev); 9849eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo return phy_start_aneg(lp->phy_dev); 9859eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo} 9869eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo 9879eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic const struct ethtool_ops temac_ethtool_ops = { 9889eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo .get_settings = temac_get_settings, 9899eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo .set_settings = temac_set_settings, 9909eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo .nway_reset = temac_nway_reset, 9919eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo .get_link = ethtool_op_get_link, 992f85e5ea28f5c1d31b22ae5777a1a08ebd76ff7e1Richard Cochran .get_ts_info = ethtool_op_get_ts_info, 9939eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}; 9949eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo 99506b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic int temac_of_probe(struct platform_device *op) 99692744989533cbe85e8057935d230e128810168ceGrant Likely{ 99792744989533cbe85e8057935d230e128810168ceGrant Likely struct device_node *np; 99892744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp; 99992744989533cbe85e8057935d230e128810168ceGrant Likely struct net_device *ndev; 100092744989533cbe85e8057935d230e128810168ceGrant Likely const void *addr; 100123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill __be32 *p; 100292744989533cbe85e8057935d230e128810168ceGrant Likely int size, rc = 0; 100392744989533cbe85e8057935d230e128810168ceGrant Likely 100492744989533cbe85e8057935d230e128810168ceGrant Likely /* Init network device structure */ 100592744989533cbe85e8057935d230e128810168ceGrant Likely ndev = alloc_etherdev(sizeof(*lp)); 100641de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1Joe Perches if (!ndev) 100792744989533cbe85e8057935d230e128810168ceGrant Likely return -ENOMEM; 100841de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1Joe Perches 100992744989533cbe85e8057935d230e128810168ceGrant Likely ether_setup(ndev); 10108513fbd880093f00a47e85a552f14ca2de8d84d6Jingoo Han platform_set_drvdata(op, ndev); 101192744989533cbe85e8057935d230e128810168ceGrant Likely SET_NETDEV_DEV(ndev, &op->dev); 101292744989533cbe85e8057935d230e128810168ceGrant Likely ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ 101392744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; 101492744989533cbe85e8057935d230e128810168ceGrant Likely ndev->netdev_ops = &temac_netdev_ops; 10159eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo ndev->ethtool_ops = &temac_ethtool_ops; 101692744989533cbe85e8057935d230e128810168ceGrant Likely#if 0 101792744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */ 101892744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */ 101992744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */ 102092744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */ 1021f646968f8f7c624587de729115d802372b9063ddPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_TX; /* Transmit VLAN hw accel */ 1022f646968f8f7c624587de729115d802372b9063ddPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; /* Receive VLAN hw acceleration */ 1023f646968f8f7c624587de729115d802372b9063ddPatrick McHardy ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; /* Receive VLAN filtering */ 102492744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */ 102592744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_GSO; /* Enable software GSO. */ 102692744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */ 102792744989533cbe85e8057935d230e128810168ceGrant Likely ndev->features |= NETIF_F_LRO; /* large receive offload */ 102892744989533cbe85e8057935d230e128810168ceGrant Likely#endif 102992744989533cbe85e8057935d230e128810168ceGrant Likely 103092744989533cbe85e8057935d230e128810168ceGrant Likely /* setup temac private info structure */ 103192744989533cbe85e8057935d230e128810168ceGrant Likely lp = netdev_priv(ndev); 103292744989533cbe85e8057935d230e128810168ceGrant Likely lp->ndev = ndev; 103392744989533cbe85e8057935d230e128810168ceGrant Likely lp->dev = &op->dev; 103492744989533cbe85e8057935d230e128810168ceGrant Likely lp->options = XTE_OPTION_DEFAULTS; 103592744989533cbe85e8057935d230e128810168ceGrant Likely spin_lock_init(&lp->rx_lock); 103692744989533cbe85e8057935d230e128810168ceGrant Likely mutex_init(&lp->indirect_mutex); 103792744989533cbe85e8057935d230e128810168ceGrant Likely 103892744989533cbe85e8057935d230e128810168ceGrant Likely /* map device registers */ 103961c7a080a5a061c976988fd4b844dfb468dda255Grant Likely lp->regs = of_iomap(op->dev.of_node, 0); 104092744989533cbe85e8057935d230e128810168ceGrant Likely if (!lp->regs) { 104192744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&op->dev, "could not map temac regs.\n"); 104292744989533cbe85e8057935d230e128810168ceGrant Likely goto nodev; 104392744989533cbe85e8057935d230e128810168ceGrant Likely } 104492744989533cbe85e8057935d230e128810168ceGrant Likely 104523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill /* Setup checksum offload, but default to off if not specified */ 104623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill lp->temac_features = 0; 104723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); 104823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill if (p && be32_to_cpu(*p)) { 104923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill lp->temac_features |= TEMAC_FEATURE_TX_CSUM; 105023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill /* Can checksum TCP/UDP over IPv4. */ 105123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill ndev->features |= NETIF_F_IP_CSUM; 105223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill } 105323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); 105423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill if (p && be32_to_cpu(*p)) 105523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill lp->temac_features |= TEMAC_FEATURE_RX_CSUM; 105623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill 105792744989533cbe85e8057935d230e128810168ceGrant Likely /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ 105861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); 105992744989533cbe85e8057935d230e128810168ceGrant Likely if (!np) { 106092744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&op->dev, "could not find DMA node\n"); 1061dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov goto err_iounmap; 106292744989533cbe85e8057935d230e128810168ceGrant Likely } 106392744989533cbe85e8057935d230e128810168ceGrant Likely 1064e44171f115de3dedf34064646206deb91549865fJohn Linn /* Setup the DMA register accesses, could be DCR or memory mapped */ 1065e44171f115de3dedf34064646206deb91549865fJohn Linn if (temac_dcr_setup(lp, op, np)) { 1066e44171f115de3dedf34064646206deb91549865fJohn Linn 1067e44171f115de3dedf34064646206deb91549865fJohn Linn /* no DCR in the device tree, try non-DCR */ 1068e44171f115de3dedf34064646206deb91549865fJohn Linn lp->sdma_regs = of_iomap(np, 0); 1069e44171f115de3dedf34064646206deb91549865fJohn Linn if (lp->sdma_regs) { 1070e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_in = temac_dma_in32; 1071e44171f115de3dedf34064646206deb91549865fJohn Linn lp->dma_out = temac_dma_out32; 1072e44171f115de3dedf34064646206deb91549865fJohn Linn dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs); 1073e44171f115de3dedf34064646206deb91549865fJohn Linn } else { 1074e44171f115de3dedf34064646206deb91549865fJohn Linn dev_err(&op->dev, "unable to map DMA registers\n"); 10757cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy of_node_put(np); 1076dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov goto err_iounmap; 1077e44171f115de3dedf34064646206deb91549865fJohn Linn } 107892744989533cbe85e8057935d230e128810168ceGrant Likely } 107992744989533cbe85e8057935d230e128810168ceGrant Likely 108092744989533cbe85e8057935d230e128810168ceGrant Likely lp->rx_irq = irq_of_parse_and_map(np, 0); 108192744989533cbe85e8057935d230e128810168ceGrant Likely lp->tx_irq = irq_of_parse_and_map(np, 1); 10827cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy 10837cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy of_node_put(np); /* Finished with the DMA node; drop the reference */ 10847cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy 10854e68ea26e76273cc62a981a414a8319a7f4c1077Michal Simek if (!lp->rx_irq || !lp->tx_irq) { 108692744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&op->dev, "could not determine irqs\n"); 108792744989533cbe85e8057935d230e128810168ceGrant Likely rc = -ENOMEM; 1088dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov goto err_iounmap_2; 108992744989533cbe85e8057935d230e128810168ceGrant Likely } 109092744989533cbe85e8057935d230e128810168ceGrant Likely 109192744989533cbe85e8057935d230e128810168ceGrant Likely 109292744989533cbe85e8057935d230e128810168ceGrant Likely /* Retrieve the MAC address */ 109361c7a080a5a061c976988fd4b844dfb468dda255Grant Likely addr = of_get_property(op->dev.of_node, "local-mac-address", &size); 109492744989533cbe85e8057935d230e128810168ceGrant Likely if ((!addr) || (size != 6)) { 109592744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(&op->dev, "could not find MAC address\n"); 109692744989533cbe85e8057935d230e128810168ceGrant Likely rc = -ENODEV; 1097dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov goto err_iounmap_2; 109892744989533cbe85e8057935d230e128810168ceGrant Likely } 109904e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko temac_init_mac_address(ndev, (void *)addr); 110092744989533cbe85e8057935d230e128810168ceGrant Likely 110161c7a080a5a061c976988fd4b844dfb468dda255Grant Likely rc = temac_mdio_setup(lp, op->dev.of_node); 110292744989533cbe85e8057935d230e128810168ceGrant Likely if (rc) 110392744989533cbe85e8057935d230e128810168ceGrant Likely dev_warn(&op->dev, "error registering MDIO bus\n"); 110492744989533cbe85e8057935d230e128810168ceGrant Likely 110561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); 110692744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->phy_node) 110792744989533cbe85e8057935d230e128810168ceGrant Likely dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); 110892744989533cbe85e8057935d230e128810168ceGrant Likely 110992744989533cbe85e8057935d230e128810168ceGrant Likely /* Add the device attributes */ 111092744989533cbe85e8057935d230e128810168ceGrant Likely rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group); 111192744989533cbe85e8057935d230e128810168ceGrant Likely if (rc) { 111292744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(lp->dev, "Error creating sysfs files\n"); 1113dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov goto err_iounmap_2; 111492744989533cbe85e8057935d230e128810168ceGrant Likely } 111592744989533cbe85e8057935d230e128810168ceGrant Likely 111692744989533cbe85e8057935d230e128810168ceGrant Likely rc = register_netdev(lp->ndev); 111792744989533cbe85e8057935d230e128810168ceGrant Likely if (rc) { 111892744989533cbe85e8057935d230e128810168ceGrant Likely dev_err(lp->dev, "register_netdev() error (%i)\n", rc); 111992744989533cbe85e8057935d230e128810168ceGrant Likely goto err_register_ndev; 112092744989533cbe85e8057935d230e128810168ceGrant Likely } 112192744989533cbe85e8057935d230e128810168ceGrant Likely 112292744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 112392744989533cbe85e8057935d230e128810168ceGrant Likely 112492744989533cbe85e8057935d230e128810168ceGrant Likely err_register_ndev: 112592744989533cbe85e8057935d230e128810168ceGrant Likely sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); 1126dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov err_iounmap_2: 1127dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov if (lp->sdma_regs) 1128dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov iounmap(lp->sdma_regs); 1129dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov err_iounmap: 1130dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov iounmap(lp->regs); 113192744989533cbe85e8057935d230e128810168ceGrant Likely nodev: 113292744989533cbe85e8057935d230e128810168ceGrant Likely free_netdev(ndev); 113392744989533cbe85e8057935d230e128810168ceGrant Likely ndev = NULL; 113492744989533cbe85e8057935d230e128810168ceGrant Likely return rc; 113592744989533cbe85e8057935d230e128810168ceGrant Likely} 113692744989533cbe85e8057935d230e128810168ceGrant Likely 113706b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic int temac_of_remove(struct platform_device *op) 113892744989533cbe85e8057935d230e128810168ceGrant Likely{ 11398513fbd880093f00a47e85a552f14ca2de8d84d6Jingoo Han struct net_device *ndev = platform_get_drvdata(op); 114092744989533cbe85e8057935d230e128810168ceGrant Likely struct temac_local *lp = netdev_priv(ndev); 114192744989533cbe85e8057935d230e128810168ceGrant Likely 114292744989533cbe85e8057935d230e128810168ceGrant Likely temac_mdio_teardown(lp); 114392744989533cbe85e8057935d230e128810168ceGrant Likely unregister_netdev(ndev); 114492744989533cbe85e8057935d230e128810168ceGrant Likely sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); 114592744989533cbe85e8057935d230e128810168ceGrant Likely if (lp->phy_node) 114692744989533cbe85e8057935d230e128810168ceGrant Likely of_node_put(lp->phy_node); 114792744989533cbe85e8057935d230e128810168ceGrant Likely lp->phy_node = NULL; 1148dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov iounmap(lp->regs); 1149dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov if (lp->sdma_regs) 1150dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov iounmap(lp->sdma_regs); 115192744989533cbe85e8057935d230e128810168ceGrant Likely free_netdev(ndev); 115292744989533cbe85e8057935d230e128810168ceGrant Likely return 0; 115392744989533cbe85e8057935d230e128810168ceGrant Likely} 115492744989533cbe85e8057935d230e128810168ceGrant Likely 115506b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic struct of_device_id temac_of_match[] = { 115692744989533cbe85e8057935d230e128810168ceGrant Likely { .compatible = "xlnx,xps-ll-temac-1.01.b", }, 1157c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani { .compatible = "xlnx,xps-ll-temac-2.00.a", }, 1158c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani { .compatible = "xlnx,xps-ll-temac-2.02.a", }, 1159c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani { .compatible = "xlnx,xps-ll-temac-2.03.a", }, 116092744989533cbe85e8057935d230e128810168ceGrant Likely {}, 116192744989533cbe85e8057935d230e128810168ceGrant Likely}; 116292744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_DEVICE_TABLE(of, temac_of_match); 116392744989533cbe85e8057935d230e128810168ceGrant Likely 116474888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic struct platform_driver temac_of_driver = { 116592744989533cbe85e8057935d230e128810168ceGrant Likely .probe = temac_of_probe, 116606b0e68327d499c3588c954d2a2d86458d451c4bBill Pemberton .remove = temac_of_remove, 116792744989533cbe85e8057935d230e128810168ceGrant Likely .driver = { 116892744989533cbe85e8057935d230e128810168ceGrant Likely .owner = THIS_MODULE, 116992744989533cbe85e8057935d230e128810168ceGrant Likely .name = "xilinx_temac", 11704018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = temac_of_match, 117192744989533cbe85e8057935d230e128810168ceGrant Likely }, 117292744989533cbe85e8057935d230e128810168ceGrant Likely}; 117392744989533cbe85e8057935d230e128810168ceGrant Likely 1174db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(temac_of_driver); 117592744989533cbe85e8057935d230e128810168ceGrant Likely 117692744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver"); 117792744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_AUTHOR("Yoshio Kashiwagi"); 117892744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_LICENSE("GPL"); 1179