/*
* meth.c -- O2 Builtin 10/100 Ethernet driver
*
* Copyright (C) 2001-2003 Ilya Volynets
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/device.h> /* struct device, et al */
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/tcp.h> /* struct tcphdr */
#include <linux/skbuff.h>
#include <linux/mii.h> /* MII definitions */
#include <asm/ip32/mace.h>
#include <asm/ip32/ip32_ints.h>
#include <asm/io.h>
#include "meth.h"
#ifndef MFE_DEBUG
#define MFE_DEBUG 0
#endif
#if MFE_DEBUG>=1
#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __func__ , ## args)
#define MFE_RX_DEBUG 2
#else
#define DPRINTK(str,args...)
#define MFE_RX_DEBUG 0
#endif
static const char *meth_str="SGI O2 Fast Ethernet";
#define HAVE_TX_TIMEOUT
/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
#define TX_TIMEOUT (400*HZ/1000)
#ifdef HAVE_TX_TIMEOUT
static int timeout = TX_TIMEOUT;
module_param(timeout, int, 0);
#endif
/*
* This structure is private to each device. It is used to pass
* packets in and out, so there is place for a packet
*/
struct meth_private {
/* in-memory copy of MAC Control register */
unsigned long mac_ctrl;
/* in-memory copy of DMA Control register */
unsigned long dma_ctrl;
/* address of PHY, used by mdio_* functions, initialized in mdio_probe */
unsigned long phy_addr;
tx_packet *tx_ring;
dma_addr_t tx_ring_dma;
struct sk_buff *tx_skbs[TX_RING_ENTRIES];
dma_addr_t tx_skb_dmas[TX_RING_ENTRIES];
unsigned long tx_read, tx_write, tx_count;
rx_packet *rx_ring[RX_RING_ENTRIES];
dma_addr_t rx_ring_dmas[RX_RING_ENTRIES];
struct sk_buff *rx_skbs[RX_RING_ENTRIES];
unsigned long rx_write;
spinlock_t meth_lock;
};
static void meth_tx_timeout(struct net_device *dev);
static irqreturn_t meth_interrupt(int irq, void *dev_id);
/* global, initialized in ip32-setup.c */
char o2meth_eaddr[8]={0,0,0,0,0,0,0,0};
static inline void load_eaddr(struct net_device *dev)
{
int i;
u64 macaddr;
DPRINTK("Loading MAC Address: %pM\n", dev->dev_addr);
macaddr = 0;
for (i = 0; i < 6; i++)
macaddr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
mace->eth.mac_addr = macaddr;
|