patch-2.4.19 linux-2.4.19/drivers/net/acenic.c
Next file: linux-2.4.19/drivers/net/acenic.h
Previous file: linux-2.4.19/drivers/net/ac3200.c
Back to the patch index
Back to the overall index
- Lines: 634
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/net/acenic.c
- Orig date:
Mon Feb 25 11:37:59 2002
diff -urN linux-2.4.18/drivers/net/acenic.c linux-2.4.19/drivers/net/acenic.c
@@ -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
@@ -65,6 +66,10 @@
#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>
#endif
@@ -83,8 +88,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
@@ -113,6 +120,10 @@
#ifndef PCI_DEVICE_ID_FARALLON_PN9000SX
#define PCI_DEVICE_ID_FARALLON_PN9000SX 0x1a
#endif
+#ifndef PCI_DEVICE_ID_FARALLON_PN9100T
+#define PCI_DEVICE_ID_FARALLON_PN9100T 0xfa
+#endif
+
#ifndef PCI_VENDOR_ID_SGI
#define PCI_VENDOR_ID_SGI 0x10a9
#endif
@@ -137,6 +148,9 @@
*/
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_FARALLON_PN9000SX,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
+ { PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_FARALLON_PN9100T,
+ PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
+
{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_ACENIC,
PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
{ }
@@ -314,6 +328,14 @@
#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
+#define ACE_RCB_VLAN_FLAG RCB_FLG_VLAN_ASSIST
+#else
+#define ACENIC_DO_VLAN 0
+#define ACE_RCB_VLAN_FLAG 0
+#endif
#include "acenic.h"
@@ -553,7 +575,7 @@
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.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;
@@ -596,6 +618,8 @@
*/
!((pdev->vendor == PCI_VENDOR_ID_DEC) &&
(pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) &&
+ !((pdev->vendor == PCI_VENDOR_ID_ALTEON) &&
+ (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T)) &&
!((pdev->vendor == PCI_VENDOR_ID_SGI) &&
(pdev->device == PCI_DEVICE_ID_SGI_ACENIC)))
continue;
@@ -620,10 +644,14 @@
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;
@@ -689,6 +717,13 @@
switch(pdev->vendor) {
case PCI_VENDOR_ID_ALTEON:
+ if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9100T) {
+ strncpy(ap->name, "Farallon PN9100-T "
+ "Gigabit Ethernet", sizeof (ap->name));
+ printk(KERN_INFO "%s: Farallon PN9100-T ",
+ dev->name);
+ break;
+ }
strncpy(ap->name, "AceNIC Gigabit Ethernet",
sizeof (ap->name));
printk(KERN_INFO "%s: Alteon AceNIC ", dev->name);
@@ -725,9 +760,9 @@
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 +995,13 @@
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 +1048,19 @@
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;
+ if (ap->tx_ring == NULL)
+ goto fail;
+ }
ap->evt_prd = pci_alloc_consistent(ap->pdev, sizeof(u32),
&ap->evt_prd_dma);
@@ -1086,6 +1135,7 @@
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 +1194,7 @@
tigonFwReleaseFix);
writel(0, ®s->LocalCtrl);
ap->version = 1;
+ ap->tx_ring_entries = TIGON_I_TX_RING_ENTRIES;
break;
#endif
case 6:
@@ -1159,6 +1210,7 @@
writel(SRAM_BANK_512K, ®s->LocalCtrl);
writel(SYNC_SRAM_TIMING, ®s->MiscCfg);
ap->version = 2;
+ ap->tx_ring_entries = MAX_TX_RING_ENTRIES;
break;
default:
printk(KERN_WARNING " Unsupported Tigon version detected "
@@ -1224,7 +1276,8 @@
* 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 +1286,7 @@
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 +1318,7 @@
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 +1345,7 @@
"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 +1387,16 @@
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 +1423,14 @@
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 +1441,7 @@
#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
@@ -1427,7 +1482,8 @@
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;
+ 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));
@@ -1442,7 +1498,8 @@
(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;
+ 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));
@@ -1464,7 +1521,7 @@
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;
+ 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 =
@@ -1494,12 +1551,30 @@
*(ap->rx_ret_prd) = 0;
writel(TX_RING_BASE, ®s->WinBase);
- memset(ap->tx_ring, 0, TX_RING_ENTRIES * sizeof(struct tx_desc));
- set_aceaddr(&info->tx_ctrl.rngptr, ap->tx_ring_dma);
+ 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 = TX_RING_ENTRIES;
- tmp = RCB_FLG_TCP_UDP_SUM|RCB_FLG_NO_PSEUDO_HDR|RCB_FLG_TX_HOST_RING;
+ info->tx_ctrl.max_len = ACE_TX_RING_ENTRIES(ap);
+ 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 ;-(
+ */
+ if (!ACE_IS_TIGON_I(ap))
+ tmp |= RCB_FLG_TX_HOST_RING;
#if TX_COAL_INTS_ONLY
tmp |= RCB_FLG_COAL_INT_ONLY;
#endif
@@ -1528,7 +1603,7 @@
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) {
@@ -2201,7 +2276,13 @@
skb->ip_summed = CHECKSUM_NONE;
}
- netif_rx(skb); /* send it up */
+ /* send it up */
+#if ACENIC_DO_VLAN
+ if (ap->vlgrp && (bd_flags & BD_FLG_VLAN_TAG)) {
+ vlan_hwaccel_rx(skb, ap->vlgrp, retdesc->vlan);
+ } else
+#endif
+ netif_rx(skb);
dev->last_rx = jiffies;
ap->stats.rx_packets++;
@@ -2260,7 +2341,7 @@
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 +2434,7 @@
* 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 +2506,37 @@
}
+#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 +2639,7 @@
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 +2649,13 @@
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 +2680,7 @@
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 +2701,28 @@
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
- desc->addr.addrhi = addr >> 32;
- desc->addr.addrlo = addr;
- desc->flagsize = flagsize;
+ 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 +2739,10 @@
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 +2750,47 @@
#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 +2807,11 @@
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 +2824,7 @@
}
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 +2842,7 @@
* 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 +2921,8 @@
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 +2970,8 @@
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 +3028,24 @@
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;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)