1d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo/* 2d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC. 3d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * 40f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom * 2005-2010 (c) Aeroflex Gaisler AB 5d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * 6d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs 7d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * available in the GRLIB VHDL IP core library. 8d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * 9d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * Full documentation of both cores can be found here: 10d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * http://www.gaisler.com/products/grlib/grip.pdf 11d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * 12d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * The Gigabit version supports scatter/gather DMA, any alignment of 13d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * buffers and checksum offloading. 14d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * 15d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * This program is free software; you can redistribute it and/or modify it 16d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * under the terms of the GNU General Public License as published by the 17d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * Free Software Foundation; either version 2 of the License, or (at your 18d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * option) any later version. 19d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * 20d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * Contributors: Kristoffer Glembo 21d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * Daniel Hellstrom 22d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * Marko Isomaki 23d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo */ 24d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 25b7f080cfe223b3b7424872639d153695615a9255Alexey Dobriyan#include <linux/dma-mapping.h> 26d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/module.h> 27d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/uaccess.h> 28d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/init.h> 29a6b7a407865aab9f849dd99a71072b7cd1175116Alexey Dobriyan#include <linux/interrupt.h> 30d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/netdevice.h> 31d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/etherdevice.h> 32d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/ethtool.h> 33d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/skbuff.h> 34d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/io.h> 35d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/crc32.h> 36d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/mii.h> 37d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/of_device.h> 38d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <linux/of_platform.h> 395a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 40d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <asm/cacheflush.h> 41d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <asm/byteorder.h> 42d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 43d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#ifdef CONFIG_SPARC 44d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include <asm/idprom.h> 45d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#endif 46d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 47d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#include "greth.h" 48d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 49d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define GRETH_DEF_MSG_ENABLE \ 50d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo (NETIF_MSG_DRV | \ 51d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo NETIF_MSG_PROBE | \ 52d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo NETIF_MSG_LINK | \ 53d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo NETIF_MSG_IFDOWN | \ 54d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo NETIF_MSG_IFUP | \ 55d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo NETIF_MSG_RX_ERR | \ 56d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo NETIF_MSG_TX_ERR) 57d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 58d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_debug = -1; /* -1 == use GRETH_DEF_MSG_ENABLE as value */ 59d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembomodule_param(greth_debug, int, 0); 60d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_PARM_DESC(greth_debug, "GRETH bitmapped debugging message enable value"); 61d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 62d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo/* Accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */ 63d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int macaddr[6]; 64d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembomodule_param_array(macaddr, int, NULL, 0); 65d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_PARM_DESC(macaddr, "GRETH Ethernet MAC address"); 66d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 67d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_edcl = 1; 68d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembomodule_param(greth_edcl, int, 0); 69d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_PARM_DESC(greth_edcl, "GRETH EDCL usage indicator. Set to 1 if EDCL is used."); 70d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 71d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_open(struct net_device *dev); 7241a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comstatic netdev_tx_t greth_start_xmit(struct sk_buff *skb, 7341a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.com struct net_device *dev); 7441a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comstatic netdev_tx_t greth_start_xmit_gbit(struct sk_buff *skb, 7541a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.com struct net_device *dev); 76d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_rx(struct net_device *dev, int limit); 77d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_rx_gbit(struct net_device *dev, int limit); 78d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_tx(struct net_device *dev); 79d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_tx_gbit(struct net_device *dev); 80d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic irqreturn_t greth_interrupt(int irq, void *dev_id); 81d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_close(struct net_device *dev); 82d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_set_mac_add(struct net_device *dev, void *p); 83d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_multicast_list(struct net_device *dev); 84d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 85d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define GRETH_REGLOAD(a) (be32_to_cpu(__raw_readl(&(a)))) 86d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define GRETH_REGSAVE(a, v) (__raw_writel(cpu_to_be32(v), &(a))) 87d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define GRETH_REGORIN(a, v) (GRETH_REGSAVE(a, (GRETH_REGLOAD(a) | (v)))) 88d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define GRETH_REGANDIN(a, v) (GRETH_REGSAVE(a, (GRETH_REGLOAD(a) & (v)))) 89d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 90d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define NEXT_TX(N) (((N) + 1) & GRETH_TXBD_NUM_MASK) 91d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define SKIP_TX(N, C) (((N) + C) & GRETH_TXBD_NUM_MASK) 92d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#define NEXT_RX(N) (((N) + 1) & GRETH_RXBD_NUM_MASK) 93d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 94d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_print_rx_packet(void *addr, int len) 95d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 96d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo print_hex_dump(KERN_DEBUG, "RX: ", DUMP_PREFIX_OFFSET, 16, 1, 97d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo addr, len, true); 98d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 99d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 100d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_print_tx_packet(struct sk_buff *skb) 101d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 102d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 103d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int length; 104d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 105d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (skb_shinfo(skb)->nr_frags == 0) 106d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo length = skb->len; 107d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 108d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo length = skb_headlen(skb); 109d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 110d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo print_hex_dump(KERN_DEBUG, "TX: ", DUMP_PREFIX_OFFSET, 16, 1, 111d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->data, length, true); 112d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 113d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 114d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 115d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo print_hex_dump(KERN_DEBUG, "TX: ", DUMP_PREFIX_OFFSET, 16, 1, 116ab7e11d9d0293ef1802d6ae8aab39ce58472b167Ian Campbell skb_frag_address(&skb_shinfo(skb)->frags[i]), 117ab7e11d9d0293ef1802d6ae8aab39ce58472b167Ian Campbell skb_shinfo(skb)->frags[i].size, true); 118d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 119d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 120d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 121d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_enable_tx(struct greth_private *greth) 122d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 123d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 124d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(greth->regs->control, GRETH_TXEN); 125d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 126d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 127d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_disable_tx(struct greth_private *greth) 128d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 129d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN); 130d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 131d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 132d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_enable_rx(struct greth_private *greth) 133d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 134d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 135d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(greth->regs->control, GRETH_RXEN); 136d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 137d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 138d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_disable_rx(struct greth_private *greth) 139d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 140d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGANDIN(greth->regs->control, ~GRETH_RXEN); 141d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 142d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 143d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_enable_irqs(struct greth_private *greth) 144d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 145d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(greth->regs->control, GRETH_RXI | GRETH_TXI); 146d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 147d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 148d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_disable_irqs(struct greth_private *greth) 149d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 150d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGANDIN(greth->regs->control, ~(GRETH_RXI|GRETH_TXI)); 151d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 152d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 153d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_write_bd(u32 *bd, u32 val) 154d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 155d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo __raw_writel(cpu_to_be32(val), bd); 156d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 157d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 158d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline u32 greth_read_bd(u32 *bd) 159d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 160d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return be32_to_cpu(__raw_readl(bd)); 161d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 162d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 163d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_rings(struct greth_private *greth) 164d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 165d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 166d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *rx_bdp = greth->rx_bd_base; 167d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *tx_bdp = greth->tx_bd_base; 168d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 169d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 170d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 171d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Free and unmap RX buffers */ 172d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) { 173d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_skbuff[i] != NULL) { 174d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(greth->rx_skbuff[i]); 175d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 176d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&rx_bdp->addr), 177d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE+NET_IP_ALIGN, 178d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 179d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 180d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 181d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 182d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* TX buffers */ 183d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (greth->tx_free < GRETH_TXBD_NUM) { 184d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 185d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb = greth->tx_skbuff[greth->tx_last]; 186d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int nr_frags = skb_shinfo(skb)->nr_frags; 187d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tx_bdp = greth->tx_bd_base + greth->tx_last; 188d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 189d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 190d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 191d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&tx_bdp->addr), 192d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_headlen(skb), 193d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 194d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 195d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < nr_frags; i++) { 196d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 197d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tx_bdp = greth->tx_bd_base + greth->tx_last; 198d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 199d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_page(greth->dev, 200d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&tx_bdp->addr), 2019e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet skb_frag_size(frag), 202d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 203d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 204d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 205d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 206d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free += nr_frags+1; 207d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(skb); 208d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 209d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 210d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 211d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { /* 10/100 Mbps MAC */ 212d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 213d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) { 214d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo kfree(greth->rx_bufs[i]); 215d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 216d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&rx_bdp->addr), 217d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 218d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 219d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 220d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_TXBD_NUM; i++, tx_bdp++) { 221d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo kfree(greth->tx_bufs[i]); 222d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 223d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&tx_bdp->addr), 224d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 225d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 226d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 227d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 228d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 229d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 230d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_init_rings(struct greth_private *greth) 231d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 232d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb; 233d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *rx_bd, *tx_bd; 234d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 dma_addr; 235d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 236d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 237d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo rx_bd = greth->rx_bd_base; 238d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tx_bd = greth->tx_bd_base; 239d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 240d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Initialize descriptor rings and buffers */ 241d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 242d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 243d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++) { 244d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = netdev_alloc_skb(greth->netdev, MAX_FRAME_SIZE+NET_IP_ALIGN); 245d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (skb == NULL) { 246d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 247d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Error allocating DMA ring.\n"); 248d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 249d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 250d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_reserve(skb, NET_IP_ALIGN); 251d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 252d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->data, 253d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE+NET_IP_ALIGN, 254d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 255d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 256d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dma_mapping_error(greth->dev, dma_addr)) { 257d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 258d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Could not create initial DMA mapping\n"); 259d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 260d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 261d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_skbuff[i] = skb; 262d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].addr, dma_addr); 263d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE); 264d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 265d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 266d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 267d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 268d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* 10/100 MAC uses a fixed set of buffers and copy to/from SKBs */ 269d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++) { 270d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 271d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL); 272d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 273d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_bufs[i] == NULL) { 274d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 275d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Error allocating DMA ring.\n"); 276d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 277d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 278d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 279d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 280d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_bufs[i], 281d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 282d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 283d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 284d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dma_mapping_error(greth->dev, dma_addr)) { 285d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 286d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Could not create initial DMA mapping\n"); 287d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 288d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 289d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].addr, dma_addr); 290d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE); 291d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 292d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_TXBD_NUM; i++) { 293d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 294d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL); 295d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 296d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_bufs[i] == NULL) { 297d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 298d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Error allocating DMA ring.\n"); 299d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 300d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 301d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 302d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 303d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_bufs[i], 304d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 305d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 306d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 307d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dma_mapping_error(greth->dev, dma_addr)) { 308d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 309d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Could not create initial DMA mapping\n"); 310d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 311d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 312d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&tx_bd[i].addr, dma_addr); 313d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&tx_bd[i].stat, 0); 314d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 315d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 316d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat, 317d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat) | GRETH_BD_WR); 318d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 319d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Initialize pointers. */ 320d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_cur = 0; 321d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_next = 0; 322d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = 0; 323d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free = GRETH_TXBD_NUM; 324d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 325d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Initialize descriptor base address */ 326d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->tx_desc_p, greth->tx_bd_base_phys); 327d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->rx_desc_p, greth->rx_bd_base_phys); 328d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 329d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 330d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 331d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembocleanup: 332d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_clean_rings(greth); 333d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENOMEM; 334d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 335d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 336d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_open(struct net_device *dev) 337d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 338d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 339d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int err; 340d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 341d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = greth_init_rings(greth); 342d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (err) { 343d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 344d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "Could not allocate memory for DMA rings\n"); 345d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 346d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 347d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 348d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = request_irq(greth->irq, greth_interrupt, 0, "eth", (void *) dev); 349d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (err) { 350d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 351d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "Could not allocate interrupt %d\n", dev->irq); 352d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_clean_rings(greth); 353d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 354d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 355d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 356d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 357d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_dbg(&dev->dev, " starting queue\n"); 358d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_start_queue(dev); 359d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 360bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, 0xFF); 361bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom 362d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo napi_enable(&greth->napi); 363d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 364d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_irqs(greth); 365d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_tx(greth); 366d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_rx(greth); 367d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 368d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 369d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 370d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 371d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_close(struct net_device *dev) 372d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 373d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 374d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 375d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo napi_disable(&greth->napi); 376d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 377bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom greth_disable_irqs(greth); 378d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_disable_tx(greth); 379bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom greth_disable_rx(greth); 380d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 381d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_stop_queue(dev); 382d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 383d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo free_irq(greth->irq, (void *) dev); 384d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 385d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_clean_rings(greth); 386d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 387d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 388d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 389d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 39041a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comstatic netdev_tx_t 39141a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comgreth_start_xmit(struct sk_buff *skb, struct net_device *dev) 392d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 393d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 394d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 395d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int err = NETDEV_TX_OK; 3960f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom u32 status, dma_addr, ctrl; 3970f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 398d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 3990f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Clean TX Ring */ 4000f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx(greth->netdev); 401d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 402d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(greth->tx_free <= 0)) { 4030f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/ 4040f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control); 4050f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Enable TX IRQ only if not already in poll() routine */ 4060f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (ctrl & GRETH_RXI) 4070f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI); 408d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_stop_queue(dev); 4090f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 410d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return NETDEV_TX_BUSY; 411d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 412d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 413d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 414d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_tx_packet(skb); 415d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 416d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 417d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(skb->len > MAX_FRAME_SIZE)) { 418d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_errors++; 419d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto out; 420d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 421d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 4220f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom bdp = greth->tx_bd_base + greth->tx_next; 423d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = greth_read_bd(&bdp->addr); 424d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 425d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len); 426d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 427d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE); 428d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 4290f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN); 4306af29a963cecf426966d56935d60a984bd5594eaDaniel Hellstrom greth->tx_bufs_length[greth->tx_next] = skb->len & GRETH_BD_LEN; 431d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 432d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Wrap around descriptor ring */ 433d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_next == GRETH_TXBD_NUM_MASK) { 434d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 435d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 436d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 437d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_next = NEXT_TX(greth->tx_next); 438d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free--; 439d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 440d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Write descriptor control word and enable transmission */ 441d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 4420f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/ 443d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_tx(greth); 4440f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 445d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 446d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboout: 447d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(skb); 448d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 449d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 450d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 451d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 45241a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comstatic netdev_tx_t 45341a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comgreth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) 454d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 455d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 456d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 4570f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom u32 status = 0, dma_addr, ctrl; 458d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int curr_tx, nr_frags, i, err = NETDEV_TX_OK; 4590f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 460d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 461d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo nr_frags = skb_shinfo(skb)->nr_frags; 462d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 4630f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Clean TX Ring */ 4640f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx_gbit(dev); 4650f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 466d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_free < nr_frags + 1) { 4670f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/ 4680f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control); 4690f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Enable TX IRQ only if not already in poll() routine */ 4700f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (ctrl & GRETH_RXI) 4710f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI); 472d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_stop_queue(dev); 4730f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 474d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = NETDEV_TX_BUSY; 475d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto out; 476d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 477d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 478d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 479d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_tx_packet(skb); 480d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 481d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(skb->len > MAX_FRAME_SIZE)) { 482d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_errors++; 483d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto out; 484d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 485d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 486d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Save skb pointer. */ 487d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_skbuff[greth->tx_next] = skb; 488d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 489d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Linear buf */ 490d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (nr_frags != 0) 491d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = GRETH_TXBD_MORE; 492d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 493d706f00f65146822c0097b796b3557ea8980c305Daniel Hellstrom if (skb->ip_summed == CHECKSUM_PARTIAL) 494d706f00f65146822c0097b796b3557ea8980c305Daniel Hellstrom status |= GRETH_TXBD_CSALL; 495d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= skb_headlen(skb) & GRETH_BD_LEN; 496d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_next == GRETH_TXBD_NUM_MASK) 497d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 498d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 499d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 500d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_next; 501d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 502d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); 503d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 504d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(dma_mapping_error(greth->dev, dma_addr))) 505d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto map_error; 506d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 507d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->addr, dma_addr); 508d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 509d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo curr_tx = NEXT_TX(greth->tx_next); 510d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 511d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Frags */ 512d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < nr_frags; i++) { 513d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 514d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_skbuff[curr_tx] = NULL; 515d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + curr_tx; 516d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 517d706f00f65146822c0097b796b3557ea8980c305Daniel Hellstrom status = GRETH_BD_EN; 518d706f00f65146822c0097b796b3557ea8980c305Daniel Hellstrom if (skb->ip_summed == CHECKSUM_PARTIAL) 519d706f00f65146822c0097b796b3557ea8980c305Daniel Hellstrom status |= GRETH_TXBD_CSALL; 5209e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet status |= skb_frag_size(frag) & GRETH_BD_LEN; 521d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 522d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Wrap around descriptor ring */ 523d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (curr_tx == GRETH_TXBD_NUM_MASK) 524d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 525d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 526d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* More fragments left */ 527d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (i < nr_frags - 1) 528d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_TXBD_MORE; 5290f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom else 5300f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom status |= GRETH_BD_IE; /* enable IRQ on last fragment */ 531d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 532d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 533d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 5349e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet dma_addr = skb_frag_dma_map(greth->dev, frag, 0, skb_frag_size(frag), 535ab7e11d9d0293ef1802d6ae8aab39ce58472b167Ian Campbell DMA_TO_DEVICE); 536d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 537d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(dma_mapping_error(greth->dev, dma_addr))) 538d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto frag_map_error; 539d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 540d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->addr, dma_addr); 541d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 542d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo curr_tx = NEXT_TX(curr_tx); 543d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 544d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 545d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 546d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 5472a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom /* Enable the descriptor chain by enabling the first descriptor */ 5482a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom bdp = greth->tx_bd_base + greth->tx_next; 5492a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN); 5502a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom greth->tx_next = curr_tx; 5512a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom greth->tx_free -= nr_frags + 1; 5522a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom 5532a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom wmb(); 554d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 5550f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/ 556d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_tx(greth); 5570f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 558d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 559d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return NETDEV_TX_OK; 560d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 561d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembofrag_map_error: 5622a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom /* Unmap SKB mappings that succeeded and disable descriptor */ 563d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; greth->tx_next + i != curr_tx; i++) { 564d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_next + i; 565d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 566d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 567d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->stat) & GRETH_BD_LEN, 568d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 5692a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom greth_write_bd(&bdp->stat, 0); 570d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 571d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembomap_error: 572d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 573d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(greth->dev, "Could not create TX DMA mapping\n"); 574d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(skb); 575d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboout: 576d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 577d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 578d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 579d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic irqreturn_t greth_interrupt(int irq, void *dev_id) 580d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 581d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct net_device *dev = dev_id; 582d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 5830f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom u32 status, ctrl; 584d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo irqreturn_t retval = IRQ_NONE; 585d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 586d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 587d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 588d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_lock(&greth->devlock); 589d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 590d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Get the interrupt events that caused us to be here. */ 591d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = GRETH_REGLOAD(greth->regs->status); 592d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 5930f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be 5940f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom * set regardless of whether IRQ is enabled or not. Especially 5950f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom * important when shared IRQ. 5960f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom */ 5970f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control); 598d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 5990f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Handle rx and tx interrupts through poll */ 6000f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) || 6010f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) { 602d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo retval = IRQ_HANDLED; 603d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 604d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Disable interrupts and schedule poll() */ 605d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_disable_irqs(greth); 606d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo napi_schedule(&greth->napi); 607d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 608d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 609d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mmiowb(); 610d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_unlock(&greth->devlock); 611d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 612d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return retval; 613d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 614d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 615d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_tx(struct net_device *dev) 616d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 617d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 618d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 619d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 stat; 620d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 621d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 622d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 623d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (1) { 624d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_last; 6250f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); 6260f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 627d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo stat = greth_read_bd(&bdp->stat); 628d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 629d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(stat & GRETH_BD_EN)) 630d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 631d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 632d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_free == GRETH_TXBD_NUM) 633d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 634d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 635d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors */ 636d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(stat & GRETH_TXBD_STATUS)) { 637d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_errors++; 638d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_AL) 639d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_aborted_errors++; 640d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_UE) 641d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_fifo_errors++; 642d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 643d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_packets++; 6446af29a963cecf426966d56935d60a984bd5594eaDaniel Hellstrom dev->stats.tx_bytes += greth->tx_bufs_length[greth->tx_last]; 645d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 646d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free++; 647d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 648d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 649d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_free > 0) { 650d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_wake_queue(dev); 651d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 652d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 653d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 654d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 655d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_update_tx_stats(struct net_device *dev, u32 stat) 656d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 657d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors */ 658d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(stat & GRETH_TXBD_STATUS)) { 659d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_errors++; 660d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_AL) 661d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_aborted_errors++; 662d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_UE) 663d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_fifo_errors++; 664d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_LC) 665d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_aborted_errors++; 666d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 667d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_packets++; 668d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 669d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 670d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_tx_gbit(struct net_device *dev) 671d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 672d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 673d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp, *bdp_last_frag; 674d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb; 675d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 stat; 676d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int nr_frags, i; 677d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 678d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 679d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 680d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (greth->tx_free < GRETH_TXBD_NUM) { 681d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 682d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = greth->tx_skbuff[greth->tx_last]; 683d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 684d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo nr_frags = skb_shinfo(skb)->nr_frags; 685d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 686d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* We only clean fully completed SKBs */ 687d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags); 6880f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 6890f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); 6900f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 6910f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom stat = greth_read_bd(&bdp_last_frag->stat); 692d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 693d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_BD_EN) 694d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 695d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 696d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_skbuff[greth->tx_last] = NULL; 697d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 698d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_update_tx_stats(dev, stat); 6996af29a963cecf426966d56935d60a984bd5594eaDaniel Hellstrom dev->stats.tx_bytes += skb->len; 700d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 701d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_last; 702d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 703d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 704d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 705d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 706d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 707d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_headlen(skb), 708d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 709d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 710d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < nr_frags; i++) { 711d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 712d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_last; 713d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 714d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_page(greth->dev, 715d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 7169e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet skb_frag_size(frag), 717d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 718d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 719d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 720d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 721d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free += nr_frags+1; 722d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(skb); 723d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 724d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 7250f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1))) 7260f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom netif_wake_queue(dev); 727d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 728d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 729d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_rx(struct net_device *dev, int limit) 730d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 731d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 732d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 733d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb; 734d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int pkt_len; 735d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int bad, count; 736d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 status, dma_addr; 7370f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 738d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 739d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 740d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 741d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (count = 0; count < limit; ++count) { 742d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 743d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->rx_bd_base + greth->rx_cur; 7440f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX); 7450f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 746d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = greth_read_bd(&bdp->stat); 747d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 748d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(status & GRETH_BD_EN)) { 749d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 750d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 751d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 7520f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom dma_addr = greth_read_bd(&bdp->addr); 7530f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom bad = 0; 7540f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 755d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors. */ 756d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(status & GRETH_RXBD_STATUS)) { 757d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_ERR_FT) { 758d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_length_errors++; 759d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 760d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 761d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) { 762d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_frame_errors++; 763d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 764d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 765d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_ERR_CRC) { 766d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_crc_errors++; 767d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 768d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 769d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 770d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(bad)) { 771d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_errors++; 772d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 773d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 774d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 775d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pkt_len = status & GRETH_BD_LEN; 776d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 777d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN); 778d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 779d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(skb == NULL)) { 780d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 781d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 782d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(&dev->dev, "low on memory - " "packet dropped\n"); 783d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 784d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_dropped++; 785d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 786d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 787d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_reserve(skb, NET_IP_ALIGN); 788d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 789d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_sync_single_for_cpu(greth->dev, 790d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr, 791d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pkt_len, 792d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 793d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 794d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 795d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_rx_packet(phys_to_virt(dma_addr), pkt_len); 796d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 797d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memcpy(skb_put(skb, pkt_len), phys_to_virt(dma_addr), pkt_len); 798d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 799d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->protocol = eth_type_trans(skb, dev); 8006af29a963cecf426966d56935d60a984bd5594eaDaniel Hellstrom dev->stats.rx_bytes += pkt_len; 801d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_packets++; 802d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_receive_skb(skb); 803d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 804d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 805d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 806d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = GRETH_BD_EN | GRETH_BD_IE; 807d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_cur == GRETH_RXBD_NUM_MASK) { 808d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 809d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 810d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 811d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 812d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 813d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 814d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); 815d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 8160f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */ 817d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_rx(greth); 8180f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 819d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 820d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_cur = NEXT_RX(greth->rx_cur); 821d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 822d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 823d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return count; 824d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 825d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 826d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline int hw_checksummed(u32 status) 827d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 828d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 829d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_IP_FRAG) 830d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 831d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 832d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_IP && status & GRETH_RXBD_IP_CSERR) 833d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 834d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 835d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_UDP && status & GRETH_RXBD_UDP_CSERR) 836d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 837d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 838d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_TCP && status & GRETH_RXBD_TCP_CSERR) 839d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 840d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 841d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 1; 842d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 843d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 844d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_rx_gbit(struct net_device *dev, int limit) 845d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 846d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 847d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 848d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb, *newskb; 849d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int pkt_len; 850d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int bad, count = 0; 851d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 status, dma_addr; 8520f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 853d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 854d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 855d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 856d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (count = 0; count < limit; ++count) { 857d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 858d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->rx_bd_base + greth->rx_cur; 859d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = greth->rx_skbuff[greth->rx_cur]; 8600f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX); 8610f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 862d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = greth_read_bd(&bdp->stat); 863d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 0; 864d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 865d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_BD_EN) 866d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 867d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 868d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors. */ 869d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(status & GRETH_RXBD_STATUS)) { 870d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 871d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_ERR_FT) { 872d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_length_errors++; 873d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 874d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else if (status & 875d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE | GRETH_RXBD_ERR_LE)) { 876d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_frame_errors++; 877d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 878d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else if (status & GRETH_RXBD_ERR_CRC) { 879d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_crc_errors++; 880d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 881d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 882d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 883d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 884b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* Allocate new skb to replace current, not needed if the 885b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * current skb can be reused */ 886b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) { 887d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_reserve(newskb, NET_IP_ALIGN); 888d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 889d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 890d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo newskb->data, 891d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE + NET_IP_ALIGN, 892d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 893d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 894d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!dma_mapping_error(greth->dev, dma_addr)) { 895d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Process the incoming frame. */ 896d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pkt_len = status & GRETH_BD_LEN; 897d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 898d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 899d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 900d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE + NET_IP_ALIGN, 901d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 902d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 903d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 904d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_rx_packet(phys_to_virt(greth_read_bd(&bdp->addr)), pkt_len); 905d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 906d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_put(skb, pkt_len); 907d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 908131ae329702755d897c6072c7839086b0702fb10Michał Mirosław if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status)) 909d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->ip_summed = CHECKSUM_UNNECESSARY; 910d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 911bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet skb_checksum_none_assert(skb); 912d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 913d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->protocol = eth_type_trans(skb, dev); 914d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_packets++; 9156af29a963cecf426966d56935d60a984bd5594eaDaniel Hellstrom dev->stats.rx_bytes += pkt_len; 916d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_receive_skb(skb); 917d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 918d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_skbuff[greth->rx_cur] = newskb; 919d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->addr, dma_addr); 920d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 921d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 922d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n"); 923d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(newskb); 924b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* reusing current skb, so it is a drop */ 925d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_dropped++; 926d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 927b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom } else if (bad) { 928b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* Bad Frame transfer, the skb is reused */ 929b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom dev->stats.rx_dropped++; 930d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 931b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* Failed Allocating a new skb. This is rather stupid 932b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * but the current "filled" skb is reused, as if 933b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * transfer failure. One could argue that RX descriptor 934b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * table handling should be divided into cleaning and 935b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * filling as the TX part of the driver 936b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom */ 937d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 938d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n"); 939b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* reusing current skb, so it is a drop */ 940d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_dropped++; 941d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 942d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 943d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = GRETH_BD_EN | GRETH_BD_IE; 944d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_cur == GRETH_RXBD_NUM_MASK) { 945d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 946d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 947d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 948d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 949d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 9500f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); 951d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_rx(greth); 9520f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 953d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_cur = NEXT_RX(greth->rx_cur); 954d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 955d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 956d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return count; 957d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 958d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 959d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 960d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_poll(struct napi_struct *napi, int budget) 961d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 962d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 963d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int work_done = 0; 9640f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 9650f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom u32 mask, ctrl; 966d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = container_of(napi, struct greth_private, napi); 967d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 9680f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstromrestart_txrx_poll: 9690f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (netif_queue_stopped(greth->netdev)) { 9700f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (greth->gbit_mac) 9710f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx_gbit(greth->netdev); 9720f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom else 9730f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx(greth->netdev); 974d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 975d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 976d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 977d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo work_done += greth_rx_gbit(greth->netdev, budget - work_done); 978d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 979d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo work_done += greth_rx(greth->netdev, budget - work_done); 980d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 981d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 982d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (work_done < budget) { 983d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 9840f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); 985d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 9860f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control); 9870f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (netif_queue_stopped(greth->netdev)) { 9880f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, 9890f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl | GRETH_TXI | GRETH_RXI); 9900f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mask = GRETH_INT_RX | GRETH_INT_RE | 9910f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_INT_TX | GRETH_INT_TE; 9920f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom } else { 9930f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI); 9940f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mask = GRETH_INT_RX | GRETH_INT_RE; 9950f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom } 9960f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 9970f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (GRETH_REGLOAD(greth->regs->status) & mask) { 9980f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl); 9990f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 10000f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom goto restart_txrx_poll; 10010f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom } else { 10020f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom __napi_complete(napi); 10030f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 1004d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1005d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1006d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1007d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return work_done; 1008d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1009d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1010d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_set_mac_add(struct net_device *dev, void *p) 1011d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1012d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sockaddr *addr = p; 1013d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 1014d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs; 1015d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 10166e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com greth = netdev_priv(dev); 1017d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo regs = (struct greth_regs *) greth->regs; 1018d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1019d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!is_valid_ether_addr(addr->sa_data)) 1020504f9b5a6bb5336ad434438d0cdd61a16db80129Danny Kukawka return -EADDRNOTAVAIL; 1021d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1022d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 10239b9cfe7cf663c16c0d93349cc0094bb28ae7135aKristoffer Glembo GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]); 10249b9cfe7cf663c16c0d93349cc0094bb28ae7135aKristoffer Glembo GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | 10259b9cfe7cf663c16c0d93349cc0094bb28ae7135aKristoffer Glembo dev->dev_addr[4] << 8 | dev->dev_addr[5]); 1026d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1027d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1028d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1029d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1030d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic u32 greth_hash_get_index(__u8 *addr) 1031d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1032d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return (ether_crc(6, addr)) & 0x3F; 1033d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1034d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1035d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_hash_filter(struct net_device *dev) 1036d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 103722bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko struct netdev_hw_addr *ha; 10386e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com struct greth_private *greth = netdev_priv(dev); 1039d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs = (struct greth_regs *) greth->regs; 1040d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 mc_filter[2]; 10416e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com unsigned int bitnr; 1042d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1043d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mc_filter[0] = mc_filter[1] = 0; 1044d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 104522bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko netdev_for_each_mc_addr(ha, dev) { 104622bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko bitnr = greth_hash_get_index(ha->addr); 1047d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); 1048d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1049d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1050d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_msb, mc_filter[1]); 1051d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_lsb, mc_filter[0]); 1052d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1053d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1054d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_multicast_list(struct net_device *dev) 1055d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1056d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int cfg; 1057d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1058d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs = (struct greth_regs *) greth->regs; 1059d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1060d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg = GRETH_REGLOAD(regs->control); 1061d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dev->flags & IFF_PROMISC) 1062d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg |= GRETH_CTRL_PR; 1063d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1064d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg &= ~GRETH_CTRL_PR; 1065d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1066d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->multicast) { 1067d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dev->flags & IFF_ALLMULTI) { 1068d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_msb, -1); 1069d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_lsb, -1); 1070d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg |= GRETH_CTRL_MCEN; 1071d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, cfg); 1072d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return; 1073d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1074d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 10756e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com if (netdev_mc_empty(dev)) { 1076d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg &= ~GRETH_CTRL_MCEN; 1077d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, cfg); 1078d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return; 1079d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1080d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1081d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Setup multicast filter */ 1082d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_set_hash_filter(dev); 1083d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg |= GRETH_CTRL_MCEN; 1084d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1085d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, cfg); 1086d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1087d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1088d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic u32 greth_get_msglevel(struct net_device *dev) 1089d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1090d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1091d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return greth->msg_enable; 1092d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1093d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1094d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_msglevel(struct net_device *dev, u32 value) 1095d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1096d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1097d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->msg_enable = value; 1098d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1099d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1100d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1101d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1102d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phy = greth->phy; 1103d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1104d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phy) 1105d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENODEV; 1106d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1107d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return phy_ethtool_gset(phy, cmd); 1108d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1109d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1110d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1111d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1112d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1113d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phy = greth->phy; 1114d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1115d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phy) 1116d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENODEV; 1117d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1118d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return phy_ethtool_sset(phy, cmd); 1119d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1120d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1121d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_get_regs_len(struct net_device *dev) 1122d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1123d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return sizeof(struct greth_regs); 1124d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1125d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1126d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 1127d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1128d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1129d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1130d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->driver, dev_driver_string(greth->dev), 32); 1131d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->version, "revision: 1.0", 32); 1132d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->bus_info, greth->dev->bus->name, 32); 1133d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->fw_version, "N/A", 32); 1134d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo info->eedump_len = 0; 1135d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo info->regdump_len = sizeof(struct greth_regs); 1136d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1137d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1138d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) 1139d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1140d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 1141d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1142d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 __iomem *greth_regs = (u32 __iomem *) greth->regs; 1143d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 *buff = p; 1144d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1145d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < sizeof(struct greth_regs) / sizeof(u32); i++) 1146d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo buff[i] = greth_read_bd(&greth_regs[i]); 1147d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1148d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1149d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic const struct ethtool_ops greth_ethtool_ops = { 1150d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_msglevel = greth_get_msglevel, 1151d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .set_msglevel = greth_set_msglevel, 1152d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_settings = greth_get_settings, 1153d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .set_settings = greth_set_settings, 1154d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_drvinfo = greth_get_drvinfo, 1155d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_regs_len = greth_get_regs_len, 1156d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_regs = greth_get_regs, 1157d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_link = ethtool_op_get_link, 1158d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1159d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1160d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic struct net_device_ops greth_netdev_ops = { 11610f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_open = greth_open, 11620f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_stop = greth_close, 11630f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_start_xmit = greth_start_xmit, 11640f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_set_mac_address = greth_set_mac_add, 11650f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_validate_addr = eth_validate_addr, 1166d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1167d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1168d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline int wait_for_mdio(struct greth_private *greth) 1169d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1170d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long timeout = jiffies + 4*HZ/100; 1171d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_BUSY) { 1172d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (time_after(jiffies, timeout)) 1173d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1174d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1175d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 1; 1176d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1177d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1178d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_read(struct mii_bus *bus, int phy, int reg) 1179d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1180d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = bus->priv; 1181d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int data; 1182d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1183d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1184d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1185d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1186d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->mdio, ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 2); 1187d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1188d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1189d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1190d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1191d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!(GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_NVALID)) { 1192d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo data = (GRETH_REGLOAD(greth->regs->mdio) >> 16) & 0xFFFF; 1193d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return data; 1194d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1195d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 1196d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -1; 1197d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1198d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1199d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1200d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) 1201d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1202d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = bus->priv; 1203d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1204d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1205d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1206d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1207d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->mdio, 1208d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo ((val & 0xFFFF) << 16) | ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 1); 1209d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1210d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1211d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1212d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1213d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1214d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1215d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1216d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_reset(struct mii_bus *bus) 1217d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1218d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1219d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1220d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1221d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_link_change(struct net_device *dev) 1222d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1223d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1224d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phydev = greth->phy; 1225d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long flags; 1226d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int status_change = 0; 12272436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom u32 ctrl; 1228d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1229d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_lock_irqsave(&greth->devlock, flags); 1230d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1231d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->link) { 1232d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1233d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) { 12342436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control) & 12352436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB); 1236d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1237d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->duplex) 12382436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl |= GRETH_CTRL_FD; 1239d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 12402436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom if (phydev->speed == SPEED_100) 12412436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl |= GRETH_CTRL_SP; 1242d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else if (phydev->speed == SPEED_1000) 12432436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl |= GRETH_CTRL_GB; 1244d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 12452436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl); 1246d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->speed = phydev->speed; 1247d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->duplex = phydev->duplex; 1248d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status_change = 1; 1249d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1250d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1251d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1252d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->link != greth->link) { 1253d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phydev->link) { 1254d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->speed = 0; 1255d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->duplex = -1; 1256d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1257d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->link = phydev->link; 1258d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1259d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status_change = 1; 1260d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1261d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1262d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_unlock_irqrestore(&greth->devlock, flags); 1263d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1264d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status_change) { 1265d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->link) 1266d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pr_debug("%s: link up (%d/%s)\n", 1267d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->name, phydev->speed, 1268d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); 1269d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1270d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pr_debug("%s: link down\n", dev->name); 1271d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1272d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1273d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1274d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_probe(struct net_device *dev) 1275d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1276d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1277d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phy = NULL; 12786e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com int ret; 1279d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1280d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Find the first PHY */ 12816e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com phy = phy_find_first(greth->mdio); 12826e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com 1283d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phy) { 1284d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1285d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "no PHY found\n"); 1286d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENXIO; 1287d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1288d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 12896e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com ret = phy_connect_direct(dev, phy, &greth_link_change, 12906e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com 0, greth->gbit_mac ? 12916e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com PHY_INTERFACE_MODE_GMII : 12926e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com PHY_INTERFACE_MODE_MII); 12936e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com if (ret) { 12946e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com if (netif_msg_ifup(greth)) 12956e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com dev_err(&dev->dev, "could not attach to PHY\n"); 12966e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com return ret; 12976e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com } 1298d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1299d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) 1300d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy->supported &= PHY_GBIT_FEATURES; 1301d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1302d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy->supported &= PHY_BASIC_FEATURES; 1303d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1304d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy->advertising = phy->supported; 1305d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1306d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->link = 0; 1307d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->speed = 0; 1308d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->duplex = -1; 1309d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->phy = phy; 1310d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1311d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1312d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1313d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1314d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline int phy_aneg_done(struct phy_device *phydev) 1315d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1316d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int retval; 1317d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1318d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo retval = phy_read(phydev, MII_BMSR); 1319d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1320d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); 1321d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1322d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1323d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_init(struct greth_private *greth) 1324d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1325d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int ret, phy; 1326d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long timeout; 1327d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1328d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio = mdiobus_alloc(); 1329d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!greth->mdio) { 1330d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENOMEM; 1331d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1332d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1333d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->name = "greth-mdio"; 1334d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq); 1335d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->read = greth_mdio_read; 1336d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->write = greth_mdio_write; 1337d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->reset = greth_mdio_reset; 1338d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->priv = greth; 1339d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1340d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->irq = greth->mdio_irqs; 1341d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1342d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (phy = 0; phy < PHY_MAX_ADDR; phy++) 1343d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->irq[phy] = PHY_POLL; 1344d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1345d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo ret = mdiobus_register(greth->mdio); 1346d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (ret) { 1347d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error; 1348d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1349d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1350d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo ret = greth_mdio_probe(greth->netdev); 1351d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (ret) { 1352d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1353d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&greth->netdev->dev, "failed to probe MDIO bus\n"); 1354d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto unreg_mdio; 1355d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1356d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1357d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy_start(greth->phy); 1358d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1359d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* If Ethernet debug link is used make autoneg happen right away */ 1360d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->edcl && greth_edcl == 1) { 1361d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy_start_aneg(greth->phy); 1362d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo timeout = jiffies + 6*HZ; 1363d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (!phy_aneg_done(greth->phy) && time_before(jiffies, timeout)) { 1364d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1365d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo genphy_read_status(greth->phy); 1366d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_link_change(greth->netdev); 1367d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1368d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1369d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1370d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1371d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembounreg_mdio: 1372d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_unregister(greth->mdio); 1373d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror: 1374d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_free(greth->mdio); 1375d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return ret; 1376d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1377d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1378d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo/* Initialize the GRETH MAC */ 137974888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic int __devinit greth_of_probe(struct platform_device *ofdev) 1380d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1381d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct net_device *dev; 1382d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 1383d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs; 1384d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1385d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 1386d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int err; 1387d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int tmp; 1388d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long timeout; 1389d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1390d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev = alloc_etherdev(sizeof(struct greth_private)); 1391d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1392d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dev == NULL) 1393d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENOMEM; 1394d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1395d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 1396d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->netdev = dev; 1397d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->dev = &ofdev->dev; 1398d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1399d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth_debug > 0) 1400d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->msg_enable = greth_debug; 1401d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1402d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->msg_enable = GRETH_DEF_MSG_ENABLE; 1403d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1404d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_lock_init(&greth->devlock); 1405d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1406d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->regs = of_ioremap(&ofdev->resource[0], 0, 1407d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo resource_size(&ofdev->resource[0]), 1408d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo "grlib-greth regs"); 1409d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1410d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->regs == NULL) { 1411d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1412d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "ioremap failure.\n"); 1413d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -EIO; 1414d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error1; 1415d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1416d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1417d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo regs = (struct greth_regs *) greth->regs; 141819e4875fb21a69fbf620e84769a74d189c69c58dGrant Likely greth->irq = ofdev->archdata.irqs[0]; 1419d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1420d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_set_drvdata(greth->dev, dev); 1421d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo SET_NETDEV_DEV(dev, greth->dev); 1422d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1423d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 142472e60278d7e4a600fd6e067b42a5822e72946d6eMasanari Iida dev_dbg(greth->dev, "resetting controller.\n"); 1425d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1426d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Reset the controller. */ 1427d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, GRETH_RESET); 1428d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1429d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Wait for MAC to reset itself */ 1430d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo timeout = jiffies + HZ/100; 1431d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (GRETH_REGLOAD(regs->control) & GRETH_RESET) { 1432d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (time_after(jiffies, timeout)) { 1433d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -EIO; 1434d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1435d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "timeout when waiting for reset.\n"); 1436d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error2; 1437d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1438d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1439d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1440d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Get default PHY address */ 1441d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->phyaddr = (GRETH_REGLOAD(regs->mdio) >> 11) & 0x1F; 1442d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1443d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check if we have GBIT capable MAC */ 1444d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tmp = GRETH_REGLOAD(regs->control); 1445d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->gbit_mac = (tmp >> 27) & 1; 1446d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1447d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check for multicast capability */ 1448d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->multicast = (tmp >> 25) & 1; 1449d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1450d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->edcl = (tmp >> 31) & 1; 1451d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1452d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* If we have EDCL we disable the EDCL speed-duplex FSM so 1453d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * it doesn't interfere with the software */ 1454d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->edcl != 0) 1455d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX); 1456d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1457d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check if MAC can handle MDIO interrupts */ 1458d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio_int_en = (tmp >> 26) & 1; 1459d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1460d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = greth_mdio_init(greth); 1461d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (err) { 1462d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1463d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "failed to register MDIO bus\n"); 1464d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error2; 1465d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1466d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1467d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Allocate TX descriptor ring in coherent memory */ 1468d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev, 1469d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1024, 1470d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo &greth->tx_bd_base_phys, 1471d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GFP_KERNEL); 1472d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1473d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!greth->tx_bd_base) { 1474d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1475d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "could not allocate descriptor memory.\n"); 1476d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -ENOMEM; 1477d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error3; 1478d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1479d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1480d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memset(greth->tx_bd_base, 0, 1024); 1481d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1482d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Allocate RX descriptor ring in coherent memory */ 1483d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev, 1484d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1024, 1485d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo &greth->rx_bd_base_phys, 1486d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GFP_KERNEL); 1487d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1488d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!greth->rx_bd_base) { 1489d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1490d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "could not allocate descriptor memory.\n"); 1491d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -ENOMEM; 1492d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error4; 1493d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1494d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1495d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memset(greth->rx_bd_base, 0, 1024); 1496d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1497d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Get MAC address from: module param, OF property or ID prom */ 1498d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) { 1499d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (macaddr[i] != 0) 1500d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 1501d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1502d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (i == 6) { 1503d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo const unsigned char *addr; 1504d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int len; 150561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely addr = of_get_property(ofdev->dev.of_node, "local-mac-address", 150661c7a080a5a061c976988fd4b844dfb468dda255Grant Likely &len); 1507d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (addr != NULL && len == 6) { 1508d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) 1509d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo macaddr[i] = (unsigned int) addr[i]; 1510d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 1511d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#ifdef CONFIG_SPARC 1512d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) 1513d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo macaddr[i] = (unsigned int) idprom->id_ethaddr[i]; 1514d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#endif 1515d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1516d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1517d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1518d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) 1519d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->dev_addr[i] = macaddr[i]; 1520d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1521d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo macaddr[5]++; 1522d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1523d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!is_valid_ether_addr(&dev->dev_addr[0])) { 1524d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1525d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "no valid ethernet address, aborting.\n"); 1526d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -EINVAL; 1527d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error5; 1528d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1529d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1530d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]); 1531d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | 1532d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->dev_addr[4] << 8 | dev->dev_addr[5]); 1533d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1534d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Clear all pending interrupts except PHY irq */ 1535d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->status, 0xFF); 1536d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1537d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 1538131ae329702755d897c6072c7839086b0702fb10Michał Mirosław dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | 1539131ae329702755d897c6072c7839086b0702fb10Michał Mirosław NETIF_F_RXCSUM; 1540131ae329702755d897c6072c7839086b0702fb10Michał Mirosław dev->features = dev->hw_features | NETIF_F_HIGHDMA; 1541d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit; 1542d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1543d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1544d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->multicast) { 1545afc4b13df143122f99a0eb10bfefb216c2806de0Jiri Pirko greth_netdev_ops.ndo_set_rx_mode = greth_set_multicast_list; 1546d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->flags |= IFF_MULTICAST; 1547d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 1548d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->flags &= ~IFF_MULTICAST; 1549d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1550d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1551d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->netdev_ops = &greth_netdev_ops; 1552d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->ethtool_ops = &greth_ethtool_ops; 1553d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1554cb5d991a99104565f7b622b1b97587f4b1effa82Tobias Klauser err = register_netdev(dev); 1555cb5d991a99104565f7b622b1b97587f4b1effa82Tobias Klauser if (err) { 1556d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1557d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "netdevice registration failed.\n"); 1558d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error5; 1559d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1560d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1561d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* setup NAPI */ 1562d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_napi_add(dev, &greth->napi, greth_poll, 64); 1563d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1564d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1565d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1566d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror5: 1567d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(greth->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys); 1568d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror4: 1569d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(greth->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys); 1570d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror3: 1571d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_unregister(greth->mdio); 1572d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror2: 1573d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo of_iounmap(&ofdev->resource[0], greth->regs, resource_size(&ofdev->resource[0])); 1574d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror1: 1575d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo free_netdev(dev); 1576d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 1577d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1578d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 15792dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit greth_of_remove(struct platform_device *of_dev) 1580d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1581d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct net_device *ndev = dev_get_drvdata(&of_dev->dev); 1582d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(ndev); 1583d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1584d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Free descriptor areas */ 1585d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(&of_dev->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys); 1586d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1587d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(&of_dev->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys); 1588d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1589d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_set_drvdata(&of_dev->dev, NULL); 1590d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1591d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->phy) 1592d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy_stop(greth->phy); 1593d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_unregister(greth->mdio); 1594d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1595d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unregister_netdev(ndev); 1596d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo free_netdev(ndev); 1597d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1598d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0])); 1599d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1600d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1601d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1602d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1603d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic struct of_device_id greth_of_match[] = { 1604d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo { 1605d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .name = "GAISLER_ETHMAC", 1606d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo }, 1607ad4650a89ac47bd153cbb76c3fd6eb1fa6f315b7Daniel Hellstrom { 1608ad4650a89ac47bd153cbb76c3fd6eb1fa6f315b7Daniel Hellstrom .name = "01_01d", 1609ad4650a89ac47bd153cbb76c3fd6eb1fa6f315b7Daniel Hellstrom }, 1610d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo {}, 1611d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1612d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1613d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_DEVICE_TABLE(of, greth_of_match); 1614d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 161574888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic struct platform_driver greth_of_driver = { 1616bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .driver = { 1617bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .name = "grlib-greth", 1618bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .owner = THIS_MODULE, 1619bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .of_match_table = greth_of_match, 1620bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller }, 1621d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .probe = greth_of_probe, 1622d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .remove = __devexit_p(greth_of_remove), 1623d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1624d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1625db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(greth_of_driver); 1626d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1627d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_AUTHOR("Aeroflex Gaisler AB."); 1628d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_DESCRIPTION("Aeroflex Gaisler Ethernet MAC driver"); 1629d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_LICENSE("GPL"); 1630