^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* stnic.c : A SH7750 specific part of driver for NS DP83902A ST-NIC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 1999 kaz Kojima
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <mach-se/mach/se.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/machvec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #ifdef CONFIG_SH_STANDARD_BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/sh_bios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "8390.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DRV_NAME "stnic"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define byte unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define half unsigned short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define word unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define vbyte volatile unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define vhalf volatile unsigned short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define vword volatile unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define STNIC_RUN 0x01 /* 1 == Run, 0 == reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define START_PG 0 /* First page of TX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define STOP_PG 128 /* Last page +1 of RX ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define STNIC_CR E8390_CMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PG0_RSAR0 EN0_RSARLO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PG0_RSAR1 EN0_RSARHI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PG0_RBCR0 EN0_RCNTLO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PG0_RBCR1 EN0_RCNTHI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define CR_RRD E8390_RREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define CR_RWR E8390_RWRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define CR_PG0 E8390_PAGE0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define CR_STA E8390_START
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CR_RDMA E8390_NODMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* FIXME! YOU MUST SET YOUR OWN ETHER ADDRESS. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static byte stnic_eadr[6] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {0x00, 0xc0, 0x6e, 0x00, 0x00, 0x07};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct net_device *stnic_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static void stnic_reset (struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static void stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int ring_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void stnic_block_input (struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct sk_buff *skb , int ring_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void stnic_block_output (struct net_device *dev, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const unsigned char *buf, int start_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static void stnic_init (struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static u32 stnic_msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) module_param_named(msg_enable, stnic_msg_enable, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* SH7750 specific read/write io. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) STNIC_DELAY (void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) vword trash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) trash = *(vword *) 0xa0000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) trash = *(vword *) 0xa0000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) trash = *(vword *) 0xa0000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) STNIC_READ (int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) byte val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) val = (*(vhalf *) (PA_83902 + ((reg) << 1)) >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return val;
^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 inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) STNIC_WRITE (int reg, byte val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *(vhalf *) (PA_83902 + ((reg) << 1)) = ((half) (val) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int __init stnic_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct ei_device *ei_local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* If we are not running on a SolutionEngine, give up now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (! MACH_SE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* New style probing API */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) dev = alloc_ei_netdev();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #ifdef CONFIG_SH_STANDARD_BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) sh_bios_get_node_addr (stnic_eadr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i = 0; i < ETH_ALEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dev->dev_addr[i] = stnic_eadr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Set the base address to point to the NIC, not the "real" base! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev->base_addr = 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dev->irq = IRQ_STNIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) dev->netdev_ops = &ei_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Snarf the interrupt now. There's no point in waiting since we cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) share and the board will usually be enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) netdev_emerg(dev, " unable to get IRQ %d.\n", dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ei_status.name = dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ei_status.word16 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #ifdef __LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ei_status.bigendian = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ei_status.bigendian = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ei_status.tx_start_page = START_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ei_status.rx_start_page = START_PG + TX_PAGES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ei_status.stop_page = STOP_PG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ei_status.reset_8390 = &stnic_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ei_status.get_8390_hdr = &stnic_get_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ei_status.block_input = &stnic_block_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ei_status.block_output = &stnic_block_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) stnic_init (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ei_local = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ei_local->msg_enable = stnic_msg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) stnic_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) netdev_info(dev, "NS ST-NIC 83902A\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) stnic_reset (struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct ei_device *ei_local = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *(vhalf *) PA_83902_RST = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) netif_warn(ei_local, hw, dev, "8390 reset done (%ld).\n", jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *(vhalf *) PA_83902_RST = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) udelay (5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int ring_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct ei_device *ei_local = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) half buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) STNIC_WRITE (PG0_RSAR0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) STNIC_WRITE (PG0_RSAR1, ring_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) STNIC_WRITE (PG0_RBCR0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) STNIC_WRITE (PG0_RBCR1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) buf[0] = *(vhalf *) PA_83902_IF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) buf[1] = *(vhalf *) PA_83902_IF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) hdr->next = buf[0] >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) hdr->status = buf[0] & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #ifdef __LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) hdr->count = buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) hdr->count = ((buf[1] >> 8) & 0xff) | (buf[1] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) netif_dbg(ei_local, probe, dev, "ring %x status %02x next %02x count %04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ring_page, hdr->status, hdr->next, hdr->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Block input and output, similar to the Crynwr packet driver. If you are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) porting to a new ethercard look at the packet driver source for hints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) The HP LAN doesn't use shared memory -- we put the packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) out through the "remote DMA" dataport. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) stnic_block_input (struct net_device *dev, int length, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) char *buf = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) half val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) STNIC_WRITE (PG0_RSAR0, offset & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) STNIC_WRITE (PG0_RSAR1, offset >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) STNIC_WRITE (PG0_RBCR0, length & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) STNIC_WRITE (PG0_RBCR1, length >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (length & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) length++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) while (length > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) val = *(vhalf *) PA_83902_IF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #ifdef __LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *buf++ = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *buf++ = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *buf++ = val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *buf++ = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) length -= sizeof (half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) stnic_block_output (struct net_device *dev, int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) const unsigned char *buf, int output_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) STNIC_WRITE (PG0_RBCR0, 1); /* Write non-zero value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) STNIC_WRITE (PG0_RBCR0, length & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) STNIC_WRITE (PG0_RBCR1, length >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) STNIC_WRITE (PG0_RSAR0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) STNIC_WRITE (PG0_RSAR1, output_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) STNIC_WRITE (STNIC_CR, CR_RWR | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (length & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) length++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) while (length > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #ifdef __LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) *(vhalf *) PA_83902_IF = ((half) buf[1] << 8) | buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *(vhalf *) PA_83902_IF = ((half) buf[0] << 8) | buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) STNIC_DELAY ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) buf += sizeof (half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) length -= sizeof (half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* This function resets the STNIC if something screws up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) stnic_init (struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) stnic_reset (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) NS8390_init (dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static void __exit stnic_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) unregister_netdev(stnic_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) free_irq(stnic_dev->irq, stnic_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) free_netdev(stnic_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) module_init(stnic_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) module_exit(stnic_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) MODULE_LICENSE("GPL");