301 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* stnic.c : A SH7750 specific part of driver for NS DP83902A ST-NIC.3 *4 * Copyright (C) 1999 kaz Kojima5 */6 7#include <linux/module.h>8#include <linux/kernel.h>9#include <linux/errno.h>10#include <linux/interrupt.h>11#include <linux/ioport.h>12#include <linux/netdevice.h>13#include <linux/etherdevice.h>14#include <linux/init.h>15#include <linux/delay.h>16 17#include <asm/io.h>18#include <mach-se/mach/se.h>19#include <asm/machvec.h>20#ifdef CONFIG_SH_STANDARD_BIOS21#include <asm/sh_bios.h>22#endif23 24#include "8390.h"25 26#define DRV_NAME "stnic"27 28#define byte unsigned char29#define half unsigned short30#define word unsigned int31#define vbyte volatile unsigned char32#define vhalf volatile unsigned short33#define vword volatile unsigned int34 35#define STNIC_RUN 0x01 /* 1 == Run, 0 == reset. */36 37#define START_PG 0 /* First page of TX buffer */38#define STOP_PG 128 /* Last page +1 of RX ring */39 40/* Alias */41#define STNIC_CR E8390_CMD42#define PG0_RSAR0 EN0_RSARLO43#define PG0_RSAR1 EN0_RSARHI44#define PG0_RBCR0 EN0_RCNTLO45#define PG0_RBCR1 EN0_RCNTHI46 47#define CR_RRD E8390_RREAD48#define CR_RWR E8390_RWRITE49#define CR_PG0 E8390_PAGE050#define CR_STA E8390_START51#define CR_RDMA E8390_NODMA52 53/* FIXME! YOU MUST SET YOUR OWN ETHER ADDRESS. */54static byte stnic_eadr[6] =55{0x00, 0xc0, 0x6e, 0x00, 0x00, 0x07};56 57static struct net_device *stnic_dev;58 59static void stnic_reset (struct net_device *dev);60static void stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,61 int ring_page);62static void stnic_block_input (struct net_device *dev, int count,63 struct sk_buff *skb , int ring_offset);64static void stnic_block_output (struct net_device *dev, int count,65 const unsigned char *buf, int start_page);66 67static void stnic_init (struct net_device *dev);68 69static u32 stnic_msg_enable;70 71module_param_named(msg_enable, stnic_msg_enable, uint, 0444);72MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");73 74/* SH7750 specific read/write io. */75static inline void76STNIC_DELAY (void)77{78 vword trash;79 trash = *(vword *) 0xa0000000;80 trash = *(vword *) 0xa0000000;81 trash = *(vword *) 0xa0000000;82}83 84static inline byte85STNIC_READ (int reg)86{87 byte val;88 89 val = (*(vhalf *) (PA_83902 + ((reg) << 1)) >> 8) & 0xff;90 STNIC_DELAY ();91 return val;92}93 94static inline void95STNIC_WRITE (int reg, byte val)96{97 *(vhalf *) (PA_83902 + ((reg) << 1)) = ((half) (val) << 8);98 STNIC_DELAY ();99}100 101static int __init stnic_probe(void)102{103 struct net_device *dev;104 struct ei_device *ei_local;105 int err;106 107 /* If we are not running on a SolutionEngine, give up now */108 if (! MACH_SE)109 return -ENODEV;110 111 /* New style probing API */112 dev = alloc_ei_netdev();113 if (!dev)114 return -ENOMEM;115 116#ifdef CONFIG_SH_STANDARD_BIOS117 sh_bios_get_node_addr (stnic_eadr);118#endif119 eth_hw_addr_set(dev, stnic_eadr);120 121 /* Set the base address to point to the NIC, not the "real" base! */122 dev->base_addr = 0x1000;123 dev->irq = IRQ_STNIC;124 dev->netdev_ops = &ei_netdev_ops;125 126 /* Snarf the interrupt now. There's no point in waiting since we cannot127 share and the board will usually be enabled. */128 err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev);129 if (err) {130 netdev_emerg(dev, " unable to get IRQ %d.\n", dev->irq);131 free_netdev(dev);132 return err;133 }134 135 ei_status.name = dev->name;136 ei_status.word16 = 1;137#ifdef __LITTLE_ENDIAN__138 ei_status.bigendian = 0;139#else140 ei_status.bigendian = 1;141#endif142 ei_status.tx_start_page = START_PG;143 ei_status.rx_start_page = START_PG + TX_PAGES;144 ei_status.stop_page = STOP_PG;145 146 ei_status.reset_8390 = &stnic_reset;147 ei_status.get_8390_hdr = &stnic_get_hdr;148 ei_status.block_input = &stnic_block_input;149 ei_status.block_output = &stnic_block_output;150 151 stnic_init (dev);152 ei_local = netdev_priv(dev);153 ei_local->msg_enable = stnic_msg_enable;154 155 err = register_netdev(dev);156 if (err) {157 free_irq(dev->irq, dev);158 free_netdev(dev);159 return err;160 }161 stnic_dev = dev;162 163 netdev_info(dev, "NS ST-NIC 83902A\n");164 165 return 0;166}167 168static void169stnic_reset (struct net_device *dev)170{171 struct ei_device *ei_local = netdev_priv(dev);172 173 *(vhalf *) PA_83902_RST = 0;174 udelay (5);175 netif_warn(ei_local, hw, dev, "8390 reset done (%ld).\n", jiffies);176 *(vhalf *) PA_83902_RST = ~0;177 udelay (5);178}179 180static void181stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr,182 int ring_page)183{184 struct ei_device *ei_local = netdev_priv(dev);185 186 half buf[2];187 188 STNIC_WRITE (PG0_RSAR0, 0);189 STNIC_WRITE (PG0_RSAR1, ring_page);190 STNIC_WRITE (PG0_RBCR0, 4);191 STNIC_WRITE (PG0_RBCR1, 0);192 STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA);193 194 buf[0] = *(vhalf *) PA_83902_IF;195 STNIC_DELAY ();196 buf[1] = *(vhalf *) PA_83902_IF;197 STNIC_DELAY ();198 hdr->next = buf[0] >> 8;199 hdr->status = buf[0] & 0xff;200#ifdef __LITTLE_ENDIAN__201 hdr->count = buf[1];202#else203 hdr->count = ((buf[1] >> 8) & 0xff) | (buf[1] << 8);204#endif205 206 netif_dbg(ei_local, probe, dev, "ring %x status %02x next %02x count %04x.\n",207 ring_page, hdr->status, hdr->next, hdr->count);208 209 STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);210}211 212/* Block input and output, similar to the Crynwr packet driver. If you are213 porting to a new ethercard look at the packet driver source for hints.214 The HP LAN doesn't use shared memory -- we put the packet215 out through the "remote DMA" dataport. */216 217static void218stnic_block_input (struct net_device *dev, int length, struct sk_buff *skb,219 int offset)220{221 char *buf = skb->data;222 half val;223 224 STNIC_WRITE (PG0_RSAR0, offset & 0xff);225 STNIC_WRITE (PG0_RSAR1, offset >> 8);226 STNIC_WRITE (PG0_RBCR0, length & 0xff);227 STNIC_WRITE (PG0_RBCR1, length >> 8);228 STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA);229 230 if (length & 1)231 length++;232 233 while (length > 0)234 {235 val = *(vhalf *) PA_83902_IF;236#ifdef __LITTLE_ENDIAN__237 *buf++ = val & 0xff;238 *buf++ = val >> 8;239#else240 *buf++ = val >> 8;241 *buf++ = val & 0xff;242#endif243 STNIC_DELAY ();244 length -= sizeof (half);245 }246 247 STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);248}249 250static void251stnic_block_output (struct net_device *dev, int length,252 const unsigned char *buf, int output_page)253{254 STNIC_WRITE (PG0_RBCR0, 1); /* Write non-zero value */255 STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA);256 STNIC_DELAY ();257 258 STNIC_WRITE (PG0_RBCR0, length & 0xff);259 STNIC_WRITE (PG0_RBCR1, length >> 8);260 STNIC_WRITE (PG0_RSAR0, 0);261 STNIC_WRITE (PG0_RSAR1, output_page);262 STNIC_WRITE (STNIC_CR, CR_RWR | CR_PG0 | CR_STA);263 264 if (length & 1)265 length++;266 267 while (length > 0)268 {269#ifdef __LITTLE_ENDIAN__270 *(vhalf *) PA_83902_IF = ((half) buf[1] << 8) | buf[0];271#else272 *(vhalf *) PA_83902_IF = ((half) buf[0] << 8) | buf[1];273#endif274 STNIC_DELAY ();275 buf += sizeof (half);276 length -= sizeof (half);277 }278 279 STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA);280}281 282/* This function resets the STNIC if something screws up. */283static void284stnic_init (struct net_device *dev)285{286 stnic_reset (dev);287 NS8390_init (dev, 0);288}289 290static void __exit stnic_cleanup(void)291{292 unregister_netdev(stnic_dev);293 free_irq(stnic_dev->irq, stnic_dev);294 free_netdev(stnic_dev);295}296 297module_init(stnic_probe);298module_exit(stnic_cleanup);299MODULE_DESCRIPTION("National Semiconductor DP83902AV ethernet driver");300MODULE_LICENSE("GPL");301