diff options
Diffstat (limited to 'drivers/net/ethernet/8390/pcnet_cs.c')
| -rw-r--r-- | drivers/net/ethernet/8390/pcnet_cs.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c index bd0a2a14b649..19f9c5db3f3b 100644 --- a/drivers/net/ethernet/8390/pcnet_cs.c +++ b/drivers/net/ethernet/8390/pcnet_cs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-1.0+ /*====================================================================== A PCMCIA ethernet driver for NS8390-based cards @@ -17,9 +18,7 @@ Written 1992,1993 by Donald Becker. Copyright 1993 United States Government as represented by the - Director, National Security Agency. This software may be used and - distributed according to the terms of the GNU General Public License, - incorporated herein by reference. + Director, National Security Agency. Donald Becker may be reached at becker@scyld.com Based also on Keith Moore's changes to Don Becker's code, for IBM @@ -66,7 +65,6 @@ #define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */ static const char *if_names[] = { "auto", "10baseT", "10base2"}; -static u32 pcnet_msg_enable; /*====================================================================*/ @@ -99,7 +97,7 @@ static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); -static void ei_watchdog(u_long arg); +static void ei_watchdog(struct timer_list *t); static void pcnet_reset_8390(struct net_device *dev); static int set_config(struct net_device *dev, struct ifmap *map); static int setup_shmem_window(struct pcmcia_device *link, int start_pg, @@ -224,7 +222,7 @@ static const struct net_device_ops pcnet_netdev_ops = { .ndo_set_config = set_config, .ndo_start_xmit = ei_start_xmit, .ndo_get_stats = ei_get_stats, - .ndo_do_ioctl = ei_ioctl, + .ndo_eth_ioctl = ei_ioctl, .ndo_set_rx_mode = ei_set_multicast_list, .ndo_tx_timeout = ei_tx_timeout, .ndo_set_mac_address = eth_mac_addr, @@ -279,6 +277,7 @@ static struct hw_info *get_hwinfo(struct pcmcia_device *link) { struct net_device *dev = link->priv; u_char __iomem *base, *virt; + u8 addr[ETH_ALEN]; int i, j; /* Allocate a small memory window */ @@ -290,6 +289,11 @@ static struct hw_info *get_hwinfo(struct pcmcia_device *link) virt = ioremap(link->resource[2]->start, resource_size(link->resource[2])); + if (unlikely(!virt)) { + pcmcia_release_window(link, link->resource[2]); + return NULL; + } + for (i = 0; i < NR_INFO; i++) { pcmcia_map_mem_page(link, link->resource[2], hw_info[i].offset & ~(resource_size(link->resource[2])-1)); @@ -298,7 +302,8 @@ static struct hw_info *get_hwinfo(struct pcmcia_device *link) (readb(base+2) == hw_info[i].a1) && (readb(base+4) == hw_info[i].a2)) { for (j = 0; j < 6; j++) - dev->dev_addr[j] = readb(base + (j<<1)); + addr[j] = readb(base + (j<<1)); + eth_hw_addr_set(dev, addr); break; } } @@ -320,6 +325,7 @@ static struct hw_info *get_prom(struct pcmcia_device *link) { struct net_device *dev = link->priv; unsigned int ioaddr = dev->base_addr; + u8 addr[ETH_ALEN]; u_char prom[32]; int i, j; @@ -358,7 +364,8 @@ static struct hw_info *get_prom(struct pcmcia_device *link) } if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { for (j = 0; j < 6; j++) - dev->dev_addr[j] = prom[j<<1]; + addr[j] = prom[j<<1]; + eth_hw_addr_set(dev, addr); return (i < NR_INFO) ? hw_info+i : &default_info; } return NULL; @@ -373,6 +380,7 @@ static struct hw_info *get_prom(struct pcmcia_device *link) static struct hw_info *get_dl10019(struct pcmcia_device *link) { struct net_device *dev = link->priv; + u8 addr[ETH_ALEN]; int i; u_char sum; @@ -381,7 +389,8 @@ static struct hw_info *get_dl10019(struct pcmcia_device *link) if (sum != 0xff) return NULL; for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i); + addr[i] = inb_p(dev->base_addr + 0x14 + i); + eth_hw_addr_set(dev, addr); i = inb(dev->base_addr + 0x1f); return ((i == 0x91)||(i == 0x99)) ? &dl10022_info : &dl10019_info; } @@ -396,6 +405,7 @@ static struct hw_info *get_ax88190(struct pcmcia_device *link) { struct net_device *dev = link->priv; unsigned int ioaddr = dev->base_addr; + u8 addr[ETH_ALEN]; int i, j; /* Not much of a test, but the alternatives are messy */ @@ -409,9 +419,10 @@ static struct hw_info *get_ax88190(struct pcmcia_device *link) for (i = 0; i < 6; i += 2) { j = inw(ioaddr + PCNET_DATAPORT); - dev->dev_addr[i] = j & 0xff; - dev->dev_addr[i+1] = j >> 8; + addr[i] = j & 0xff; + addr[i+1] = j >> 8; } + eth_hw_addr_set(dev, addr); return NULL; } @@ -426,6 +437,7 @@ static struct hw_info *get_ax88190(struct pcmcia_device *link) static struct hw_info *get_hwired(struct pcmcia_device *link) { struct net_device *dev = link->priv; + u8 addr[ETH_ALEN]; int i; for (i = 0; i < 6; i++) @@ -434,7 +446,8 @@ static struct hw_info *get_hwired(struct pcmcia_device *link) return NULL; for (i = 0; i < 6; i++) - dev->dev_addr[i] = hw_addr[i]; + addr[i] = hw_addr[i]; + eth_hw_addr_set(dev, addr); return &default_info; } /* get_hwired */ @@ -556,7 +569,6 @@ static int pcnet_config(struct pcmcia_device *link) int start_pg, stop_pg, cm_offset; int has_shmem = 0; struct hw_info *local_hw_info; - struct ei_device *ei_local; dev_dbg(&link->dev, "pcnet_config\n"); @@ -606,8 +618,6 @@ static int pcnet_config(struct pcmcia_device *link) mii_phy_probe(dev); SET_NETDEV_DEV(dev, &link->dev); - ei_local = netdev_priv(dev); - ei_local->msg_enable = pcnet_msg_enable; if (register_netdev(dev) != 0) { pr_notice("register_netdev() failed\n"); @@ -917,7 +927,7 @@ static int pcnet_open(struct net_device *dev) info->phy_id = info->eth_phy; info->link_status = 0x00; - setup_timer(&info->watchdog, ei_watchdog, (u_long)dev); + timer_setup(&info->watchdog, ei_watchdog, 0); mod_timer(&info->watchdog, jiffies + HZ); return ei_open(dev); @@ -937,7 +947,7 @@ static int pcnet_close(struct net_device *dev) link->open--; netif_stop_queue(dev); - del_timer_sync(&info->watchdog); + timer_delete_sync(&info->watchdog); return 0; } /* pcnet_close */ @@ -984,7 +994,7 @@ static int set_config(struct net_device *dev, struct ifmap *map) return -EOPNOTSUPP; else if ((map->port < 1) || (map->port > 2)) return -EINVAL; - dev->if_port = map->port; + WRITE_ONCE(dev->if_port, map->port); netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); NS8390_init(dev, 1); } @@ -1006,10 +1016,10 @@ static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) return ret; } -static void ei_watchdog(u_long arg) +static void ei_watchdog(struct timer_list *t) { - struct net_device *dev = (struct net_device *)arg; - struct pcnet_dev *info = PRIV(dev); + struct pcnet_dev *info = timer_container_of(info, t, watchdog); + struct net_device *dev = info->p_dev->priv; unsigned int nic_base = dev->base_addr; unsigned int mii_addr = nic_base + DLINK_GPIO; u_short link; @@ -1107,6 +1117,7 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) switch (cmd) { case SIOCGMIIPHY: data->phy_id = info->phy_id; + fallthrough; case SIOCGMIIREG: /* Read MII PHY register. */ data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); return 0; @@ -1176,8 +1187,10 @@ static void dma_block_input(struct net_device *dev, int count, outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); insw(nic_base + PCNET_DATAPORT,buf,count>>1); - if (count & 0x01) - buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++; + if (count & 0x01) { + buf[count-1] = inb(nic_base + PCNET_DATAPORT); + xfer_count++; + } /* This was for the ALPHA version only, but enough people have been encountering problems that it is still here. */ @@ -1426,6 +1439,11 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, /* Try scribbling on the buffer */ info->base = ioremap(link->resource[3]->start, resource_size(link->resource[3])); + if (unlikely(!info->base)) { + ret = -ENOMEM; + goto failed; + } + for (i = 0; i < (TX_PAGES<<8); i += 2) __raw_writew((i>>1), info->base+offset+i); udelay(100); @@ -1518,7 +1536,7 @@ static const struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), - PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), + PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8010", 0x5070a7f9, 0x82f96e96), PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8610", 0x5070a7f9, 0x86741224), |
