Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");