Commit 24a17a26 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://gkernel.bkbits.net/net-drivers-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents eadb448c 937d5b67
......@@ -2,7 +2,7 @@
* acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card
* and other Tigon based cards.
*
* Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>.
* Copyright 1998-2002 by Jes Sorensen, <jes@trained-monkey.org>.
*
* Thanks to Alteon and 3Com for providing hardware and documentation
* enabling me to write this driver.
......@@ -30,6 +30,7 @@
* Pierrick Pinasseau (CERN): For lending me an Ultra 5 to test the
* driver under Linux/Sparc64
* Matt Domsch <Matt_Domsch@dell.com>: Detect Alteon 1000baseT cards
* ETHTOOL_GDRVINFO support
* Chip Salzenberg <chip@valinux.com>: Fix race condition between tx
* handler and close() cleanup.
* Ken Aaker <kdaaker@rchland.vnet.ibm.com>: Correct check for whether
......@@ -64,6 +65,7 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/sockios.h>
#include <linux/if_vlan.h>
#ifdef SIOCETHTOOL
#include <linux/ethtool.h>
......@@ -83,8 +85,10 @@
#ifdef CONFIG_ACENIC_OMIT_TIGON_I
#define ACE_IS_TIGON_I(ap) 0
#define ACE_TX_RING_ENTRIES(ap) MAX_TX_RING_ENTRIES
#else
#define ACE_IS_TIGON_I(ap) (ap->version == 1)
#define ACE_TX_RING_ENTRIES(ap) ap->tx_ring_entries
#endif
#ifndef PCI_VENDOR_ID_ALTEON
......@@ -314,6 +318,12 @@ static inline void tasklet_init(struct tasklet_struct *tasklet,
#define BOARD_IDX_STATIC 0
#define BOARD_IDX_OVERFLOW -1
#if (defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)) && \
defined(NETIF_F_HW_VLAN_RX)
#define ACENIC_DO_VLAN 1
#else
#define ACENIC_DO_VLAN 0
#endif
#include "acenic.h"
......@@ -553,7 +563,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.85 11/08/2001 Jes Sorensen, linux-acenic@SunSITE.dk\n"
"acenic.c: v0.88 03/14/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
static struct net_device *root_dev;
......@@ -620,10 +630,14 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
ap = dev->priv;
ap->pdev = pdev;
dev->irq = pdev->irq;
dev->open = &ace_open;
dev->hard_start_xmit = &ace_start_xmit;
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
#if ACENIC_DO_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = ace_vlan_rx_register;
dev->vlan_rx_kill_vid = ace_vlan_rx_kill_vid;
#endif
if (1) {
static void ace_watchdog(struct net_device *dev);
dev->tx_timeout = &ace_watchdog;
......@@ -725,9 +739,9 @@ int __devinit acenic_probe (ACE_PROBE_ARG)
ap->name [sizeof (ap->name) - 1] = '\0';
printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr);
#ifdef __sparc__
printk("irq %s\n", __irq_itoa(dev->irq));
printk("irq %s\n", __irq_itoa(pdev->irq));
#else
printk("irq %i\n", dev->irq);
printk("irq %i\n", pdev->irq);
#endif
#ifdef CONFIG_ACENIC_OMIT_TIGON_I
......@@ -960,6 +974,13 @@ static void ace_free_descriptors(struct net_device *dev)
ap->evt_ring_dma);
ap->evt_ring = NULL;
}
if (ap->tx_ring != NULL && !ACE_IS_TIGON_I(ap)) {
size = (sizeof(struct tx_desc) * MAX_TX_RING_ENTRIES);
pci_free_consistent(ap->pdev, size, ap->tx_ring,
ap->tx_ring_dma);
}
ap->tx_ring = NULL;
if (ap->evt_prd != NULL) {
pci_free_consistent(ap->pdev, sizeof(u32),
(void *)ap->evt_prd, ap->evt_prd_dma);
......@@ -1006,12 +1027,19 @@ static int ace_allocate_descriptors(struct net_device *dev)
if (ap->evt_ring == NULL)
goto fail;
size = (sizeof(struct tx_desc) * TX_RING_ENTRIES);
/*
* Only allocate a host TX ring for the Tigon II, the Tigon I
* has to use PCI registers for this ;-(
*/
if (!ACE_IS_TIGON_I(ap)) {
size = (sizeof(struct tx_desc) * MAX_TX_RING_ENTRIES);
ap->tx_ring = pci_alloc_consistent(ap->pdev, size, &ap->tx_ring_dma);
ap->tx_ring = pci_alloc_consistent(ap->pdev, size,
&ap->tx_ring_dma);
if (ap->tx_ring == NULL)
goto fail;
}
ap->evt_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),
&ap->evt_prd_dma);
......@@ -1086,6 +1114,7 @@ static int __init ace_init(struct net_device *dev)
struct ace_private *ap;
struct ace_regs *regs;
struct ace_info *info = NULL;
struct pci_dev *pdev;
unsigned long myjif;
u64 tmp_ptr;
u32 tig_ver, mac1, mac2, tmp, pci_state;
......@@ -1144,6 +1173,7 @@ static int __init ace_init(struct net_device *dev)
tigonFwReleaseFix);
writel(0, &regs->LocalCtrl);
ap->version = 1;
ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES;
break;
#endif
case 6:
......@@ -1159,6 +1189,7 @@ static int __init ace_init(struct net_device *dev)
writel(SRAM_BANK_512K, &regs->LocalCtrl);
writel(SYNC_SRAM_TIMING, &regs->MiscCfg);
ap->version = 2;
ap->tx_ring_entries = MAX_TX_RING_ENTRIES;
break;
default:
printk(KERN_WARNING " Unsupported Tigon version detected "
......@@ -1224,7 +1255,8 @@ static int __init ace_init(struct net_device *dev)
* Ie. having two NICs in the machine, one will have the cache
* line set at boot time, the other will not.
*/
pci_read_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE, &cache_size);
pdev = ap->pdev;
pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_size);
cache_size <<= 2;
if (cache_size != SMP_CACHE_BYTES) {
printk(KERN_INFO " PCI cache line size set incorrectly "
......@@ -1233,7 +1265,7 @@ static int __init ace_init(struct net_device *dev)
printk("expecting %i\n", SMP_CACHE_BYTES);
else {
printk("correcting to %i\n", SMP_CACHE_BYTES);
pci_write_config_byte(ap->pdev, PCI_CACHE_LINE_SIZE,
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
SMP_CACHE_BYTES >> 2);
}
}
......@@ -1265,7 +1297,7 @@ static int __init ace_init(struct net_device *dev)
dis_pci_mem_inval[board_idx]) {
if (ap->pci_command & PCI_COMMAND_INVALIDATE) {
ap->pci_command &= ~PCI_COMMAND_INVALIDATE;
pci_write_config_word(ap->pdev, PCI_COMMAND,
pci_write_config_word(pdev, PCI_COMMAND,
ap->pci_command);
printk(KERN_INFO " Disabling PCI memory "
"write and invalidate\n");
......@@ -1292,7 +1324,7 @@ static int __init ace_init(struct net_device *dev)
"supported, PCI write and invalidate "
"disabled\n", SMP_CACHE_BYTES);
ap->pci_command &= ~PCI_COMMAND_INVALIDATE;
pci_write_config_word(ap->pdev, PCI_COMMAND,
pci_write_config_word(pdev, PCI_COMMAND,
ap->pci_command);
}
}
......@@ -1334,16 +1366,16 @@ static int __init ace_init(struct net_device *dev)
if (!(ap->pci_command & PCI_COMMAND_FAST_BACK)) {
printk(KERN_INFO " Enabling PCI Fast Back to Back\n");
ap->pci_command |= PCI_COMMAND_FAST_BACK;
pci_write_config_word(ap->pdev, PCI_COMMAND, ap->pci_command);
pci_write_config_word(pdev, PCI_COMMAND, ap->pci_command);
}
#endif
/*
* Configure DMA attributes.
*/
if (!pci_set_dma_mask(ap->pdev, 0xffffffffffffffffULL)) {
if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
ap->pci_using_dac = 1;
} else if (!pci_set_dma_mask(ap->pdev, 0xffffffffULL)) {
} else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) {
ap->pci_using_dac = 0;
} else {
ecode = -ENODEV;
......@@ -1370,12 +1402,14 @@ static int __init ace_init(struct net_device *dev)
goto init_error;
}
ecode = request_irq(dev->irq, ace_interrupt, SA_SHIRQ, dev->name, dev);
ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ,
dev->name, dev);
if (ecode) {
printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
dev->name, dev->irq);
dev->name, pdev->irq);
goto init_error;
}
} else
dev->irq = pdev->irq;
/*
* Register the device here to be able to catch allocated
......@@ -1386,7 +1420,7 @@ static int __init ace_init(struct net_device *dev)
#ifdef INDEX_DEBUG
spin_lock_init(&ap->debug_lock);
ap->last_tx = TX_RING_ENTRIES - 1;
ap->last_tx = ACE_TX_RING_ENTRIES(ap) - 1;
ap->last_std_rx = 0;
ap->last_mini_rx = 0;
#endif
......@@ -1428,6 +1462,9 @@ 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
memset(ap->rx_std_ring, 0,
RX_STD_RING_ENTRIES * sizeof(struct rx_desc));
......@@ -1443,6 +1480,9 @@ static int __init ace_init(struct net_device *dev)
(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
memset(ap->rx_jumbo_ring, 0,
RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc));
......@@ -1465,6 +1505,9 @@ static int __init ace_init(struct net_device *dev)
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
for (i = 0; i < RX_MINI_RING_ENTRIES; i++)
ap->rx_mini_ring[i].flags =
......@@ -1494,14 +1537,35 @@ static int __init ace_init(struct net_device *dev)
*(ap->rx_ret_prd) = 0;
writel(TX_RING_BASE, &regs->WinBase);
memset(ap->tx_ring, 0, TX_RING_ENTRIES * sizeof(struct tx_desc));
if (ACE_IS_TIGON_I(ap)) {
ap->tx_ring = (struct tx_desc *)regs->Window;
for (i = 0; i < (TIGON_I_TX_RING_ENTRIES *
sizeof(struct tx_desc) / 4); i++) {
writel(0, (unsigned long)ap->tx_ring + i * 4);
}
set_aceaddr(&info->tx_ctrl.rngptr, TX_RING_BASE);
} else {
memset(ap->tx_ring, 0,
MAX_TX_RING_ENTRIES * sizeof(struct tx_desc));
set_aceaddr(&info->tx_ctrl.rngptr, ap->tx_ring_dma);
}
info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap);
tmp = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR;
info->tx_ctrl.max_len = TX_RING_ENTRIES;
tmp = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|RCB_FLG_TX_HOST_RING;
/*
* The Tigon I does not like having the TX ring in host memory ;-(
*/
if (!ACE_IS_TIGON_I(ap))
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;
......@@ -1528,7 +1592,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 than %i NICs detected, "
printk(KERN_WARNING "%s: more then %i NICs detected, "
"ignoring module parameters!\n",
dev->name, ACE_MAX_MOD_PARMS);
} else if (board_idx >= 0) {
......@@ -2117,6 +2181,14 @@ 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;
......@@ -2201,7 +2273,15 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
skb->ip_summed = CHECKSUM_NONE;
}
netif_rx(skb); /* send it up */
/* send it up */
#if ACENIC_DO_VLAN
if (ap->vlgrp != NULL &&
(bd_flags & BD_FLG_VLAN_TAG)) {
ace_vlan_rx(ap, skb, retdesc->vlan);
} else
#endif
netif_rx(skb);
dev->last_rx = jiffies;
ap->stats.rx_packets++;
......@@ -2260,7 +2340,7 @@ static inline void ace_tx_int(struct net_device *dev,
info->skb = NULL;
}
idx = (idx + 1) % TX_RING_ENTRIES;
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
} while (idx != txcsm);
if (netif_queue_stopped(dev))
......@@ -2353,7 +2433,7 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
* update releases enough of space, otherwise we just
* wait for device to make more work.
*/
if (!tx_ring_full(txcsm, ap->tx_prd))
if (!tx_ring_full(ap, txcsm, ap->tx_prd))
ace_tx_int(dev, txcsm, idx);
}
......@@ -2425,6 +2505,37 @@ static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
}
#if ACENIC_DO_VLAN
static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
struct ace_private *ap = dev->priv;
unsigned long flags;
save_flags(flags);
cli();
ap->vlgrp = grp;
restore_flags(flags);
}
static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
struct ace_private *ap = dev->priv;
unsigned long flags;
save_flags(flags);
cli();
if (ap->vlgrp)
ap->vlgrp->vlan_devices[vid] = NULL;
restore_flags(flags);
}
#endif /* ACENIC_DO_VLAN */
static int ace_open(struct net_device *dev)
{
struct ace_private *ap;
......@@ -2527,7 +2638,7 @@ static int ace_close(struct net_device *dev)
save_flags(flags);
cli();
for (i = 0; i < TX_RING_ENTRIES; i++) {
for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
struct sk_buff *skb;
dma_addr_t mapping;
struct tx_ring_info *info;
......@@ -2537,7 +2648,13 @@ static int ace_close(struct net_device *dev)
mapping = pci_unmap_addr(info, mapping);
if (mapping) {
memset(ap->tx_ring + i, 0, sizeof(struct tx_desc));
if (ACE_IS_TIGON_I(ap)) {
writel(0, &ap->tx_ring[i].addr.addrhi);
writel(0, &ap->tx_ring[i].addr.addrlo);
writel(0, &ap->tx_ring[i].flagsize);
} else
memset(ap->tx_ring + i, 0,
sizeof(struct tx_desc));
pci_unmap_page(ap->pdev, mapping,
pci_unmap_len(info, maplen),
PCI_DMA_TODEVICE);
......@@ -2562,6 +2679,7 @@ static int ace_close(struct net_device *dev)
return 0;
}
static inline dma_addr_t
ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
struct sk_buff *tail, u32 idx)
......@@ -2582,15 +2700,28 @@ ace_map_tx_skb(struct ace_private *ap, struct sk_buff *skb,
static inline void
ace_load_tx_bd(struct tx_desc *desc, u64 addr, u32 flagsize)
ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr,
u32 flagsize, u32 vlan_tag)
{
#if !USE_TX_COAL_NOW
flagsize &= ~BD_FLG_COAL_NOW;
#endif
if (!ACE_IS_TIGON_I(ap)) {
writel(addr >> 32, &desc->addr.addrhi);
writel(addr & 0xffffffff, &desc->addr.addrlo);
writel(flagsize, &desc->flagsize);
#if ACENIC_DO_VLAN
writel(vlan_tag, &desc->vlanres);
#endif
} else {
desc->addr.addrhi = addr >> 32;
desc->addr.addrlo = addr;
desc->flagsize = flagsize;
#if ACENIC_DO_VLAN
desc->vlanres = vlan_tag;
#endif
}
}
......@@ -2607,11 +2738,10 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (early_stop_netif_stop_queue(dev))
return 1;
restart:
idx = ap->tx_prd;
if (tx_ring_full(ap->tx_ret_csm, idx))
if (tx_ring_full(ap, ap->tx_ret_csm, idx))
goto overflow;
#if MAX_SKB_FRAGS
......@@ -2619,33 +2749,47 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
#endif
{
dma_addr_t mapping;
u32 vlan_tag = 0;
mapping = ace_map_tx_skb(ap, skb, skb, idx);
flagsize = (skb->len << 16) | (BD_FLG_END);
if (skb->ip_summed == CHECKSUM_HW)
flagsize |= BD_FLG_TCP_UDP_SUM;
#if ACENIC_DO_VLAN
if (vlan_tx_tag_present(skb)) {
flagsize |= BD_FLG_VLAN_TAG;
vlan_tag = vlan_tx_tag_get(skb);
}
#endif
desc = ap->tx_ring + idx;
idx = (idx + 1) % TX_RING_ENTRIES;
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
/* Look at ace_tx_int for explanations. */
if (tx_ring_full(ap->tx_ret_csm, idx))
if (tx_ring_full(ap, ap->tx_ret_csm, idx))
flagsize |= BD_FLG_COAL_NOW;
ace_load_tx_bd(desc, mapping, flagsize);
ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
}
#if MAX_SKB_FRAGS
else {
dma_addr_t mapping;
u32 vlan_tag = 0;
int i, len = 0;
mapping = ace_map_tx_skb(ap, skb, NULL, idx);
flagsize = ((skb->len - skb->data_len) << 16);
if (skb->ip_summed == CHECKSUM_HW)
flagsize |= BD_FLG_TCP_UDP_SUM;
#if ACENIC_DO_VLAN
if (vlan_tx_tag_present(skb)) {
flagsize |= BD_FLG_VLAN_TAG;
vlan_tag = vlan_tx_tag_get(skb);
}
#endif
ace_load_tx_bd(ap->tx_ring + idx, mapping, flagsize);
ace_load_tx_bd(ap, ap->tx_ring + idx, mapping, flagsize, vlan_tag);
idx = (idx + 1) % TX_RING_ENTRIES;
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
......@@ -2662,11 +2806,11 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
flagsize = (frag->size << 16);
if (skb->ip_summed == CHECKSUM_HW)
flagsize |= BD_FLG_TCP_UDP_SUM;
idx = (idx + 1) % TX_RING_ENTRIES;
idx = (idx + 1) % ACE_TX_RING_ENTRIES(ap);
if (i == skb_shinfo(skb)->nr_frags - 1) {
flagsize |= BD_FLG_END;
if (tx_ring_full(ap->tx_ret_csm, idx))
if (tx_ring_full(ap, ap->tx_ret_csm, idx))
flagsize |= BD_FLG_COAL_NOW;
/*
......@@ -2679,7 +2823,7 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
pci_unmap_addr_set(info, mapping, mapping);
pci_unmap_len_set(info, maplen, frag->size);
ace_load_tx_bd(desc, mapping, flagsize);
ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
}
}
#endif
......@@ -2697,7 +2841,7 @@ static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
* serialized, this is the only situation we have to
* re-test.
*/
if (!tx_ring_full(ap->tx_ret_csm, idx))
if (!tx_ring_full(ap, ap->tx_ret_csm, idx))
netif_wake_queue(dev);
}
......@@ -2776,8 +2920,8 @@ static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
return -EFAULT;
if (ecmd.cmd == ETHTOOL_GSET) {
switch (ecmd.cmd) {
case ETHTOOL_GSET:
ecmd.supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
......@@ -2825,7 +2969,8 @@ static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
} else if (ecmd.cmd == ETHTOOL_SSET) {
case ETHTOOL_SSET:
if(!capable(CAP_NET_ADMIN))
return -EPERM;
......@@ -2882,7 +3027,24 @@ static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
ace_issue_cmd(regs, &cmd);
}
return 0;
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strncpy(info.driver, "acenic", sizeof(info.driver) - 1);
sprintf(info.fw_version, "%i.%i.%i",
tigonFwReleaseMajor, tigonFwReleaseMinor,
tigonFwReleaseFix);
strncpy(info.version, version, sizeof(info.version) - 1);
if (ap && ap->pdev)
strcpy(info.bus_info, ap->pdev->slot_name);
if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
return -EFAULT;
return 0;
}
default:
break;
}
#endif
return -EOPNOTSUPP;
......
......@@ -417,7 +417,16 @@ struct cmd {
#define BD_FLG_TCP_UDP_SUM 0x01
#define BD_FLG_IP_SUM 0x02
#define BD_FLG_END 0x04
#define BD_FLG_MORE 0x08
#define BD_FLG_JUMBO 0x10
#define BD_FLG_UCAST 0x20
#define BD_FLG_MCAST 0x40
#define BD_FLG_BCAST 0x60
#define BD_FLG_TYP_MASK 0x60
#define BD_FLG_IP_FRAG 0x80
#define BD_FLG_IP_FRAG_END 0x100
#define BD_FLG_VLAN_TAG 0x200
#define BD_FLG_FRAME_ERROR 0x400
#define BD_FLG_COAL_NOW 0x800
#define BD_FLG_MINI 0x1000
......@@ -437,10 +446,11 @@ struct cmd {
/*
* TX ring
* TX ring - maximum TX ring entries for Tigon I's is 128
*/
#define TX_RING_ENTRIES 256
#define TX_RING_SIZE (TX_RING_ENTRIES * sizeof(struct tx_desc))
#define MAX_TX_RING_ENTRIES 256
#define TIGON_I_TX_RING_ENTRIES 128
#define TX_RING_SIZE (MAX_TX_RING_ENTRIES * sizeof(struct tx_desc))
#define TX_RING_BASE 0x3800
struct tx_desc{
......@@ -608,7 +618,7 @@ struct tx_ring_info {
*/
struct ace_skb
{
struct tx_ring_info tx_skbuff[TX_RING_ENTRIES];
struct tx_ring_info tx_skbuff[MAX_TX_RING_ENTRIES];
struct ring_info rx_std_skbuff[RX_STD_RING_ENTRIES];
struct ring_info rx_mini_skbuff[RX_MINI_RING_ENTRIES];
struct ring_info rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES];
......@@ -632,6 +642,10 @@ 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;
......@@ -642,6 +656,7 @@ struct ace_private
u32 tx_prd;
volatile u32 tx_ret_csm;
struct timer_list timer;
int tx_ring_entries;
/*
* RX elements
......@@ -692,15 +707,15 @@ struct ace_private
#define TX_RESERVED MAX_SKB_FRAGS
static inline int tx_space (u32 csm, u32 prd)
static inline int tx_space (struct ace_private *ap, u32 csm, u32 prd)
{
return (csm - prd - 1) & (TX_RING_ENTRIES - 1);
return (csm - prd - 1) & (ACE_TX_RING_ENTRIES(ap) - 1);
}
#define tx_free(ap) tx_space((ap)->tx_ret_csm, (ap)->tx_prd)
#define tx_free(ap) tx_space((ap)->tx_ret_csm, (ap)->tx_prd, ap)
#if MAX_SKB_FRAGS
#define tx_ring_full(csm, prd) (tx_space(csm, prd) <= TX_RESERVED)
#define tx_ring_full(ap, csm, prd) (tx_space(ap, csm, prd) <= TX_RESERVED)
#else
#define tx_ring_full 0
#endif
......@@ -711,7 +726,7 @@ static inline void set_aceaddr(aceaddr *aa, dma_addr_t addr)
u64 baddr = (u64) addr;
aa->addrlo = baddr & 0xffffffff;
aa->addrhi = baddr >> 32;
mb();
wmb();
}
......@@ -758,5 +773,9 @@ static void ace_free_descriptors(struct net_device *dev);
static void ace_init_cleanup(struct net_device *dev);
static struct net_device_stats *ace_get_stats(struct net_device *dev);
static int read_eeprom_byte(struct net_device *dev, unsigned long offset);
#if ACENIC_DO_VLAN
static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
#endif
#endif /* _ACENIC_H_ */
......@@ -836,6 +836,7 @@ set_rx_mode(struct net_device *dev)
i++, mclist = mclist->next)
set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26,
mc_filter);
outb(0x02, ioaddr + RX_MODE); /* Use normal mode. */
}
save_flags(flags);
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......@@ -119,26 +118,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* defaults as considerably less data will be queued.
*/
#define MAX_TCB 64 /* number of transmit control blocks */
#define MAX_TBD MAX_TCB
#define TX_FRAME_CNT 8 /* consecutive transmit frames per interrupt */
/* TX_FRAME_CNT must be less than MAX_TCB */
#define MAX_RFD 64
#define E100_DEFAULT_TCB MAX_TCB
#define E100_DEFAULT_TCB 64
#define E100_MIN_TCB 2*TX_FRAME_CNT + 3 /* make room for at least 2 interrupts */
#define E100_MAX_TCB 1024
#define E100_DEFAULT_RFD MAX_RFD
#define E100_DEFAULT_RFD 64
#define E100_MIN_RFD 8
#ifdef __ia64__
/* We can't use too many DMAble buffers on IA64 machines with >4 GB mem */
#define E100_MAX_RFD 64
#else
#define E100_MAX_RFD 1024
#endif /* __ia64__ */
#define E100_DEFAULT_XSUM true
#define E100_DEFAULT_BER ZLOCK_MAX_ERRORS
......@@ -149,10 +138,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define TX_THRSHLD 8
/* sleep time is at least 50 ms, in jiffies */
#define SLEEP_TIME ((HZ / 20) + 1)
#define CUS_TIMEOUT 1000
/* IFS parameters */
#define MIN_NUMBER_OF_TRANSMITS_100 1000
#define MIN_NUMBER_OF_TRANSMITS_10 100
......@@ -529,8 +514,6 @@ typedef struct net_device_stats net_dev_stats_t;
#define RFD_POINTER(skb,bdp) ((rfd_t *) (((unsigned char *)((skb)->data))-((bdp)->rfd_size)))
#define SKB_RFD_STATUS(skb,bdp) ((RFD_POINTER((skb),(bdp)))->rfd_header.cb_status)
#define GET_SKB_DMA_ADDR(skb) ( *(dma_addr_t *)( (skb)->cb) )
#define SET_SKB_DMA_ADDR(skb,dma_addr) ( *(dma_addr_t *)( (skb)->cb) = (dma_addr) )
/* ====================================================================== */
/* 82557 */
......@@ -1032,6 +1015,14 @@ extern unsigned char e100_selftest(struct e100_private *bdp, u32 *st_timeout,
extern unsigned char e100_get_link_state(struct e100_private *bdp);
extern unsigned char e100_wait_scb(struct e100_private *bdp);
#ifndef yield
#define yield() \
do { \
current->policy |= SCHED_YIELD; \
schedule(); \
} while (0)
#endif
extern void e100_deisolate_driver(struct e100_private *bdp,
u8 recover, u8 full_reset);
extern unsigned char e100_hw_reset_recover(struct e100_private *bdp,
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......@@ -138,7 +137,7 @@ eeprom_set_semaphore(struct e100_private *adapter)
u16 data = 0;
unsigned long expiration_time = jiffies + HZ / 100 + 1;
while (time_before(jiffies, expiration_time)) {
do {
// Get current value of General Control 2
data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
......@@ -155,10 +154,12 @@ eeprom_set_semaphore(struct e100_private *adapter)
return true;
}
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1+(HZ-1)/100);
}
if (time_before(jiffies, expiration_time))
yield();
else
return false;
} while (true);
}
//----------------------------------------------------------------------------------------
......@@ -580,17 +581,16 @@ eeprom_wait_cmd_done(struct e100_private *adapter)
eeprom_stand_by(adapter);
while (time_before(jiffies, expiration_time)) {
do {
rmb();
x = readw(&CSR_EEPROM_CONTROL_FIELD(adapter));
if (x & EEDO)
return true;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1+(HZ-1)/100);
}
if (time_before(jiffies, expiration_time))
yield();
else
return false;
} while (true);
}
//----------------------------------------------------------------------------------------
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......@@ -166,7 +165,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.22-pre1"
#define E100_VERSION "2.0.24-pre1"
#define E100_FULL_DRIVER_NAME "Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver "
......@@ -187,8 +186,7 @@ static int e100_resume(struct pci_dev *pcid);
* See the item "Labeled Elements in Initializers" in the section
* "Extensions to the C Language Family" of the GCC documentation.
*********************************************************************/
#define E100_PARAM_INIT { [0 ... E100_MAX_NIC-1] = -1 }
#define E100_PARAM_INIT { [0 ... E100_MAX_NIC] = -1 }
/* All parameters are treated the same, as an integer array of values.
* This macro just reduces the need to repeat the same declaration code
......@@ -543,6 +541,7 @@ static inline void
e100_set_intr_mask(struct e100_private *bdp)
{
writeb(bdp->intr_mask, &bdp->scb->scb_cmd_hi);
readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */
}
static inline void
......@@ -802,79 +801,66 @@ module_exit(e100_cleanup_module);
void __devinit
e100_check_options(int board, struct e100_private *bdp)
{
int val;
if (board >= E100_MAX_NIC) {
printk(KERN_NOTICE "No configuration available for board #%d\n",
board);
printk(KERN_NOTICE "Using defaults for all values\n");
board = E100_MAX_NIC;
}
val = (board < E100_MAX_NIC) ? TxDescriptors[board] : -1;
e100_set_int_option(&(bdp->params.TxDescriptors), val, E100_MIN_TCB,
E100_MAX_TCB, E100_DEFAULT_TCB,
e100_set_int_option(&(bdp->params.TxDescriptors), TxDescriptors[board],
E100_MIN_TCB, E100_MAX_TCB, E100_DEFAULT_TCB,
"TxDescriptor count");
val = (board < E100_MAX_NIC) ? RxDescriptors[board] : -1;
e100_set_int_option(&(bdp->params.RxDescriptors), val, E100_MIN_RFD,
E100_MAX_RFD, E100_DEFAULT_RFD,
e100_set_int_option(&(bdp->params.RxDescriptors), RxDescriptors[board],
E100_MIN_RFD, E100_MAX_RFD, E100_DEFAULT_RFD,
"RxDescriptor count");
val = (board < E100_MAX_NIC) ? e100_speed_duplex[board] : -1;
e100_set_int_option(&(bdp->params.e100_speed_duplex), val, 0, 4,
e100_set_int_option(&(bdp->params.e100_speed_duplex),
e100_speed_duplex[board], 0, 4,
E100_DEFAULT_SPEED_DUPLEX, "speed/duplex mode");
val = (board < E100_MAX_NIC) ? ber[board] : -1;
e100_set_int_option(&(bdp->params.ber), val, 0, ZLOCK_MAX_ERRORS,
e100_set_int_option(&(bdp->params.ber), ber[board], 0, ZLOCK_MAX_ERRORS,
E100_DEFAULT_BER, "Bit Error Rate count");
val = (board < E100_MAX_NIC) ? XsumRX[board] : -1;
e100_set_bool_option(bdp, val, PRM_XSUMRX, E100_DEFAULT_XSUM,
e100_set_bool_option(bdp, XsumRX[board], PRM_XSUMRX, E100_DEFAULT_XSUM,
"XsumRX value");
/* Default ucode value depended on controller revision */
val = (board < E100_MAX_NIC) ? ucode[board] : -1;
if (bdp->rev_id >= D101MA_REV_ID) {
e100_set_bool_option(bdp, val, PRM_UCODE, E100_DEFAULT_UCODE,
"ucode value");
e100_set_bool_option(bdp, ucode[board], PRM_UCODE,
E100_DEFAULT_UCODE, "ucode value");
} else {
e100_set_bool_option(bdp, val, PRM_UCODE, false, "ucode value");
e100_set_bool_option(bdp, ucode[board], PRM_UCODE, false,
"ucode value");
}
val = (board < E100_MAX_NIC) ? flow_control[board] : -1;
e100_set_bool_option(bdp, val, PRM_FC, E100_DEFAULT_FC,
e100_set_bool_option(bdp, flow_control[board], PRM_FC, E100_DEFAULT_FC,
"flow control value");
val = (board < E100_MAX_NIC) ? IFS[board] : -1;
e100_set_bool_option(bdp, val, PRM_IFS, E100_DEFAULT_IFS, "IFS value");
e100_set_bool_option(bdp, IFS[board], PRM_IFS, E100_DEFAULT_IFS,
"IFS value");
val = (board < E100_MAX_NIC) ? BundleSmallFr[board] : -1;
e100_set_bool_option(bdp, val, PRM_BUNDLE_SMALL,
e100_set_bool_option(bdp, BundleSmallFr[board], PRM_BUNDLE_SMALL,
E100_DEFAULT_BUNDLE_SMALL_FR,
"CPU saver bundle small frames value");
val = (board < E100_MAX_NIC) ? IntDelay[board] : -1;
e100_set_int_option(&(bdp->params.IntDelay), val, 0x0, 0xFFFF,
E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY,
e100_set_int_option(&(bdp->params.IntDelay), IntDelay[board], 0x0,
0xFFFF, E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY,
"CPU saver interrupt delay value");
val = (board < E100_MAX_NIC) ? BundleMax[board] : -1;
e100_set_int_option(&(bdp->params.BundleMax), val, 0x1, 0xFFFF,
E100_DEFAULT_CPUSAVER_BUNDLE_MAX,
e100_set_int_option(&(bdp->params.BundleMax), BundleMax[board], 0x1,
0xFFFF, E100_DEFAULT_CPUSAVER_BUNDLE_MAX,
"CPU saver bundle max value");
val = (board < E100_MAX_NIC) ? RxCongestionControl[board] : -1;
e100_set_bool_option(bdp, val, PRM_RX_CONG,
e100_set_bool_option(bdp, RxCongestionControl[board], PRM_RX_CONG,
E100_DEFAULT_RX_CONGESTION_CONTROL,
"Rx Congestion Control value");
val = (board < E100_MAX_NIC) ? PollingMaxWork[board] : -1;
e100_set_int_option(&(bdp->params.PollingMaxWork), val, 1, E100_MAX_RFD,
RxDescriptors[board], "Polling Max Work value");
if (val <= 0) {
bdp->params.b_params &= ~PRM_RX_CONG;
}
e100_set_int_option(&(bdp->params.PollingMaxWork),
PollingMaxWork[board], 1, E100_MAX_RFD,
bdp->params.RxDescriptors,
"Polling Max Work value");
}
/**
......@@ -2221,6 +2207,12 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
tcb = bdp->tcb_pool.data;
tcb += TCB_TO_USE(bdp->tcb_pool);
if (bdp->flags & USE_IPCB) {
tcb->tcbu.ipcb.ip_activation_high = IPCB_IP_ACTIVATION_DEFAULT;
tcb->tcbu.ipcb.ip_schedule &= ~IPCB_TCP_PACKET;
tcb->tcbu.ipcb.ip_schedule &= ~IPCB_TCPUDP_CHECKSUM_ENABLE;
}
tcb->tcb_hdr.cb_status = 0;
tcb->tcb_thrshld = bdp->tx_thld;
tcb->tcb_hdr.cb_cmd |= __constant_cpu_to_le16(CB_S_BIT);
......@@ -2261,15 +2253,6 @@ e100_prepare_xmit_buff(struct e100_private *bdp, struct sk_buff *skb)
*chksum = e100_pseudo_hdr_csum(ip);
}
} else {
if (bdp->flags & USE_IPCB) {
tcb->tcbu.ipcb.ip_activation_high =
IPCB_IP_ACTIVATION_DEFAULT;
tcb->tcbu.ipcb.ip_schedule &= ~IPCB_TCP_PACKET;
tcb->tcbu.ipcb.ip_schedule &=
~IPCB_TCPUDP_CHECKSUM_ENABLE;
}
}
if (!skb_shinfo(skb)->nr_frags) {
......@@ -2722,7 +2705,7 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
cb_header_t *ntcb_hdr;
unsigned long lock_flag;
unsigned long expiration_time;
unsigned char rc = false;
unsigned char rc = true;
ntcb_hdr = (cb_header_t *) command->non_tx_cmd; /* get hdr of non tcb cmd */
......@@ -2757,6 +2740,7 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
if (!e100_wait_exec_cmplx(bdp, command->dma_addr, SCB_CUC_START)) {
spin_unlock_irqrestore(&(bdp->bd_lock), lock_flag);
rc = false;
goto exit;
}
......@@ -2765,20 +2749,21 @@ e100_exec_non_cu_cmd(struct e100_private *bdp, nxmit_cb_entry_t *command)
/* now wait for completion of non-cu CB up to 20 msec */
expiration_time = jiffies + HZ / 50 + 1;
while (time_before(jiffies, expiration_time)) {
rmb();
if ((ntcb_hdr->cb_status &
while (!(ntcb_hdr->cb_status &
__constant_cpu_to_le16(CB_STATUS_COMPLETE))) {
rc = true;
goto exit;
}
if (time_before(jiffies, expiration_time)) {
spin_unlock_bh(&(bdp->bd_non_tx_lock));
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
yield();
spin_lock_bh(&(bdp->bd_non_tx_lock));
} else {
rc = false;
goto exit;
}
rmb();
}
/* didn't get a C bit assume command failed */
exit:
e100_free_non_tx_cmd(bdp, command);
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......@@ -654,7 +653,7 @@ static void
e100_force_speed_duplex(struct e100_private *bdp)
{
u16 control;
int neg_timeout = 2 * HZ; //2 sec in jiffies
unsigned long expires;
bdp->flags |= DF_SPEED_FORCED;
......@@ -697,20 +696,18 @@ e100_force_speed_duplex(struct e100_private *bdp)
e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
/* loop must run at least once */
expires = jiffies + 2 * HZ;
do {
if (e100_update_link_state(bdp) ||
time_after(jiffies, expires)) {
break;
} else {
spin_unlock_bh(&(bdp->mdi_access_lock));
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(SLEEP_TIME);
yield();
spin_lock_bh(&(bdp->mdi_access_lock));
if (e100_update_link_state(bdp)) {
break;
}
neg_timeout -= SLEEP_TIME;
} while (neg_timeout > 0);
} while (true);
spin_unlock_bh(&(bdp->mdi_access_lock));
}
......@@ -820,7 +817,7 @@ static void
e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
{
u16 stat_reg;
unsigned int i;
unsigned long expires;
bdp->flags &= ~DF_SPEED_FORCED;
......@@ -841,22 +838,21 @@ e100_auto_neg(struct e100_private *bdp, unsigned char force_restart)
BMCR_ANENABLE | BMCR_ANRESTART);
/* wait for autoneg to complete (up to 3 seconds) */
for (i = 0; i < 60; i++) {
expires = jiffies + HZ * 3;
do {
/* now re-read the value. Sticky so read twice */
e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
if (stat_reg & BMSR_ANEGCOMPLETE)
if ((stat_reg & BMSR_ANEGCOMPLETE) ||
time_after(jiffies, expires) ) {
goto exit;
} else {
spin_unlock_bh(&(bdp->mdi_access_lock));
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(SLEEP_TIME);
yield();
spin_lock_bh(&(bdp->mdi_access_lock));
}
} while (true);
}
exit:
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......@@ -98,7 +97,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef E100_CONFIG_PROC_FS
#include "e100.h"
/* MDI sleep time is at least 50 ms, in jiffies */
#define MDI_SLEEP_TIME ((HZ / 20) + 1)
/***************************************************************************/
/* /proc File System Interaface Support Functions */
/***************************************************************************/
......@@ -231,7 +231,7 @@ set_led(struct e100_private *bdp, u16 led_mdi_op)
spin_unlock_bh(&bdp->mdi_access_lock);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(SLEEP_TIME);
schedule_timeout(MDI_SLEEP_TIME);
spin_lock_bh(&bdp->mdi_access_lock);
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......
......@@ -2,9 +2,8 @@
This software program is available to you under a choice of one of two
licenses. You may choose to be licensed under either the GNU General Public
License (GPL) Version 2, June 1991, available at
http://www.fsf.org/copyleft/gpl.html, or the Intel BSD + Patent License, the
text of which follows:
License 2.0, June 1991, available at http://www.fsf.org/copyleft/gpl.html,
or the Intel BSD + Patent License, the text of which follows:
Recipient has requested a license and Intel Corporation ("Intel") is willing
to grant a license for the software entitled Linux Base Driver for the
......@@ -18,7 +17,7 @@ combined with the operating system referred to below.
"Recipient" means the party to whom Intel delivers this Software.
"Licensee" means Recipient and those third parties that receive a license to
any operating system available under the GNU Public License version 2.0 or
any operating system available under the GNU General Public License 2.0 or
later.
Copyright (c) 1999 - 2002 Intel Corporation.
......@@ -51,10 +50,10 @@ not add functionality or features when the Software is incorporated in any
version of an operating system that has been distributed under the GNU
General Public License 2.0 or later. This patent license shall apply to the
combination of the Software and any operating system licensed under the GNU
Public License version 2.0 or later if, at the time Intel provides the
General Public License 2.0 or later if, at the time Intel provides the
Software to Recipient, such addition of the Software to the then publicly
available versions of such operating systems available under the GNU Public
License version 2.0 or later (whether in gold, beta or alpha form) causes
available versions of such operating systems available under the GNU General
Public License 2.0 or later (whether in gold, beta or alpha form) causes
such combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Software. NO
hardware per se is licensed hereunder.
......
......@@ -183,7 +183,7 @@ static struct pci_driver e1000_driver = {
name: e1000_driver_name,
id_table: e1000_pci_tbl,
probe: e1000_probe,
remove: e1000_remove,
remove: __devexit_p(e1000_remove),
/* Power Managment Hooks */
suspend: NULL,
resume: NULL
......
......@@ -114,7 +114,6 @@ static int debug = -1; /* The debug level */
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
......
......@@ -83,8 +83,6 @@
**
*/
#error Please convert me to Documentation/DMA-mapping.txt
#define HP100_DEFAULT_PRIORITY_TX 0
#undef HP100_DEBUG
......@@ -212,8 +210,8 @@ struct hp100_private {
hp100_ring_t rxring[MAX_RX_PDL];
hp100_ring_t txring[MAX_TX_PDL];
u_int *page_vaddr; /* Virtual address of allocated page */
u_int *page_vaddr_algn; /* Aligned virtual address of allocated page */
u_long whatever_offset; /* Offset to bus/phys/dma address */
int rxrcommit; /* # Rx PDLs commited to adapter */
int txrcommit; /* # Tx PDLs commited to adapter */
};
......@@ -350,6 +348,18 @@ static void hp100_clean_txring(struct net_device *dev);
static void hp100_RegisterDump(struct net_device *dev);
#endif
/* Conversion to new PCI API :
* Convert an address in a kernel buffer to a bus/phys/dma address.
* This work *only* for memory fragments part of lp->page_vaddr,
* because it was properly DMA allocated via pci_alloc_consistent(),
* so we just need to "retreive" the original mapping to bus/phys/dma
* address - Jean II */
static inline dma_addr_t virt_to_whatever(struct net_device *dev, u32 * ptr)
{
return ((u_long) ptr) +
((struct hp100_private *) (dev->priv))->whatever_offset;
}
/* TODO: This function should not really be needed in a good design... */
static void wait(void)
{
......@@ -627,9 +637,20 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
local_mode = 3;
} else if (chip == HP100_CHIPID_LASSEN &&
(lsw & (HP100_BM_WRITE | HP100_BM_READ)) == (HP100_BM_WRITE | HP100_BM_READ)) {
/* Conversion to new PCI API :
* I don't have the doc, but I assume that the card
* can map the full 32bit address space.
* Also, we can have EISA Busmaster cards (not tested),
* so beware !!! - Jean II */
if((bus == HP100_BUS_PCI) &&
(pci_set_dma_mask(pci_dev, 0xffffffff))) {
/* Gracefully fallback to shared memory */
goto busmasterfail;
}
printk("hp100: %s: Busmaster mode enabled.\n", dev->name);
hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW);
} else {
busmasterfail:
#ifdef HP100_DEBUG
printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name);
printk("hp100: %s: Trying shared memory mode.\n", dev->name);
......@@ -772,11 +793,14 @@ static int __init hp100_probe1(struct net_device *dev, int ioaddr,
* in the cards shared memory area. But currently, busmaster has been
* implemented/tested only with the lassen chip anyway... */
if (lp->mode == 1) { /* busmaster */
dma_addr_t page_baddr;
/* Get physically continous memory for TX & RX PDLs */
if ((lp->page_vaddr = kmalloc(MAX_RINGSIZE + 0x0f, GFP_KERNEL)) == NULL)
/* Conversion to new PCI API :
* Pages are always aligned and zeroed, no need to it ourself.
* Doc says should be OK for EISA bus as well - Jean II */
if ((lp->page_vaddr_algn = pci_alloc_consistent(lp->pci_dev, MAX_RINGSIZE, &page_baddr)) == NULL)
return -ENOMEM;
lp->page_vaddr_algn = ((u_int *) (((u_int) (lp->page_vaddr) + 0x0f) & ~0x0f));
memset(lp->page_vaddr, 0, MAX_RINGSIZE + 0x0f);
lp->whatever_offset = ((u_long) page_baddr) - ((u_long) lp->page_vaddr_algn);
#ifdef HP100_DEBUG_BM
printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", dev->name, (u_int) lp->page_vaddr_algn, (u_int) lp->page_vaddr_algn + MAX_RINGSIZE);
......@@ -1189,7 +1213,7 @@ static void hp100_init_pdls(struct net_device *dev)
{
struct hp100_private *lp = (struct hp100_private *) dev->priv;
hp100_ring_t *ringptr;
u_int *pageptr;
u_int *pageptr; /* Warning : increment by 4 - Jean II */
int i;
#ifdef HP100_DEBUG_B
......@@ -1246,7 +1270,7 @@ static int hp100_init_rxpdl(struct net_device *dev,
dev->name, (unsigned) pdlptr);
ringptr->pdl = pdlptr + 1;
ringptr->pdl_paddr = virt_to_bus(pdlptr + 1);
ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1);
ringptr->skb = (void *) NULL;
/*
......@@ -1257,7 +1281,7 @@ static int hp100_init_rxpdl(struct net_device *dev,
*/
/* Note that pdlptr+1 and not pdlptr is the pointer to the PDH */
*(pdlptr + 2) = (u_int) virt_to_bus(pdlptr); /* Address Frag 1 */
*(pdlptr + 2) = (u_int) virt_to_whatever(dev, pdlptr); /* Address Frag 1 */
*(pdlptr + 3) = 4; /* Length Frag 1 */
return ((((MAX_RX_FRAG * 2 + 2) + 3) / 4) * 4);
......@@ -1272,7 +1296,7 @@ static int hp100_init_txpdl(struct net_device *dev,
printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n", dev->name, (unsigned) pdlptr);
ringptr->pdl = pdlptr; /* +1; */
ringptr->pdl_paddr = virt_to_bus(pdlptr); /* +1 */
ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr); /* +1 */
ringptr->skb = (void *) NULL;
return ((((MAX_TX_FRAG * 2 + 2) + 3) / 4) * 4);
......@@ -1331,8 +1355,10 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr,
(unsigned int) ringptr->skb->data);
#endif
/* Conversion to new PCI API : map skbuf data to PCI bus.
* Doc says it's OK for EISA as well - Jean II */
ringptr->pdl[0] = 0x00020000; /* Write PDH */
ringptr->pdl[3] = ((u_int) virt_to_bus(ringptr->skb->data));
ringptr->pdl[3] = ((u_int) pci_map_single(((struct hp100_private *) (dev->priv))->pci_dev, ringptr->skb->data, MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE));
ringptr->pdl[4] = MAX_ETHER_SIZE; /* Length of Data */
#ifdef HP100_DEBUG_BM
......@@ -1585,7 +1611,6 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
ringptr->skb = skb;
ringptr->pdl[0] = ((1 << 16) | i); /* PDH: 1 Fragment & length */
ringptr->pdl[1] = (u32) virt_to_bus(skb->data); /* 1st Frag: Adr. of data */
if (lp->chip == HP100_CHIPID_SHASTA) {
/* TODO:Could someone who has the EISA card please check if this works? */
ringptr->pdl[2] = i;
......@@ -1593,6 +1618,9 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
/* In the PDL, don't use the padded size but the real packet size: */
ringptr->pdl[2] = skb->len; /* 1st Frag: Length of frag */
}
/* Conversion to new PCI API : map skbuf data to PCI bus.
* Doc says it's OK for EISA as well - Jean II */
ringptr->pdl[1] = ((u32) pci_map_single(lp->pci_dev, skb->data, ringptr->pdl[2], PCI_DMA_TODEVICE)); /* 1st Frag: Adr. of data */
/* Hand this PDL to the card. */
hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */
......@@ -1641,6 +1669,8 @@ static void hp100_clean_txring(struct net_device *dev)
dev->name, (u_int) lp->txrhead->skb->data,
lp->txrcommit, hp100_inb(TX_PDL), donecount);
#endif
/* Conversion to new PCI API : NOP */
pci_unmap_single(lp->pci_dev, (dma_addr_t) lp->txrhead->pdl[1], lp->txrhead->pdl[2], PCI_DMA_TODEVICE);
dev_kfree_skb_any(lp->txrhead->skb);
lp->txrhead->skb = (void *) NULL;
lp->txrhead = lp->txrhead->next;
......@@ -1950,6 +1980,9 @@ static void hp100_rx_bm(struct net_device *dev)
header = *(ptr->pdl - 1);
pkt_len = (header & HP100_PKT_LEN_MASK);
/* Conversion to new PCI API : NOP */
pci_unmap_single(lp->pci_dev, (dma_addr_t) ptr->pdl[3], MAX_ETHER_SIZE, PCI_DMA_FROMDEVICE);
#ifdef HP100_DEBUG_BM
printk("hp100: %s: rx_bm: header@0x%x=0x%x length=%d, errors=0x%x, dest=0x%x\n",
dev->name, (u_int) (ptr->pdl - 1), (u_int) header,
......@@ -2910,7 +2943,7 @@ static void release_dev(int i)
release_region(d->base_addr, HP100_REGION_SIZE);
if (p->mode == 1) /* busmaster */
kfree(p->page_vaddr);
pci_free_consistent(p->pci_dev, MAX_RINGSIZE + 0x0f, p->page_vaddr_algn, virt_to_whatever(d, p->page_vaddr_algn));
if (p->mem_ptr_virt)
iounmap(p->mem_ptr_virt);
kfree(d->priv);
......
......@@ -354,7 +354,7 @@ MODULE_LICENSE("GPL");
board probes now that kmalloc() can allocate ISA DMA-able regions.
This also allows the LANCE driver to be used as a module.
*/
int lance_probe(struct net_device *dev)
int __init lance_probe(struct net_device *dev)
{
int *port, result;
......
#define _VERSION "0.15"
#define _VERSION "0.17"
/* ns83820.c by Benjamin LaHaise <bcrl@redhat.com> with contributions.
*
* $Revision: 1.34.2.12 $
* $Revision: 1.34.2.14 $
*
* Copyright 2001 Benjamin LaHaise.
* Copyright 2001 Red Hat.
......@@ -51,6 +51,8 @@
* suppress duplicate link status messages
* 20011117 0.14 - ethtool GDRVINFO, GLINK support
* 20011204 0.15 get ppc (big endian) working
* 20011218 0.16 various cleanups
* 20020310 0.17 speedups
*
* Driver Overview
* ===============
......@@ -93,8 +95,8 @@
#include <linux/in.h> /* for IPPROTO_... */
#include <linux/eeprom.h>
#include <linux/compiler.h>
#include <linux/prefetch.h>
#include <linux/ethtool.h>
//#include <linux/skbrefill.h>
#include <asm/io.h>
#include <asm/uaccess.h>
......@@ -154,10 +156,16 @@ pci_map_single_high(struct pci_dev *hwdev, struct page *page,
#endif
/* tunables */
#define RX_BUF_SIZE 6144 /* 8192 */
#define NR_RX_DESC 256
#define RX_BUF_SIZE 1500 /* 8192 */
#define NR_TX_DESC 256
/* Must not exceed ~65000. */
#define NR_RX_DESC 64
#define NR_TX_DESC 64
/* not tunable */
#define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14) /* rx/tx mac addr + type */
#define MIN_TX_DESC_FREE 8
/* register defines */
#define CFGCS 0x04
......@@ -408,7 +416,8 @@ struct rx_info {
struct sk_buff *skbs[NR_RX_DESC];
unsigned next_rx, next_empty;
u32 *next_rx_desc;
u16 next_rx, next_empty;
u32 *descs;
dma_addr_t phy_descs;
......@@ -423,6 +432,7 @@ struct ns83820 {
struct pci_dev *pci_dev;
struct rx_info rx_info;
struct tasklet_struct rx_tasklet;
unsigned ihr;
struct tq_struct tq_refill;
......@@ -441,10 +451,11 @@ struct ns83820 {
spinlock_t tx_lock;
long tx_idle;
u32 tx_done_idx;
u32 tx_idx;
volatile u32 tx_free_idx; /* idx of free desc chain */
u32 tx_intr_idx;
u16 tx_done_idx;
u16 tx_idx;
volatile u16 tx_free_idx; /* idx of free desc chain */
u16 tx_intr_idx;
struct sk_buff *tx_skbs[NR_TX_DESC];
......@@ -455,7 +466,7 @@ struct ns83820 {
//free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC
#define start_tx_okay(dev) \
(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > NR_TX_DESC/2)
(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE)
/* Packet Receiver
......@@ -509,7 +520,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
next_empty = dev->rx_info.next_empty;
/* don't overrun last rx marker */
if (nr_rx_empty(dev) <= 2) {
if (unlikely(nr_rx_empty(dev) <= 2)) {
kfree_skb(skb);
return 1;
}
......@@ -523,34 +534,39 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
#endif
sg = dev->rx_info.descs + (next_empty * DESC_SIZE);
if (dev->rx_info.skbs[next_empty])
if (unlikely(NULL != dev->rx_info.skbs[next_empty]))
BUG();
dev->rx_info.skbs[next_empty] = skb;
dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
cmdsts = RX_BUF_SIZE | CMDSTS_INTR;
buf = pci_map_single(dev->pci_dev, skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
buf = pci_map_single(dev->pci_dev, skb->tail,
REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
/* update link of previous rx */
if (next_empty != dev->rx_info.next_rx)
if (likely(next_empty != dev->rx_info.next_rx))
dev->rx_info.descs[((NR_RX_DESC + next_empty - 1) % NR_RX_DESC) * DESC_SIZE] = cpu_to_le32(dev->rx_info.phy_descs + (next_empty * DESC_SIZE * 4));
return 0;
}
static int rx_refill(struct ns83820 *dev, int gfp)
static inline int rx_refill(struct ns83820 *dev, int gfp)
{
unsigned i;
long flags = 0;
if (unlikely(nr_rx_empty(dev) <= 2))
return 0;
dprintk("rx_refill(%p)\n", dev);
if (gfp == GFP_ATOMIC)
spin_lock_irqsave(&dev->rx_info.lock, flags);
for (i=0; i<NR_RX_DESC; i++) {
struct sk_buff *skb;
long res;
skb = __dev_alloc_skb(RX_BUF_SIZE+16, gfp);
if (!skb)
/* extra 16 bytes for alignment */
skb = __dev_alloc_skb(REAL_RX_BUF_SIZE+16, gfp);
if (unlikely(!skb))
break;
res = (long)skb->tail & 0xf;
......@@ -575,6 +591,12 @@ static int rx_refill(struct ns83820 *dev, int gfp)
return i ? 0 : -ENOMEM;
}
static void FASTCALL(rx_refill_atomic(struct ns83820 *dev));
static void rx_refill_atomic(struct ns83820 *dev)
{
rx_refill(dev, GFP_ATOMIC);
}
/* REFILL */
static inline void queue_refill(void *_dev)
{
......@@ -590,6 +612,7 @@ static inline void clear_rx_desc(struct ns83820 *dev, unsigned i)
build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
}
static void FASTCALL(phy_intr(struct ns83820 *dev));
static void phy_intr(struct ns83820 *dev)
{
static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
......@@ -600,7 +623,6 @@ static void phy_intr(struct ns83820 *dev)
cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;
if (dev->CFG_cache & CFG_TBI_EN) {
/* we have an optical transceiver */
tbisr = readl(dev->base + TBISR);
tanar = readl(dev->base + TANAR);
......@@ -646,20 +668,24 @@ static void phy_intr(struct ns83820 *dev)
new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
if (cfg & CFG_SPDSTS1)
new_cfg |= CFG_MODE_1000 | CFG_SB;
new_cfg |= CFG_MODE_1000;
else
new_cfg &= ~CFG_MODE_1000 | CFG_SB;
new_cfg &= ~CFG_MODE_1000;
speed = ((cfg / CFG_SPDSTS0) & 3);
fullduplex = (cfg & CFG_DUPSTS);
if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
if (fullduplex)
new_cfg |= CFG_SB;
if ((cfg & CFG_LNKSTS) &&
((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
writel(new_cfg, dev->base + CFG);
dev->CFG_cache = new_cfg;
}
dev->CFG_cache &= ~CFG_SPDSTS;
dev->CFG_cache |= cfg & CFG_SPDSTS;
speed = ((cfg / CFG_SPDSTS0) & 3);
fullduplex = (cfg & CFG_DUPSTS);
}
newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
......@@ -690,6 +716,7 @@ static int ns83820_setup_rx(struct ns83820 *dev)
dev->rx_info.idle = 1;
dev->rx_info.next_rx = 0;
dev->rx_info.next_rx_desc = dev->rx_info.descs;
dev->rx_info.next_empty = 0;
for (i=0; i<NR_RX_DESC; i++)
......@@ -724,7 +751,7 @@ static int ns83820_setup_rx(struct ns83820 *dev)
dev->IMR_cache |= ISR_RXDESC;
dev->IMR_cache |= ISR_RXIDLE;
dev->IMR_cache |= ISR_TXDESC;
//dev->IMR_cache |= ISR_TXIDLE;
dev->IMR_cache |= ISR_TXIDLE;
writel(dev->IMR_cache, dev->base + IMR);
writel(1, dev->base + IER);
......@@ -770,6 +797,41 @@ static void ns83820_cleanup_rx(struct ns83820 *dev)
}
}
/* I hate the network stack sometimes */
#ifdef __i386__
#define skb_mangle_for_davem(skb,len) (skb)
#else
static inline struct sk_buff *skb_mangle_for_davem(struct sk_buff *skb, int len)
{
tmp = __dev_alloc_skb(len+2, GFP_ATOMIC);
if (!tmp)
goto done;
tmp->dev = &dev->net_dev;
skb_reserve(tmp, 2);
memcpy(skb_put(tmp, len), skb->data, len);
kfree_skb(skb);
return tmp;
}
#endif
static void FASTCALL(ns83820_rx_kick(struct ns83820 *dev));
static void ns83820_rx_kick(struct ns83820 *dev)
{
/*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ {
if (dev->rx_info.up) {
rx_refill_atomic(dev);
kick_rx(dev);
}
}
if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
schedule_task(&dev->tq_refill);
else
kick_rx(dev);
if (dev->rx_info.idle)
Dprintk("BAD\n");
}
/* rx_irq
*
*/
......@@ -785,10 +847,10 @@ static void rx_irq(struct ns83820 *dev)
dprintk("rx_irq(%p)\n", dev);
dprintk("rxdp: %08x, descs: %08lx next_rx[%d]: %p next_empty[%d]: %p\n",
readl(dev->base + RXDP),
(dev->rx_info.phy_descs),
dev->rx_info.next_rx,
(long)(dev->rx_info.phy_descs),
(int)dev->rx_info.next_rx,
(dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_rx)),
dev->rx_info.next_empty,
(int)dev->rx_info.next_empty,
(dev->rx_info.descs + (DESC_SIZE * dev->rx_info.next_empty))
);
......@@ -798,7 +860,7 @@ static void rx_irq(struct ns83820 *dev)
dprintk("walking descs\n");
next_rx = info->next_rx;
desc = info->descs + (DESC_SIZE * next_rx);
desc = info->next_rx_desc;
while ((CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) &&
(cmdsts != CMDSTS_OWN)) {
struct sk_buff *skb;
......@@ -813,29 +875,17 @@ static void rx_irq(struct ns83820 *dev)
info->skbs[next_rx] = NULL;
info->next_rx = (next_rx + 1) % NR_RX_DESC;
barrier();
mb();
clear_rx_desc(dev, next_rx);
pci_unmap_single(dev->pci_dev, bufptr,
RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
if (CMDSTS_OK & cmdsts) {
#if 0 //ndef __i386__
struct sk_buff *tmp;
#endif
if (likely(CMDSTS_OK & cmdsts)) {
int len = cmdsts & 0xffff;
if (!skb)
BUG();
skb_put(skb, len);
#if 0 //ndef __i386__ /* I hate the network stack sometimes */
tmp = __dev_alloc_skb(RX_BUF_SIZE+16, GFP_ATOMIC);
if (!tmp)
goto done;
tmp->dev = &dev->net_dev;
skb_reserve(tmp, 2);
memcpy(skb_put(tmp, len), skb->data, len);
kfree_skb(skb);
skb = tmp;
#endif
skb = skb_mangle_for_davem(skb, len);
if (unlikely(!skb))
goto netdev_mangle_me_harder_failed;
if (cmdsts & CMDSTS_DEST_MULTI)
dev->stats.multicast ++;
dev->stats.rx_packets ++;
......@@ -846,11 +896,10 @@ static void rx_irq(struct ns83820 *dev)
skb->ip_summed = CHECKSUM_NONE;
}
skb->protocol = eth_type_trans(skb, &dev->net_dev);
if (NET_RX_DROP == netif_rx(skb))
if (NET_RX_DROP == netif_rx(skb)) {
netdev_mangle_me_harder_failed:
dev->stats.rx_dropped ++;
#if 0 //ndef __i386__
done:;
#endif
}
} else {
kfree_skb(skb);
}
......@@ -860,6 +909,7 @@ static void rx_irq(struct ns83820 *dev)
desc = info->descs + (DESC_SIZE * next_rx);
}
info->next_rx = next_rx;
info->next_rx_desc = info->descs + (DESC_SIZE * next_rx);
out:
if (0 && !nr) {
......@@ -869,6 +919,15 @@ static void rx_irq(struct ns83820 *dev)
spin_unlock_irqrestore(&info->lock, flags);
}
static void rx_action(unsigned long _dev)
{
struct ns83820 *dev = (void *)_dev;
rx_irq(dev);
writel(0x002, dev->base + IHR);
writel(dev->IMR_cache | ISR_RXDESC, dev->base + IMR);
rx_irq(dev);
ns83820_rx_kick(dev);
}
/* Packet Transmit code
*/
......@@ -879,7 +938,9 @@ static inline void kick_tx(struct ns83820 *dev)
writel(CR_TXE, dev->base + CR);
}
/* no spinlock needed on the transmit irq path as the interrupt handler is serialized */
/* No spinlock needed on the transmit irq path as the interrupt handler is
* serialized.
*/
static void do_tx_done(struct ns83820 *dev)
{
u32 cmdsts, tx_done_idx, *desc;
......@@ -917,7 +978,7 @@ static void do_tx_done(struct ns83820 *dev)
tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC;
dev->tx_done_idx = tx_done_idx;
desc[CMDSTS] = cpu_to_le32(0);
barrier();
mb();
desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
}
......@@ -952,7 +1013,6 @@ static void ns83820_cleanup_tx(struct ns83820 *dev)
* while trying to track down a bug in either the zero copy code or
* the tx fifo (hence the MAX_FRAG_LEN).
*/
#define MAX_FRAG_LEN 8192 /* disabled for now */
static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
{
struct ns83820 *dev = (struct ns83820 *)_dev;
......@@ -970,9 +1030,9 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
nr_frags = skb_shinfo(skb)->nr_frags;
again:
if (__builtin_expect(dev->CFG_cache & CFG_LNKSTS, 0)) {
if (unlikely(dev->CFG_cache & CFG_LNKSTS)) {
netif_stop_queue(&dev->net_dev);
if (__builtin_expect(dev->CFG_cache & CFG_LNKSTS, 0))
if (unlikely(dev->CFG_cache & CFG_LNKSTS))
return 1;
netif_start_queue(&dev->net_dev);
}
......@@ -981,7 +1041,7 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
tx_done_idx = dev->tx_done_idx;
nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC;
nr_free -= 1;
if ((nr_free <= nr_frags) || (nr_free <= 8192 / MAX_FRAG_LEN)) {
if (nr_free <= nr_frags) {
dprintk("stop_queue - not enough(%p)\n", dev);
netif_stop_queue(&dev->net_dev);
......@@ -996,11 +1056,11 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
if (free_idx == dev->tx_intr_idx) {
do_intr = 1;
dev->tx_intr_idx = (dev->tx_intr_idx + NR_TX_DESC/2) % NR_TX_DESC;
dev->tx_intr_idx = (dev->tx_intr_idx + NR_TX_DESC/4) % NR_TX_DESC;
}
nr_free -= nr_frags;
if (nr_free < 1) {
if (nr_free < MIN_TX_DESC_FREE) {
dprintk("stop_queue - last entry(%p)\n", dev);
netif_stop_queue(&dev->net_dev);
stopped = 1;
......@@ -1028,14 +1088,6 @@ static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *_dev)
for (;;) {
volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE);
u32 residue = 0;
#if 0
if (len > MAX_FRAG_LEN) {
residue = len;
/* align the start address of the next fragment */
len = MAX_FRAG_LEN;
residue -= len;
}
#endif
dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
(unsigned long long)buf);
......@@ -1084,6 +1136,7 @@ static void ns83820_update_stats(struct ns83820 *dev)
{
u8 *base = dev->base;
/* the DP83820 will freeze counters, so we need to read all of them */
dev->stats.rx_errors += readl(base + 0x60) & 0xffff;
dev->stats.rx_crc_errors += readl(base + 0x64) & 0xffff;
dev->stats.rx_missed_errors += readl(base + 0x68) & 0xffff;
......@@ -1162,54 +1215,54 @@ static int ns83820_ioctl(struct net_device *_dev, struct ifreq *rq, int cmd)
}
}
static void ns83820_mib_isr(struct ns83820 *dev)
{
spin_lock(&dev->misc_lock);
ns83820_update_stats(dev);
spin_unlock(&dev->misc_lock);
}
static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
{
struct ns83820 *dev = data;
int count = 0;
u32 isr;
dprintk("ns83820_irq(%p)\n", dev);
dev->ihr = 0;
while (count++ < 32 && (isr = readl(dev->base + ISR))) {
isr = readl(dev->base + ISR);
dprintk("irq: %08x\n", isr);
#ifdef DEBUG
if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
Dprintk("odd isr? 0x%08x\n", isr);
#endif
if ((ISR_RXEARLY | ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr) {
if (ISR_RXIDLE & isr) {
dev->rx_info.idle = 1;
Dprintk("oh dear, we are idle\n");
ns83820_rx_kick(dev);
}
if ((ISR_RXDESC) & isr) {
rx_irq(dev);
writel(4, dev->base + IHR);
if ((ISR_RXDESC | ISR_RXOK) & isr) {
prefetch(dev->rx_info.next_rx_desc);
writel(dev->IMR_cache & ~(ISR_RXDESC | ISR_RXOK), dev->base + IMR);
tasklet_schedule(&dev->rx_tasklet);
//rx_irq(dev);
//writel(4, dev->base + IHR);
}
if (nr_rx_empty(dev) >= NR_RX_DESC/4) {
if (dev->rx_info.up) {
rx_refill(dev, GFP_ATOMIC);
kick_rx(dev);
}
}
if (dev->rx_info.up && nr_rx_empty(dev) > NR_RX_DESC*3/4)
schedule_task(&dev->tq_refill);
else
kick_rx(dev);
if (dev->rx_info.idle)
Dprintk("BAD\n");
}
if ((ISR_RXIDLE | ISR_RXORN | ISR_RXDESC | ISR_RXOK | ISR_RXERR) & isr)
ns83820_rx_kick(dev);
if (unlikely(ISR_RXSOVR & isr)) {
Dprintk("overrun: rxsovr\n");
dev->stats.rx_over_errors ++;
//printk("overrun: rxsovr\n");
dev->stats.rx_fifo_errors ++;
}
if (unlikely(ISR_RXORN & isr)) {
Dprintk("overrun: rxorn\n");
dev->stats.rx_over_errors ++;
//printk("overrun: rxorn\n");
dev->stats.rx_fifo_errors ++;
}
if ((ISR_RXRCMP & isr) && dev->rx_info.up)
......@@ -1241,15 +1294,11 @@ static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
if ((ISR_TXDESC | ISR_TXIDLE) & isr)
do_tx_done(dev);
if (ISR_MIB & isr) {
spin_lock(&dev->misc_lock);
ns83820_update_stats(dev);
spin_unlock(&dev->misc_lock);
}
if (unlikely(ISR_MIB & isr))
ns83820_mib_isr(dev);
if (ISR_PHY & isr)
if (unlikely(ISR_PHY & isr))
phy_intr(dev);
}
#if 0 /* Still working on the interrupt mitigation strategy */
if (dev->ihr)
......@@ -1412,6 +1461,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
dev->net_dev.owner = THIS_MODULE;
PREPARE_TQUEUE(&dev->tq_refill, queue_refill, dev);
tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)dev);
err = pci_enable_device(pci_dev);
if (err) {
......@@ -1430,8 +1480,9 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
if (!dev->base || !dev->tx_descs || !dev->rx_info.descs)
goto out_disable;
dprintk("%p: %08lx %p: %08lx\n", dev->tx_descs, dev->tx_phy_descs,
dev->rx_info.descs, dev->rx_info.phy_descs);
dprintk("%p: %08lx %p: %08lx\n",
dev->tx_descs, (long)dev->tx_phy_descs,
dev->rx_info.descs, (long)dev->rx_info.phy_descs);
/* disable interrupts */
writel(0, dev->base + IMR);
writel(0, dev->base + IER);
......@@ -1484,14 +1535,14 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
dev->CFG_cache = readl(dev->base + CFG);
if ((dev->CFG_cache & CFG_PCI64_DET)) {
printk("%s: enabling 64 bit PCI addressing.\n",
printk("%s: detected 64 bit PCI data bus.\n",
dev->net_dev.name);
/*dev->CFG_cache |= CFG_DATA64_EN;*/
if (!(dev->CFG_cache & CFG_DATA64_EN))
printk("%s: EEPROM did not enable 64 bit bus. Disabled.\n",
dev->net_dev.name);
dev->CFG_cache |= CFG_T64ADDR | CFG_DATA64_EN;
#if defined(USE_64BIT_ADDR)
dev->net_dev.features |= NETIF_F_HIGHDMA;
#endif
} else
dev->CFG_cache &= ~(CFG_T64ADDR | CFG_DATA64_EN);
dev->CFG_cache &= ~(CFG_DATA64_EN);
dev->CFG_cache &= (CFG_TBI_EN | CFG_MRM_DIS | CFG_MWI_DIS |
CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 |
......@@ -1528,8 +1579,12 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
writel(dev->CFG_cache, dev->base + CFG);
dprintk("CFG: %08x\n", dev->CFG_cache);
#if 1 /* Huh? This sets the PCI latency register. Should be done via
* the PCI layer. FIXME.
*/
if (readl(dev->base + SRR))
writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);
#endif
/* Note! The DMA burst size interacts with packet
* transmission, such that the largest packet that
......@@ -1543,13 +1598,15 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
/* Flush the interrupt holdoff timer */
writel(0x000, dev->base + IHR);
writel(0x100, dev->base + IHR);
writel(0x000, dev->base + IHR);
/* Set Rx to full duplex, don't accept runt, errored, long or length
* range errored packets. Set MXDMA to 7 => 512 word burst
* range errored packets. Set MXDMA to 0 => 1024 word burst
*/
writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
| RXCFG_STRIPCRC
| RXCFG_ALP
| RXCFG_MXDMA | 0, dev->base + RXCFG);
| (RXCFG_MXDMA0 * 0) | 0, dev->base + RXCFG);
/* Disable priority queueing */
writel(0, dev->base + PQCR);
......@@ -1576,7 +1633,11 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
dev->net_dev.features |= NETIF_F_SG;
dev->net_dev.features |= NETIF_F_IP_CSUM;
#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
if ((dev->CFG_cache & CFG_T64ADDR)) {
printk(KERN_INFO "%s: using 64 bit addressing.\n",
dev->net_dev.name);
dev->net_dev.features |= NETIF_F_HIGHDMA;
}
#endif
printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %02x:%02x:%02x:%02x:%02x:%02x io=0x%08lx irq=%d f=%s\n",
......@@ -1587,7 +1648,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
addr, pci_dev->irq,
(dev->net_dev.features & NETIF_F_HIGHDMA) ? "sg" : "h,sg"
(dev->net_dev.features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
);
return 0;
......
......@@ -323,7 +323,7 @@ struct pcnet32_private {
static void pcnet32_probe_vlbus(void);
static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
static int pcnet32_probe1(unsigned long, unsigned char, int, struct pci_dev *);
static int pcnet32_probe1(unsigned long, unsigned int, int, struct pci_dev *);
static int pcnet32_open(struct net_device *);
static int pcnet32_init_ring(struct net_device *);
static int pcnet32_start_xmit(struct sk_buff *, struct net_device *);
......@@ -507,7 +507,7 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
* pdev will be NULL when called from pcnet32_probe_vlbus.
*/
static int __devinit
pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared,
pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
struct pci_dev *pdev)
{
struct pcnet32_private *lp;
......@@ -522,13 +522,13 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared,
u8 promaddr[6];
/* reset the chip */
pcnet32_dwio_reset(ioaddr);
pcnet32_wio_reset(ioaddr);
/* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */
if (pcnet32_wio_read_csr(ioaddr, 0) == 4 && pcnet32_wio_check(ioaddr)) {
a = &pcnet32_wio;
} else {
pcnet32_dwio_reset(ioaddr);
if (pcnet32_dwio_read_csr(ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) {
a = &pcnet32_dwio;
} else
......@@ -789,7 +789,7 @@ pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared,
dev->set_multicast_list = &pcnet32_set_multicast_list;
dev->do_ioctl = &pcnet32_ioctl;
dev->tx_timeout = pcnet32_tx_timeout;
dev->watchdog_timeo = (HZ >> 1);
dev->watchdog_timeo = (5*HZ);
lp->next = pcnet32_dev;
pcnet32_dev = dev;
......@@ -946,7 +946,7 @@ pcnet32_purge_tx_ring(struct net_device *dev)
for (i = 0; i < TX_RING_SIZE; i++) {
if (lp->tx_skbuff[i]) {
pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i], lp->tx_skbuff[i]->len, PCI_DMA_TODEVICE);
dev_kfree_skb(lp->tx_skbuff[i]);
dev_kfree_skb_any(lp->tx_skbuff[i]);
lp->tx_skbuff[i] = NULL;
lp->tx_dma_addr[i] = 0;
}
......@@ -1022,8 +1022,9 @@ static void
pcnet32_tx_timeout (struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
unsigned int ioaddr = dev->base_addr;
unsigned long ioaddr = dev->base_addr, flags;
spin_lock_irqsave(&lp->lock, flags);
/* Transmitter timeout, serious problems. */
printk(KERN_ERR "%s: transmit timed out, status %4.4x, resetting.\n",
dev->name, lp->a.read_csr(ioaddr, 0));
......@@ -1048,6 +1049,8 @@ pcnet32_tx_timeout (struct net_device *dev)
dev->trans_start = jiffies;
netif_start_queue(dev);
spin_unlock_irqrestore(&lp->lock, flags);
}
......@@ -1055,7 +1058,7 @@ static int
pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
unsigned int ioaddr = dev->base_addr;
unsigned long ioaddr = dev->base_addr;
u16 status;
int entry;
unsigned long flags;
......@@ -1307,6 +1310,7 @@ pcnet32_rx(struct net_device *dev)
if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) {
skb_reserve (newskb, 2);
skb = lp->rx_skbuff[entry];
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], skb->len, PCI_DMA_FROMDEVICE);
skb_put (skb, pkt_len);
lp->rx_skbuff[entry] = newskb;
newskb->dev = dev;
......@@ -1473,9 +1477,10 @@ static void pcnet32_load_multicast (struct net_device *dev)
*/
static void pcnet32_set_multicast_list(struct net_device *dev)
{
unsigned long ioaddr = dev->base_addr;
unsigned long ioaddr = dev->base_addr, flags;
struct pcnet32_private *lp = dev->priv;
spin_lock_irqsave(&lp->lock, flags);
if (dev->flags&IFF_PROMISC) {
/* Log any net taps. */
printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
......@@ -1488,6 +1493,7 @@ static void pcnet32_set_multicast_list(struct net_device *dev)
lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */
pcnet32_restart(dev, 0x0042); /* Resume normal operation */
spin_unlock_irqrestore(&lp->lock, flags);
}
static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
......
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