** Extended for new busmaster capable chipsets by
** Siegfried "Frieder" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>
**
-** Maintained by: Jaroslav Kysela <perex@suse.cz>
+** Maintained by: Jaroslav Kysela <perex@perex.cz>
**
** This driver has only been tested with
** -- HP J2585B 10/100 Mbit/s PCI Busmaster
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/eisa.h>
#include <linux/pci.h>
/*
* variables
*/
-#ifndef MODULE
+#ifdef CONFIG_ISA
static const char *hp100_isa_tbl[] = {
"HWPF150", /* HP J2573 rev A */
"HWP1950", /* HP J2573 */
#endif
#ifdef CONFIG_PCI
-static struct pci_device_id hp100_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(hp100_pci_tbl) = {
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B, PCI_ANY_ID, PCI_ANY_ID,},
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2970A, PCI_ANY_ID, PCI_ANY_ID,},
static int hp100_open(struct net_device *dev);
static int hp100_close(struct net_device *dev);
-static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int hp100_start_xmit_bm(struct sk_buff *skb,
- struct net_device *dev);
+static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
+static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
+ struct net_device *dev);
static void hp100_rx(struct net_device *dev);
static struct net_device_stats *hp100_get_stats(struct net_device *dev);
static void hp100_misc_interrupt(struct net_device *dev);
static void hp100_update_stats(struct net_device *dev);
static void hp100_clear_stats(struct hp100_private *lp, int ioaddr);
static void hp100_set_multicast_list(struct net_device *dev);
-static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t hp100_interrupt(int irq, void *dev_id);
static void hp100_start_interface(struct net_device *dev);
static void hp100_stop_interface(struct net_device *dev);
static void hp100_load_eeprom(struct net_device *dev, u_short ioaddr);
return str;
}
-#ifndef MODULE
+#ifdef CONFIG_ISA
static __init int hp100_isa_probe1(struct net_device *dev, int ioaddr)
{
const char *sig;
}
return err;
}
+#endif /* CONFIG_ISA */
+#if !defined(MODULE) && defined(CONFIG_ISA)
struct net_device * __init hp100_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct hp100_private));
if (!dev)
return ERR_PTR(-ENODEV);
- SET_MODULE_OWNER(dev);
-
#ifdef HP100_DEBUG_B
hp100_outw(0x4200, TRACE);
printk("hp100: %s: probe\n", dev->name);
free_netdev(dev);
return ERR_PTR(err);
}
-#endif
+#endif /* !MODULE && CONFIG_ISA */
+
+static const struct net_device_ops hp100_bm_netdev_ops = {
+ .ndo_open = hp100_open,
+ .ndo_stop = hp100_close,
+ .ndo_start_xmit = hp100_start_xmit_bm,
+ .ndo_get_stats = hp100_get_stats,
+ .ndo_set_multicast_list = hp100_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops hp100_netdev_ops = {
+ .ndo_open = hp100_open,
+ .ndo_stop = hp100_close,
+ .ndo_start_xmit = hp100_start_xmit,
+ .ndo_get_stats = hp100_get_stats,
+ .ndo_set_multicast_list = hp100_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int __devinit hp100_probe1(struct net_device *dev, int ioaddr,
u_char bus, struct pci_dev *pci_dev)
* Also, we can have EISA Busmaster cards (not tested),
* so beware !!! - Jean II */
if((bus == HP100_BUS_PCI) &&
- (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK))) {
+ (pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)))) {
/* Gracefully fallback to shared memory */
goto busmasterfail;
}
lp->virt_memory_size = virt_memory_size;
lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */
- dev->open = hp100_open;
- dev->stop = hp100_close;
-
if (lp->mode == 1) /* busmaster */
- dev->hard_start_xmit = hp100_start_xmit_bm;
+ dev->netdev_ops = &hp100_bm_netdev_ops;
else
- dev->hard_start_xmit = hp100_start_xmit;
-
- dev->get_stats = hp100_get_stats;
- dev->set_multicast_list = &hp100_set_multicast_list;
+ dev->netdev_ops = &hp100_netdev_ops;
/* Ask the card for which IRQ line it is configured */
if (bus == HP100_BUS_PCI) {
if (lp->mode == 1) { /* only needed for Busmaster */
int xmit_stop, recv_stop;
- if ((lp->chip == HP100_CHIPID_RAINIER)
- || (lp->chip == HP100_CHIPID_SHASTA)) {
+ if ((lp->chip == HP100_CHIPID_RAINIER) ||
+ (lp->chip == HP100_CHIPID_SHASTA)) {
int pdl_stop;
/*
return -EAGAIN;
}
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* prevent tx timeout */
netif_start_queue(dev);
lp->lan_type = hp100_sense_lan(dev);
printk("hp100: %s: init pdls\n", dev->name);
#endif
- if (0 == lp->page_vaddr_algn)
+ if (!lp->page_vaddr_algn)
printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n", dev->name);
else {
/* pageptr shall point into the DMA accessible memory region */
*(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);
+ return roundup(MAX_RX_FRAG * 2 + 2, 4);
}
ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr); /* +1 */
ringptr->skb = (void *) NULL;
- return ((((MAX_TX_FRAG * 2 + 2) + 3) / 4) * 4);
+ return roundup(MAX_TX_FRAG * 2 + 2, 4);
}
/*
/* Note: This depends on the alloc_skb functions allocating more
* space than requested, i.e. aligning to 16bytes */
- ringptr->skb = dev_alloc_skb(((MAX_ETHER_SIZE + 2 + 3) / 4) * 4);
+ ringptr->skb = dev_alloc_skb(roundup(MAX_ETHER_SIZE + 2, 4));
if (NULL != ringptr->skb) {
/*
#ifdef HP100_DEBUG_BM
printk("hp100: %s: build_rx_pdl: PDH@0x%x, skb->data (len %d) at 0x%x\n",
dev->name, (u_int) ringptr->pdl,
- ((MAX_ETHER_SIZE + 2 + 3) / 4) * 4,
+ roundup(MAX_ETHER_SIZE + 2, 4),
(unsigned int) ringptr->skb->data);
#endif
*/
/* tx function for busmaster mode */
-static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
+ struct net_device *dev)
{
unsigned long flags;
int i, ok_flag;
hp100_outw(0x4210, TRACE);
printk("hp100: %s: start_xmit_bm\n", dev->name);
#endif
-
- if (skb == NULL) {
- return 0;
- }
-
if (skb->len <= 0)
- return 0;
+ goto drop;
if (lp->chip == HP100_CHIPID_SHASTA && skb_padto(skb, ETH_ZLEN))
- return 0;
+ return NETDEV_TX_OK;
/* Get Tx ring tail pointer */
if (lp->txrtail->next == lp->txrhead) {
printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name);
#endif
/* not waited long enough since last tx? */
- if (time_before(jiffies, dev->trans_start + HZ))
- return -EAGAIN;
+ if (time_before(jiffies, dev_trans_start(dev) + HZ))
+ goto drop;
if (hp100_check_lan(dev))
- return -EIO;
+ goto drop;
if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) {
/* we have a 100Mb/s adapter but it isn't connected to hub */
}
}
- dev->trans_start = jiffies;
- return -EAGAIN;
+ goto drop;
}
/*
/* Update statistics */
lp->stats.tx_packets++;
lp->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
- return 0;
+ return NETDEV_TX_OK;
+
+drop:
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
}
}
/* tx function for slave modes */
-static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
{
unsigned long flags;
int i, ok_flag;
hp100_outw(0x4212, TRACE);
printk("hp100: %s: start_xmit\n", dev->name);
#endif
-
- if (skb == NULL) {
- return 0;
- }
-
if (skb->len <= 0)
- return 0;
+ goto drop;
if (hp100_check_lan(dev))
- return -EIO;
+ goto drop;
/* If there is not enough free memory on the card... */
i = hp100_inl(TX_MEM_FREE) & 0x7fffffff;
printk("hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i);
#endif
/* not waited long enough since last failed tx try? */
- if (time_before(jiffies, dev->trans_start + HZ)) {
+ if (time_before(jiffies, dev_trans_start(dev) + HZ)) {
#ifdef HP100_DEBUG
printk("hp100: %s: trans_start timing problem\n",
dev->name);
#endif
- return -EAGAIN;
+ goto drop;
}
if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) {
/* we have a 100Mb/s adapter but it isn't connected to hub */
mdelay(1);
}
}
- dev->trans_start = jiffies;
- return -EAGAIN;
+ goto drop;
}
for (i = 0; i < 6000 && (hp100_inb(OPTION_MSW) & HP100_TX_CMD); i++) {
lp->stats.tx_packets++;
lp->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
hp100_ints_on();
spin_unlock_irqrestore(&lp->lock, flags);
printk("hp100: %s: start_xmit: end\n", dev->name);
#endif
- return 0;
+ return NETDEV_TX_OK;
+
+drop:
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+
}
u_char *ptr;
skb_reserve(skb,2);
- skb->dev = dev;
/* ptr to start of the sk_buff data area */
skb_put(skb, pkt_len);
ptr[9], ptr[10], ptr[11]);
#endif
netif_rx(skb);
- dev->last_rx = jiffies;
lp->stats.rx_packets++;
lp->stats.rx_bytes += pkt_len;
}
netif_rx(ptr->skb); /* Up and away... */
- dev->last_rx = jiffies;
lp->stats.rx_packets++;
lp->stats.rx_bytes += pkt_len;
}
lp->mac2_mode = HP100_MAC2MODE6; /* promiscuous mode = get all good */
lp->mac1_mode = HP100_MAC1MODE6; /* packets on the net */
memset(&lp->hash_bytes, 0xff, 8);
- } else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
+ } else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI)) {
lp->mac2_mode = HP100_MAC2MODE5; /* multicast mode = get packets for */
lp->mac1_mode = HP100_MAC1MODE5; /* me, broadcasts and all multicasts */
#ifdef HP100_MULTICAST_FILTER /* doesn't work!!! */
/* set hash filter to receive all multicast packets */
memset(&lp->hash_bytes, 0xff, 8);
} else {
- int i, j, idx;
+ int i, idx;
u_char *addrs;
- struct dev_mc_list *dmi;
+ struct netdev_hw_addr *ha;
memset(&lp->hash_bytes, 0x00, 8);
#ifdef HP100_DEBUG
- printk("hp100: %s: computing hash filter - mc_count = %i\n", dev->name, dev->mc_count);
+ printk("hp100: %s: computing hash filter - mc_count = %i\n",
+ dev->name, netdev_mc_count(dev));
#endif
- for (i = 0, dmi = dev->mc_list; i < dev->mc_count; i++, dmi = dmi->next) {
- addrs = dmi->dmi_addr;
+ netdev_for_each_mc_addr(ha, dev) {
+ addrs = ha->addr;
if ((*addrs & 0x01) == 0x01) { /* multicast address? */
#ifdef HP100_DEBUG
- printk("hp100: %s: multicast = %02x:%02x:%02x:%02x:%02x:%02x, ",
- dev->name, addrs[0], addrs[1], addrs[2],
- addrs[3], addrs[4], addrs[5]);
+ printk("hp100: %s: multicast = %pM, ",
+ dev->name, addrs);
#endif
- for (j = idx = 0; j < 6; j++) {
+ for (i = idx = 0; i < 6; i++) {
idx ^= *addrs++ & 0x3f;
printk(":%02x:", idx);
}
* hardware interrupt handling
*/
-static irqreturn_t hp100_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t hp100_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
struct hp100_private *lp = netdev_priv(dev);
if (!dev)
return -ENOMEM;
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &edev->dev);
err = hp100_probe1(dev, edev->base_addr + 0xC38, HP100_BUS_EISA, NULL);
printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name,
dev->base_addr);
#endif
- gendev->driver_data = dev;
+ dev_set_drvdata(gendev, dev);
return 0;
out1:
free_netdev(dev);
static int __devexit hp100_eisa_remove (struct device *gendev)
{
- struct net_device *dev = gendev->driver_data;
+ struct net_device *dev = dev_get_drvdata(gendev);
cleanup_dev(dev);
return 0;
}
goto out0;
}
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
*/
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, "
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, "
"Siegfried \"Frieder\" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>");
MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters");
return -ENOMEM;
}
- SET_MODULE_OWNER(dev);
err = hp100_isa_probe(dev, hp100_port[i]);
if (!err)
return cards > 0 ? 0 : -ENODEV;
}
-static void __exit hp100_isa_cleanup(void)
+static void hp100_isa_cleanup(void)
{
int i;
goto out2;
#endif
#ifdef CONFIG_PCI
- err = pci_module_init(&hp100_pci_driver);
+ err = pci_register_driver(&hp100_pci_driver);
if (err && err != -ENODEV)
goto out3;
#endif
module_init(hp100_module_init)
module_exit(hp100_module_exit)
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c hp100.c"
- * c-indent-level: 2
- * tab-width: 8
- * End:
- */