#include <linux/config.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
+#define DRV_NAME "acenic"
+
#undef INDEX_DEBUG
#ifdef CONFIG_ACENIC_OMIT_TIGON_I
*/
#define ACE_MINI_SIZE 100
-#define ACE_MINI_BUFSIZE (ACE_MINI_SIZE + 2 + 16)
-#define ACE_STD_BUFSIZE (ACE_STD_MTU + ETH_HLEN + 2+4+16)
-#define ACE_JUMBO_BUFSIZE (ACE_JUMBO_MTU + ETH_HLEN + 2+4+16)
+#define ACE_MINI_BUFSIZE ACE_MINI_SIZE
+#define ACE_STD_BUFSIZE (ACE_STD_MTU + ETH_HLEN + 4)
+#define ACE_JUMBO_BUFSIZE (ACE_JUMBO_MTU + ETH_HLEN + 4)
/*
* There seems to be a magic difference in the effect between 995 and 996
MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
-MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(tx_ratio, "1-" __MODULE_STRING(8) "i");
+
+static int num_params;
+module_param_array(link, int, num_params, 0);
+module_param_array(trace, int, num_params, 0);
+module_param_array(tx_coal_tick, int, num_params, 0);
+module_param_array(max_tx_desc, int, num_params, 0);
+module_param_array(rx_coal_tick, int, num_params, 0);
+module_param_array(max_rx_desc, int, num_params, 0);
+module_param_array(tx_ratio, int, num_params, 0);
MODULE_PARM_DESC(link, "AceNIC/3C985/NetGear link state");
MODULE_PARM_DESC(trace, "AceNIC/3C985/NetGear firmware trace level");
MODULE_PARM_DESC(tx_coal_tick, "AceNIC/3C985/GA620 max clock ticks to wait from first tx descriptor arrives");
"acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
+static int ace_get_settings(struct net_device *, struct ethtool_cmd *);
+static int ace_set_settings(struct net_device *, struct ethtool_cmd *);
+static void ace_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
+
+static struct ethtool_ops ace_ethtool_ops = {
+ .get_settings = ace_get_settings,
+ .set_settings = ace_set_settings,
+ .get_drvinfo = ace_get_drvinfo,
+};
+
static int __devinit acenic_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
ap = dev->priv;
ap->pdev = pdev;
+ ap->name = pci_name(pdev);
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
#if ACENIC_DO_VLAN
dev->hard_start_xmit = &ace_start_xmit;
dev->get_stats = &ace_get_stats;
dev->set_multicast_list = &ace_set_multicast_list;
- dev->do_ioctl = &ace_ioctl;
+ SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
dev->set_mac_address = &ace_set_mac_addr;
dev->change_mtu = &ace_change_mtu;
if (!(ap->pci_command & PCI_COMMAND_MEMORY)) {
printk(KERN_INFO "%s: Enabling PCI Memory Mapped "
"access - was not enabled by BIOS/Firmware\n",
- dev->name);
+ ap->name);
ap->pci_command = ap->pci_command | PCI_COMMAND_MEMORY;
pci_write_config_word(ap->pdev, PCI_COMMAND,
ap->pci_command);
if (!ap->regs) {
printk(KERN_ERR "%s: Unable to map I/O register, "
"AceNIC %i will be disabled.\n",
- dev->name, boards_found);
+ ap->name, boards_found);
goto fail_free_netdev;
}
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);
+ ap->name);
} else {
- strncpy(ap->name, "AceNIC Gigabit Ethernet",
- sizeof (ap->name));
printk(KERN_INFO "%s: Alteon AceNIC ",
- dev->name);
+ ap->name);
}
break;
case PCI_VENDOR_ID_3COM:
- strncpy(ap->name, "3Com 3C985 Gigabit Ethernet",
- sizeof (ap->name));
- printk(KERN_INFO "%s: 3Com 3C985 ", dev->name);
+ printk(KERN_INFO "%s: 3Com 3C985 ", ap->name);
break;
case PCI_VENDOR_ID_NETGEAR:
- strncpy(ap->name, "NetGear GA620 Gigabit Ethernet",
- sizeof (ap->name));
- printk(KERN_INFO "%s: NetGear GA620 ", dev->name);
+ printk(KERN_INFO "%s: NetGear GA620 ", ap->name);
break;
case PCI_VENDOR_ID_DEC:
if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX) {
- strncpy(ap->name, "Farallon PN9000-SX "
- "Gigabit Ethernet", sizeof (ap->name));
printk(KERN_INFO "%s: Farallon PN9000-SX ",
- dev->name);
+ ap->name);
break;
}
case PCI_VENDOR_ID_SGI:
- strncpy(ap->name, "SGI AceNIC Gigabit Ethernet",
- sizeof (ap->name));
- printk(KERN_INFO "%s: SGI AceNIC ", dev->name);
+ printk(KERN_INFO "%s: SGI AceNIC ", ap->name);
break;
default:
- strncpy(ap->name, "Unknown AceNIC based Gigabit "
- "Ethernet", sizeof (ap->name));
- printk(KERN_INFO "%s: Unknown AceNIC ", dev->name);
+ printk(KERN_INFO "%s: Unknown AceNIC ", ap->name);
break;
}
- ap->name [sizeof (ap->name) - 1] = '\0';
printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr);
#ifdef __sparc__
printk("irq %s\n", __irq_itoa(pdev->irq));
printk(KERN_ERR "acenic: device registration failed\n");
goto fail_uninit;
}
+ ap->name = dev->name;
if (ap->pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
static void __devexit acenic_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs *regs = ap->regs;
short i;
ringp = &ap->skb->rx_std_skbuff[i];
mapping = pci_unmap_addr(ringp, mapping);
pci_unmap_page(ap->pdev, mapping,
- ACE_STD_BUFSIZE - (2 + 16),
+ ACE_STD_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->rx_std_ring[i].size = 0;
ringp = &ap->skb->rx_mini_skbuff[i];
mapping = pci_unmap_addr(ringp,mapping);
pci_unmap_page(ap->pdev, mapping,
- ACE_MINI_BUFSIZE - (2 + 16),
+ ACE_MINI_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->rx_mini_ring[i].size = 0;
ringp = &ap->skb->rx_jumbo_skbuff[i];
mapping = pci_unmap_addr(ringp, mapping);
pci_unmap_page(ap->pdev, mapping,
- ACE_JUMBO_BUFSIZE - (2 + 16),
+ ACE_JUMBO_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->rx_jumbo_ring[i].size = 0;
static void ace_free_descriptors(struct net_device *dev)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
int size;
if (ap->rx_std_ring != NULL) {
static int ace_allocate_descriptors(struct net_device *dev)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
int size;
size = (sizeof(struct rx_desc) *
{
struct ace_private *ap;
- ap = dev->priv;
+ ap = netdev_priv(dev);
ace_free_descriptors(dev);
short i;
unsigned char cache_size;
- ap = dev->priv;
+ ap = netdev_priv(dev);
regs = ap->regs;
board_idx = ap->board_idx;
}
ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ,
- dev->name, dev);
+ DRV_NAME, dev);
if (ecode) {
printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
- dev->name, pdev->irq);
+ DRV_NAME, pdev->irq);
goto init_error;
} else
dev->irq = pdev->irq;
set_aceaddr(&info->stats2_ptr, (dma_addr_t) tmp_ptr);
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.max_len = ACE_STD_BUFSIZE;
info->rx_std_ctrl.flags =
RCB_FLG_TCP_UDP_SUM | RCB_FLG_NO_PSEUDO_HDR | ACE_RCB_VLAN_FLAG;
if (board_idx == BOARD_IDX_OVERFLOW) {
printk(KERN_WARNING "%s: more than %i NICs detected, "
"ignoring module parameters!\n",
- dev->name, ACE_MAX_MOD_PARMS);
+ ap->name, ACE_MAX_MOD_PARMS);
} else if (board_idx >= 0) {
if (tx_coal_tick[board_idx])
writel(tx_coal_tick[board_idx],
if (option & 0x01) {
printk(KERN_INFO "%s: Setting half duplex link\n",
- dev->name);
+ ap->name);
tmp &= ~LNK_FULL_DUPLEX;
}
if (option & 0x02)
tmp |= LNK_1000MB;
if ((option & 0x70) == 0) {
printk(KERN_WARNING "%s: No media speed specified, "
- "forcing auto negotiation\n", dev->name);
+ "forcing auto negotiation\n", ap->name);
tmp |= LNK_NEGOTIATE | LNK_1000MB |
LNK_100MB | LNK_10MB;
}
tmp |= LNK_NEG_FCTL;
else
printk(KERN_INFO "%s: Disabling flow control "
- "negotiation\n", dev->name);
+ "negotiation\n", ap->name);
if (option & 0x200)
tmp |= LNK_RX_FLOW_CTL_Y;
if ((option & 0x400) && (ap->version >= 2)) {
printk(KERN_INFO "%s: Enabling TX flow control\n",
- dev->name);
+ ap->name);
tmp |= LNK_TX_FLOW_CTL_Y;
}
}
cpu_relax();
if (!ap->fw_running) {
- printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name);
+ printk(KERN_ERR "%s: Firmware NOT running!\n", ap->name);
ace_dump_trace(ap);
writel(readl(®s->CpuCtrl) | CPU_HALT, ®s->CpuCtrl);
ace_load_std_rx_ring(ap, RX_RING_SIZE);
else
printk(KERN_ERR "%s: Someone is busy refilling the RX ring\n",
- dev->name);
+ ap->name);
if (ap->version >= 2) {
if (!test_and_set_bit(0, &ap->mini_refill_busy))
ace_load_mini_rx_ring(ap, RX_MINI_SIZE);
else
printk(KERN_ERR "%s: Someone is busy refilling "
- "the RX mini ring\n", dev->name);
+ "the RX mini ring\n", ap->name);
}
return 0;
struct ace_regs *regs;
int board_idx;
- ap = dev->priv;
+ ap = netdev_priv(dev);
regs = ap->regs;
board_idx = ap->board_idx;
static void ace_watchdog(struct net_device *data)
{
struct net_device *dev = data;
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs *regs = ap->regs;
/*
cur_size = atomic_read(&ap->cur_rx_bufs);
if ((cur_size < RX_LOW_STD_THRES) &&
!test_and_set_bit(0, &ap->std_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
printk("refilling buffers (current %i)\n", cur_size);
#endif
ace_load_std_rx_ring(ap, RX_RING_SIZE - cur_size);
cur_size = atomic_read(&ap->cur_mini_bufs);
if ((cur_size < RX_LOW_MINI_THRES) &&
!test_and_set_bit(0, &ap->mini_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
printk("refilling mini buffers (current %i)\n",
cur_size);
#endif
cur_size = atomic_read(&ap->cur_jumbo_bufs);
if (ap->jumbo && (cur_size < RX_LOW_JUMBO_THRES) &&
!test_and_set_bit(0, &ap->jumbo_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
printk("refilling jumbo buffers (current %i)\n", cur_size);
#endif
ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size);
struct rx_desc *rd;
dma_addr_t mapping;
- skb = alloc_skb(ACE_STD_BUFSIZE, GFP_ATOMIC);
+ skb = alloc_skb(ACE_STD_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC);
if (!skb)
break;
- /*
- * Make sure IP header starts on a fresh cache line.
- */
- skb_reserve(skb, 2 + 16);
+ skb_reserve(skb, NET_IP_ALIGN);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
offset_in_page(skb->data),
- ACE_STD_BUFSIZE - (2 + 16),
+ ACE_STD_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->skb->rx_std_skbuff[idx].skb = skb;
pci_unmap_addr_set(&ap->skb->rx_std_skbuff[idx],
rd = &ap->rx_std_ring[idx];
set_aceaddr(&rd->addr, mapping);
- rd->size = ACE_STD_MTU + ETH_HLEN + 4;
+ rd->size = ACE_STD_BUFSIZE;
rd->idx = idx;
idx = (idx + 1) % RX_STD_RING_ENTRIES;
}
struct rx_desc *rd;
dma_addr_t mapping;
- skb = alloc_skb(ACE_MINI_BUFSIZE, GFP_ATOMIC);
+ skb = alloc_skb(ACE_MINI_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC);
if (!skb)
break;
- /*
- * Make sure the IP header ends up on a fresh cache line
- */
- skb_reserve(skb, 2 + 16);
+ skb_reserve(skb, NET_IP_ALIGN);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
offset_in_page(skb->data),
- ACE_MINI_BUFSIZE - (2 + 16),
+ ACE_MINI_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->skb->rx_mini_skbuff[idx].skb = skb;
pci_unmap_addr_set(&ap->skb->rx_mini_skbuff[idx],
rd = &ap->rx_mini_ring[idx];
set_aceaddr(&rd->addr, mapping);
- rd->size = ACE_MINI_SIZE;
+ rd->size = ACE_MINI_BUFSIZE;
rd->idx = idx;
idx = (idx + 1) % RX_MINI_RING_ENTRIES;
}
struct rx_desc *rd;
dma_addr_t mapping;
- skb = alloc_skb(ACE_JUMBO_BUFSIZE, GFP_ATOMIC);
+ skb = alloc_skb(ACE_JUMBO_BUFSIZE + NET_IP_ALIGN, GFP_ATOMIC);
if (!skb)
break;
- /*
- * Make sure the IP header ends up on a fresh cache line
- */
- skb_reserve(skb, 2 + 16);
+ skb_reserve(skb, NET_IP_ALIGN);
mapping = pci_map_page(ap->pdev, virt_to_page(skb->data),
offset_in_page(skb->data),
- ACE_JUMBO_BUFSIZE - (2 + 16),
+ ACE_JUMBO_BUFSIZE,
PCI_DMA_FROMDEVICE);
ap->skb->rx_jumbo_skbuff[idx].skb = skb;
pci_unmap_addr_set(&ap->skb->rx_jumbo_skbuff[idx],
rd = &ap->rx_jumbo_ring[idx];
set_aceaddr(&rd->addr, mapping);
- rd->size = ACE_JUMBO_MTU + ETH_HLEN + 4;
+ rd->size = ACE_JUMBO_BUFSIZE;
rd->idx = idx;
idx = (idx + 1) % RX_JUMBO_RING_ENTRIES;
}
{
struct ace_private *ap;
- ap = dev->priv;
+ ap = netdev_priv(dev);
while (evtcsm != evtprd) {
switch (ap->evt_ring[evtcsm].evt) {
case E_FW_RUNNING:
printk(KERN_INFO "%s: Firmware up and running\n",
- dev->name);
+ ap->name);
ap->fw_running = 1;
wmb();
break;
u32 state = readl(&ap->regs->GigLnkState);
printk(KERN_WARNING "%s: Optical link UP "
"(%s Duplex, Flow Control: %s%s)\n",
- dev->name,
+ ap->name,
state & LNK_FULL_DUPLEX ? "Full":"Half",
state & LNK_TX_FLOW_CTL_Y ? "TX " : "",
state & LNK_RX_FLOW_CTL_Y ? "RX" : "");
}
case E_C_LINK_DOWN:
printk(KERN_WARNING "%s: Optical link DOWN\n",
- dev->name);
+ ap->name);
break;
case E_C_LINK_10_100:
printk(KERN_WARNING "%s: 10/100BaseT link "
- "UP\n", dev->name);
+ "UP\n", ap->name);
break;
default:
printk(KERN_ERR "%s: Unknown optical link "
- "state %02x\n", dev->name, code);
+ "state %02x\n", ap->name, code);
}
break;
}
switch(ap->evt_ring[evtcsm].code) {
case E_C_ERR_INVAL_CMD:
printk(KERN_ERR "%s: invalid command error\n",
- dev->name);
+ ap->name);
break;
case E_C_ERR_UNIMP_CMD:
printk(KERN_ERR "%s: unimplemented command "
- "error\n", dev->name);
+ "error\n", ap->name);
break;
case E_C_ERR_BAD_CFG:
printk(KERN_ERR "%s: bad config error\n",
- dev->name);
+ ap->name);
break;
default:
printk(KERN_ERR "%s: unknown error %02x\n",
- dev->name, ap->evt_ring[evtcsm].code);
+ ap->name, ap->evt_ring[evtcsm].code);
}
break;
case E_RESET_JUMBO_RNG:
ap->jumbo = 0;
ap->rx_jumbo_skbprd = 0;
printk(KERN_INFO "%s: Jumbo ring flushed\n",
- dev->name);
+ ap->name);
clear_bit(0, &ap->jumbo_refill_busy);
break;
}
default:
printk(KERN_ERR "%s: Unhandled event 0x%02x\n",
- dev->name, ap->evt_ring[evtcsm].evt);
+ ap->name, ap->evt_ring[evtcsm].evt);
}
evtcsm = (evtcsm + 1) % EVT_RING_ENTRIES;
}
static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
u32 idx;
int mini_count = 0, std_count = 0;
int bd_flags, desc_type, mapsize;
u16 csum;
+
+ /* make sure the rx descriptor isn't read before rxretprd */
+ if (idx == rxretcsm)
+ rmb();
+
retdesc = &ap->rx_return_ring[idx];
skbidx = retdesc->idx;
bd_flags = retdesc->flags;
*/
case 0:
rip = &ap->skb->rx_std_skbuff[skbidx];
- mapsize = ACE_STD_BUFSIZE - (2 + 16);
+ mapsize = ACE_STD_BUFSIZE;
rxdesc = &ap->rx_std_ring[skbidx];
std_count++;
break;
case BD_FLG_JUMBO:
rip = &ap->skb->rx_jumbo_skbuff[skbidx];
- mapsize = ACE_JUMBO_BUFSIZE - (2 + 16);
+ mapsize = ACE_JUMBO_BUFSIZE;
rxdesc = &ap->rx_jumbo_ring[skbidx];
atomic_dec(&ap->cur_jumbo_bufs);
break;
case BD_FLG_MINI:
rip = &ap->skb->rx_mini_skbuff[skbidx];
- mapsize = ACE_MINI_BUFSIZE - (2 + 16);
+ mapsize = ACE_MINI_BUFSIZE;
rxdesc = &ap->rx_mini_ring[skbidx];
mini_count++;
break;
static inline void ace_tx_int(struct net_device *dev,
u32 txcsm, u32 idx)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
do {
struct sk_buff *skb;
u32 txcsm, rxretcsm, rxretprd;
u32 evtcsm, evtprd;
- ap = dev->priv;
+ ap = netdev_priv(dev);
regs = ap->regs;
/*
if (cur_size < RX_LOW_STD_THRES) {
if ((cur_size < RX_PANIC_STD_THRES) &&
!test_and_set_bit(0, &ap->std_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
printk("low on std buffers %i\n", cur_size);
#endif
ace_load_std_rx_ring(ap,
if ((cur_size < RX_PANIC_MINI_THRES) &&
!test_and_set_bit(0,
&ap->mini_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
printk("low on mini buffers %i\n",
cur_size);
#endif
if ((cur_size < RX_PANIC_JUMBO_THRES) &&
!test_and_set_bit(0,
&ap->jumbo_refill_busy)){
-#if DEBUG
+#ifdef DEBUG
printk("low on jumbo buffers %i\n",
cur_size);
#endif
#if ACENIC_DO_VLAN
static void ace_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
unsigned long flags;
local_irq_save(flags);
static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
unsigned long flags;
local_irq_save(flags);
struct ace_regs *regs;
struct cmd cmd;
- ap = dev->priv;
+ ap = netdev_priv(dev);
regs = ap->regs;
if (!(ap->fw_running)) {
*/
netif_stop_queue(dev);
- ap = dev->priv;
+ ap = netdev_priv(dev);
regs = ap->regs;
if (ap->promisc) {
static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs *regs = ap->regs;
struct tx_desc *desc;
u32 idx, flagsize;
static int ace_change_mtu(struct net_device *dev, int new_mtu)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs *regs = ap->regs;
if (new_mtu > ACE_JUMBO_MTU)
return 0;
}
-
-static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs *regs = ap->regs;
-#ifdef SIOCETHTOOL
- struct ethtool_cmd ecmd;
- u32 link, speed;
+ u32 link;
- if (cmd != SIOCETHTOOL)
- return -EOPNOTSUPP;
- if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
- return -EFAULT;
- switch (ecmd.cmd) {
- case ETHTOOL_GSET:
- ecmd.supported =
- (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_FIBRE);
-
- ecmd.port = PORT_FIBRE;
- ecmd.transceiver = XCVR_INTERNAL;
- ecmd.phy_address = 0;
-
- link = readl(®s->GigLnkState);
- if (link & LNK_1000MB)
- ecmd.speed = SPEED_1000;
- else {
- link = readl(®s->FastLnkState);
- if (link & LNK_100MB)
- ecmd.speed = SPEED_100;
- else if (link & LNK_100MB)
- ecmd.speed = SPEED_10;
- else
- ecmd.speed = 0;
- }
- if (link & LNK_FULL_DUPLEX)
- ecmd.duplex = DUPLEX_FULL;
- else
- ecmd.duplex = DUPLEX_HALF;
+ memset(ecmd, 0, sizeof(struct ethtool_cmd));
+ ecmd->supported =
+ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_FIBRE);
+
+ ecmd->port = PORT_FIBRE;
+ ecmd->transceiver = XCVR_INTERNAL;
- if (link & LNK_NEGOTIATE)
- ecmd.autoneg = AUTONEG_ENABLE;
+ link = readl(®s->GigLnkState);
+ if (link & LNK_1000MB)
+ ecmd->speed = SPEED_1000;
+ else {
+ link = readl(®s->FastLnkState);
+ if (link & LNK_100MB)
+ ecmd->speed = SPEED_100;
+ else if (link & LNK_10MB)
+ ecmd->speed = SPEED_10;
else
- ecmd.autoneg = AUTONEG_DISABLE;
+ ecmd->speed = 0;
+ }
+ if (link & LNK_FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+
+ if (link & LNK_NEGOTIATE)
+ ecmd->autoneg = AUTONEG_ENABLE;
+ else
+ ecmd->autoneg = AUTONEG_DISABLE;
#if 0
- /*
- * Current struct ethtool_cmd is insufficient
- */
- ecmd.trace = readl(®s->TuneTrace);
+ /*
+ * Current struct ethtool_cmd is insufficient
+ */
+ ecmd->trace = readl(®s->TuneTrace);
- ecmd.txcoal = readl(®s->TuneTxCoalTicks);
- ecmd.rxcoal = readl(®s->TuneRxCoalTicks);
+ ecmd->txcoal = readl(®s->TuneTxCoalTicks);
+ ecmd->rxcoal = readl(®s->TuneRxCoalTicks);
#endif
- ecmd.maxtxpkt = readl(®s->TuneMaxTxDesc);
- ecmd.maxrxpkt = readl(®s->TuneMaxRxDesc);
+ ecmd->maxtxpkt = readl(®s->TuneMaxTxDesc);
+ ecmd->maxrxpkt = readl(®s->TuneMaxRxDesc);
- if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
- return -EFAULT;
- return 0;
+ return 0;
+}
- case ETHTOOL_SSET:
- link = readl(®s->GigLnkState);
- if (link & LNK_1000MB)
- speed = SPEED_1000;
- else {
- link = readl(®s->FastLnkState);
- if (link & LNK_100MB)
- speed = SPEED_100;
- else if (link & LNK_100MB)
- speed = SPEED_10;
- else
- speed = SPEED_100;
- }
+static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+ struct ace_private *ap = netdev_priv(dev);
+ struct ace_regs *regs = ap->regs;
+ u32 link, speed;
- link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
- LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
- if (!ACE_IS_TIGON_I(ap))
- link |= LNK_TX_FLOW_CTL_Y;
- if (ecmd.autoneg == AUTONEG_ENABLE)
- link |= LNK_NEGOTIATE;
- if (ecmd.speed != speed) {
- link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
- switch (speed) {
- case SPEED_1000:
- link |= LNK_1000MB;
- break;
- case SPEED_100:
- link |= LNK_100MB;
- break;
- case SPEED_10:
- link |= LNK_10MB;
- break;
- }
+ link = readl(®s->GigLnkState);
+ if (link & LNK_1000MB)
+ speed = SPEED_1000;
+ else {
+ link = readl(®s->FastLnkState);
+ if (link & LNK_100MB)
+ speed = SPEED_100;
+ else if (link & LNK_10MB)
+ speed = SPEED_10;
+ else
+ speed = SPEED_100;
+ }
+
+ link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
+ LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
+ if (!ACE_IS_TIGON_I(ap))
+ link |= LNK_TX_FLOW_CTL_Y;
+ if (ecmd->autoneg == AUTONEG_ENABLE)
+ link |= LNK_NEGOTIATE;
+ if (ecmd->speed != speed) {
+ link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
+ switch (speed) {
+ case SPEED_1000:
+ link |= LNK_1000MB;
+ break;
+ case SPEED_100:
+ link |= LNK_100MB;
+ break;
+ case SPEED_10:
+ link |= LNK_10MB;
+ break;
}
- if (ecmd.duplex == DUPLEX_FULL)
- link |= LNK_FULL_DUPLEX;
+ }
- if (link != ap->link) {
- struct cmd cmd;
- printk(KERN_INFO "%s: Renegotiating link state\n",
- dev->name);
+ if (ecmd->duplex == DUPLEX_FULL)
+ link |= LNK_FULL_DUPLEX;
- ap->link = link;
- writel(link, ®s->TuneLink);
- if (!ACE_IS_TIGON_I(ap))
- writel(link, ®s->TuneFastLink);
- wmb();
+ if (link != ap->link) {
+ struct cmd cmd;
+ printk(KERN_INFO "%s: Renegotiating link state\n",
+ dev->name);
- cmd.evt = C_LNK_NEGOTIATION;
- cmd.code = 0;
- cmd.idx = 0;
- 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, pci_name(ap->pdev));
- if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
- return -EFAULT;
- return 0;
- }
- default:
- break;
- }
-
-#endif
+ ap->link = link;
+ writel(link, ®s->TuneLink);
+ if (!ACE_IS_TIGON_I(ap))
+ writel(link, ®s->TuneFastLink);
+ wmb();
- return -EOPNOTSUPP;
+ cmd.evt = C_LNK_NEGOTIATION;
+ cmd.code = 0;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+ }
+ return 0;
}
+static void ace_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct ace_private *ap = netdev_priv(dev);
+
+ strlcpy(info->driver, "acenic", sizeof(info->driver));
+ snprintf(info->version, sizeof(info->version), "%i.%i.%i",
+ tigonFwReleaseMajor, tigonFwReleaseMinor,
+ tigonFwReleaseFix);
+
+ if (ap->pdev)
+ strlcpy(info->bus_info, pci_name(ap->pdev),
+ sizeof(info->bus_info));
+
+}
/*
* Set the hardware MAC address.
da = (u8 *)dev->dev_addr;
- regs = ((struct ace_private *)dev->priv)->regs;
+ regs = ((struct ace_private *)netdev_priv(dev))->regs;
writel(da[0] << 8 | da[1], ®s->MacAddrHi);
writel((da[2] << 24) | (da[3] << 16) | (da[4] << 8) | da[5],
®s->MacAddrLo);
static void ace_set_multicast_list(struct net_device *dev)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_regs *regs = ap->regs;
struct cmd cmd;
static struct net_device_stats *ace_get_stats(struct net_device *dev)
{
- struct ace_private *ap = dev->priv;
+ struct ace_private *ap = netdev_priv(dev);
struct ace_mac_stats *mac_stats =
(struct ace_mac_stats *)ap->regs->Stats;
struct ace_private *ap;
struct ace_regs *regs;
- ap = dev->priv;
+ ap = netdev_priv(dev);
regs = ap->regs;
if (!(readl(®s->CpuCtrl) & CPU_HALTED)) {
printk(KERN_ERR "%s: trying to download firmware while the "
- "CPU is running!\n", dev->name);
+ "CPU is running!\n", ap->name);
return -EFAULT;
}
static int __init read_eeprom_byte(struct net_device *dev,
unsigned long offset)
{
+ struct ace_private *ap;
struct ace_regs *regs;
unsigned long flags;
u32 local;
if (!dev) {
printk(KERN_ERR "No device!\n");
result = -ENODEV;
- goto eeprom_read_error;
+ goto out;
}
- regs = ((struct ace_private *)dev->priv)->regs;
+ ap = netdev_priv(dev);
+ regs = ap->regs;
/*
* Don't take interrupts on this CPU will bit banging
eeprom_prep(regs, EEPROM_WRITE_SELECT);
if (eeprom_check_ack(regs)) {
local_irq_restore(flags);
- printk(KERN_ERR "%s: Unable to sync eeprom\n", dev->name);
+ printk(KERN_ERR "%s: Unable to sync eeprom\n", ap->name);
result = -EIO;
goto eeprom_read_error;
}
if (eeprom_check_ack(regs)) {
local_irq_restore(flags);
printk(KERN_ERR "%s: Unable to set address byte 0\n",
- dev->name);
+ ap->name);
result = -EIO;
goto eeprom_read_error;
}
if (eeprom_check_ack(regs)) {
local_irq_restore(flags);
printk(KERN_ERR "%s: Unable to set address byte 1\n",
- dev->name);
+ ap->name);
result = -EIO;
goto eeprom_read_error;
}
if (eeprom_check_ack(regs)) {
local_irq_restore(flags);
printk(KERN_ERR "%s: Unable to set READ_SELECT\n",
- dev->name);
+ ap->name);
result = -EIO;
goto eeprom_read_error;
}
eeprom_read_error:
printk(KERN_ERR "%s: Unable to read eeprom byte 0x%02lx\n",
- dev->name, offset);
+ ap->name, offset);
goto out;
}