greth.c revision afc4b13df143122f99a0eb10bfefb216c2806de0
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, 116d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phys_to_virt(page_to_phys(skb_shinfo(skb)->frags[i].page)) + 117d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_shinfo(skb)->frags[i].page_offset, 118d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo length, true); 119d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 120d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 121d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 122d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_enable_tx(struct greth_private *greth) 123d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 124d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 125d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(greth->regs->control, GRETH_TXEN); 126d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 127d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 128d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_disable_tx(struct greth_private *greth) 129d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 130d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN); 131d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 132d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 133d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_enable_rx(struct greth_private *greth) 134d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 135d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 136d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(greth->regs->control, GRETH_RXEN); 137d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 138d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 139d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_disable_rx(struct greth_private *greth) 140d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 141d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGANDIN(greth->regs->control, ~GRETH_RXEN); 142d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 143d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 144d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_enable_irqs(struct greth_private *greth) 145d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 146d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(greth->regs->control, GRETH_RXI | GRETH_TXI); 147d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 148d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 149d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_disable_irqs(struct greth_private *greth) 150d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 151d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGANDIN(greth->regs->control, ~(GRETH_RXI|GRETH_TXI)); 152d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 153d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 154d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_write_bd(u32 *bd, u32 val) 155d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 156d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo __raw_writel(cpu_to_be32(val), bd); 157d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 158d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 159d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline u32 greth_read_bd(u32 *bd) 160d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 161d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return be32_to_cpu(__raw_readl(bd)); 162d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 163d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 164d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_rings(struct greth_private *greth) 165d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 166d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 167d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *rx_bdp = greth->rx_bd_base; 168d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *tx_bdp = greth->tx_bd_base; 169d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 170d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 171d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 172d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Free and unmap RX buffers */ 173d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) { 174d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_skbuff[i] != NULL) { 175d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(greth->rx_skbuff[i]); 176d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 177d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&rx_bdp->addr), 178d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE+NET_IP_ALIGN, 179d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 180d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 181d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 182d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 183d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* TX buffers */ 184d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (greth->tx_free < GRETH_TXBD_NUM) { 185d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 186d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb = greth->tx_skbuff[greth->tx_last]; 187d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int nr_frags = skb_shinfo(skb)->nr_frags; 188d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tx_bdp = greth->tx_bd_base + greth->tx_last; 189d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 190d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 191d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 192d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&tx_bdp->addr), 193d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_headlen(skb), 194d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 195d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 196d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < nr_frags; i++) { 197d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 198d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tx_bdp = greth->tx_bd_base + greth->tx_last; 199d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 200d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_page(greth->dev, 201d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&tx_bdp->addr), 202d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo frag->size, 203d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 204d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 205d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 206d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 207d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free += nr_frags+1; 208d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(skb); 209d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 210d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 211d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 212d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { /* 10/100 Mbps MAC */ 213d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 214d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) { 215d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo kfree(greth->rx_bufs[i]); 216d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 217d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&rx_bdp->addr), 218d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 219d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 220d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 221d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_TXBD_NUM; i++, tx_bdp++) { 222d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo kfree(greth->tx_bufs[i]); 223d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 224d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&tx_bdp->addr), 225d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 226d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 227d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 228d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 229d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 230d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 231d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_init_rings(struct greth_private *greth) 232d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 233d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb; 234d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *rx_bd, *tx_bd; 235d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 dma_addr; 236d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 237d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 238d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo rx_bd = greth->rx_bd_base; 239d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tx_bd = greth->tx_bd_base; 240d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 241d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Initialize descriptor rings and buffers */ 242d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 243d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 244d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++) { 245d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = netdev_alloc_skb(greth->netdev, MAX_FRAME_SIZE+NET_IP_ALIGN); 246d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (skb == NULL) { 247d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 248d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Error allocating DMA ring.\n"); 249d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 250d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 251d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_reserve(skb, NET_IP_ALIGN); 252d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 253d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->data, 254d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE+NET_IP_ALIGN, 255d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 256d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 257d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dma_mapping_error(greth->dev, dma_addr)) { 258d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 259d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Could not create initial DMA mapping\n"); 260d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 261d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 262d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_skbuff[i] = skb; 263d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].addr, dma_addr); 264d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE); 265d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 266d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 267d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 268d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 269d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* 10/100 MAC uses a fixed set of buffers and copy to/from SKBs */ 270d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_RXBD_NUM; i++) { 271d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 272d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL); 273d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 274d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_bufs[i] == NULL) { 275d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 276d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Error allocating DMA ring.\n"); 277d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 278d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 279d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 280d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 281d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_bufs[i], 282d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 283d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 284d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 285d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dma_mapping_error(greth->dev, dma_addr)) { 286d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 287d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Could not create initial DMA mapping\n"); 288d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 289d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 290d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].addr, dma_addr); 291d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[i].stat, GRETH_BD_EN | GRETH_BD_IE); 292d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 293d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < GRETH_TXBD_NUM; i++) { 294d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 295d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_bufs[i] = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL); 296d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 297d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_bufs[i] == NULL) { 298d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 299d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Error allocating DMA ring.\n"); 300d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 301d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 302d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 303d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 304d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_bufs[i], 305d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE, 306d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 307d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 308d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dma_mapping_error(greth->dev, dma_addr)) { 309d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 310d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "Could not create initial DMA mapping\n"); 311d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto cleanup; 312d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 313d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&tx_bd[i].addr, dma_addr); 314d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&tx_bd[i].stat, 0); 315d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 316d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 317d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat, 318d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&rx_bd[GRETH_RXBD_NUM - 1].stat) | GRETH_BD_WR); 319d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 320d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Initialize pointers. */ 321d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_cur = 0; 322d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_next = 0; 323d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = 0; 324d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free = GRETH_TXBD_NUM; 325d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 326d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Initialize descriptor base address */ 327d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->tx_desc_p, greth->tx_bd_base_phys); 328d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->rx_desc_p, greth->rx_bd_base_phys); 329d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 330d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 331d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 332d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembocleanup: 333d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_clean_rings(greth); 334d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENOMEM; 335d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 336d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 337d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_open(struct net_device *dev) 338d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 339d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 340d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int err; 341d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 342d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = greth_init_rings(greth); 343d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (err) { 344d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 345d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "Could not allocate memory for DMA rings\n"); 346d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 347d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 348d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 349d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = request_irq(greth->irq, greth_interrupt, 0, "eth", (void *) dev); 350d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (err) { 351d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 352d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "Could not allocate interrupt %d\n", dev->irq); 353d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_clean_rings(greth); 354d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 355d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 356d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 357d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_ifup(greth)) 358d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_dbg(&dev->dev, " starting queue\n"); 359d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_start_queue(dev); 360d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 361bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, 0xFF); 362bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom 363d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo napi_enable(&greth->napi); 364d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 365d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_irqs(greth); 366d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_tx(greth); 367d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_rx(greth); 368d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 369d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 370d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 371d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 372d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_close(struct net_device *dev) 373d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 374d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 375d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 376d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo napi_disable(&greth->napi); 377d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 378bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom greth_disable_irqs(greth); 379d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_disable_tx(greth); 380bbe9e637330abe55442aebe799425e224086959fDaniel Hellstrom greth_disable_rx(greth); 381d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 382d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_stop_queue(dev); 383d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 384d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo free_irq(greth->irq, (void *) dev); 385d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 386d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_clean_rings(greth); 387d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 388d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 389d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 390d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 39141a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comstatic netdev_tx_t 39241a655ba5654e47847505c164f77f8190ca9ed27kirjanov@gmail.comgreth_start_xmit(struct sk_buff *skb, struct net_device *dev) 393d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 394d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 395d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 396d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int err = NETDEV_TX_OK; 3970f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom u32 status, dma_addr, ctrl; 3980f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 399d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 4000f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Clean TX Ring */ 4010f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx(greth->netdev); 402d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 403d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(greth->tx_free <= 0)) { 4040f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/ 4050f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control); 4060f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom /* Enable TX IRQ only if not already in poll() routine */ 4070f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (ctrl & GRETH_RXI) 4080f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI); 409d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_stop_queue(dev); 4100f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 411d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return NETDEV_TX_BUSY; 412d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 413d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 414d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 415d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_tx_packet(skb); 416d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 417d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 418d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(skb->len > MAX_FRAME_SIZE)) { 419d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_errors++; 420d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto out; 421d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 422d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 4230f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom bdp = greth->tx_bd_base + greth->tx_next; 424d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = greth_read_bd(&bdp->addr); 425d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 426d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len); 427d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 428d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE); 429d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 4300f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom status = GRETH_BD_EN | GRETH_BD_IE | (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 493d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_TXBD_CSALL; 494d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= skb_headlen(skb) & GRETH_BD_LEN; 495d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_next == GRETH_TXBD_NUM_MASK) 496d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 497d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 498d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 499d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_next; 500d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 501d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); 502d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 503d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(dma_mapping_error(greth->dev, dma_addr))) 504d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto map_error; 505d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 506d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->addr, dma_addr); 507d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 508d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo curr_tx = NEXT_TX(greth->tx_next); 509d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 510d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Frags */ 511d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < nr_frags; i++) { 512d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 513d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_skbuff[curr_tx] = NULL; 514d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + curr_tx; 515d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 5162a2bc012b98729ce9a39386faed28d11ee021683Daniel Hellstrom status = GRETH_TXBD_CSALL | GRETH_BD_EN; 517d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= frag->size & GRETH_BD_LEN; 518d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 519d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Wrap around descriptor ring */ 520d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (curr_tx == GRETH_TXBD_NUM_MASK) 521d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 522d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 523d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* More fragments left */ 524d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (i < nr_frags - 1) 525d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_TXBD_MORE; 5260f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom else 5270f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom status |= GRETH_BD_IE; /* enable IRQ on last fragment */ 528d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 529d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 530d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 531d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_page(greth->dev, 532d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo frag->page, 533d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo frag->page_offset, 534d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo frag->size, 535d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 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++; 644d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 645d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free++; 646d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 647d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 648d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->tx_free > 0) { 649d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_wake_queue(dev); 650d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 651d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 652d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 653d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 654d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline void greth_update_tx_stats(struct net_device *dev, u32 stat) 655d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 656d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors */ 657d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(stat & GRETH_TXBD_STATUS)) { 658d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_errors++; 659d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_AL) 660d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_aborted_errors++; 661d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_UE) 662d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_fifo_errors++; 663d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_TXBD_ERR_LC) 664d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_aborted_errors++; 665d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 666d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.tx_packets++; 667d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 668d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 669d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_clean_tx_gbit(struct net_device *dev) 670d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 671d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 672d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp, *bdp_last_frag; 673d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb; 674d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 stat; 675d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int nr_frags, i; 676d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 677d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 678d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 679d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (greth->tx_free < GRETH_TXBD_NUM) { 680d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 681d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = greth->tx_skbuff[greth->tx_last]; 682d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 683d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo nr_frags = skb_shinfo(skb)->nr_frags; 684d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 685d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* We only clean fully completed SKBs */ 686d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags); 6870f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 6880f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX); 6890f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 6900f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom stat = greth_read_bd(&bdp_last_frag->stat); 691d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 692d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (stat & GRETH_BD_EN) 693d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 694d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 695d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_skbuff[greth->tx_last] = NULL; 696d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 697d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_update_tx_stats(dev, stat); 698d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 699d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_last; 700d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 701d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 702d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 703d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 704d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 705d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_headlen(skb), 706d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 707d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 708d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < nr_frags; i++) { 709d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 710d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->tx_bd_base + greth->tx_last; 711d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 712d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_page(greth->dev, 713d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 714d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo frag->size, 715d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_TO_DEVICE); 716d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 717d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_last = NEXT_TX(greth->tx_last); 718d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 719d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_free += nr_frags+1; 720d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(skb); 721d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 722d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 7230f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1))) 7240f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom netif_wake_queue(dev); 725d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 726d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 727d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_rx(struct net_device *dev, int limit) 728d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 729d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 730d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 731d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb; 732d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int pkt_len; 733d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int bad, count; 734d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 status, dma_addr; 7350f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 736d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 737d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 738d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 739d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (count = 0; count < limit; ++count) { 740d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 741d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->rx_bd_base + greth->rx_cur; 7420f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX); 7430f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 744d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = greth_read_bd(&bdp->stat); 745d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 746d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(status & GRETH_BD_EN)) { 747d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 748d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 749d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 7500f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom dma_addr = greth_read_bd(&bdp->addr); 7510f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom bad = 0; 7520f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 753d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors. */ 754d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(status & GRETH_RXBD_STATUS)) { 755d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_ERR_FT) { 756d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_length_errors++; 757d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 758d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 759d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) { 760d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_frame_errors++; 761d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 762d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 763d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_ERR_CRC) { 764d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_crc_errors++; 765d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 766d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 767d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 768d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(bad)) { 769d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_errors++; 770d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 771d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 772d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 773d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pkt_len = status & GRETH_BD_LEN; 774d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 775d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN); 776d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 777d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(skb == NULL)) { 778d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 779d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 780d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(&dev->dev, "low on memory - " "packet dropped\n"); 781d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 782d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_dropped++; 783d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 784d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 785d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_reserve(skb, NET_IP_ALIGN); 786d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->dev = dev; 787d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 788d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_sync_single_for_cpu(greth->dev, 789d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr, 790d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pkt_len, 791d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 792d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 793d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 794d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_rx_packet(phys_to_virt(dma_addr), pkt_len); 795d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 796d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memcpy(skb_put(skb, pkt_len), phys_to_virt(dma_addr), pkt_len); 797d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 798d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->protocol = eth_type_trans(skb, dev); 799d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_packets++; 800d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_receive_skb(skb); 801d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 802d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 803d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 804d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = GRETH_BD_EN | GRETH_BD_IE; 805d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_cur == GRETH_RXBD_NUM_MASK) { 806d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 807d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 808d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 809d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 810d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 811d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 812d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE); 813d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 8140f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */ 815d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_rx(greth); 8160f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 817d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 818d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_cur = NEXT_RX(greth->rx_cur); 819d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 820d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 821d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return count; 822d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 823d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 824d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline int hw_checksummed(u32 status) 825d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 826d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 827d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_IP_FRAG) 828d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 829d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 830d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_IP && status & GRETH_RXBD_IP_CSERR) 831d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 832d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 833d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_UDP && status & GRETH_RXBD_UDP_CSERR) 834d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 835d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 836d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_TCP && status & GRETH_RXBD_TCP_CSERR) 837d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 838d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 839d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 1; 840d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 841d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 842d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_rx_gbit(struct net_device *dev, int limit) 843d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 844d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 845d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_bd *bdp; 846d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sk_buff *skb, *newskb; 847d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int pkt_len; 848d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int bad, count = 0; 849d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 status, dma_addr; 8500f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 851d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 852d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 853d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 854d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (count = 0; count < limit; ++count) { 855d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 856d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bdp = greth->rx_bd_base + greth->rx_cur; 857d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb = greth->rx_skbuff[greth->rx_cur]; 8580f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX); 8590f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mb(); 860d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = greth_read_bd(&bdp->stat); 861d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 0; 862d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 863d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_BD_EN) 864d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 865d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 866d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check status for errors. */ 867d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (unlikely(status & GRETH_RXBD_STATUS)) { 868d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 869d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status & GRETH_RXBD_ERR_FT) { 870d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_length_errors++; 871d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 872d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else if (status & 873d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE | GRETH_RXBD_ERR_LE)) { 874d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_frame_errors++; 875d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 876d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else if (status & GRETH_RXBD_ERR_CRC) { 877d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_crc_errors++; 878d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo bad = 1; 879d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 880d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 881d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 882b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* Allocate new skb to replace current, not needed if the 883b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * current skb can be reused */ 884b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) { 885d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_reserve(newskb, NET_IP_ALIGN); 886d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 887d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_addr = dma_map_single(greth->dev, 888d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo newskb->data, 889d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE + NET_IP_ALIGN, 890d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 891d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 892d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!dma_mapping_error(greth->dev, dma_addr)) { 893d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Process the incoming frame. */ 894d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pkt_len = status & GRETH_BD_LEN; 895d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 896d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_unmap_single(greth->dev, 897d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_read_bd(&bdp->addr), 898d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo MAX_FRAME_SIZE + NET_IP_ALIGN, 899d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DMA_FROM_DEVICE); 900d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 901d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_pktdata(greth)) 902d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_print_rx_packet(phys_to_virt(greth_read_bd(&bdp->addr)), pkt_len); 903d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 904d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb_put(skb, pkt_len); 905d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 906131ae329702755d897c6072c7839086b0702fb10Michał Mirosław if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status)) 907d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->ip_summed = CHECKSUM_UNNECESSARY; 908d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 909bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet skb_checksum_none_assert(skb); 910d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 911d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo skb->protocol = eth_type_trans(skb, dev); 912d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_packets++; 913d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_receive_skb(skb); 914d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 915d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_skbuff[greth->rx_cur] = newskb; 916d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->addr, dma_addr); 917d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 918d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 919d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n"); 920d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_kfree_skb(newskb); 921b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* reusing current skb, so it is a drop */ 922d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_dropped++; 923d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 924b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom } else if (bad) { 925b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* Bad Frame transfer, the skb is reused */ 926b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom dev->stats.rx_dropped++; 927d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 928b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* Failed Allocating a new skb. This is rather stupid 929b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * but the current "filled" skb is reused, as if 930b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * transfer failure. One could argue that RX descriptor 931b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * table handling should be divided into cleaning and 932b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom * filling as the TX part of the driver 933b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom */ 934d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (net_ratelimit()) 935d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n"); 936b669e7f0580f3c0058f1b32c276ef6da8f05c138Daniel Hellstrom /* reusing current skb, so it is a drop */ 937d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->stats.rx_dropped++; 938d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 939d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 940d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status = GRETH_BD_EN | GRETH_BD_IE; 941d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->rx_cur == GRETH_RXBD_NUM_MASK) { 942d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status |= GRETH_BD_WR; 943d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 944d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 945d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo wmb(); 946d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_write_bd(&bdp->stat, status); 9470f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); 948d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_enable_rx(greth); 9490f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 950d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_cur = NEXT_RX(greth->rx_cur); 951d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 952d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 953d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return count; 954d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 955d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 956d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 957d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_poll(struct napi_struct *napi, int budget) 958d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 959d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 960d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int work_done = 0; 9610f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom unsigned long flags; 9620f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom u32 mask, ctrl; 963d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = container_of(napi, struct greth_private, napi); 964d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 9650f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstromrestart_txrx_poll: 9660f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (netif_queue_stopped(greth->netdev)) { 9670f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (greth->gbit_mac) 9680f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx_gbit(greth->netdev); 9690f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom else 9700f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom greth_clean_tx(greth->netdev); 971d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 972d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 973d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 974d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo work_done += greth_rx_gbit(greth->netdev, budget - work_done); 975d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 976d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo work_done += greth_rx(greth->netdev, budget - work_done); 977d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 978d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 979d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (work_done < budget) { 980d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 9810f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_lock_irqsave(&greth->devlock, flags); 982d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 9830f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control); 9840f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (netif_queue_stopped(greth->netdev)) { 9850f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, 9860f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom ctrl | GRETH_TXI | GRETH_RXI); 9870f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mask = GRETH_INT_RX | GRETH_INT_RE | 9880f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_INT_TX | GRETH_INT_TE; 9890f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom } else { 9900f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI); 9910f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom mask = GRETH_INT_RX | GRETH_INT_RE; 9920f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom } 9930f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom 9940f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom if (GRETH_REGLOAD(greth->regs->status) & mask) { 9950f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl); 9960f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 9970f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom goto restart_txrx_poll; 9980f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom } else { 9990f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom __napi_complete(napi); 10000f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom spin_unlock_irqrestore(&greth->devlock, flags); 1001d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1002d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1003d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1004d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return work_done; 1005d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1006d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1007d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_set_mac_add(struct net_device *dev, void *p) 1008d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1009d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct sockaddr *addr = p; 1010d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 1011d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs; 1012d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 10136e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com greth = netdev_priv(dev); 1014d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo regs = (struct greth_regs *) greth->regs; 1015d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1016d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!is_valid_ether_addr(addr->sa_data)) 1017d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EINVAL; 1018d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1019d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 10209b9cfe7cf663c16c0d93349cc0094bb28ae7135aKristoffer Glembo GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]); 10219b9cfe7cf663c16c0d93349cc0094bb28ae7135aKristoffer Glembo GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | 10229b9cfe7cf663c16c0d93349cc0094bb28ae7135aKristoffer Glembo dev->dev_addr[4] << 8 | dev->dev_addr[5]); 1023d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1024d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1025d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1026d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1027d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic u32 greth_hash_get_index(__u8 *addr) 1028d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1029d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return (ether_crc(6, addr)) & 0x3F; 1030d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1031d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1032d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_hash_filter(struct net_device *dev) 1033d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 103422bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko struct netdev_hw_addr *ha; 10356e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com struct greth_private *greth = netdev_priv(dev); 1036d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs = (struct greth_regs *) greth->regs; 1037d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 mc_filter[2]; 10386e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com unsigned int bitnr; 1039d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1040d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mc_filter[0] = mc_filter[1] = 0; 1041d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 104222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko netdev_for_each_mc_addr(ha, dev) { 104322bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko bitnr = greth_hash_get_index(ha->addr); 1044d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); 1045d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1046d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1047d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_msb, mc_filter[1]); 1048d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_lsb, mc_filter[0]); 1049d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1050d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1051d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_multicast_list(struct net_device *dev) 1052d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1053d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int cfg; 1054d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1055d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs = (struct greth_regs *) greth->regs; 1056d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1057d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg = GRETH_REGLOAD(regs->control); 1058d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dev->flags & IFF_PROMISC) 1059d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg |= GRETH_CTRL_PR; 1060d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1061d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg &= ~GRETH_CTRL_PR; 1062d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1063d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->multicast) { 1064d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dev->flags & IFF_ALLMULTI) { 1065d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_msb, -1); 1066d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->hash_lsb, -1); 1067d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg |= GRETH_CTRL_MCEN; 1068d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, cfg); 1069d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return; 1070d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1071d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 10726e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com if (netdev_mc_empty(dev)) { 1073d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg &= ~GRETH_CTRL_MCEN; 1074d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, cfg); 1075d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return; 1076d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1077d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1078d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Setup multicast filter */ 1079d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_set_hash_filter(dev); 1080d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo cfg |= GRETH_CTRL_MCEN; 1081d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1082d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, cfg); 1083d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1084d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1085d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic u32 greth_get_msglevel(struct net_device *dev) 1086d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1087d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1088d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return greth->msg_enable; 1089d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1090d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1091d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_set_msglevel(struct net_device *dev, u32 value) 1092d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1093d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1094d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->msg_enable = value; 1095d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1096d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1097d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1098d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1099d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phy = greth->phy; 1100d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1101d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phy) 1102d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENODEV; 1103d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1104d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return phy_ethtool_gset(phy, cmd); 1105d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1106d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1107d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1108d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1109d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1110d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phy = greth->phy; 1111d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1112d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phy) 1113d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENODEV; 1114d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1115d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return phy_ethtool_sset(phy, cmd); 1116d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1117d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1118d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_get_regs_len(struct net_device *dev) 1119d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1120d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return sizeof(struct greth_regs); 1121d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1122d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1123d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 1124d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1125d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1126d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1127d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->driver, dev_driver_string(greth->dev), 32); 1128d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->version, "revision: 1.0", 32); 1129d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->bus_info, greth->dev->bus->name, 32); 1130d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo strncpy(info->fw_version, "N/A", 32); 1131d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo info->eedump_len = 0; 1132d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo info->regdump_len = sizeof(struct greth_regs); 1133d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1134d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1135d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) 1136d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1137d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 1138d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1139d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 __iomem *greth_regs = (u32 __iomem *) greth->regs; 1140d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo u32 *buff = p; 1141d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1142d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < sizeof(struct greth_regs) / sizeof(u32); i++) 1143d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo buff[i] = greth_read_bd(&greth_regs[i]); 1144d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1145d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1146d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic const struct ethtool_ops greth_ethtool_ops = { 1147d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_msglevel = greth_get_msglevel, 1148d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .set_msglevel = greth_set_msglevel, 1149d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_settings = greth_get_settings, 1150d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .set_settings = greth_set_settings, 1151d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_drvinfo = greth_get_drvinfo, 1152d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_regs_len = greth_get_regs_len, 1153d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_regs = greth_get_regs, 1154d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .get_link = ethtool_op_get_link, 1155d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1156d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1157d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic struct net_device_ops greth_netdev_ops = { 11580f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_open = greth_open, 11590f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_stop = greth_close, 11600f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_start_xmit = greth_start_xmit, 11610f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_set_mac_address = greth_set_mac_add, 11620f73f2c5a3ebb957ee66718c903c17ed71a4fc2eDaniel Hellstrom .ndo_validate_addr = eth_validate_addr, 1163d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1164d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1165d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline int wait_for_mdio(struct greth_private *greth) 1166d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1167d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long timeout = jiffies + 4*HZ/100; 1168d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_BUSY) { 1169d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (time_after(jiffies, timeout)) 1170d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1171d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1172d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 1; 1173d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1174d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1175d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_read(struct mii_bus *bus, int phy, int reg) 1176d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1177d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = bus->priv; 1178d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int data; 1179d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1180d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1181d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1182d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1183d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->mdio, ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 2); 1184d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1185d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1186d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1187d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1188d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!(GRETH_REGLOAD(greth->regs->mdio) & GRETH_MII_NVALID)) { 1189d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo data = (GRETH_REGLOAD(greth->regs->mdio) >> 16) & 0xFFFF; 1190d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return data; 1191d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1192d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 1193d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -1; 1194d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1195d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1196d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1197d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) 1198d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1199d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = bus->priv; 1200d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1201d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1202d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1203d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1204d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(greth->regs->mdio, 1205d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo ((val & 0xFFFF) << 16) | ((phy & 0x1F) << 11) | ((reg & 0x1F) << 6) | 1); 1206d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1207d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!wait_for_mdio(greth)) 1208d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -EBUSY; 1209d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1210d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1211d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1212d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1213d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_reset(struct mii_bus *bus) 1214d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1215d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1216d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1217d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1218d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void greth_link_change(struct net_device *dev) 1219d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1220d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1221d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phydev = greth->phy; 1222d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long flags; 1223d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int status_change = 0; 12242436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom u32 ctrl; 1225d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1226d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_lock_irqsave(&greth->devlock, flags); 1227d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1228d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->link) { 1229d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1230d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) { 12312436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl = GRETH_REGLOAD(greth->regs->control) & 12322436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB); 1233d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1234d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->duplex) 12352436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl |= GRETH_CTRL_FD; 1236d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 12372436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom if (phydev->speed == SPEED_100) 12382436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl |= GRETH_CTRL_SP; 1239d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else if (phydev->speed == SPEED_1000) 12402436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom ctrl |= GRETH_CTRL_GB; 1241d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 12422436af8ca7a6c4679cf7da7e3867f1d5cd8528b7Daniel Hellstrom GRETH_REGSAVE(greth->regs->control, ctrl); 1243d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->speed = phydev->speed; 1244d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->duplex = phydev->duplex; 1245d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status_change = 1; 1246d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1247d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1248d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1249d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->link != greth->link) { 1250d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phydev->link) { 1251d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->speed = 0; 1252d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->duplex = -1; 1253d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1254d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->link = phydev->link; 1255d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1256d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo status_change = 1; 1257d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1258d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1259d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_unlock_irqrestore(&greth->devlock, flags); 1260d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1261d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (status_change) { 1262d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (phydev->link) 1263d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pr_debug("%s: link up (%d/%s)\n", 1264d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->name, phydev->speed, 1265d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); 1266d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1267d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo pr_debug("%s: link down\n", dev->name); 1268d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1269d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1270d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1271d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_probe(struct net_device *dev) 1272d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1273d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(dev); 1274d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct phy_device *phy = NULL; 12756e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com int ret; 1276d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1277d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Find the first PHY */ 12786e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com phy = phy_find_first(greth->mdio); 12796e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com 1280d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!phy) { 1281d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1282d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "no PHY found\n"); 1283d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENXIO; 1284d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1285d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 12866e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com ret = phy_connect_direct(dev, phy, &greth_link_change, 12876e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com 0, greth->gbit_mac ? 12886e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com PHY_INTERFACE_MODE_GMII : 12896e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com PHY_INTERFACE_MODE_MII); 12906e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com if (ret) { 12916e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com if (netif_msg_ifup(greth)) 12926e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com dev_err(&dev->dev, "could not attach to PHY\n"); 12936e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com return ret; 12946e03718c852a7b2ce756e37ae340f4ebfec2f6f3kirjanov@gmail.com } 1295d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1296d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) 1297d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy->supported &= PHY_GBIT_FEATURES; 1298d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1299d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy->supported &= PHY_BASIC_FEATURES; 1300d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1301d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy->advertising = phy->supported; 1302d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1303d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->link = 0; 1304d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->speed = 0; 1305d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->duplex = -1; 1306d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->phy = phy; 1307d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1308d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1309d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1310d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1311d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic inline int phy_aneg_done(struct phy_device *phydev) 1312d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1313d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int retval; 1314d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1315d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo retval = phy_read(phydev, MII_BMSR); 1316d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1317d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); 1318d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1319d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1320d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int greth_mdio_init(struct greth_private *greth) 1321d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1322d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int ret, phy; 1323d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long timeout; 1324d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1325d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio = mdiobus_alloc(); 1326d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!greth->mdio) { 1327d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENOMEM; 1328d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1329d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1330d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->name = "greth-mdio"; 1331d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo snprintf(greth->mdio->id, MII_BUS_ID_SIZE, "%s-%d", greth->mdio->name, greth->irq); 1332d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->read = greth_mdio_read; 1333d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->write = greth_mdio_write; 1334d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->reset = greth_mdio_reset; 1335d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->priv = greth; 1336d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1337d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->irq = greth->mdio_irqs; 1338d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1339d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (phy = 0; phy < PHY_MAX_ADDR; phy++) 1340d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio->irq[phy] = PHY_POLL; 1341d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1342d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo ret = mdiobus_register(greth->mdio); 1343d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (ret) { 1344d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error; 1345d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1346d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1347d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo ret = greth_mdio_probe(greth->netdev); 1348d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (ret) { 1349d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1350d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&greth->netdev->dev, "failed to probe MDIO bus\n"); 1351d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto unreg_mdio; 1352d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1353d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1354d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy_start(greth->phy); 1355d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1356d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* If Ethernet debug link is used make autoneg happen right away */ 1357d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->edcl && greth_edcl == 1) { 1358d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy_start_aneg(greth->phy); 1359d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo timeout = jiffies + 6*HZ; 1360d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (!phy_aneg_done(greth->phy) && time_before(jiffies, timeout)) { 1361d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1362d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo genphy_read_status(greth->phy); 1363d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_link_change(greth->netdev); 1364d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1365d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1366d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1367d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1368d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembounreg_mdio: 1369d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_unregister(greth->mdio); 1370d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror: 1371d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_free(greth->mdio); 1372d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return ret; 1373d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1374d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1375d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo/* Initialize the GRETH MAC */ 137674888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic int __devinit greth_of_probe(struct platform_device *ofdev) 1377d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1378d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct net_device *dev; 1379d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth; 1380d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_regs *regs; 1381d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1382d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int i; 1383d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int err; 1384d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int tmp; 1385d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unsigned long timeout; 1386d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1387d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev = alloc_etherdev(sizeof(struct greth_private)); 1388d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1389d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (dev == NULL) 1390d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return -ENOMEM; 1391d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1392d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth = netdev_priv(dev); 1393d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->netdev = dev; 1394d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->dev = &ofdev->dev; 1395d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1396d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth_debug > 0) 1397d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->msg_enable = greth_debug; 1398d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo else 1399d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->msg_enable = GRETH_DEF_MSG_ENABLE; 1400d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1401d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo spin_lock_init(&greth->devlock); 1402d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1403d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->regs = of_ioremap(&ofdev->resource[0], 0, 1404d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo resource_size(&ofdev->resource[0]), 1405d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo "grlib-greth regs"); 1406d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1407d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->regs == NULL) { 1408d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1409d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "ioremap failure.\n"); 1410d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -EIO; 1411d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error1; 1412d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1413d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1414d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo regs = (struct greth_regs *) greth->regs; 141519e4875fb21a69fbf620e84769a74d189c69c58dGrant Likely greth->irq = ofdev->archdata.irqs[0]; 1416d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1417d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_set_drvdata(greth->dev, dev); 1418d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo SET_NETDEV_DEV(dev, greth->dev); 1419d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1420d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1421d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_dbg(greth->dev, "reseting controller.\n"); 1422d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1423d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Reset the controller. */ 1424d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->control, GRETH_RESET); 1425d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1426d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Wait for MAC to reset itself */ 1427d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo timeout = jiffies + HZ/100; 1428d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo while (GRETH_REGLOAD(regs->control) & GRETH_RESET) { 1429d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (time_after(jiffies, timeout)) { 1430d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -EIO; 1431d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1432d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "timeout when waiting for reset.\n"); 1433d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error2; 1434d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1435d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1436d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1437d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Get default PHY address */ 1438d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->phyaddr = (GRETH_REGLOAD(regs->mdio) >> 11) & 0x1F; 1439d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1440d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check if we have GBIT capable MAC */ 1441d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo tmp = GRETH_REGLOAD(regs->control); 1442d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->gbit_mac = (tmp >> 27) & 1; 1443d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1444d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check for multicast capability */ 1445d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->multicast = (tmp >> 25) & 1; 1446d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1447d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->edcl = (tmp >> 31) & 1; 1448d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1449d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* If we have EDCL we disable the EDCL speed-duplex FSM so 1450d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo * it doesn't interfere with the software */ 1451d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->edcl != 0) 1452d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX); 1453d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1454d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Check if MAC can handle MDIO interrupts */ 1455d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->mdio_int_en = (tmp >> 26) & 1; 1456d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1457d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = greth_mdio_init(greth); 1458d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (err) { 1459d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1460d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "failed to register MDIO bus\n"); 1461d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error2; 1462d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1463d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1464d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Allocate TX descriptor ring in coherent memory */ 1465d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->tx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev, 1466d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1024, 1467d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo &greth->tx_bd_base_phys, 1468d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GFP_KERNEL); 1469d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1470d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!greth->tx_bd_base) { 1471d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1472d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(&dev->dev, "could not allocate descriptor memory.\n"); 1473d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -ENOMEM; 1474d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error3; 1475d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1476d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1477d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memset(greth->tx_bd_base, 0, 1024); 1478d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1479d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Allocate RX descriptor ring in coherent memory */ 1480d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth->rx_bd_base = (struct greth_bd *) dma_alloc_coherent(greth->dev, 1481d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1024, 1482d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo &greth->rx_bd_base_phys, 1483d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GFP_KERNEL); 1484d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1485d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!greth->rx_bd_base) { 1486d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1487d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "could not allocate descriptor memory.\n"); 1488d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -ENOMEM; 1489d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error4; 1490d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1491d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1492d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo memset(greth->rx_bd_base, 0, 1024); 1493d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1494d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Get MAC address from: module param, OF property or ID prom */ 1495d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) { 1496d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (macaddr[i] != 0) 1497d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo break; 1498d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1499d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (i == 6) { 1500d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo const unsigned char *addr; 1501d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo int len; 150261c7a080a5a061c976988fd4b844dfb468dda255Grant Likely addr = of_get_property(ofdev->dev.of_node, "local-mac-address", 150361c7a080a5a061c976988fd4b844dfb468dda255Grant Likely &len); 1504d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (addr != NULL && len == 6) { 1505d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) 1506d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo macaddr[i] = (unsigned int) addr[i]; 1507d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 1508d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#ifdef CONFIG_SPARC 1509d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) 1510d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo macaddr[i] = (unsigned int) idprom->id_ethaddr[i]; 1511d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo#endif 1512d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1513d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1514d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1515d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo for (i = 0; i < 6; i++) 1516d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->dev_addr[i] = macaddr[i]; 1517d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1518d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo macaddr[5]++; 1519d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1520d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (!is_valid_ether_addr(&dev->dev_addr[0])) { 1521d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1522d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "no valid ethernet address, aborting.\n"); 1523d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo err = -EINVAL; 1524d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error5; 1525d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1526d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1527d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]); 1528d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | 1529d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->dev_addr[4] << 8 | dev->dev_addr[5]); 1530d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1531d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Clear all pending interrupts except PHY irq */ 1532d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo GRETH_REGSAVE(regs->status, 0xFF); 1533d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1534d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->gbit_mac) { 1535131ae329702755d897c6072c7839086b0702fb10Michał Mirosław dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | 1536131ae329702755d897c6072c7839086b0702fb10Michał Mirosław NETIF_F_RXCSUM; 1537131ae329702755d897c6072c7839086b0702fb10Michał Mirosław dev->features = dev->hw_features | NETIF_F_HIGHDMA; 1538d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit; 1539d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1540d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1541d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->multicast) { 1542afc4b13df143122f99a0eb10bfefb216c2806de0Jiri Pirko greth_netdev_ops.ndo_set_rx_mode = greth_set_multicast_list; 1543d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->flags |= IFF_MULTICAST; 1544d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } else { 1545d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->flags &= ~IFF_MULTICAST; 1546d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1547d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1548d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->netdev_ops = &greth_netdev_ops; 1549d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev->ethtool_ops = &greth_ethtool_ops; 1550d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1551cb5d991a99104565f7b622b1b97587f4b1effa82Tobias Klauser err = register_netdev(dev); 1552cb5d991a99104565f7b622b1b97587f4b1effa82Tobias Klauser if (err) { 1553d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (netif_msg_probe(greth)) 1554d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_err(greth->dev, "netdevice registration failed.\n"); 1555d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo goto error5; 1556d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo } 1557d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1558d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* setup NAPI */ 1559d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo netif_napi_add(dev, &greth->napi, greth_poll, 64); 1560d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1561d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1562d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1563d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror5: 1564d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(greth->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys); 1565d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror4: 1566d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(greth->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys); 1567d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror3: 1568d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_unregister(greth->mdio); 1569d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror2: 1570d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo of_iounmap(&ofdev->resource[0], greth->regs, resource_size(&ofdev->resource[0])); 1571d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glemboerror1: 1572d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo free_netdev(dev); 1573d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return err; 1574d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1575d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 15762dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit greth_of_remove(struct platform_device *of_dev) 1577d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 1578d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct net_device *ndev = dev_get_drvdata(&of_dev->dev); 1579d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo struct greth_private *greth = netdev_priv(ndev); 1580d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1581d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo /* Free descriptor areas */ 1582d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(&of_dev->dev, 1024, greth->rx_bd_base, greth->rx_bd_base_phys); 1583d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1584d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dma_free_coherent(&of_dev->dev, 1024, greth->tx_bd_base, greth->tx_bd_base_phys); 1585d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1586d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo dev_set_drvdata(&of_dev->dev, NULL); 1587d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1588d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo if (greth->phy) 1589d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo phy_stop(greth->phy); 1590d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo mdiobus_unregister(greth->mdio); 1591d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1592d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo unregister_netdev(ndev); 1593d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo free_netdev(ndev); 1594d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1595d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0])); 1596d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1597d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo return 0; 1598d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1599d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1600d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic struct of_device_id greth_of_match[] = { 1601d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo { 1602d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .name = "GAISLER_ETHMAC", 1603d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo }, 1604ad4650a89ac47bd153cbb76c3fd6eb1fa6f315b7Daniel Hellstrom { 1605ad4650a89ac47bd153cbb76c3fd6eb1fa6f315b7Daniel Hellstrom .name = "01_01d", 1606ad4650a89ac47bd153cbb76c3fd6eb1fa6f315b7Daniel Hellstrom }, 1607d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo {}, 1608d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1609d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1610d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_DEVICE_TABLE(of, greth_of_match); 1611d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 161274888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic struct platform_driver greth_of_driver = { 1613bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .driver = { 1614bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .name = "grlib-greth", 1615bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .owner = THIS_MODULE, 1616bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller .of_match_table = greth_of_match, 1617bc284f94f84c3d76e49c6f3df9028c503f9589d9David S. Miller }, 1618d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .probe = greth_of_probe, 1619d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo .remove = __devexit_p(greth_of_remove), 1620d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo}; 1621d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1622d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic int __init greth_init(void) 1623d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 162474888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likely return platform_driver_register(&greth_of_driver); 1625d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1626d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1627d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembostatic void __exit greth_cleanup(void) 1628d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo{ 162974888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likely platform_driver_unregister(&greth_of_driver); 1630d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo} 1631d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1632d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembomodule_init(greth_init); 1633d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembomodule_exit(greth_cleanup); 1634d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer Glembo 1635d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_AUTHOR("Aeroflex Gaisler AB."); 1636d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_DESCRIPTION("Aeroflex Gaisler Ethernet MAC driver"); 1637d4c41139df6e74c6fff0cbac43e51cab782133beKristoffer GlemboMODULE_LICENSE("GPL"); 1638