Commit f9ff0abb authored by Jeff Garzik's avatar Jeff Garzik

Merge mandrakesoft.com:/home/jgarzik/vanilla/linus-2.5

into mandrakesoft.com:/home/jgarzik/repo/net-drivers-2.5
parents 8cceac24 4008bc66
D-Link DL2000-based Gigabit Ethernet Adapter Installation
for Linux
Jan 02, 2002
Jan 29, 2002
Contents
========
......@@ -199,8 +199,8 @@ media=media_type - Specifies the media type the NIC operates at.
6 1000Mbps full duplex.
By default, the NIC operates at autosense.
Note that only 1000mbps_fd and 1000mbps_hd
types are available for fiber adapter.
1000mbps_fd and 1000mbps_hd types are only
available for fiber adapter.
vlan=[0|1] - Specifies the VLAN ID. If vlan=0, the
Virtual Local Area Network (VLAN) function is
......
......@@ -65,7 +65,10 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/sockios.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#include <linux/if_vlan.h>
#endif
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
......@@ -320,9 +323,11 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
#if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \
defined(NETIF_F_HW_VLAN_RX)
#define ACENIC_DO_VLAN 1
#define ACENIC_DO_VLAN 1
#define ACE_RCB_VLAN_FLAG RCB_FLG_VLAN_ASSIST
#else
#define ACENIC_DO_VLAN 0
#define ACENIC_DO_VLAN 0
#define ACE_RCB_VLAN_FLAG 0
#endif
#include "acenic.h"
......@@ -563,7 +568,7 @@ static int tx_ratio[ACE_MAX_MOD_PARMS];
static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
static char version[] __initdata =
"acenic.c: v0.88 03/14/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
"acenic.c: v0.89 03/15/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
static struct net_device *root_dev;
......@@ -1461,10 +1466,8 @@ static int __init ace_init(struct net_device *dev)
set_aceaddr(&info->rx_std_ctrl.rngptr, ap->rx_ring_base_dma);
info->rx_std_ctrl.max_len = ACE_STD_MTU + ETH_HLEN + 4;
info->rx_std_ctrl.flags = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
#if ACENIC_DO_VLAN
info->rx_std_ctrl.flags |= RCB_FLG_VLAN_ASSIST;
#endif
info->rx_std_ctrl.flags =
RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
memset(ap->rx_std_ring, 0,
RX_STD_RING_ENTRIES * sizeof(struct rx_desc));
......@@ -1479,10 +1482,8 @@ static int __init ace_init(struct net_device *dev)
(ap->rx_ring_base_dma +
(sizeof(struct rx_desc) * RX_STD_RING_ENTRIES)));
info->rx_jumbo_ctrl.max_len = 0;
info->rx_jumbo_ctrl.flags = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
#if ACENIC_DO_VLAN
info->rx_jumbo_ctrl.flags |= RCB_FLG_VLAN_ASSIST;
#endif
info->rx_jumbo_ctrl.flags =
RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
memset(ap->rx_jumbo_ring, 0,
RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc));
......@@ -1504,10 +1505,7 @@ static int __init ace_init(struct net_device *dev)
RX_JUMBO_RING_ENTRIES))));
info->rx_mini_ctrl.max_len = ACE_MINI_SIZE;
info->rx_mini_ctrl.flags =
RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
#if ACENIC_DO_VLAN
info->rx_mini_ctrl.flags |= RCB_FLG_VLAN_ASSIST;
#endif
RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|ACE_RCB_VLAN_FLAG;
for (i = 0; i < RX_MINI_RING_ENTRIES; i++)
ap->rx_mini_ring[i].flags =
......@@ -1554,7 +1552,7 @@ static int __init ace_init(struct net_device *dev)
}
info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap);
tmp = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
tmp = RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
/*
* The Tigon I does not like having the TX ring in host memory ;-(
......@@ -1563,9 +1561,6 @@ static int __init ace_init(struct net_device *dev)
tmp |= RCB_FLG_TX_HOST_RING;
#if TX_COAL_INTS_ONLY
tmp |= RCB_FLG_COAL_INT_ONLY;
#endif
#if ACENIC_DO_VLAN
tmp |= RCB_FLG_VLAN_ASSIST;
#endif
info->tx_ctrl.flags = tmp;
......@@ -1592,7 +1587,7 @@ static int __init ace_init(struct net_device *dev)
ace_set_rxtx_parms(dev, 0);
if (board_idx == BOARD_IDX_OVERFLOW) {
printk(KERN_WARNING "%s: more then %i NICs detected, "
printk(KERN_WARNING "%s: more than %i NICs detected, "
"ignoring module parameters!\n",
dev->name, ACE_MAX_MOD_PARMS);
} else if (board_idx >= 0) {
......@@ -2181,14 +2176,6 @@ static u32 ace_handle_event(struct net_device *dev, u32 evtcsm, u32 evtprd)
}
#if ACENIC_DO_VLAN
static int ace_vlan_rx(struct ace_private *ap, struct sk_buff *skb, u16 vlan_tag)
{
return vlan_hwaccel_rx(skb, ap->vlgrp, vlan_tag);
}
#endif
static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
{
struct ace_private *ap = dev->priv;
......@@ -2274,11 +2261,9 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
}
/* send it up */
#if ACENIC_DO_VLAN
if (ap->vlgrp != NULL &&
(bd_flags & BD_FLG_VLAN_TAG)) {
ace_vlan_rx(ap, skb, retdesc->vlan);
if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) {
vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan);
} else
#endif
netif_rx(skb);
......
......@@ -642,10 +642,6 @@ struct ace_private
struct ace_skb *skb;
dma_addr_t info_dma; /* 32/64 bit */
#if ACENIC_DO_VLAN
struct vlan_group *vlgrp;
#endif
int version, link;
int promisc, mcast_all;
......@@ -655,7 +651,6 @@ struct ace_private
struct tx_desc *tx_ring;
u32 tx_prd;
volatile u32 tx_ret_csm;
struct timer_list timer;
int tx_ring_entries;
/*
......@@ -675,6 +670,10 @@ struct ace_private
struct rx_desc *rx_mini_ring;
struct rx_desc *rx_return_ring;
#if ACENIC_DO_VLAN
struct vlan_group *vlgrp;
#endif
int tasklet_pending, jumbo;
struct tasklet_struct ace_tasklet;
......
......@@ -449,11 +449,17 @@ static int de620_open(struct net_device *dev)
return ret;
}
if (adapter_init(dev))
return -EIO;
if (adapter_init(dev)) {
ret = -EIO;
goto out_free_irq;
}
netif_start_queue(dev);
return 0;
out_free_irq:
free_irq(dev->irq, dev);
return ret;
}
/************************************************
......@@ -850,7 +856,10 @@ int __init de620_probe(struct net_device *dev)
return -EBUSY;
}
#endif
request_region(dev->base_addr, 3, "de620");
if (!request_region(dev->base_addr, 3, "de620")) {
printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr);
return -EBUSY;
}
/* else, got it! */
printk(", Ethernet Address: %2.2X",
......
/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
/*
Copyright (c) 2001 by D-Link Corporation
Copyright (c) 2001,2002 by D-Link Corporation
Written by Edward Peng.<edward_peng@dlink.com.tw>
Created 03-May-2001, base on Linux' sundance.c.
......@@ -27,12 +27,14 @@
Added tx_coalesce paramter.
1.07 2002/01/03 Fixed miscount of RX frame error.
1.08 2002/01/17 Fixed the multicast bug.
1.09 2002/03/07 Move rx-poll-now to re-fill loop.
Added rio_timer() to watch rx buffers.
*/
#include "dl2k.h"
static char version[] __devinitdata =
KERN_INFO "D-Link DL2000-based linux driver v1.08 2002/01/17\n";
KERN_INFO "D-Link DL2000-based linux driver v1.09 2002/03/07\n";
#define MAX_UNITS 8
static int mtu[MAX_UNITS];
......@@ -42,9 +44,10 @@ static char *media[MAX_UNITS];
static int tx_flow[MAX_UNITS];
static int rx_flow[MAX_UNITS];
static int copy_thresh;
static int rx_coalesce = DEFAULT_RXC;
static int rx_timeout = DEFAULT_RXT;
static int tx_coalesce = DEFAULT_TXC;
static int rx_coalesce; /* Rx frame count each interrupt */
static int rx_timeout; /* Rx DMA wait time in 64ns increments */
static int tx_coalesce = DEFAULT_TXC; /* HW xmit count each TxComplete [1-8] */
MODULE_AUTHOR ("Edward Peng");
MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
......@@ -71,6 +74,7 @@ static int max_intrloop = 50;
static int multicast_filter_limit = 0x40;
static int rio_open (struct net_device *dev);
static void rio_timer (unsigned long data);
static void tx_timeout (struct net_device *dev);
static void alloc_list (struct net_device *dev);
static int start_xmit (struct sk_buff *skb, struct net_device *dev);
......@@ -146,6 +150,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
np->chip_id = chip_idx;
np->pdev = pdev;
spin_lock_init (&np->lock);
spin_lock_init (&np->rx_lock);
/* Parse manual configuration */
np->an_enable = 1;
......@@ -260,6 +265,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
np->an_enable = 1;
mii_set_media (dev);
}
pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id);
/* Reset all logic functions */
writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
......@@ -340,7 +346,7 @@ parse_eeprom (struct net_device *dev)
}
/* Check CRC */
crc = ~ether_crc_le(256 - 4, sromdata);
crc = ~ether_crc_le(256 - 4, sromdata);
if (psrom->crc != crc) {
printk (KERN_ERR "%s: EEPROM data CRC error.\n", dev->name);
return -1;
......@@ -421,8 +427,10 @@ rio_open (struct net_device *dev)
ioaddr + RxDMAIntCtrl);
}
/* Set RIO to poll every N*320nsec. */
writeb (0xff, ioaddr + RxDMAPollPeriod);
writeb (0x20, ioaddr + RxDMAPollPeriod);
writeb (0xff, ioaddr + TxDMAPollPeriod);
writeb (0x30, ioaddr + RxDMABurstThresh);
writeb (0x30, ioaddr + RxDMAUrgentThresh);
netif_start_queue (dev);
writel (StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl);
/* VLAN supported */
......@@ -445,9 +453,59 @@ rio_open (struct net_device *dev)
/* clear statistics */
get_stats (dev);
init_timer (&np->timer);
np->timer.expires = jiffies + 1*HZ;
np->timer.data = (unsigned long) dev;
np->timer.function = &rio_timer;
add_timer (&np->timer);
return 0;
}
static void
rio_timer (unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct netdev_private *np = dev->priv;
unsigned int entry;
int next_tick = 1*HZ;
unsigned long flags;
/* Recover rx ring exhausted error */
if (np->cur_rx - np->old_rx >= RX_RING_SIZE) {
printk(KERN_INFO "Try to recover rx ring exhausted...\n");
spin_lock_irqsave(&np->rx_lock, flags);
/* Re-allocate skbuffs to fill the descriptor ring */
for (; np->cur_rx - np->old_rx > 0; np->old_rx++) {
struct sk_buff *skb;
entry = np->old_rx % RX_RING_SIZE;
/* Dropped packets don't need to re-allocate */
if (np->rx_skbuff[entry] == NULL) {
skb = dev_alloc_skb (np->rx_buf_sz);
if (skb == NULL) {
np->rx_ring[entry].fraginfo = 0;
printk (KERN_INFO
"%s: Still unable to re-allocate Rx skbuff.#%d\n",
dev->name, entry);
break;
}
np->rx_skbuff[entry] = skb;
skb->dev = dev;
/* 16 byte align the IP header */
skb_reserve (skb, 2);
np->rx_ring[entry].fraginfo =
cpu_to_le64 (pci_map_single
(np->pdev, skb->tail, np->rx_buf_sz,
PCI_DMA_FROMDEVICE));
}
np->rx_ring[entry].fraginfo |=
cpu_to_le64 (np->rx_buf_sz) << 48;
np->rx_ring[entry].status = 0;
} /* end for */
spin_unlock_irqrestore (&np->rx_lock, flags);
} /* end if */
np->timer.expires = jiffies + next_tick;
add_timer(&np->timer);
}
static void
tx_timeout (struct net_device *dev)
{
......@@ -499,16 +557,14 @@ alloc_list (struct net_device *dev)
np->tx_ring[i].status = cpu_to_le64 (TFDDone);
np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma +
((i+1)%TX_RING_SIZE) *
sizeof (struct
netdev_desc));
sizeof (struct netdev_desc));
}
/* Initialize Rx descriptors */
for (i = 0; i < RX_RING_SIZE; i++) {
np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma +
((i + 1) % RX_RING_SIZE) *
sizeof (struct
netdev_desc));
sizeof (struct netdev_desc));
np->rx_ring[i].status = 0;
np->rx_ring[i].fraginfo = 0;
np->rx_skbuff[i] = 0;
......@@ -529,8 +585,8 @@ alloc_list (struct net_device *dev)
skb_reserve (skb, 2); /* 16 byte align the IP header. */
/* Rubicon now supports 40 bits of addressing space. */
np->rx_ring[i].fraginfo =
cpu_to_le64 (pci_map_single
(np->pdev, skb->tail, np->rx_buf_sz,
cpu_to_le64 ( pci_map_single (
np->pdev, skb->tail, np->rx_buf_sz,
PCI_DMA_FROMDEVICE));
np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
}
......@@ -773,6 +829,8 @@ receive_packet (struct net_device *dev)
int entry = np->cur_rx % RX_RING_SIZE;
int cnt = np->old_rx + RX_RING_SIZE - np->cur_rx;
int rx_shift;
spin_lock (&np->rx_lock);
if (np->old_rx > RX_RING_SIZE) {
rx_shift = RX_RING_SIZE;
np->old_rx -= rx_shift;
......@@ -828,12 +886,14 @@ receive_packet (struct net_device *dev)
skb_put (skb, pkt_len);
}
skb->protocol = eth_type_trans (skb, dev);
#if 0
#if 0
/* Checksum done by hw, but csum value unavailable. */
if (!(frame_status & (TCPError | UDPError | IPError))) {
if (np->pci_rev_id >= 0x0c &&
!(frame_status & (TCPError | UDPError | IPError))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
}
#endif
netif_rx (skb);
dev->last_rx = jiffies;
}
......@@ -849,9 +909,10 @@ receive_packet (struct net_device *dev)
skb = dev_alloc_skb (np->rx_buf_sz);
if (skb == NULL) {
np->rx_ring[entry].fraginfo = 0;
printk (KERN_ERR
"%s: Allocate Rx buffer error!",
dev->name);
printk (KERN_INFO
"%s: receive_packet: "
"Unable to re-allocate Rx skbuff.#%d\n",
dev->name, entry);
break;
}
np->rx_skbuff[entry] = skb;
......@@ -866,13 +927,12 @@ receive_packet (struct net_device *dev)
np->rx_ring[entry].fraginfo |=
cpu_to_le64 (np->rx_buf_sz) << 48;
np->rx_ring[entry].status = 0;
/* RxDMAPollNow */
writel (readl (dev->base_addr + DMACtrl) | 0x00000010,
dev->base_addr + DMACtrl);
}
/* RxDMAPollNow */
writel (readl (dev->base_addr + DMACtrl) | 0x00000010,
dev->base_addr + DMACtrl);
DEBUG_RFD_DUMP (np, 2);
spin_unlock(&np->rx_lock);
return 0;
}
......@@ -1006,7 +1066,7 @@ set_multicast (struct net_device *dev)
hash_table[0] = hash_table[1] = 0;
/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
hash_table[1] |= 0x02000000;
hash_table[1] |= cpu_to_le32(0x02000000);
if (dev->flags & IFF_PROMISC) {
/* Receive all frames promiscuously. */
rx_mode = ReceiveAllFrames;
......@@ -1020,11 +1080,16 @@ set_multicast (struct net_device *dev)
rx_mode =
ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist=mclist->next) {
i++, mclist=mclist->next) {
crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
for (index=0, bit=0; bit<6; bit++, crc<<=1) {
if (crc & 0x80000000) index |= 1 << bit;
}
/* The inverted high significant 6 bits of CRC are
used as an index to hashtable */
for (index = 0, bit = 0; bit < 6; bit++)
if (test_bit(31 - bit, &crc))
set_bit(bit, &index);
hash_table[index / 32] |= (1 << (index % 32));
}
} else {
......@@ -1094,6 +1159,7 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
np->old_rx);
break;
case SIOCDEVPRIVATE + 8:
printk("TX ring:\n");
for (i = 0; i < TX_RING_SIZE; i++) {
desc = &np->tx_ring[i];
printk
......@@ -1629,7 +1695,8 @@ rio_close (struct net_device *dev)
writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
synchronize_irq ();
free_irq (dev->irq, dev);
del_timer_sync (&np->timer);
/* Free all the skbuffs in the queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
np->rx_ring[i].status = 0;
......@@ -1679,10 +1746,10 @@ rio_remove1 (struct pci_dev *pdev)
}
static struct pci_driver rio_driver = {
name:"dl2k",
id_table:rio_pci_tbl,
probe:rio_probe1,
remove: __devexit_p(rio_remove1),
name: "dl2k",
id_table: rio_pci_tbl,
probe: rio_probe1,
remove: __devexit_p(rio_remove1),
};
static int __init
......
/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
/*
Copyright (c) 2001 by D-Link Corporation
Copyright (c) 2001, 2002 by D-Link Corporation
Written by Edward Peng.<edward_peng@dlink.com.tw>
Created 03-May-2001, base on Linux' sundance.c.
......@@ -649,6 +649,7 @@ struct netdev_private {
dma_addr_t rx_ring_dma;
struct pci_dev *pdev;
spinlock_t lock;
spinlock_t rx_lock;
struct net_device_stats stats;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int speed; /* Operating speed */
......@@ -664,9 +665,11 @@ struct netdev_private {
unsigned int tx_flow:1; /* Tx flow control enable */
unsigned int rx_flow:1; /* Rx flow control enable */
unsigned int phy_media:1; /* 1: fiber, 0: copper */
unsigned char pci_rev_id; /* PCI revision ID */
struct netdev_desc *last_tx; /* Last Tx descriptor used. */
unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */
unsigned long cur_tx, old_tx;
struct timer_list timer;
int wake_polarity;
char name[256]; /* net device description */
u8 duplex_polarity;
......
......@@ -10,7 +10,7 @@
O_TARGET := e100.o
obj-y := e100_main.o e100_config.o e100_proc.o e100_phy.o \
e100_eeprom.o
e100_eeprom.o e100_test.o
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make
......@@ -899,6 +899,15 @@ struct cfg_params {
int PollingMaxWork;
u32 b_params;
};
#ifdef ETHTOOL_TEST
struct ethtool_lpbk_data{
dma_addr_t dma_handle;
tcb_t *tcb;
rfd_t *rfd;
};
#endif
struct e100_private {
u32 flags; /* board management flags */
......@@ -988,6 +997,9 @@ struct e100_private {
u32 wolopts;
u16 ip_lbytes;
#endif
#ifdef ETHTOOL_TEST
struct ethtool_lpbk_data loopback;
#endif
#ifdef CONFIG_PM
u32 pci_state[16];
......@@ -1028,4 +1040,23 @@ extern void e100_deisolate_driver(struct e100_private *bdp,
extern unsigned char e100_hw_reset_recover(struct e100_private *bdp,
u32 reset_cmd);
#ifdef ETHTOOL_TEST
#define ROM_TEST_FAIL 0x01
#define REGISTER_TEST_FAIL 0x02
#define SELF_TEST_FAIL 0x04
#define TEST_TIMEOUT 0x08
enum test_offsets {
E100_EEPROM_TEST_FAIL = 0,
E100_CHIP_TIMEOUT,
E100_ROM_TEST_FAIL,
E100_REG_TEST_FAIL,
E100_MAC_TEST_FAIL,
E100_LPBK_MAC_FAIL,
E100_LPBK_PHY_FAIL,
E100_MAX_TEST_RES
};
#endif
#endif
......@@ -593,3 +593,102 @@ e100_config_wol(struct e100_private *bdp)
}
#endif
#ifdef ETHTOOL_TEST
/**
* e100_config_loopback_mode
* @bdp: atapter's private data struct
* @mode: loopback mode(phy/mac/none)
*
*/
unsigned char
e100_config_loopback_mode(struct e100_private *bdp, u8 mode)
{
unsigned char bc_changed = false;
u8 config_byte;
spin_lock_bh(&(bdp->config_lock));
switch (mode) {
case NO_LOOPBACK:
config_byte = CB_CFIG_LOOPBACK_NORMAL;
break;
case MAC_LOOPBACK:
config_byte = CB_CFIG_LOOPBACK_INTERNAL;
break;
case PHY_LOOPBACK:
config_byte = CB_CFIG_LOOPBACK_EXTERNAL;
break;
default:
printk(KERN_NOTICE "e100_config_loopback_mode: "
"Invalid argument 'mode': %d\n", mode);
goto exit;
}
if ((bdp->config[10] & CB_CFIG_LOOPBACK_MODE) != config_byte) {
bdp->config[10] &= (~CB_CFIG_LOOPBACK_MODE);
bdp->config[10] |= config_byte;
E100_CONFIG(bdp, 10);
bc_changed = true;
}
exit:
spin_unlock_bh(&(bdp->config_lock));
return bc_changed;
}
unsigned char
e100_config_tcb_ext_enable(struct e100_private *bdp, unsigned char enable)
{
unsigned char bc_changed = false;
spin_lock_bh(&(bdp->config_lock));
if (enable) {
if (bdp->config[6] & CB_CFIG_EXT_TCB_DIS) {
bdp->config[6] &= (~CB_CFIG_EXT_TCB_DIS);
E100_CONFIG(bdp, 6);
bc_changed = true;
}
} else {
if (!(bdp->config[6] & CB_CFIG_EXT_TCB_DIS)) {
bdp->config[6] |= CB_CFIG_EXT_TCB_DIS;
E100_CONFIG(bdp, 6);
bc_changed = true;
}
}
spin_unlock_bh(&(bdp->config_lock));
return bc_changed;
}
unsigned char
e100_config_dynamic_tbd(struct e100_private *bdp, unsigned char enable)
{
unsigned char bc_changed = false;
spin_lock_bh(&(bdp->config_lock));
if (enable) {
if (!(bdp->config[7] & CB_CFIG_DYNTBD_EN)) {
bdp->config[7] |= CB_CFIG_DYNTBD_EN;
E100_CONFIG(bdp, 7);
bc_changed = true;
}
} else {
if (bdp->config[7] & CB_CFIG_DYNTBD_EN) {
bdp->config[7] &= (~CB_CFIG_DYNTBD_EN);
E100_CONFIG(bdp, 7);
bc_changed = true;
}
}
spin_unlock_bh(&(bdp->config_lock));
return bc_changed;
}
#endif
......@@ -190,6 +190,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define CB_CFIG_LONG_RX_OK BIT_3
#define NO_LOOPBACK 0
#define MAC_LOOPBACK 0x01
#define PHY_LOOPBACK 0x02
/* function prototypes */
extern void e100_config_init(struct e100_private *bdp);
extern unsigned char e100_force_config(struct e100_private *bdp);
......@@ -201,5 +205,8 @@ extern void e100_config_mulcast_enbl(struct e100_private *bdp,
unsigned char enable);
extern void e100_config_ifs(struct e100_private *bdp);
extern void e100_config_force_dplx(struct e100_private *bdp);
extern u8 e100_config_loopback_mode(struct e100_private *bdp, u8 mode);
extern u8 e100_config_dynamic_tbd(struct e100_private *bdp, u8 enable);
extern u8 e100_config_tcb_ext_enable(struct e100_private *bdp, u8 enable);
#endif /* _E100_CONFIG_INC_ */
......@@ -146,6 +146,23 @@ static unsigned char e100_setup_filter(struct e100_private *bdp);
static void e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp);
static u16 e100_get_ip_lbytes(struct net_device *dev);
extern void e100_config_wol(struct e100_private *bdp);
#endif
#ifdef ETHTOOL_TEST
extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags);
static int e100_ethtool_test(struct net_device *, struct ifreq *);
#endif
#ifdef ETHTOOL_GSTRINGS
static int e100_ethtool_gstrings(struct net_device *, struct ifreq *);
static char *test_strings[] = {
"E100_EEPROM_TEST_FAIL",
"E100_CHIP_TIMEOUT",
"E100_ROM_TEST_FAIL",
"E100_REG_TEST_FAIL",
"E100_MAC_TEST_FAIL",
"E100_LPBK_MAC_FAIL",
"E100_LPBK_PHY_FAIL"
};
#endif
#endif /*E100_ETHTOOL_IOCTL */
......@@ -165,7 +182,7 @@ static void e100_non_tx_background(unsigned long);
/* Global Data structures and variables */
char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
#define E100_VERSION "2.0.24-pre1"
#define E100_VERSION "2.0.25-pre1"
#define E100_FULL_DRIVER_NAME "Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver "
......@@ -382,6 +399,7 @@ static void e100_set_multi_exec(struct net_device *dev);
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
MODULE_DESCRIPTION(E100_FULL_DRIVER_NAME E100_VERSION);
MODULE_LICENSE("Dual BSD/GPL");
EXPORT_NO_SYMBOLS;
E100_PARAM(TxDescriptors, "Number of transmit descriptors");
E100_PARAM(RxDescriptors, "Number of receive descriptors");
......@@ -2715,8 +2733,10 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
ntcb_hdr->cb_lnk_ptr = 0;
wmb();
if (in_interrupt())
return e100_delayed_exec_non_cu_cmd(bdp, command);
if (in_interrupt() || netif_running(bdp->device))
if (netif_running(bdp->device) && (!bdp->driver_isolated))
return e100_delayed_exec_non_cu_cmd(bdp, command);
spin_lock_bh(&(bdp->bd_non_tx_lock));
......@@ -3301,6 +3321,16 @@ e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
case ETHTOOL_SWOL:
rc = e100_ethtool_wol(dev, ifr);
break;
#endif
#ifdef ETHTOOL_TEST
case ETHTOOL_TEST:
rc = e100_ethtool_test(dev, ifr);
break;
#endif
#ifdef ETHTOOL_GSTRINGS
case ETHTOOL_GSTRINGS:
rc = e100_ethtool_gstrings(dev,ifr);
break;
#endif
default:
break;
......@@ -3464,6 +3494,36 @@ e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr)
}
#endif
#ifdef ETHTOOL_TEST
static int
e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
{
struct ethtool_test *info;
int rc = -EFAULT;
info = kmalloc(sizeof(*info) + E100_MAX_TEST_RES * sizeof(u64),
GFP_ATOMIC);
if (!info)
return -EFAULT;
memset((void *) info, 0, sizeof(*info) +
E100_MAX_TEST_RES * sizeof(u64));
if (copy_from_user(info, ifr->ifr_data, sizeof(*info)))
goto exit;
info->flags = e100_run_diag(dev, info->data, info->flags);
if (!copy_to_user(ifr->ifr_data, info,
sizeof(*info) + E100_MAX_TEST_RES * sizeof(u64)))
rc = 0;
exit:
kfree(info);
return rc;
}
#endif
#ifdef ETHTOOL_NWAY_RST
static int
e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr)
......@@ -3505,7 +3565,9 @@ e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
#ifdef ETHTOOL_GEEPROM
info.eedump_len = (bdp->eeprom_size << 1);
#endif
#ifdef ETHTOOL_TEST
info.testinfo_len = E100_MAX_TEST_RES;
#endif
if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
return -EFAULT;
......@@ -3737,6 +3799,51 @@ e100_ethtool_wol(struct net_device *dev, struct ifreq *ifr)
return res;
}
#endif
#ifdef ETHTOOL_GSTRINGS
static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
{
struct ethtool_gstrings info;
char *strings = NULL;
char *usr_strings;
int i;
memset((void *) &info, 0, sizeof(info));
usr_strings = (u8 *) (ifr->ifr_data +
offsetof(struct ethtool_gstrings, data));
if (copy_from_user(&info, ifr->ifr_data, sizeof (info)))
return -EFAULT;
switch (info.string_set) {
case ETH_SS_TEST:
if (info.len > E100_MAX_TEST_RES)
info.len = E100_MAX_TEST_RES;
strings = kmalloc(info.len * ETH_GSTRING_LEN, GFP_ATOMIC);
if (!strings)
return -EFAULT;
memset(strings, 0, info.len * ETH_GSTRING_LEN);
for (i = 0; i < info.len; i++) {
sprintf(strings + i * ETH_GSTRING_LEN, "%-31s",
test_strings[i]);
}
break;
default:
return -EOPNOTSUPP;
}
if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
return -EFAULT;
if (copy_to_user(usr_strings, strings, info.len * ETH_GSTRING_LEN))
return -EFAULT;
kfree(strings);
return 0;
}
#endif
#endif /*E100_ETHTOOL_IOCTL */
......
This diff is collapsed.
......@@ -60,11 +60,14 @@
LK1.1.12:
* fix power-up sequence
LK1.1.13:
* revert version 1.1.12, power-up sequence "fix"
*/
#define DRV_NAME "epic100"
#define DRV_VERSION "1.11+LK1.1.12"
#define DRV_RELDATE "Jan 18, 2002"
#define DRV_VERSION "1.11+LK1.1.13"
#define DRV_RELDATE "Mar 20, 2002"
/* The user-configurable values.
......@@ -678,8 +681,9 @@ static int epic_open(struct net_device *dev)
required by the details of which bits are reset and the transceiver
wiring on the Ositech CardBus card.
*/
outl(0x12, ioaddr + MIICfg);
#if 0
outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg);
#endif
if (ep->chip_flags & MII_PWRDWN)
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
......
......@@ -267,21 +267,28 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
{0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},
{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */
#if 0
{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga */
#endif
{0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, /* SMC EZConnect SMC2602W,
Eumitcom PCI WL11000,
Addtron AWA-100*/
{0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, /* Global Sun Tech GL24110P */
{0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,}, /* Reported working, but unknown */
{0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,}, /* Linksys WDT11 */
{0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,}, /* USR 2415 */
{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, /* Belkin F5D6000 */
{0,},
};
MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table);
static struct pci_driver orinoco_plx_driver = {
name:"orinoco_plx",
id_table:orinoco_plx_pci_id_table,
probe:orinoco_plx_init_one,
remove:__devexit_p(orinoco_plx_remove_one),
suspend:0,
resume:0
name: "orinoco_plx",
id_table: orinoco_plx_pci_id_table,
probe: orinoco_plx_init_one,
remove: __devexit_p(orinoco_plx_remove_one),
};
static int __init orinoco_plx_init(void)
......
......@@ -36,7 +36,8 @@ struct ethtool_drvinfo {
char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
/* For PCI devices, use pci_dev->slot_name. */
char reserved1[32];
char reserved2[24];
char reserved2[20];
u32 testinfo_len;
u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
};
......@@ -210,6 +211,34 @@ struct ethtool_pauseparam {
u32 tx_pause;
};
#define ETH_GSTRING_LEN 32
enum ethtool_stringset {
ETH_SS_TEST = 0,
ETH_SS_STATS,
};
/* for passing string sets for data tagging */
struct ethtool_gstrings {
u32 cmd; /* ETHTOOL_GSTRINGS */
u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
u32 len; /* number of strings in the string set */
u8 data[0];
};
enum ethtool_test_flags {
ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */
ETH_TEST_FL_FAILED = (1 << 1), /* test passed / failed */
};
/* for requesting NIC test and getting results*/
struct ethtool_test {
u32 cmd; /* ETHTOOL_TEST */
u32 flags; /* ETH_TEST_FL_xxx */
u32 reserved;
u32 len; /* result length, in number of u64 elements */
u64 data[0];
};
/* CMDs currently supported */
#define ETHTOOL_GSET 0x00000001 /* Get settings. */
#define ETHTOOL_SSET 0x00000002 /* Set settings, privileged. */
......@@ -222,13 +251,13 @@ struct ethtool_pauseparam {
#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv. */
#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */
#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data, priv. */
#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config */
#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config, priv. */
#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters */
#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */
#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters */
#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters, priv. */
#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
......@@ -236,7 +265,9 @@ struct ethtool_pauseparam {
#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
* (ethtool_value) */
#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
* (ethtool_value) */
* (ethtool_value), priv. */
#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */
#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment