^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * SDLA An implementation of a driver for the Sangoma S502/S508 series
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * multi-protocol PC interface card. Initial offering is with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * the DLCI driver, providing Frame Relay support for linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Global definitions for the Frame relay interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Version: @(#)sdla.c 0.30 12 Sep 1996
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Credits: Sangoma Technologies, for the use of 2 cards for an extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * period of time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * David Mandelstam <dm@sangoma.com> for getting me started on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * this project, and incentive to complete it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Gene Kozen <74604.152@compuserve.com> for providing me with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * important information about the cards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Author: Mike McLagan <mike.mclagan@linux.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 0.15 Mike McLagan Improved error handling, packet dropping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 0.20 Mike McLagan New transmit/receive flags for config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * If in FR mode, don't accept packets from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * non DLCI devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * 0.25 Mike McLagan Fixed problem with rejecting packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * from non DLCI devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * 0.30 Mike McLagan Fixed kernel panic when used with modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * ifconfig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/if_frad.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/sdla.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static unsigned int valid_mem[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static DEFINE_SPINLOCK(sdla_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*********************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * these are the core routines that access the card itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *********************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static void __sdla_read(struct net_device *dev, int addr, void *buf, short len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) char *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const void *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int offset, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) temp = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) while(len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) offset = addr & SDLA_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) base = (const void *) (dev->mem_start + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) SDLA_WINDOW(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) memcpy(temp, base, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) addr += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) temp += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) len -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) spin_lock_irqsave(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __sdla_read(dev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) spin_unlock_irqrestore(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void __sdla_write(struct net_device *dev, int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const void *buf, short len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) const char *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int offset, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) temp = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) while(len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) offset = addr & SDLA_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) base = (void *) (dev->mem_start + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) SDLA_WINDOW(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) memcpy(base, temp, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) addr += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) temp += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) len -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void sdla_write(struct net_device *dev, int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) const void *buf, short len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) spin_lock_irqsave(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) __sdla_write(dev, addr, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) spin_unlock_irqrestore(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void sdla_clear(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) char *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int len, addr, bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) len = 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) bytes = SDLA_WINDOW_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) base = (void *) dev->mem_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) spin_lock_irqsave(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) while(len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) SDLA_WINDOW(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) memset(base, 0, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) addr += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) len -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) spin_unlock_irqrestore(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static char sdla_byte(struct net_device *dev, int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) char byte, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) spin_lock_irqsave(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) SDLA_WINDOW(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) byte = *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) spin_unlock_irqrestore(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return byte;
^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 void sdla_stop(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) switch(flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) flp->state = SDLA_HALT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) flp->state = SDLA_S502E_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case SDLA_S507:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) flp->state &= ~SDLA_CPUEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) flp->state &= ~SDLA_CPUEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static void sdla_start(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) switch(flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) flp->state = SDLA_S502A_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) flp->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case SDLA_S507:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) flp->state |= SDLA_CPUEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) flp->state |= SDLA_CPUEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^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) * this is used for the S502A/E cards to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * the speed of the onboard CPU. Calibration is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * necessary for the Frame Relay code uploaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * later. Incorrect results cause timing problems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * with link checks & status messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ***************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned long start, done, now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) char resp, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) start = now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) done = jiffies + jiffs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) temp = (void *)dev->mem_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) temp += z80_addr & SDLA_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) resp = ~resp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) while (time_before(jiffies, done) && (resp != resp1) && (!resp2 || (resp != resp2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (jiffies != now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) SDLA_WINDOW(dev, z80_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) now = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) resp = *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return time_before(jiffies, done) ? jiffies - start : -1;
^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) /* constants for Z80 CPU speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define Z80_READY '1' /* Z80 is ready to begin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define LOADER_READY '2' /* driver is ready to begin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define Z80_SCC_OK '3' /* SCC is on board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define Z80_SCC_BAD '4' /* SCC was not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int jiffs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) char data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) sdla_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) data = LOADER_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) sdla_write(dev, 0, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) sdla_stop(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sdla_read(dev, 0, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (data == Z80_SCC_BAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) printk("%s: SCC bad\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (data != Z80_SCC_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (jiffs < 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ifr->ifr_mtu = SDLA_CPU_16M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) else if (jiffs < 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ifr->ifr_mtu = SDLA_CPU_10M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) else if (jiffs < 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ifr->ifr_mtu = SDLA_CPU_8M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else if (jiffs < 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ifr->ifr_mtu = SDLA_CPU_7M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) else if (jiffs < 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ifr->ifr_mtu = SDLA_CPU_5M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ifr->ifr_mtu = SDLA_CPU_3M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * Direct interaction with the Frame Relay code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * starts here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct _dlci_stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) short dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) char flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct _frad_stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) char flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct _dlci_stat dlcis[SDLA_MAX_DLCI];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int len, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct _dlci_stat *pstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) short *pdlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) char *state, line[30];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) switch (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case SDLA_RET_MODEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) state = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (*state & SDLA_MODEM_DCD_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) netdev_info(dev, "Modem DCD unexpectedly low!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (*state & SDLA_MODEM_CTS_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) netdev_info(dev, "Modem CTS unexpectedly low!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* I should probably do something about this! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case SDLA_RET_CHANNEL_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) netdev_info(dev, "Channel became inoperative!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* same here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case SDLA_RET_CHANNEL_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) netdev_info(dev, "Channel became operative!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* same here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case SDLA_RET_DLCI_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) netdev_info(dev, "Status change reported by Access Node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) len /= sizeof(struct _dlci_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) for(pstatus = data, i=0;i < len;i++,pstatus++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (pstatus->flags & SDLA_DLCI_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) state = "new";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) else if (pstatus->flags & SDLA_DLCI_DELETED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) state = "deleted";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) else if (pstatus->flags & SDLA_DLCI_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) state = "active";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sprintf(line, "unknown status: %02X", pstatus->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) state = line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) netdev_info(dev, "DLCI %i: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) pstatus->dlci, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* same here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case SDLA_RET_DLCI_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) netdev_info(dev, "Received unknown DLCIs:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) len /= sizeof(short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for(pdlci = data,i=0;i < len;i++,pdlci++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) pr_cont(" %i", *pdlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case SDLA_RET_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) netdev_err(dev, "Command timed out!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) case SDLA_RET_BUF_OVERSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) netdev_info(dev, "Bc/CIR overflow, acceptable size is %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) case SDLA_RET_BUF_TOO_BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) netdev_info(dev, "Buffer size over specified max of %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) case SDLA_RET_CHANNEL_INACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) case SDLA_RET_DLCI_INACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case SDLA_RET_CIR_OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case SDLA_RET_NO_BUFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (cmd == SDLA_INFORMATION_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) netdev_dbg(dev, "Cmd 0x%02X generated return code 0x%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) cmd, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* Further processing could be done here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) void *inbuf, short inlen, void *outbuf, short *outlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static struct _frad_stat status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct sdla_cmd *cmd_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned long pflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) unsigned long jiffs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int ret, waiting, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) long window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) cmd_buf = (struct sdla_cmd *)(dev->mem_start + (window & SDLA_ADDR_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) jiffs = jiffies + HZ; /* 1 second is plenty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) spin_lock_irqsave(&sdla_lock, pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) SDLA_WINDOW(dev, window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) cmd_buf->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) cmd_buf->dlci = dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) cmd_buf->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (inbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) memcpy(cmd_buf->data, inbuf, inlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) cmd_buf->length = inlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) cmd_buf->opp_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) spin_unlock_irqrestore(&sdla_lock, pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) waiting = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) while (waiting && time_before_eq(jiffies, jiffs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (waiting++ % 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) spin_lock_irqsave(&sdla_lock, pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) SDLA_WINDOW(dev, window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) waiting = ((volatile int)(cmd_buf->opp_flag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) spin_unlock_irqrestore(&sdla_lock, pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!waiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) spin_lock_irqsave(&sdla_lock, pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) SDLA_WINDOW(dev, window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ret = cmd_buf->retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) len = cmd_buf->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (outbuf && outlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *outlen = *outlen >= len ? len : *outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (*outlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) memcpy(outbuf, cmd_buf->data, *outlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* This is a local copy that's used for error handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) spin_unlock_irqrestore(&sdla_lock, pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ret = SDLA_RET_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret != SDLA_RET_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) sdla_errors(dev, cmd, dlci, ret, len, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /***********************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * these functions are called by the DLCI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ***********************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int sdla_reconfig(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static int sdla_activate(struct net_device *slave, struct net_device *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) flp = netdev_priv(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (flp->master[i] == master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (i == CONFIG_DLCI_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) flp->dlci[i] = abs(flp->dlci[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int sdla_deactivate(struct net_device *slave, struct net_device *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) flp = netdev_priv(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (flp->master[i] == master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (i == CONFIG_DLCI_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) flp->dlci[i] = -abs(flp->dlci[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static int sdla_assoc(struct net_device *slave, struct net_device *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (master->type != ARPHRD_DLCI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) flp = netdev_priv(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (!flp->master[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return -EADDRINUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (i == CONFIG_DLCI_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -EMLINK; /* #### Alan: Comments on this ?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) flp->master[i] = master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) flp->dlci[i] = -*(short *)(master->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) master->mtu = slave->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (netif_running(slave)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (flp->config.station == FRAD_STATION_CPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) sdla_reconfig(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int sdla_deassoc(struct net_device *slave, struct net_device *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) flp = netdev_priv(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (flp->master[i] == master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (i == CONFIG_DLCI_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) flp->master[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) flp->dlci[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (netif_running(slave)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (flp->config.station == FRAD_STATION_CPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) sdla_reconfig(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct dlci_local *dlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) short len, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) flp = netdev_priv(slave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (flp->master[i] == master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (i == CONFIG_DLCI_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dlp = netdev_priv(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = SDLA_RET_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) len = sizeof(struct dlci_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (netif_running(slave)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) ret = sdla_cmd(slave, SDLA_READ_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) NULL, 0, &dlp->config, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return ret == SDLA_RET_OK ? 0 : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /**************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * now for the Linux driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) **************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* NOTE: the DLCI driver deals with freeing the SKB!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static netdev_tx_t sdla_transmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int ret, addr, accept, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) short size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct buf_entry *pbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) accept = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * stupid GateD insists on setting up the multicast router thru us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * and we're ill equipped to handle a non Frame Relay packet at this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * time!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) accept = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) switch (dev->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) case ARPHRD_FRAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (skb->dev->type != ARPHRD_DLCI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) netdev_warn(dev, "Non DLCI device, type %i, tried to send on FRAD module\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) skb->dev->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) accept = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) netdev_warn(dev, "unknown firmware type 0x%04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dev->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) accept = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (accept)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* this is frame specific, but till there's a PPP module, it's the default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) switch (flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) size = sizeof(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (ret == SDLA_RET_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) spin_lock_irqsave(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) SDLA_WINDOW(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) pbuf = (void *)(dev->mem_start + (addr & SDLA_ADDR_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) SDLA_WINDOW(dev, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) pbuf->opp_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) spin_unlock_irqrestore(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) switch (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case SDLA_RET_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) case SDLA_RET_CIR_OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case SDLA_RET_BUF_OVERSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case SDLA_RET_NO_BUFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) dev->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if(flp->master[i]!=NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) netif_wake_queue(flp->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static void sdla_receive(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct net_device *master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct dlci_local *dlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct sdla_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct buf_info *pbufi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct buf_entry *pbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int i=0, received, success, addr, buf_base, buf_top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) short dlci, len, len2, split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) success = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) received = addr = buf_top = buf_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) len = dlci = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) master = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) pbufi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) pbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) spin_lock_irqsave(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) switch (flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & SDLA_ADDR_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) success = cmd->opp_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) dlci = cmd->dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) len = cmd->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & SDLA_ADDR_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & SDLA_ADDR_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) success = pbuf->opp_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) buf_top = pbufi->buf_top;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) buf_base = pbufi->buf_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) dlci = pbuf->dlci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) len = pbuf->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) addr = pbuf->buf_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* common code, find the DLCI and get the SKB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) for (i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (flp->dlci[i] == dlci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (i == CONFIG_DLCI_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) netdev_notice(dev, "Received packet from invalid DLCI %i, ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) dlci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) success = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) master = flp->master[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) skb = dev_alloc_skb(len + sizeof(struct frhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) netdev_notice(dev, "Memory squeeze, dropping packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) success = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) skb_reserve(skb, sizeof(struct frhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* pick up the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) switch (flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) cmd->opp_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* is this buffer split off the end of the internal ring buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) len2 = len - split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) __sdla_read(dev, addr, skb_put(skb, len2), len2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) __sdla_read(dev, buf_base, skb_put(skb, split), split);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /* increment the buffer we're looking at */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) pbuf->opp_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (success)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) dlp = netdev_priv(master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) (*dlp->receive)(skb, master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) spin_unlock_irqrestore(&sdla_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static irqreturn_t sdla_isr(int dummy, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (!flp->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) netdev_warn(dev, "irq %d for uninitialized device\n", dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) switch (byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case SDLA_INTR_RX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) sdla_receive(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* the command will get an error return, which is processed above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) case SDLA_INTR_MODEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) case SDLA_INTR_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case SDLA_INTR_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) case SDLA_INTR_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) case SDLA_INTR_TIMER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) netdev_warn(dev, "invalid irq flag 0x%02X\n", byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* the S502E requires a manual acknowledgement of the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (flp->type == SDLA_S502E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) flp->state &= ~SDLA_S502E_INTACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) flp->state |= SDLA_S502E_INTACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* this clears the byte, informing the Z80 we're done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static void sdla_poll(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct frad_local *flp = from_timer(flp, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct net_device *dev = flp->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (sdla_byte(dev, SDLA_502_RCV_BUF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) sdla_receive(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) flp->timer.expires = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) add_timer(&flp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int sdla_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct intr_info intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) short dlcis[CONFIG_DLCI_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (flp->dlci[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) dlcis[len++] = abs(flp->dlci[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) len *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (flp->config.station == FRAD_STATION_NODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (flp->dlci[i] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) memset(&intr, 0, sizeof(intr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /* let's start up the reception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) switch(flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) del_timer(&flp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) flp->state &= ~SDLA_S502E_INTACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) case SDLA_S507:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) flp->state &= ~SDLA_S508_INTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct conf_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct frad_conf config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) short dlci[CONFIG_DLCI_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static int sdla_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct dlci_local *dlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct conf_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct intr_info intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!flp->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (!flp->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* time to send in the configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (flp->dlci[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) data.dlci[len++] = abs(flp->dlci[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) len *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) len += sizeof(struct frad_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (flp->type == SDLA_S508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) flp->buffer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* let's start up the reception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) memset(&intr, 0, sizeof(intr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) switch(flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) flp->timer.expires = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) add_timer(&flp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) flp->state |= SDLA_S502E_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) flp->state |= SDLA_S502E_INTACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) case SDLA_S507:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) flp->state |= SDLA_S508_INTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) intr.irq = dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (flp->config.station == FRAD_STATION_CPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) byte = SDLA_ICS_STATUS_ENQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (flp->dlci[i] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /* configure any specific DLCI settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (flp->dlci[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dlp = netdev_priv(flp->master[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (dlp->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct conf_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) short size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (dev->type == 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return -EUNATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (!get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (data.config.station & ~FRAD_STATION_NODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (data.config.flags & ~FRAD_VALID_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if ((data.config.kbaud < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if ((data.config.T391 < 5) || (data.config.T391 > 30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if ((data.config.T392 < 5) || (data.config.T392 > 30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if ((data.config.N391 < 1) || (data.config.N391 > 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if ((data.config.N392 < 1) || (data.config.N392 > 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if ((data.config.N393 < 1) || (data.config.N393 > 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) flp->config.flags |= SDLA_DIRECT_RECV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (flp->type == SDLA_S508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) flp->config.flags |= SDLA_TX70_RX30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (dev->mtu != flp->config.mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /* this is required to change the MTU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) dev->mtu = flp->config.mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (flp->master[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) flp->master[i]->mtu = flp->config.mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) flp->config.mtu += sizeof(struct frhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* off to the races! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (!flp->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) sdla_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) flp->configured = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* no sense reading if the CPU isn't started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) size = sizeof(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (flp->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) memset(&data.config, 0, sizeof(struct frad_conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) data.config.flags &= FRAD_VALID_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) data.config.mtu -= data.config.mtu > sizeof(struct frhdr) ? sizeof(struct frhdr) : data.config.mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct sdla_mem mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) char *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if(copy_from_user(&mem, info, sizeof(mem)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) temp = kzalloc(mem.len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (!temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) sdla_read(dev, mem.addr, temp, mem.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if(copy_to_user(mem.data, temp, mem.len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) kfree(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) kfree(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) temp = memdup_user(mem.data, mem.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (IS_ERR(temp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return PTR_ERR(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) sdla_write(dev, mem.addr, temp, mem.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) kfree(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int sdla_reconfig(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct conf_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) for(i=0;i<CONFIG_DLCI_MAX;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (flp->dlci[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) data.dlci[len++] = flp->dlci[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) len *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) memcpy(&data, &flp->config, sizeof(struct frad_conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) len += sizeof(struct frad_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if(!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (!flp->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) switch (cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) case FRAD_GET_CONF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) case FRAD_SET_CONF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) case SDLA_IDENTIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ifr->ifr_flags = flp->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) case SDLA_CPUSPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return sdla_cpuspeed(dev, ifr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /* ==========================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) NOTE: This is rather a useless action right now, as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) current driver does not support protocols other than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) FR. However, Sangoma has modules for a number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) other protocols in the works.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) ============================================================*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case SDLA_PROTOCOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (flp->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) switch (ifr->ifr_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case ARPHRD_FRAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) dev->type = ifr->ifr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) case SDLA_CLEARMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) sdla_clear(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) case SDLA_WRITEMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) case SDLA_READMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if(!capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case SDLA_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) sdla_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case SDLA_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) sdla_stop(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static int sdla_change_mtu(struct net_device *dev, int new_mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (netif_running(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* for now, you can't change the MTU! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) static int sdla_set_config(struct net_device *dev, struct ifmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct frad_local *flp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) char byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) unsigned base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (flp->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) for(i=0; i < ARRAY_SIZE(valid_port); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (valid_port[i] == map->base_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (i == ARRAY_SIZE(valid_port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) pr_warn("io-port 0x%04lx in use\n", dev->base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) base = map->base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) /* test for card types, S502A, S502E, S507, S508 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /* these tests shut down the card completely, so clear the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) flp->type = SDLA_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) flp->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) for(i=1;i<SDLA_IO_EXTENTS;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (inb(base + i) != 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (i == SDLA_IO_EXTENTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) outb(SDLA_HALT, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) flp->type = SDLA_S502E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) goto got_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (inb(base + i) != byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if (i == SDLA_IO_EXTENTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) outb(SDLA_HALT, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) outb(SDLA_HALT, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) flp->type = SDLA_S507;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) goto got_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) outb(SDLA_HALT, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) outb(SDLA_HALT, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) flp->type = SDLA_S508;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) goto got_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (inb(base + SDLA_S502_STS) == 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (inb(base + SDLA_S502_STS) == 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (inb(base + SDLA_S502_STS) == 0x44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) flp->type = SDLA_S502A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) goto got_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) netdev_notice(dev, "Unknown card type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) got_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) switch(base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) case 0x270:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) case 0x280:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) case 0x380:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) case 0x390:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) switch (map->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (flp->type != SDLA_S502E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (flp->type == SDLA_S502A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (request_irq(dev->irq, sdla_isr, 0, dev->name, dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (flp->type == SDLA_S507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) switch(dev->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) flp->state = SDLA_S507_IRQ3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) flp->state = SDLA_S507_IRQ4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) flp->state = SDLA_S507_IRQ5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) flp->state = SDLA_S507_IRQ7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) flp->state = SDLA_S507_IRQ10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) flp->state = SDLA_S507_IRQ11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) flp->state = SDLA_S507_IRQ12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) case 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) flp->state = SDLA_S507_IRQ15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) for(i=0; i < ARRAY_SIZE(valid_mem); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) if (valid_mem[i] == map->mem_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (i == ARRAY_SIZE(valid_mem))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) switch(flp->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) case SDLA_S502A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) switch (map->mem_start >> 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) case 0x0A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) byte |= SDLA_S502_SEG_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) case 0x0C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) byte |= SDLA_S502_SEG_C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) case 0x0D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) byte |= SDLA_S502_SEG_D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) case 0x0E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) byte |= SDLA_S502_SEG_E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) case SDLA_S507:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) switch (map->mem_start >> 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) case 0x0A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) byte |= SDLA_S507_SEG_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) case 0x0B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) byte |= SDLA_S507_SEG_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) case 0x0C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) byte |= SDLA_S507_SEG_C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) case 0x0E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) byte |= SDLA_S507_SEG_E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) switch (map->mem_start >> 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) case 0x0A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) byte |= SDLA_S508_SEG_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) case 0x0C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) byte |= SDLA_S508_SEG_C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) case 0x0D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) byte |= SDLA_S508_SEG_D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) case 0x0E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) byte |= SDLA_S508_SEG_E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) /* set the memory bits, and enable access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) outb(byte, base + SDLA_REG_PC_WINDOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) switch(flp->type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) case SDLA_S502E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) flp->state = SDLA_S502E_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) case SDLA_S507:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) flp->state |= SDLA_MEMEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) case SDLA_S508:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) flp->state = SDLA_MEMEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) outb(flp->state, base + SDLA_REG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) dev->irq = map->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) dev->base_addr = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) dev->mem_start = map->mem_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) dev->mem_end = dev->mem_start + 0x2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) flp->initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) fail2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) free_irq(map->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) release_region(base, SDLA_IO_EXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) static const struct net_device_ops sdla_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .ndo_open = sdla_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .ndo_stop = sdla_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .ndo_do_ioctl = sdla_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) .ndo_set_config = sdla_set_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) .ndo_start_xmit = sdla_transmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) .ndo_change_mtu = sdla_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) static void setup_sdla(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) struct frad_local *flp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) netdev_boot_setup_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) dev->netdev_ops = &sdla_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) dev->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) dev->type = 0xFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) dev->hard_header_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) dev->addr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) dev->mtu = SDLA_MAX_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) flp->activate = sdla_activate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) flp->deactivate = sdla_deactivate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) flp->assoc = sdla_assoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) flp->deassoc = sdla_deassoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) flp->dlci_conf = sdla_dlci_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) flp->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) timer_setup(&flp->timer, sdla_poll, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) flp->timer.expires = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static struct net_device *sdla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) static int __init init_sdla(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) printk("%s.\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) sdla = alloc_netdev(sizeof(struct frad_local), "sdla0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) NET_NAME_UNKNOWN, setup_sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (!sdla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) err = register_netdev(sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) free_netdev(sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) static void __exit exit_sdla(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) struct frad_local *flp = netdev_priv(sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) unregister_netdev(sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (flp->initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) free_irq(sdla->irq, sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) release_region(sdla->base_addr, SDLA_IO_EXTENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) del_timer_sync(&flp->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) free_netdev(sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) module_init(init_sdla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) module_exit(exit_sdla);