^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* New Hydra driver using generic 8390 core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Based on old hydra driver by Topi Kanerva (topi@susanna.oulu.fi) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) /* This file is subject to the terms and conditions of the GNU General */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) /* Public License. See the file COPYING in the main directory of the */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /* Linux distribution for more details. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /* Peter De Schrijver (p2@mind.be) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* Oldenburg 2000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* and 10BASE-2 (thin coax) and AUI connectors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/amigaints.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <asm/amigahw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/zorro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define EI_SHIFT(x) (ei_local->reg_offset[x])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ei_inb(port) in_8(port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ei_outb(val,port) out_8(port,val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ei_inb_p(port) in_8(port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ei_outb_p(val,port) out_8(port,val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "lib8390.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define NE_EN0_DCFG (0x0e*2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define NESM_START_PG 0x0 /* First page of TX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define NESM_STOP_PG 0x40 /* Last page +1 of RX ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define HYDRA_NIC_BASE 0xffe1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define HYDRA_ADDRPROM 0xffc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define HYDRA_VERSION "v3.0alpha"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int hydra_init_one(struct zorro_dev *z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const struct zorro_device_id *ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int hydra_init(struct zorro_dev *z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int hydra_open(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int hydra_close(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void hydra_reset_8390(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void hydra_get_8390_hdr(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct e8390_pkt_hdr *hdr, int ring_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static void hydra_block_input(struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct sk_buff *skb, int ring_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void hydra_block_output(struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const unsigned char *buf, int start_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void hydra_remove_one(struct zorro_dev *z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static struct zorro_device_id hydra_zorro_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static struct zorro_driver hydra_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .name = "hydra",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .id_table = hydra_zorro_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .probe = hydra_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .remove = hydra_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int hydra_init_one(struct zorro_dev *z,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const struct zorro_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!request_mem_region(z->resource.start, 0x10000, "Hydra"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if ((err = hydra_init(z))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) release_mem_region(z->resource.start, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const struct net_device_ops hydra_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .ndo_open = hydra_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .ndo_stop = hydra_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .ndo_start_xmit = __ei_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .ndo_tx_timeout = __ei_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .ndo_get_stats = __ei_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .ndo_set_rx_mode = __ei_set_multicast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #ifdef CONFIG_NET_POLL_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .ndo_poll_controller = __ei_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int hydra_init(struct zorro_dev *z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned long board = (unsigned long)ZTWO_VADDR(z->resource.start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned long ioaddr = board+HYDRA_NIC_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) const char name[] = "NE2000";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int start_page, stop_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static u32 hydra_offsets[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dev = ____alloc_ei_netdev(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) for (j = 0; j < ETH_ALEN; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* We must set the 8390 for word mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) z_writeb(0x4b, ioaddr + NE_EN0_DCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) start_page = NESM_START_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) stop_page = NESM_STOP_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev->base_addr = ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev->irq = IRQ_AMIGA_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Install the Interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, IRQF_SHARED, "Hydra Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ei_status.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ei_status.tx_start_page = start_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ei_status.stop_page = stop_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ei_status.word16 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ei_status.bigendian = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ei_status.rx_start_page = start_page + TX_PAGES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ei_status.reset_8390 = hydra_reset_8390;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ei_status.block_input = hydra_block_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ei_status.block_output = hydra_block_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ei_status.get_8390_hdr = hydra_get_8390_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ei_status.reg_offset = hydra_offsets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) dev->netdev_ops = &hydra_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) __NS8390_init(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) free_irq(IRQ_AMIGA_PORTS, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) zorro_set_drvdata(z, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dev->name, &z->resource, dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int hydra_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __ei_open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int hydra_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct ei_device *ei_local = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) __ei_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void hydra_reset_8390(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) netdev_info(dev, "Hydra hw reset not there\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void hydra_get_8390_hdr(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct e8390_pkt_hdr *hdr, int ring_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int nic_base = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) short *ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned long hdr_start= (nic_base-HYDRA_NIC_BASE) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ((ring_page - NESM_START_PG)<<8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ptrs = (short *)hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) *(ptrs++) = z_readw(hdr_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) *((short *)hdr) = WORDSWAP(*((short *)hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) hdr_start += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) *(ptrs++) = z_readw(hdr_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *((short *)hdr+1) = WORDSWAP(*((short *)hdr+1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static void hydra_block_input(struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct sk_buff *skb, int ring_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) unsigned long nic_base = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned long mem_base = nic_base - HYDRA_NIC_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned long xfer_start = mem_base + ring_offset - (NESM_START_PG<<8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (count&1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (xfer_start+count > mem_base + (NESM_STOP_PG<<8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int semi_count = (mem_base + (NESM_STOP_PG<<8)) - xfer_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) z_memcpy_fromio(skb->data,xfer_start,semi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) count -= semi_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) z_memcpy_fromio(skb->data+semi_count, mem_base, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) z_memcpy_fromio(skb->data, xfer_start,count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void hydra_block_output(struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const unsigned char *buf, int start_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned long nic_base = dev->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned long mem_base = nic_base - HYDRA_NIC_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (count&1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) z_memcpy_toio(mem_base+((start_page - NESM_START_PG)<<8), buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void hydra_remove_one(struct zorro_dev *z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct net_device *dev = zorro_get_drvdata(z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) free_irq(IRQ_AMIGA_PORTS, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) release_mem_region(ZTWO_PADDR(dev->base_addr)-HYDRA_NIC_BASE, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int __init hydra_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return zorro_register_driver(&hydra_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void __exit hydra_cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) zorro_unregister_driver(&hydra_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) module_init(hydra_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) module_exit(hydra_cleanup_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) MODULE_LICENSE("GPL");