#ifndef CONFIG_ISA_DMA_API
#define ALLOW_DMA …
#else
#define ALLOW_DMA …
#endif
#define DEBUGGING …
#define pr_fmt(fmt) …
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/jiffies.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/io.h>
#include <net/Space.h>
#include <asm/irq.h>
#include <linux/atomic.h>
#if ALLOW_DMA
#include <asm/dma.h>
#endif
#include "cs89x0.h"
#define cs89_dbg(val, level, fmt, ...) …
static char version[] __initdata = …;
#define DRV_NAME …
#if IS_ENABLED(CONFIG_CS89x0_ISA)
static unsigned int netcard_portlist[] __used __initdata = {
0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240,
0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0
};
static unsigned int cs8900_irq_map[] = {
10, 11, 12, 5
};
#endif
#if DEBUGGING
static unsigned int net_debug = …;
#else
#define net_debug …
#endif
#define NETCARD_IO_EXTENT …
#define FORCE_RJ45 …
#define FORCE_AUI …
#define FORCE_BNC …
#define FORCE_AUTO …
#define FORCE_HALF …
#define FORCE_FULL …
struct net_local { … };
#define tx_done(dev) …
#if !defined(MODULE)
#if ALLOW_DMA
static int g_cs89x0_dma;
static int __init dma_fn(char *str)
{ … }
__setup(…);
#endif
static int g_cs89x0_media__force;
static int __init media_fn(char *str)
{ … }
__setup(…);
#endif
static void readwords(struct net_local *lp, int portno, void *buf, int length)
{ … }
static void writewords(struct net_local *lp, int portno, void *buf, int length)
{ … }
static u16
readreg(struct net_device *dev, u16 regno)
{ … }
static void
writereg(struct net_device *dev, u16 regno, u16 value)
{ … }
static int __init
wait_eeprom_ready(struct net_device *dev)
{ … }
static int __init
get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
{ … }
static int __init
get_eeprom_cksum(int off, int len, int *buffer)
{ … }
static void
write_irq(struct net_device *dev, int chip_type, int irq)
{ … }
static void
count_rx_errors(int status, struct net_device *dev)
{ … }
#if ALLOW_DMA
#define dma_page_eq(ptr1, ptr2) …
static void
get_dma_channel(struct net_device *dev)
{ … }
static void
write_dma(struct net_device *dev, int chip_type, int dma)
{ … }
static void
set_dma_cfg(struct net_device *dev)
{ … }
static int
dma_bufcfg(struct net_device *dev)
{ … }
static int
dma_busctl(struct net_device *dev)
{ … }
static void
dma_rx(struct net_device *dev)
{ … }
static void release_dma_buff(struct net_local *lp)
{ … }
#endif
static void
control_dc_dc(struct net_device *dev, int on_not_off)
{ … }
static int
send_test_pkt(struct net_device *dev)
{ … }
#define DETECTED_NONE …
#define DETECTED_RJ45H …
#define DETECTED_RJ45F …
#define DETECTED_AUI …
#define DETECTED_BNC …
static int
detect_tp(struct net_device *dev)
{ … }
static int
detect_bnc(struct net_device *dev)
{ … }
static int
detect_aui(struct net_device *dev)
{ … }
static void
net_rx(struct net_device *dev)
{ … }
static irqreturn_t net_interrupt(int irq, void *dev_id)
{ … }
static int
net_open(struct net_device *dev)
{ … }
static int
net_close(struct net_device *dev)
{ … }
static struct net_device_stats *
net_get_stats(struct net_device *dev)
{ … }
static void net_timeout(struct net_device *dev, unsigned int txqueue)
{ … }
static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev)
{ … }
static void set_multicast_list(struct net_device *dev)
{ … }
static int set_mac_address(struct net_device *dev, void *p)
{ … }
#ifdef CONFIG_NET_POLL_CONTROLLER
static void net_poll_controller(struct net_device *dev)
{ … }
#endif
static const struct net_device_ops net_ops = …;
static void __init reset_chip(struct net_device *dev)
{ … }
static int __init
cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
{ … }
#if IS_ENABLED(CONFIG_CS89x0_ISA)
static int __init
cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
{
struct net_local *lp = netdev_priv(dev);
int ret;
void __iomem *io_mem;
if (!lp)
return -ENOMEM;
dev->base_addr = ioport;
if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
ret = -EBUSY;
goto out;
}
io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT);
if (!io_mem) {
ret = -ENOMEM;
goto release;
}
if (ioport & 1) {
cs89_dbg(1, info, "%s: odd ioaddr 0x%lx\n", dev->name, ioport);
if ((ioport & 2) != 2) {
if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) !=
ADD_SIG) {
pr_err("%s: bad signature 0x%x\n",
dev->name, ioread16(io_mem + ADD_PORT));
ret = -ENODEV;
goto unmap;
}
}
}
ret = cs89x0_probe1(dev, io_mem, modular);
if (!ret)
goto out;
unmap:
ioport_unmap(io_mem);
release:
release_region(ioport, NETCARD_IO_EXTENT);
out:
return ret;
}
#ifndef MODULE
struct net_device * __init cs89x0_probe(int unit)
{
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
unsigned *port;
int err = 0;
int irq;
int io;
if (!dev)
return ERR_PTR(-ENODEV);
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
io = dev->base_addr;
irq = dev->irq;
cs89_dbg(0, info, "cs89x0_probe(0x%x)\n", io);
if (io > 0x1ff) {
err = cs89x0_ioport_probe(dev, io, 0);
} else if (io != 0) {
err = -ENXIO;
} else {
for (port = netcard_portlist; *port; port++) {
if (cs89x0_ioport_probe(dev, *port, 0) == 0)
break;
dev->irq = irq;
}
if (!*port)
err = -ENODEV;
}
if (err)
goto out;
return dev;
out:
free_netdev(dev);
pr_warn("no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
return ERR_PTR(err);
}
#else
static struct net_device *dev_cs89x0;
static int io;
static int irq;
static int debug;
static char media[8];
static int duplex = -1;
static int use_dma;
static int dma;
static int dmasize = 16;
module_param_hw(io, int, ioport, 0);
module_param_hw(irq, int, irq, 0);
module_param(debug, int, 0);
module_param_string(media, media, sizeof(media), 0);
module_param(duplex, int, 0);
module_param_hw(dma , int, dma, 0);
module_param(dmasize , int, 0);
module_param(use_dma , int, 0);
MODULE_PARM_DESC(io, "cs89x0 I/O base address");
MODULE_PARM_DESC(irq, "cs89x0 IRQ number");
#if DEBUGGING
MODULE_PARM_DESC(debug, "cs89x0 debug level (0-6)");
#else
MODULE_PARM_DESC(debug, "(ignored)");
#endif
MODULE_PARM_DESC(media, "Set cs89x0 adapter(s) media type(s) (rj45,bnc,aui)");
MODULE_PARM_DESC(duplex, "(ignored)");
#if ALLOW_DMA
MODULE_PARM_DESC(dma , "cs89x0 ISA DMA channel; ignored if use_dma=0");
MODULE_PARM_DESC(dmasize , "cs89x0 DMA size in kB (16,64); ignored if use_dma=0");
MODULE_PARM_DESC(use_dma , "cs89x0 using DMA (0-1)");
#else
MODULE_PARM_DESC(dma , "(ignored)");
MODULE_PARM_DESC(dmasize , "(ignored)");
MODULE_PARM_DESC(use_dma , "(ignored)");
#endif
MODULE_AUTHOR("Mike Cruse, Russwll Nelson <[email protected]>, Andrew Morton");
MODULE_LICENSE("GPL");
static int __init cs89x0_isa_init_module(void)
{
struct net_device *dev;
struct net_local *lp;
int ret = 0;
#if DEBUGGING
net_debug = debug;
#else
debug = 0;
#endif
dev = alloc_etherdev(sizeof(struct net_local));
if (!dev)
return -ENOMEM;
dev->irq = irq;
dev->base_addr = io;
lp = netdev_priv(dev);
#if ALLOW_DMA
if (use_dma) {
lp->use_dma = use_dma;
lp->dma = dma;
lp->dmasize = dmasize;
}
#endif
spin_lock_init(&lp->lock);
if (!strcmp(media, "rj45"))
lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
else if (!strcmp(media, "aui"))
lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI;
else if (!strcmp(media, "bnc"))
lp->adapter_cnf = A_CNF_MEDIA_10B_2 | A_CNF_10B_2;
else
lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
if (duplex == -1)
lp->auto_neg_cnf = AUTO_NEG_ENABLE;
if (io == 0) {
pr_err("Module autoprobing not allowed\n");
pr_err("Append io=0xNNN\n");
ret = -EPERM;
goto out;
} else if (io <= 0x1ff) {
ret = -ENXIO;
goto out;
}
#if ALLOW_DMA
if (use_dma && dmasize != 16 && dmasize != 64) {
pr_err("dma size must be either 16K or 64K, not %dK\n",
dmasize);
ret = -EPERM;
goto out;
}
#endif
ret = cs89x0_ioport_probe(dev, io, 1);
if (ret)
goto out;
dev_cs89x0 = dev;
return 0;
out:
free_netdev(dev);
return ret;
}
module_init(cs89x0_isa_init_module);
static void __exit cs89x0_isa_cleanup_module(void)
{
struct net_local *lp = netdev_priv(dev_cs89x0);
unregister_netdev(dev_cs89x0);
iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
ioport_unmap(lp->virt_addr);
release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
free_netdev(dev_cs89x0);
}
module_exit(cs89x0_isa_cleanup_module);
#endif
#endif
#if IS_ENABLED(CONFIG_CS89x0_PLATFORM)
static int __init cs89x0_platform_probe(struct platform_device *pdev)
{ … }
static void cs89x0_platform_remove(struct platform_device *pdev)
{ … }
static const struct of_device_id __maybe_unused cs89x0_match[] = …;
MODULE_DEVICE_TABLE(of, cs89x0_match);
static struct platform_driver cs89x0_driver = …;
module_platform_driver_probe(…);
#endif
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_AUTHOR(…) …;