The DLCI driver (dlci.c) implements the Frame Relay protocol. However, we already have another newer and better implementation of Frame Relay provided by the HDLC_FR driver (hdlc_fr.c). The DLCI driver's implementation of Frame Relay is used by only one hardware driver in the kernel - the SDLA driver (sdla.c). The SDLA driver provides Frame Relay support for the Sangoma S50x devices. However, the vendor provides their own driver (along with their own multi-WAN-protocol implementations including Frame Relay), called WANPIPE. I believe most users of the hardware would use the vendor-provided WANPIPE driver instead. (The WANPIPE driver was even once in the kernel, but was deleted in commit 8db60bcf3021 ("[WAN]: Remove broken and unmaintained Sangoma drivers.") because the vendor no longer updated the in-kernel WANPIPE driver.)
Unified · Split
| @@ -2499,15 +2499,6 @@ W: http://www.rdrop.com/users/paulmck/ · 2498 unmodified lines | ||
| 2499 | 2499 | D: RCU and variants |
| 2500 | 2500 | D: rcutorture module |
| 2501 | 2501 | |
| 2502 | −N: Mike McLagan | |
| 2503 | −E: mike.mclagan@linux.org | |
| 2504 | −W: http://www.invlogic.com/~mmclagan | |
| 2505 | −D: DLCI/FRAD drivers for Sangoma SDLAs | |
| 2506 | −S: Innovative Logic Corp | |
| 2507 | −S: Post Office Box 1068 | |
| 2508 | −S: Laurel, Maryland 20732 | |
| 2509 | −S: USA | |
| 2510 | − | |
| 2511 | 2502 | N: Bradley McLean |
| 2512 | 2503 | E: brad@bradpc.gaylord.com |
| 2513 | 2504 | D: Device driver hacker |
| @@ -1,44 +0,0 @@ | ||
| 1 | −.. SPDX-License-Identifier: GPL-2.0 | |
| 2 | − | |
| 3 | −================ | |
| 4 | −Frame Relay (FR) | |
| 5 | −================ | |
| 6 | − | |
| 7 | −Frame Relay (FR) support for linux is built into a two tiered system of device | |
| 8 | −drivers. The upper layer implements RFC1490 FR specification, and uses the | |
| 9 | −Data Link Connection Identifier (DLCI) as its hardware address. Usually these | |
| 10 | −are assigned by your network supplier, they give you the number/numbers of | |
| 11 | −the Virtual Connections (VC) assigned to you. | |
| 12 | − | |
| 13 | −Each DLCI is a point-to-point link between your machine and a remote one. | |
| 14 | −As such, a separate device is needed to accommodate the routing. Within the | |
| 15 | −net-tools archives is 'dlcicfg'. This program will communicate with the | |
| 16 | −base "DLCI" device, and create new net devices named 'dlci00', 'dlci01'... | |
| 17 | −The configuration script will ask you how many DLCIs you need, as well as | |
| 18 | −how many DLCIs you want to assign to each Frame Relay Access Device (FRAD). | |
| 19 | − | |
| 20 | −The DLCI uses a number of function calls to communicate with the FRAD, all | |
| 21 | −of which are stored in the FRAD's private data area. assoc/deassoc, | |
| 22 | −activate/deactivate and dlci_config. The DLCI supplies a receive function | |
| 23 | −to the FRAD to accept incoming packets. | |
| 24 | − | |
| 25 | −With this initial offering, only 1 FRAD driver is available. With many thanks | |
| 26 | −to Sangoma Technologies, David Mandelstam & Gene Kozin, the S502A, S502E & | |
| 27 | −S508 are supported. This driver is currently set up for only FR, but as | |
| 28 | −Sangoma makes more firmware modules available, it can be updated to provide | |
| 29 | −them as well. | |
| 30 | − | |
| 31 | −Configuration of the FRAD makes use of another net-tools program, 'fradcfg'. | |
| 32 | −This program makes use of a configuration file (which dlcicfg can also read) | |
| 33 | −to specify the types of boards to be configured as FRADs, as well as perform | |
| 34 | −any board specific configuration. The Sangoma module of fradcfg loads the | |
| 35 | −FR firmware into the card, sets the irq/port/memory information, and provides | |
| 36 | −an initial configuration. | |
| 37 | − | |
| 38 | −Additional FRAD device drivers can be added as hardware is available. | |
| 39 | − | |
| 40 | −At this time, the dlcicfg and fradcfg programs have not been incorporated into | |
| 41 | −the net-tools distribution. They can be found at ftp.invlogic.com, in | |
| 42 | −/pub/linux. Note that with OS/2 FTPD, you end up in /pub by default, so just | |
| 43 | −use 'cd linux'. v0.10 is for use on pre-2.0.3 and earlier, v0.15 is for | |
| 44 | −pre-2.0.4 and later. | |
| @@ -6905,12 +6905,6 @@ S: Maintained · 6904 unmodified lines | ||
| 6905 | 6905 | W: http://floatingpoint.sourceforge.net/emulator/index.html |
| 6906 | 6906 | F: arch/x86/math-emu/ |
| 6907 | 6907 | |
| 6908 | −FRAME RELAY DLCI/FRAD (Sangoma drivers too) | |
| 6909 | −L: netdev@vger.kernel.org | |
| 6910 | −S: Orphan | |
| 6911 | −F: drivers/net/wan/dlci.c | |
| 6912 | −F: drivers/net/wan/sdla.c | |
| 6913 | − | |
| 6914 | 6908 | FRAMEBUFFER LAYER |
| 6915 | 6909 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
| 6916 | 6910 | L: dri-devel@lists.freedesktop.org |
| @@ -141,7 +141,6 @@ CONFIG_HDLC_CISCO=m · 140 unmodified lines | ||
| 141 | 141 | CONFIG_HDLC_FR=m |
| 142 | 142 | CONFIG_HDLC_PPP=m |
| 143 | 143 | CONFIG_HDLC_X25=m |
| 144 | −CONFIG_DLCI=m | |
| 145 | 144 | CONFIG_WAN_ROUTER_DRIVERS=m |
| 146 | 145 | CONFIG_ATM_TCP=m |
| 147 | 146 | # CONFIG_INPUT_KEYBOARD is not set |
| @@ -228,7 +228,6 @@ CONFIG_FARSYNC=m · 227 unmodified lines | ||
| 228 | 228 | CONFIG_DSCC4=m |
| 229 | 229 | CONFIG_DSCC4_PCISYNC=y |
| 230 | 230 | CONFIG_DSCC4_PCI_RST=y |
| 231 | −CONFIG_DLCI=m | |
| 232 | 231 | CONFIG_LAPBETHER=m |
| 233 | 232 | # CONFIG_INPUT_KEYBOARD is not set |
| 234 | 233 | # CONFIG_INPUT_MOUSE is not set |
| @@ -378,7 +378,6 @@ CONFIG_FARSYNC=m · 377 unmodified lines | ||
| 378 | 378 | CONFIG_DSCC4=m |
| 379 | 379 | CONFIG_DSCC4_PCISYNC=y |
| 380 | 380 | CONFIG_DSCC4_PCI_RST=y |
| 381 | −CONFIG_DLCI=m | |
| 382 | 381 | CONFIG_LAPBETHER=m |
| 383 | 382 | # CONFIG_KEYBOARD_ATKBD is not set |
| 384 | 383 | CONFIG_KEYBOARD_GPIO=y |
| @@ -321,51 +321,6 @@ config IXP4XX_HSS · 320 unmodified lines | ||
| 321 | 321 | Say Y here if you want to use built-in HSS ports |
| 322 | 322 | on IXP4xx processor. |
| 323 | 323 | |
| 324 | −config DLCI | |
| 325 | − tristate "Frame Relay DLCI support" | |
| 326 | − help | |
| 327 | − Support for the Frame Relay protocol. | |
| 328 | − | |
| 329 | − Frame Relay is a fast low-cost way to connect to a remote Internet | |
| 330 | − access provider or to form a private wide area network. The one | |
| 331 | − physical line from your box to the local "switch" (i.e. the entry | |
| 332 | − point to the Frame Relay network, usually at the phone company) can | |
| 333 | − carry several logical point-to-point connections to other computers | |
| 334 | − connected to the Frame Relay network. For a general explanation of | |
| 335 | − the protocol, check out <http://www.mplsforum.org/>. | |
| 336 | − | |
| 337 | − To use frame relay, you need supporting hardware (called FRAD) and | |
| 338 | − certain programs from the net-tools package as explained in | |
| 339 | − <file:Documentation/networking/framerelay.rst>. | |
| 340 | − | |
| 341 | − To compile this driver as a module, choose M here: the | |
| 342 | − module will be called dlci. | |
| 343 | − | |
| 344 | −config DLCI_MAX | |
| 345 | − int "Max DLCI per device" | |
| 346 | − depends on DLCI | |
| 347 | − default "8" | |
| 348 | − help | |
| 349 | − How many logical point-to-point frame relay connections (the | |
| 350 | − identifiers of which are called DCLIs) should be handled by each | |
| 351 | − of your hardware frame relay access devices. | |
| 352 | − | |
| 353 | − Go with the default. | |
| 354 | − | |
| 355 | −config SDLA | |
| 356 | − tristate "SDLA (Sangoma S502/S508) support" | |
| 357 | − depends on DLCI && ISA | |
| 358 | − help | |
| 359 | − Driver for the Sangoma S502A, S502E, and S508 Frame Relay Access | |
| 360 | − Devices. | |
| 361 | − | |
| 362 | − These are multi-protocol cards, but only Frame Relay is supported | |
| 363 | − by the driver at this time. Please read | |
| 364 | − <file:Documentation/networking/framerelay.rst>. | |
| 365 | − | |
| 366 | − To compile this driver as a module, choose M here: the | |
| 367 | − module will be called sdla. | |
| 368 | − | |
| 369 | 324 | # X.25 network drivers |
| 370 | 325 | config LAPBETHER |
| 371 | 326 | tristate "LAPB over Ethernet driver" |
| @@ -21,8 +21,6 @@ obj-$(CONFIG_FARSYNC) += farsync.o · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | obj-$(CONFIG_LANMEDIA) += lmc/ |
| 23 | 23 | |
| 24 | −obj-$(CONFIG_DLCI) += dlci.o | |
| 25 | −obj-$(CONFIG_SDLA) += sdla.o | |
| 26 | 24 | obj-$(CONFIG_LAPBETHER) += lapbether.o |
| 27 | 25 | obj-$(CONFIG_SBNI) += sbni.o |
| 28 | 26 | obj-$(CONFIG_N2) += n2.o |
| @@ -1,541 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | −/* | |
| 3 | − * DLCI Implementation of Frame Relay protocol for Linux, according to | |
| 4 | − * RFC 1490. This generic device provides en/decapsulation for an | |
| 5 | − * underlying hardware driver. Routes & IPs are assigned to these | |
| 6 | − * interfaces. Requires 'dlcicfg' program to create usable | |
| 7 | − * interfaces, the initial one, 'dlci' is for IOCTL use only. | |
| 8 | − * | |
| 9 | − * Version: @(#)dlci.c 0.35 4 Jan 1997 | |
| 10 | − * | |
| 11 | − * Author: Mike McLagan <mike.mclagan@linux.org> | |
| 12 | − * | |
| 13 | − * Changes: | |
| 14 | − * | |
| 15 | − * 0.15 Mike Mclagan Packet freeing, bug in kmalloc call | |
| 16 | − * DLCI_RET handling | |
| 17 | − * 0.20 Mike McLagan More conservative on which packets | |
| 18 | − * are returned for retry and which are | |
| 19 | − * are dropped. If DLCI_RET_DROP is | |
| 20 | − * returned from the FRAD, the packet is | |
| 21 | − * sent back to Linux for re-transmission | |
| 22 | − * 0.25 Mike McLagan Converted to use SIOC IOCTL calls | |
| 23 | − * 0.30 Jim Freeman Fixed to allow IPX traffic | |
| 24 | − * 0.35 Michael Elizabeth Fixed incorrect memcpy_fromfs | |
| 25 | − */ | |
| 26 | − | |
| 27 | −#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 28 | − | |
| 29 | −#include <linux/module.h> | |
| 30 | −#include <linux/kernel.h> | |
| 31 | −#include <linux/types.h> | |
| 32 | −#include <linux/fcntl.h> | |
| 33 | −#include <linux/interrupt.h> | |
| 34 | −#include <linux/ptrace.h> | |
| 35 | −#include <linux/ioport.h> | |
| 36 | −#include <linux/in.h> | |
| 37 | −#include <linux/init.h> | |
| 38 | −#include <linux/slab.h> | |
| 39 | −#include <linux/string.h> | |
| 40 | −#include <linux/errno.h> | |
| 41 | −#include <linux/netdevice.h> | |
| 42 | −#include <linux/skbuff.h> | |
| 43 | −#include <linux/if_arp.h> | |
| 44 | −#include <linux/if_frad.h> | |
| 45 | −#include <linux/bitops.h> | |
| 46 | − | |
| 47 | −#include <net/sock.h> | |
| 48 | − | |
| 49 | −#include <asm/io.h> | |
| 50 | −#include <asm/dma.h> | |
| 51 | −#include <linux/uaccess.h> | |
| 52 | − | |
| 53 | −static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org"; | |
| 54 | − | |
| 55 | −static LIST_HEAD(dlci_devs); | |
| 56 | − | |
| 57 | −static void dlci_setup(struct net_device *); | |
| 58 | − | |
| 59 | −/* | |
| 60 | − * these encapsulate the RFC 1490 requirements as well as | |
| 61 | − * deal with packet transmission and reception, working with | |
| 62 | − * the upper network layers | |
| 63 | − */ | |
| 64 | − | |
| 65 | −static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |
| 66 | − unsigned short type, const void *daddr, | |
| 67 | − const void *saddr, unsigned len) | |
| 68 | −{ | |
| 69 | − struct frhdr hdr; | |
| 70 | − unsigned int hlen; | |
| 71 | − char *dest; | |
| 72 | − | |
| 73 | − hdr.control = FRAD_I_UI; | |
| 74 | − switch (type) | |
| 75 | − { | |
| 76 | − case ETH_P_IP: | |
| 77 | − hdr.IP_NLPID = FRAD_P_IP; | |
| 78 | − hlen = sizeof(hdr.control) + sizeof(hdr.IP_NLPID); | |
| 79 | − break; | |
| 80 | − | |
| 81 | − /* feel free to add other types, if necessary */ | |
| 82 | − | |
| 83 | − default: | |
| 84 | − hdr.pad = FRAD_P_PADDING; | |
| 85 | − hdr.NLPID = FRAD_P_SNAP; | |
| 86 | − memset(hdr.OUI, 0, sizeof(hdr.OUI)); | |
| 87 | − hdr.PID = htons(type); | |
| 88 | − hlen = sizeof(hdr); | |
| 89 | − break; | |
| 90 | − } | |
| 91 | − | |
| 92 | − dest = skb_push(skb, hlen); | |
| 93 | − if (!dest) | |
| 94 | − return 0; | |
| 95 | − | |
| 96 | − memcpy(dest, &hdr, hlen); | |
| 97 | − | |
| 98 | − return hlen; | |
| 99 | −} | |
| 100 | − | |
| 101 | −static void dlci_receive(struct sk_buff *skb, struct net_device *dev) | |
| 102 | −{ | |
| 103 | − struct frhdr *hdr; | |
| 104 | − int process, header; | |
| 105 | − | |
| 106 | − if (!pskb_may_pull(skb, sizeof(*hdr))) { | |
| 107 | − netdev_notice(dev, "invalid data no header\n"); | |
| 108 | − dev->stats.rx_errors++; | |
| 109 | − kfree_skb(skb); | |
| 110 | − return; | |
| 111 | − } | |
| 112 | − | |
| 113 | − hdr = (struct frhdr *) skb->data; | |
| 114 | − process = 0; | |
| 115 | − header = 0; | |
| 116 | − skb->dev = dev; | |
| 117 | − | |
| 118 | − if (hdr->control != FRAD_I_UI) | |
| 119 | − { | |
| 120 | − netdev_notice(dev, "Invalid header flag 0x%02X\n", | |
| 121 | − hdr->control); | |
| 122 | − dev->stats.rx_errors++; | |
| 123 | − } | |
| 124 | − else | |
| 125 | − switch (hdr->IP_NLPID) | |
| 126 | − { | |
| 127 | − case FRAD_P_PADDING: | |
| 128 | − if (hdr->NLPID != FRAD_P_SNAP) | |
| 129 | − { | |
| 130 | − netdev_notice(dev, "Unsupported NLPID 0x%02X\n", | |
| 131 | − hdr->NLPID); | |
| 132 | − dev->stats.rx_errors++; | |
| 133 | − break; | |
| 134 | − } | |
| 135 | − | |
| 136 | − if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0) | |
| 137 | − { | |
| 138 | − netdev_notice(dev, "Unsupported organizationally unique identifier 0x%02X-%02X-%02X\n", | |
| 139 | − hdr->OUI[0], | |
| 140 | − hdr->OUI[1], | |
| 141 | − hdr->OUI[2]); | |
| 142 | − dev->stats.rx_errors++; | |
| 143 | − break; | |
| 144 | − } | |
| 145 | − | |
| 146 | − /* at this point, it's an EtherType frame */ | |
| 147 | − header = sizeof(struct frhdr); | |
| 148 | − /* Already in network order ! */ | |
| 149 | − skb->protocol = hdr->PID; | |
| 150 | − process = 1; | |
| 151 | − break; | |
| 152 | − | |
| 153 | − case FRAD_P_IP: | |
| 154 | − header = sizeof(hdr->control) + sizeof(hdr->IP_NLPID); | |
| 155 | − skb->protocol = htons(ETH_P_IP); | |
| 156 | − process = 1; | |
| 157 | − break; | |
| 158 | − | |
| 159 | − case FRAD_P_SNAP: | |
| 160 | − case FRAD_P_Q933: | |
| 161 | − case FRAD_P_CLNP: | |
| 162 | − netdev_notice(dev, "Unsupported NLPID 0x%02X\n", | |
| 163 | − hdr->pad); | |
| 164 | − dev->stats.rx_errors++; | |
| 165 | − break; | |
| 166 | − | |
| 167 | − default: | |
| 168 | − netdev_notice(dev, "Invalid pad byte 0x%02X\n", | |
| 169 | − hdr->pad); | |
| 170 | − dev->stats.rx_errors++; | |
| 171 | − break; | |
| 172 | − } | |
| 173 | − | |
| 174 | − if (process) | |
| 175 | − { | |
| 176 | − /* we've set up the protocol, so discard the header */ | |
| 177 | − skb_reset_mac_header(skb); | |
| 178 | − skb_pull(skb, header); | |
| 179 | − dev->stats.rx_bytes += skb->len; | |
| 180 | − netif_rx(skb); | |
| 181 | − dev->stats.rx_packets++; | |
| 182 | − } | |
| 183 | − else | |
| 184 | − dev_kfree_skb(skb); | |
| 185 | −} | |
| 186 | − | |
| 187 | −static netdev_tx_t dlci_transmit(struct sk_buff *skb, struct net_device *dev) | |
| 188 | −{ | |
| 189 | − struct dlci_local *dlp = netdev_priv(dev); | |
| 190 | − | |
| 191 | − if (skb) { | |
| 192 | − struct netdev_queue *txq = skb_get_tx_queue(dev, skb); | |
| 193 | − netdev_start_xmit(skb, dlp->slave, txq, false); | |
| 194 | − } | |
| 195 | − return NETDEV_TX_OK; | |
| 196 | −} | |
| 197 | − | |
| 198 | −static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, int get) | |
| 199 | −{ | |
| 200 | − struct dlci_conf config; | |
| 201 | − struct dlci_local *dlp; | |
| 202 | − struct frad_local *flp; | |
| 203 | − int err; | |
| 204 | − | |
| 205 | − dlp = netdev_priv(dev); | |
| 206 | − | |
| 207 | − flp = netdev_priv(dlp->slave); | |
| 208 | − | |
| 209 | − if (!get) | |
| 210 | − { | |
| 211 | − if (copy_from_user(&config, conf, sizeof(struct dlci_conf))) | |
| 212 | − return -EFAULT; | |
| 213 | − if (config.flags & ~DLCI_VALID_FLAGS) | |
| 214 | − return -EINVAL; | |
| 215 | − memcpy(&dlp->config, &config, sizeof(struct dlci_conf)); | |
| 216 | − dlp->configured = 1; | |
| 217 | − } | |
| 218 | − | |
| 219 | − err = (*flp->dlci_conf)(dlp->slave, dev, get); | |
| 220 | − if (err) | |
| 221 | − return err; | |
| 222 | − | |
| 223 | − if (get) | |
| 224 | − { | |
| 225 | − if (copy_to_user(conf, &dlp->config, sizeof(struct dlci_conf))) | |
| 226 | − return -EFAULT; | |
| 227 | − } | |
| 228 | − | |
| 229 | − return 0; | |
| 230 | −} | |
| 231 | − | |
| 232 | −static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |
| 233 | −{ | |
| 234 | − struct dlci_local *dlp; | |
| 235 | − | |
| 236 | − if (!capable(CAP_NET_ADMIN)) | |
| 237 | − return -EPERM; | |
| 238 | − | |
| 239 | − dlp = netdev_priv(dev); | |
| 240 | − | |
| 241 | − switch (cmd) | |
| 242 | − { | |
| 243 | − case DLCI_GET_SLAVE: | |
| 244 | − if (!*(short *)(dev->dev_addr)) | |
| 245 | − return -EINVAL; | |
| 246 | − | |
| 247 | − strncpy(ifr->ifr_slave, dlp->slave->name, sizeof(ifr->ifr_slave)); | |
| 248 | − break; | |
| 249 | − | |
| 250 | − case DLCI_GET_CONF: | |
| 251 | − case DLCI_SET_CONF: | |
| 252 | − if (!*(short *)(dev->dev_addr)) | |
| 253 | − return -EINVAL; | |
| 254 | − | |
| 255 | − return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF); | |
| 256 | − | |
| 257 | − default: | |
| 258 | − return -EOPNOTSUPP; | |
| 259 | − } | |
| 260 | − return 0; | |
| 261 | −} | |
| 262 | − | |
| 263 | −static int dlci_change_mtu(struct net_device *dev, int new_mtu) | |
| 264 | −{ | |
| 265 | − struct dlci_local *dlp = netdev_priv(dev); | |
| 266 | − | |
| 267 | − return dev_set_mtu(dlp->slave, new_mtu); | |
| 268 | −} | |
| 269 | − | |
| 270 | −static int dlci_open(struct net_device *dev) | |
| 271 | −{ | |
| 272 | − struct dlci_local *dlp; | |
| 273 | − struct frad_local *flp; | |
| 274 | − int err; | |
| 275 | − | |
| 276 | − dlp = netdev_priv(dev); | |
| 277 | − | |
| 278 | − if (!*(short *)(dev->dev_addr)) | |
| 279 | − return -EINVAL; | |
| 280 | − | |
| 281 | − if (!netif_running(dlp->slave)) | |
| 282 | − return -ENOTCONN; | |
| 283 | − | |
| 284 | − flp = netdev_priv(dlp->slave); | |
| 285 | − err = (*flp->activate)(dlp->slave, dev); | |
| 286 | − if (err) | |
| 287 | − return err; | |
| 288 | − | |
| 289 | − netif_start_queue(dev); | |
| 290 | − | |
| 291 | − return 0; | |
| 292 | −} | |
| 293 | − | |
| 294 | −static int dlci_close(struct net_device *dev) | |
| 295 | −{ | |
| 296 | − struct dlci_local *dlp; | |
| 297 | − struct frad_local *flp; | |
| 298 | − | |
| 299 | − netif_stop_queue(dev); | |
| 300 | − | |
| 301 | − dlp = netdev_priv(dev); | |
| 302 | − | |
| 303 | − flp = netdev_priv(dlp->slave); | |
| 304 | − (*flp->deactivate)(dlp->slave, dev); | |
| 305 | − | |
| 306 | − return 0; | |
| 307 | −} | |
| 308 | − | |
| 309 | −static int dlci_add(struct dlci_add *dlci) | |
| 310 | −{ | |
| 311 | − struct net_device *master, *slave; | |
| 312 | − struct dlci_local *dlp; | |
| 313 | − struct frad_local *flp; | |
| 314 | − int err = -EINVAL; | |
| 315 | − | |
| 316 | − | |
| 317 | − /* validate slave device */ | |
| 318 | − slave = dev_get_by_name(&init_net, dlci->devname); | |
| 319 | − if (!slave) | |
| 320 | − return -ENODEV; | |
| 321 | − | |
| 322 | − if (slave->type != ARPHRD_FRAD || netdev_priv(slave) == NULL) | |
| 323 | − goto err1; | |
| 324 | − | |
| 325 | − /* create device name */ | |
| 326 | − master = alloc_netdev(sizeof(struct dlci_local), "dlci%d", | |
| 327 | − NET_NAME_UNKNOWN, dlci_setup); | |
| 328 | − if (!master) { | |
| 329 | − err = -ENOMEM; | |
| 330 | − goto err1; | |
| 331 | − } | |
| 332 | − | |
| 333 | − /* make sure same slave not already registered */ | |
| 334 | − rtnl_lock(); | |
| 335 | − list_for_each_entry(dlp, &dlci_devs, list) { | |
| 336 | − if (dlp->slave == slave) { | |
| 337 | − err = -EBUSY; | |
| 338 | − goto err2; | |
| 339 | − } | |
| 340 | − } | |
| 341 | − | |
| 342 | − *(short *)(master->dev_addr) = dlci->dlci; | |
| 343 | − | |
| 344 | − dlp = netdev_priv(master); | |
| 345 | − dlp->slave = slave; | |
| 346 | − dlp->master = master; | |
| 347 | − | |
| 348 | − flp = netdev_priv(slave); | |
| 349 | − err = (*flp->assoc)(slave, master); | |
| 350 | − if (err < 0) | |
| 351 | − goto err2; | |
| 352 | − | |
| 353 | − err = register_netdevice(master); | |
| 354 | − if (err < 0) | |
| 355 | − goto err2; | |
| 356 | − | |
| 357 | − strcpy(dlci->devname, master->name); | |
| 358 | − | |
| 359 | − list_add(&dlp->list, &dlci_devs); | |
| 360 | − rtnl_unlock(); | |
| 361 | − | |
| 362 | − return 0; | |
| 363 | − | |
| 364 | − err2: | |
| 365 | − rtnl_unlock(); | |
| 366 | − free_netdev(master); | |
| 367 | − err1: | |
| 368 | − dev_put(slave); | |
| 369 | − return err; | |
| 370 | −} | |
| 371 | − | |
| 372 | −static int dlci_del(struct dlci_add *dlci) | |
| 373 | −{ | |
| 374 | − struct dlci_local *dlp; | |
| 375 | − struct frad_local *flp; | |
| 376 | − struct net_device *master, *slave; | |
| 377 | − int err; | |
| 378 | − bool found = false; | |
| 379 | − | |
| 380 | − rtnl_lock(); | |
| 381 | − | |
| 382 | − /* validate slave device */ | |
| 383 | − master = __dev_get_by_name(&init_net, dlci->devname); | |
| 384 | − if (!master) { | |
| 385 | − err = -ENODEV; | |
| 386 | − goto out; | |
| 387 | − } | |
| 388 | − | |
| 389 | − list_for_each_entry(dlp, &dlci_devs, list) { | |
| 390 | − if (dlp->master == master) { | |
| 391 | − found = true; | |
| 392 | − break; | |
| 393 | − } | |
| 394 | − } | |
| 395 | − if (!found) { | |
| 396 | − err = -ENODEV; | |
| 397 | − goto out; | |
| 398 | − } | |
| 399 | − | |
| 400 | − if (netif_running(master)) { | |
| 401 | − err = -EBUSY; | |
| 402 | − goto out; | |
| 403 | − } | |
| 404 | − | |
| 405 | − dlp = netdev_priv(master); | |
| 406 | − slave = dlp->slave; | |
| 407 | − flp = netdev_priv(slave); | |
| 408 | − | |
| 409 | − err = (*flp->deassoc)(slave, master); | |
| 410 | − if (!err) { | |
| 411 | − list_del(&dlp->list); | |
| 412 | − | |
| 413 | − unregister_netdevice(master); | |
| 414 | − | |
| 415 | − dev_put(slave); | |
| 416 | − } | |
| 417 | −out: | |
| 418 | − rtnl_unlock(); | |
| 419 | − return err; | |
| 420 | −} | |
| 421 | − | |
| 422 | −static int dlci_ioctl(unsigned int cmd, void __user *arg) | |
| 423 | −{ | |
| 424 | − struct dlci_add add; | |
| 425 | − int err; | |
| 426 | − | |
| 427 | − if (!capable(CAP_NET_ADMIN)) | |
| 428 | − return -EPERM; | |
| 429 | − | |
| 430 | − if (copy_from_user(&add, arg, sizeof(struct dlci_add))) | |
| 431 | − return -EFAULT; | |
| 432 | − | |
| 433 | − switch (cmd) | |
| 434 | − { | |
| 435 | − case SIOCADDDLCI: | |
| 436 | − err = dlci_add(&add); | |
| 437 | − | |
| 438 | − if (!err) | |
| 439 | − if (copy_to_user(arg, &add, sizeof(struct dlci_add))) | |
| 440 | − return -EFAULT; | |
| 441 | − break; | |
| 442 | − | |
| 443 | − case SIOCDELDLCI: | |
| 444 | − err = dlci_del(&add); | |
| 445 | − break; | |
| 446 | − | |
| 447 | − default: | |
| 448 | − err = -EINVAL; | |
| 449 | − } | |
| 450 | − | |
| 451 | − return err; | |
| 452 | −} | |
| 453 | − | |
| 454 | −static const struct header_ops dlci_header_ops = { | |
| 455 | − .create = dlci_header, | |
| 456 | −}; | |
| 457 | − | |
| 458 | −static const struct net_device_ops dlci_netdev_ops = { | |
| 459 | − .ndo_open = dlci_open, | |
| 460 | − .ndo_stop = dlci_close, | |
| 461 | − .ndo_do_ioctl = dlci_dev_ioctl, | |
| 462 | − .ndo_start_xmit = dlci_transmit, | |
| 463 | − .ndo_change_mtu = dlci_change_mtu, | |
| 464 | −}; | |
| 465 | − | |
| 466 | −static void dlci_setup(struct net_device *dev) | |
| 467 | −{ | |
| 468 | − struct dlci_local *dlp = netdev_priv(dev); | |
| 469 | − | |
| 470 | − dev->flags = 0; | |
| 471 | − dev->header_ops = &dlci_header_ops; | |
| 472 | − dev->netdev_ops = &dlci_netdev_ops; | |
| 473 | − dev->needs_free_netdev = true; | |
| 474 | − | |
| 475 | − dlp->receive = dlci_receive; | |
| 476 | − | |
| 477 | − dev->type = ARPHRD_DLCI; | |
| 478 | − dev->hard_header_len = sizeof(struct frhdr); | |
| 479 | − dev->addr_len = sizeof(short); | |
| 480 | − | |
| 481 | −} | |
| 482 | − | |
| 483 | −/* if slave is unregistering, then cleanup master */ | |
| 484 | −static int dlci_dev_event(struct notifier_block *unused, | |
| 485 | − unsigned long event, void *ptr) | |
| 486 | −{ | |
| 487 | − struct net_device *dev = netdev_notifier_info_to_dev(ptr); | |
| 488 | − | |
| 489 | − if (dev_net(dev) != &init_net) | |
| 490 | − return NOTIFY_DONE; | |
| 491 | − | |
| 492 | − if (event == NETDEV_UNREGISTER) { | |
| 493 | − struct dlci_local *dlp; | |
| 494 | − | |
| 495 | − list_for_each_entry(dlp, &dlci_devs, list) { | |
| 496 | − if (dlp->slave == dev) { | |
| 497 | − list_del(&dlp->list); | |
| 498 | − unregister_netdevice(dlp->master); | |
| 499 | − dev_put(dlp->slave); | |
| 500 | − break; | |
| 501 | − } | |
| 502 | − } | |
| 503 | − } | |
| 504 | − return NOTIFY_DONE; | |
| 505 | −} | |
| 506 | − | |
| 507 | −static struct notifier_block dlci_notifier = { | |
| 508 | − .notifier_call = dlci_dev_event, | |
| 509 | −}; | |
| 510 | − | |
| 511 | −static int __init init_dlci(void) | |
| 512 | −{ | |
| 513 | − dlci_ioctl_set(dlci_ioctl); | |
| 514 | − register_netdevice_notifier(&dlci_notifier); | |
| 515 | − | |
| 516 | − printk("%s.\n", version); | |
| 517 | − | |
| 518 | − return 0; | |
| 519 | −} | |
| 520 | − | |
| 521 | −static void __exit dlci_exit(void) | |
| 522 | −{ | |
| 523 | − struct dlci_local *dlp, *nxt; | |
| 524 | − | |
| 525 | − dlci_ioctl_set(NULL); | |
| 526 | − unregister_netdevice_notifier(&dlci_notifier); | |
| 527 | − | |
| 528 | − rtnl_lock(); | |
| 529 | − list_for_each_entry_safe(dlp, nxt, &dlci_devs, list) { | |
| 530 | − unregister_netdevice(dlp->master); | |
| 531 | − dev_put(dlp->slave); | |
| 532 | − } | |
| 533 | − rtnl_unlock(); | |
| 534 | −} | |
| 535 | − | |
| 536 | −module_init(init_dlci); | |
| 537 | −module_exit(dlci_exit); | |
| 538 | − | |
| 539 | −MODULE_AUTHOR("Mike McLagan"); | |
| 540 | −MODULE_DESCRIPTION("Frame Relay DLCI layer"); | |
| 541 | −MODULE_LICENSE("GPL"); | |
| @@ -1,1655 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | −/* | |
| 3 | − * SDLA An implementation of a driver for the Sangoma S502/S508 series | |
| 4 | − * multi-protocol PC interface card. Initial offering is with | |
| 5 | − * the DLCI driver, providing Frame Relay support for linux. | |
| 6 | − * | |
| 7 | − * Global definitions for the Frame relay interface. | |
| 8 | − * | |
| 9 | − * Version: @(#)sdla.c 0.30 12 Sep 1996 | |
| 10 | − * | |
| 11 | − * Credits: Sangoma Technologies, for the use of 2 cards for an extended | |
| 12 | − * period of time. | |
| 13 | − * David Mandelstam <dm@sangoma.com> for getting me started on | |
| 14 | − * this project, and incentive to complete it. | |
| 15 | − * Gene Kozen <74604.152@compuserve.com> for providing me with | |
| 16 | − * important information about the cards. | |
| 17 | − * | |
| 18 | − * Author: Mike McLagan <mike.mclagan@linux.org> | |
| 19 | − * | |
| 20 | − * Changes: | |
| 21 | − * 0.15 Mike McLagan Improved error handling, packet dropping | |
| 22 | − * 0.20 Mike McLagan New transmit/receive flags for config | |
| 23 | − * If in FR mode, don't accept packets from | |
| 24 | − * non DLCI devices. | |
| 25 | − * 0.25 Mike McLagan Fixed problem with rejecting packets | |
| 26 | − * from non DLCI devices. | |
| 27 | − * 0.30 Mike McLagan Fixed kernel panic when used with modified | |
| 28 | − * ifconfig | |
| 29 | − */ | |
| 30 | − | |
| 31 | −#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
| 32 | − | |
| 33 | −#include <linux/module.h> | |
| 34 | −#include <linux/kernel.h> | |
| 35 | −#include <linux/types.h> | |
| 36 | −#include <linux/fcntl.h> | |
| 37 | −#include <linux/interrupt.h> | |
| 38 | −#include <linux/ptrace.h> | |
| 39 | −#include <linux/ioport.h> | |
| 40 | −#include <linux/in.h> | |
| 41 | −#include <linux/slab.h> | |
| 42 | −#include <linux/string.h> | |
| 43 | −#include <linux/timer.h> | |
| 44 | −#include <linux/errno.h> | |
| 45 | −#include <linux/init.h> | |
| 46 | −#include <linux/netdevice.h> | |
| 47 | −#include <linux/skbuff.h> | |
| 48 | −#include <linux/if_arp.h> | |
| 49 | −#include <linux/if_frad.h> | |
| 50 | −#include <linux/sdla.h> | |
| 51 | −#include <linux/bitops.h> | |
| 52 | − | |
| 53 | −#include <asm/io.h> | |
| 54 | −#include <asm/dma.h> | |
| 55 | −#include <linux/uaccess.h> | |
| 56 | − | |
| 57 | −static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org"; | |
| 58 | − | |
| 59 | −static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; | |
| 60 | − | |
| 61 | −static unsigned int valid_mem[] = { | |
| 62 | − 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, | |
| 63 | − 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, | |
| 64 | − 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, | |
| 65 | − 0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000, | |
| 66 | − 0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; | |
| 67 | − | |
| 68 | −static DEFINE_SPINLOCK(sdla_lock); | |
| 69 | − | |
| 70 | −/********************************************************* | |
| 71 | − * | |
| 72 | − * these are the core routines that access the card itself | |
| 73 | − * | |
| 74 | − *********************************************************/ | |
| 75 | − | |
| 76 | −#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW) | |
| 77 | − | |
| 78 | −static void __sdla_read(struct net_device *dev, int addr, void *buf, short len) | |
| 79 | −{ | |
| 80 | − char *temp; | |
| 81 | − const void *base; | |
| 82 | − int offset, bytes; | |
| 83 | − | |
| 84 | − temp = buf; | |
| 85 | − while(len) | |
| 86 | − { | |
| 87 | − offset = addr & SDLA_ADDR_MASK; | |
| 88 | − bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len; | |
| 89 | − base = (const void *) (dev->mem_start + offset); | |
| 90 | − | |
| 91 | − SDLA_WINDOW(dev, addr); | |
| 92 | − memcpy(temp, base, bytes); | |
| 93 | − | |
| 94 | − addr += bytes; | |
| 95 | − temp += bytes; | |
| 96 | − len -= bytes; | |
| 97 | − } | |
| 98 | −} | |
| 99 | − | |
| 100 | −static void sdla_read(struct net_device *dev, int addr, void *buf, short len) | |
| 101 | −{ | |
| 102 | − unsigned long flags; | |
| 103 | − spin_lock_irqsave(&sdla_lock, flags); | |
| 104 | − __sdla_read(dev, addr, buf, len); | |
| 105 | − spin_unlock_irqrestore(&sdla_lock, flags); | |
| 106 | −} | |
| 107 | − | |
| 108 | −static void __sdla_write(struct net_device *dev, int addr, | |
| 109 | − const void *buf, short len) | |
| 110 | −{ | |
| 111 | − const char *temp; | |
| 112 | − void *base; | |
| 113 | − int offset, bytes; | |
| 114 | − | |
| 115 | − temp = buf; | |
| 116 | − while(len) | |
| 117 | − { | |
| 118 | − offset = addr & SDLA_ADDR_MASK; | |
| 119 | − bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len; | |
| 120 | − base = (void *) (dev->mem_start + offset); | |
| 121 | − | |
| 122 | − SDLA_WINDOW(dev, addr); | |
| 123 | − memcpy(base, temp, bytes); | |
| 124 | − | |
| 125 | − addr += bytes; | |
| 126 | − temp += bytes; | |
| 127 | − len -= bytes; | |
| 128 | − } | |
| 129 | −} | |
| 130 | − | |
| 131 | −static void sdla_write(struct net_device *dev, int addr, | |
| 132 | − const void *buf, short len) | |
| 133 | −{ | |
| 134 | − unsigned long flags; | |
| 135 | − | |
| 136 | − spin_lock_irqsave(&sdla_lock, flags); | |
| 137 | − __sdla_write(dev, addr, buf, len); | |
| 138 | − spin_unlock_irqrestore(&sdla_lock, flags); | |
| 139 | −} | |
| 140 | − | |
| 141 | − | |
| 142 | −static void sdla_clear(struct net_device *dev) | |
| 143 | −{ | |
| 144 | − unsigned long flags; | |
| 145 | − char *base; | |
| 146 | − int len, addr, bytes; | |
| 147 | − | |
| 148 | − len = 65536; | |
| 149 | − addr = 0; | |
| 150 | − bytes = SDLA_WINDOW_SIZE; | |
| 151 | − base = (void *) dev->mem_start; | |
| 152 | − | |
| 153 | − spin_lock_irqsave(&sdla_lock, flags); | |
| 154 | − while(len) | |
| 155 | − { | |
| 156 | − SDLA_WINDOW(dev, addr); | |
| 157 | − memset(base, 0, bytes); | |
| 158 | − | |
| 159 | − addr += bytes; | |
| 160 | − len -= bytes; | |
| 161 | − } | |
| 162 | − spin_unlock_irqrestore(&sdla_lock, flags); | |
| 163 | − | |
| 164 | −} | |
| 165 | − | |
| 166 | −static char sdla_byte(struct net_device *dev, int addr) | |
| 167 | −{ | |
| 168 | − unsigned long flags; | |
| 169 | − char byte, *temp; | |
| 170 | − | |
| 171 | − temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK)); | |
| 172 | − | |
| 173 | − spin_lock_irqsave(&sdla_lock, flags); | |
| 174 | − SDLA_WINDOW(dev, addr); | |
| 175 | − byte = *temp; | |
| 176 | − spin_unlock_irqrestore(&sdla_lock, flags); | |
| 177 | − | |
| 178 | − return byte; | |
| 179 | −} | |
| 180 | − | |
| 181 | −static void sdla_stop(struct net_device *dev) | |
| 182 | −{ | |
| 183 | − struct frad_local *flp; | |
| 184 | − | |
| 185 | − flp = netdev_priv(dev); | |
| 186 | − switch(flp->type) | |
| 187 | − { | |
| 188 | − case SDLA_S502A: | |
| 189 | − outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL); | |
| 190 | − flp->state = SDLA_HALT; | |
| 191 | − break; | |
| 192 | − case SDLA_S502E: | |
| 193 | − outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL); | |
| 194 | − outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL); | |
| 195 | − flp->state = SDLA_S502E_ENABLE; | |
| 196 | − break; | |
| 197 | − case SDLA_S507: | |
| 198 | − flp->state &= ~SDLA_CPUEN; | |
| 199 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 200 | − break; | |
| 201 | − case SDLA_S508: | |
| 202 | − flp->state &= ~SDLA_CPUEN; | |
| 203 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 204 | − break; | |
| 205 | − } | |
| 206 | −} | |
| 207 | − | |
| 208 | −static void sdla_start(struct net_device *dev) | |
| 209 | −{ | |
| 210 | − struct frad_local *flp; | |
| 211 | − | |
| 212 | − flp = netdev_priv(dev); | |
| 213 | − switch(flp->type) | |
| 214 | − { | |
| 215 | − case SDLA_S502A: | |
| 216 | − outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL); | |
| 217 | − outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL); | |
| 218 | − flp->state = SDLA_S502A_START; | |
| 219 | − break; | |
| 220 | − case SDLA_S502E: | |
| 221 | − outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL); | |
| 222 | − outb(0x00, dev->base_addr + SDLA_REG_CONTROL); | |
| 223 | − flp->state = 0; | |
| 224 | − break; | |
| 225 | − case SDLA_S507: | |
| 226 | − flp->state |= SDLA_CPUEN; | |
| 227 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 228 | − break; | |
| 229 | − case SDLA_S508: | |
| 230 | − flp->state |= SDLA_CPUEN; | |
| 231 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 232 | − break; | |
| 233 | − } | |
| 234 | −} | |
| 235 | − | |
| 236 | −/**************************************************** | |
| 237 | − * | |
| 238 | − * this is used for the S502A/E cards to determine | |
| 239 | − * the speed of the onboard CPU. Calibration is | |
| 240 | − * necessary for the Frame Relay code uploaded | |
| 241 | − * later. Incorrect results cause timing problems | |
| 242 | − * with link checks & status messages | |
| 243 | − * | |
| 244 | − ***************************************************/ | |
| 245 | − | |
| 246 | −static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2) | |
| 247 | −{ | |
| 248 | − unsigned long start, done, now; | |
| 249 | − char resp, *temp; | |
| 250 | − | |
| 251 | − start = now = jiffies; | |
| 252 | − done = jiffies + jiffs; | |
| 253 | − | |
| 254 | − temp = (void *)dev->mem_start; | |
| 255 | − temp += z80_addr & SDLA_ADDR_MASK; | |
| 256 | − | |
| 257 | − resp = ~resp1; | |
| 258 | − while (time_before(jiffies, done) && (resp != resp1) && (!resp2 || (resp != resp2))) | |
| 259 | − { | |
| 260 | − if (jiffies != now) | |
| 261 | − { | |
| 262 | − SDLA_WINDOW(dev, z80_addr); | |
| 263 | − now = jiffies; | |
| 264 | − resp = *temp; | |
| 265 | − } | |
| 266 | − } | |
| 267 | − return time_before(jiffies, done) ? jiffies - start : -1; | |
| 268 | −} | |
| 269 | − | |
| 270 | −/* constants for Z80 CPU speed */ | |
| 271 | −#define Z80_READY '1' /* Z80 is ready to begin */ | |
| 272 | −#define LOADER_READY '2' /* driver is ready to begin */ | |
| 273 | −#define Z80_SCC_OK '3' /* SCC is on board */ | |
| 274 | −#define Z80_SCC_BAD '4' /* SCC was not found */ | |
| 275 | − | |
| 276 | −static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) | |
| 277 | −{ | |
| 278 | − int jiffs; | |
| 279 | − char data; | |
| 280 | − | |
| 281 | − sdla_start(dev); | |
| 282 | − if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0) | |
| 283 | − return -EIO; | |
| 284 | − | |
| 285 | − data = LOADER_READY; | |
| 286 | − sdla_write(dev, 0, &data, 1); | |
| 287 | − | |
| 288 | − if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0) | |
| 289 | − return -EIO; | |
| 290 | − | |
| 291 | − sdla_stop(dev); | |
| 292 | − sdla_read(dev, 0, &data, 1); | |
| 293 | − | |
| 294 | − if (data == Z80_SCC_BAD) | |
| 295 | − { | |
| 296 | − printk("%s: SCC bad\n", dev->name); | |
| 297 | − return -EIO; | |
| 298 | − } | |
| 299 | − | |
| 300 | − if (data != Z80_SCC_OK) | |
| 301 | − return -EINVAL; | |
| 302 | − | |
| 303 | − if (jiffs < 165) | |
| 304 | − ifr->ifr_mtu = SDLA_CPU_16M; | |
| 305 | − else if (jiffs < 220) | |
| 306 | − ifr->ifr_mtu = SDLA_CPU_10M; | |
| 307 | − else if (jiffs < 258) | |
| 308 | − ifr->ifr_mtu = SDLA_CPU_8M; | |
| 309 | − else if (jiffs < 357) | |
| 310 | − ifr->ifr_mtu = SDLA_CPU_7M; | |
| 311 | − else if (jiffs < 467) | |
| 312 | − ifr->ifr_mtu = SDLA_CPU_5M; | |
| 313 | − else | |
| 314 | − ifr->ifr_mtu = SDLA_CPU_3M; | |
| 315 | − | |
| 316 | − return 0; | |
| 317 | −} | |
| 318 | − | |
| 319 | −/************************************************ | |
| 320 | − * | |
| 321 | − * Direct interaction with the Frame Relay code | |
| 322 | − * starts here. | |
| 323 | − * | |
| 324 | − ************************************************/ | |
| 325 | − | |
| 326 | −struct _dlci_stat | |
| 327 | −{ | |
| 328 | − short dlci; | |
| 329 | − char flags; | |
| 330 | −} __packed; | |
| 331 | − | |
| 332 | −struct _frad_stat | |
| 333 | −{ | |
| 334 | − char flags; | |
| 335 | − struct _dlci_stat dlcis[SDLA_MAX_DLCI]; | |
| 336 | −}; | |
| 337 | − | |
| 338 | −static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int len, void *data) | |
| 339 | −{ | |
| 340 | − struct _dlci_stat *pstatus; | |
| 341 | − short *pdlci; | |
| 342 | − int i; | |
| 343 | − char *state, line[30]; | |
| 344 | − | |
| 345 | − switch (ret) | |
| 346 | − { | |
| 347 | − case SDLA_RET_MODEM: | |
| 348 | − state = data; | |
| 349 | − if (*state & SDLA_MODEM_DCD_LOW) | |
| 350 | − netdev_info(dev, "Modem DCD unexpectedly low!\n"); | |
| 351 | − if (*state & SDLA_MODEM_CTS_LOW) | |
| 352 | − netdev_info(dev, "Modem CTS unexpectedly low!\n"); | |
| 353 | − /* I should probably do something about this! */ | |
| 354 | − break; | |
| 355 | − | |
| 356 | − case SDLA_RET_CHANNEL_OFF: | |
| 357 | − netdev_info(dev, "Channel became inoperative!\n"); | |
| 358 | − /* same here */ | |
| 359 | − break; | |
| 360 | − | |
| 361 | − case SDLA_RET_CHANNEL_ON: | |
| 362 | − netdev_info(dev, "Channel became operative!\n"); | |
| 363 | − /* same here */ | |
| 364 | − break; | |
| 365 | − | |
| 366 | − case SDLA_RET_DLCI_STATUS: | |
| 367 | − netdev_info(dev, "Status change reported by Access Node\n"); | |
| 368 | − len /= sizeof(struct _dlci_stat); | |
| 369 | − for(pstatus = data, i=0;i < len;i++,pstatus++) | |
| 370 | − { | |
| 371 | − if (pstatus->flags & SDLA_DLCI_NEW) | |
| 372 | − state = "new"; | |
| 373 | − else if (pstatus->flags & SDLA_DLCI_DELETED) | |
| 374 | − state = "deleted"; | |
| 375 | − else if (pstatus->flags & SDLA_DLCI_ACTIVE) | |
| 376 | − state = "active"; | |
| 377 | − else | |
| 378 | − { | |
| 379 | − sprintf(line, "unknown status: %02X", pstatus->flags); | |
| 380 | − state = line; | |
| 381 | − } | |
| 382 | − netdev_info(dev, "DLCI %i: %s\n", | |
| 383 | − pstatus->dlci, state); | |
| 384 | − /* same here */ | |
| 385 | − } | |
| 386 | − break; | |
| 387 | − | |
| 388 | − case SDLA_RET_DLCI_UNKNOWN: | |
| 389 | − netdev_info(dev, "Received unknown DLCIs:"); | |
| 390 | − len /= sizeof(short); | |
| 391 | − for(pdlci = data,i=0;i < len;i++,pdlci++) | |
| 392 | − pr_cont(" %i", *pdlci); | |
| 393 | − pr_cont("\n"); | |
| 394 | − break; | |
| 395 | − | |
| 396 | − case SDLA_RET_TIMEOUT: | |
| 397 | − netdev_err(dev, "Command timed out!\n"); | |
| 398 | − break; | |
| 399 | − | |
| 400 | − case SDLA_RET_BUF_OVERSIZE: | |
| 401 | − netdev_info(dev, "Bc/CIR overflow, acceptable size is %i\n", | |
| 402 | − len); | |
| 403 | − break; | |
| 404 | − | |
| 405 | − case SDLA_RET_BUF_TOO_BIG: | |
| 406 | − netdev_info(dev, "Buffer size over specified max of %i\n", | |
| 407 | − len); | |
| 408 | − break; | |
| 409 | − | |
| 410 | − case SDLA_RET_CHANNEL_INACTIVE: | |
| 411 | − case SDLA_RET_DLCI_INACTIVE: | |
| 412 | − case SDLA_RET_CIR_OVERFLOW: | |
| 413 | − case SDLA_RET_NO_BUFS: | |
| 414 | − if (cmd == SDLA_INFORMATION_WRITE) | |
| 415 | − break; | |
| 416 | − fallthrough; | |
| 417 | − | |
| 418 | − default: | |
| 419 | − netdev_dbg(dev, "Cmd 0x%02X generated return code 0x%02X\n", | |
| 420 | − cmd, ret); | |
| 421 | − /* Further processing could be done here */ | |
| 422 | − break; | |
| 423 | − } | |
| 424 | −} | |
| 425 | − | |
| 426 | −static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, | |
| 427 | − void *inbuf, short inlen, void *outbuf, short *outlen) | |
| 428 | −{ | |
| 429 | − static struct _frad_stat status; | |
| 430 | − struct frad_local *flp; | |
| 431 | − struct sdla_cmd *cmd_buf; | |
| 432 | − unsigned long pflags; | |
| 433 | − unsigned long jiffs; | |
| 434 | − int ret, waiting, len; | |
| 435 | − long window; | |
| 436 | − | |
| 437 | − flp = netdev_priv(dev); | |
| 438 | − window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF; | |
| 439 | − cmd_buf = (struct sdla_cmd *)(dev->mem_start + (window & SDLA_ADDR_MASK)); | |
| 440 | − ret = 0; | |
| 441 | − len = 0; | |
| 442 | − jiffs = jiffies + HZ; /* 1 second is plenty */ | |
| 443 | − | |
| 444 | − spin_lock_irqsave(&sdla_lock, pflags); | |
| 445 | − SDLA_WINDOW(dev, window); | |
| 446 | − cmd_buf->cmd = cmd; | |
| 447 | − cmd_buf->dlci = dlci; | |
| 448 | − cmd_buf->flags = flags; | |
| 449 | − | |
| 450 | − if (inbuf) | |
| 451 | − memcpy(cmd_buf->data, inbuf, inlen); | |
| 452 | − | |
| 453 | − cmd_buf->length = inlen; | |
| 454 | − | |
| 455 | − cmd_buf->opp_flag = 1; | |
| 456 | − spin_unlock_irqrestore(&sdla_lock, pflags); | |
| 457 | − | |
| 458 | − waiting = 1; | |
| 459 | − len = 0; | |
| 460 | − while (waiting && time_before_eq(jiffies, jiffs)) | |
| 461 | − { | |
| 462 | − if (waiting++ % 3) | |
| 463 | − { | |
| 464 | − spin_lock_irqsave(&sdla_lock, pflags); | |
| 465 | − SDLA_WINDOW(dev, window); | |
| 466 | − waiting = ((volatile int)(cmd_buf->opp_flag)); | |
| 467 | − spin_unlock_irqrestore(&sdla_lock, pflags); | |
| 468 | − } | |
| 469 | − } | |
| 470 | − | |
| 471 | − if (!waiting) | |
| 472 | − { | |
| 473 | − | |
| 474 | − spin_lock_irqsave(&sdla_lock, pflags); | |
| 475 | − SDLA_WINDOW(dev, window); | |
| 476 | − ret = cmd_buf->retval; | |
| 477 | − len = cmd_buf->length; | |
| 478 | − if (outbuf && outlen) | |
| 479 | − { | |
| 480 | − *outlen = *outlen >= len ? len : *outlen; | |
| 481 | − | |
| 482 | − if (*outlen) | |
| 483 | − memcpy(outbuf, cmd_buf->data, *outlen); | |
| 484 | − } | |
| 485 | − | |
| 486 | − /* This is a local copy that's used for error handling */ | |
| 487 | − if (ret) | |
| 488 | − memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len); | |
| 489 | − | |
| 490 | − spin_unlock_irqrestore(&sdla_lock, pflags); | |
| 491 | − } | |
| 492 | − else | |
| 493 | − ret = SDLA_RET_TIMEOUT; | |
| 494 | − | |
| 495 | − if (ret != SDLA_RET_OK) | |
| 496 | − sdla_errors(dev, cmd, dlci, ret, len, &status); | |
| 497 | − | |
| 498 | − return ret; | |
| 499 | −} | |
| 500 | − | |
| 501 | −/*********************************************** | |
| 502 | − * | |
| 503 | − * these functions are called by the DLCI driver | |
| 504 | − * | |
| 505 | − ***********************************************/ | |
| 506 | − | |
| 507 | −static int sdla_reconfig(struct net_device *dev); | |
| 508 | − | |
| 509 | −static int sdla_activate(struct net_device *slave, struct net_device *master) | |
| 510 | −{ | |
| 511 | − struct frad_local *flp; | |
| 512 | − int i; | |
| 513 | − | |
| 514 | − flp = netdev_priv(slave); | |
| 515 | − | |
| 516 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 517 | − if (flp->master[i] == master) | |
| 518 | − break; | |
| 519 | − | |
| 520 | − if (i == CONFIG_DLCI_MAX) | |
| 521 | − return -ENODEV; | |
| 522 | − | |
| 523 | − flp->dlci[i] = abs(flp->dlci[i]); | |
| 524 | − | |
| 525 | − if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) | |
| 526 | − sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); | |
| 527 | − | |
| 528 | − return 0; | |
| 529 | −} | |
| 530 | − | |
| 531 | −static int sdla_deactivate(struct net_device *slave, struct net_device *master) | |
| 532 | −{ | |
| 533 | − struct frad_local *flp; | |
| 534 | − int i; | |
| 535 | − | |
| 536 | − flp = netdev_priv(slave); | |
| 537 | − | |
| 538 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 539 | − if (flp->master[i] == master) | |
| 540 | − break; | |
| 541 | − | |
| 542 | − if (i == CONFIG_DLCI_MAX) | |
| 543 | − return -ENODEV; | |
| 544 | − | |
| 545 | − flp->dlci[i] = -abs(flp->dlci[i]); | |
| 546 | − | |
| 547 | − if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) | |
| 548 | − sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); | |
| 549 | − | |
| 550 | − return 0; | |
| 551 | −} | |
| 552 | − | |
| 553 | −static int sdla_assoc(struct net_device *slave, struct net_device *master) | |
| 554 | −{ | |
| 555 | − struct frad_local *flp; | |
| 556 | − int i; | |
| 557 | − | |
| 558 | − if (master->type != ARPHRD_DLCI) | |
| 559 | − return -EINVAL; | |
| 560 | − | |
| 561 | − flp = netdev_priv(slave); | |
| 562 | − | |
| 563 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 564 | − { | |
| 565 | − if (!flp->master[i]) | |
| 566 | − break; | |
| 567 | − if (abs(flp->dlci[i]) == *(short *)(master->dev_addr)) | |
| 568 | − return -EADDRINUSE; | |
| 569 | − } | |
| 570 | − | |
| 571 | − if (i == CONFIG_DLCI_MAX) | |
| 572 | − return -EMLINK; /* #### Alan: Comments on this ?? */ | |
| 573 | − | |
| 574 | − | |
| 575 | − flp->master[i] = master; | |
| 576 | − flp->dlci[i] = -*(short *)(master->dev_addr); | |
| 577 | − master->mtu = slave->mtu; | |
| 578 | − | |
| 579 | − if (netif_running(slave)) { | |
| 580 | − if (flp->config.station == FRAD_STATION_CPE) | |
| 581 | − sdla_reconfig(slave); | |
| 582 | − else | |
| 583 | − sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); | |
| 584 | − } | |
| 585 | − | |
| 586 | − return 0; | |
| 587 | −} | |
| 588 | − | |
| 589 | −static int sdla_deassoc(struct net_device *slave, struct net_device *master) | |
| 590 | −{ | |
| 591 | − struct frad_local *flp; | |
| 592 | − int i; | |
| 593 | − | |
| 594 | − flp = netdev_priv(slave); | |
| 595 | − | |
| 596 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 597 | − if (flp->master[i] == master) | |
| 598 | − break; | |
| 599 | − | |
| 600 | − if (i == CONFIG_DLCI_MAX) | |
| 601 | − return -ENODEV; | |
| 602 | − | |
| 603 | − flp->master[i] = NULL; | |
| 604 | − flp->dlci[i] = 0; | |
| 605 | − | |
| 606 | − | |
| 607 | − if (netif_running(slave)) { | |
| 608 | − if (flp->config.station == FRAD_STATION_CPE) | |
| 609 | − sdla_reconfig(slave); | |
| 610 | − else | |
| 611 | − sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); | |
| 612 | − } | |
| 613 | − | |
| 614 | − return 0; | |
| 615 | −} | |
| 616 | − | |
| 617 | −static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) | |
| 618 | −{ | |
| 619 | − struct frad_local *flp; | |
| 620 | − struct dlci_local *dlp; | |
| 621 | − int i; | |
| 622 | − short len, ret; | |
| 623 | − | |
| 624 | − flp = netdev_priv(slave); | |
| 625 | − | |
| 626 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 627 | − if (flp->master[i] == master) | |
| 628 | − break; | |
| 629 | − | |
| 630 | − if (i == CONFIG_DLCI_MAX) | |
| 631 | − return -ENODEV; | |
| 632 | − | |
| 633 | − dlp = netdev_priv(master); | |
| 634 | − | |
| 635 | − ret = SDLA_RET_OK; | |
| 636 | − len = sizeof(struct dlci_conf); | |
| 637 | − if (netif_running(slave)) { | |
| 638 | − if (get) | |
| 639 | − ret = sdla_cmd(slave, SDLA_READ_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, | |
| 640 | − NULL, 0, &dlp->config, &len); | |
| 641 | − else | |
| 642 | − ret = sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, | |
| 643 | − &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL); | |
| 644 | − } | |
| 645 | − | |
| 646 | − return ret == SDLA_RET_OK ? 0 : -EIO; | |
| 647 | −} | |
| 648 | − | |
| 649 | −/************************** | |
| 650 | − * | |
| 651 | − * now for the Linux driver | |
| 652 | − * | |
| 653 | − **************************/ | |
| 654 | − | |
| 655 | −/* NOTE: the DLCI driver deals with freeing the SKB!! */ | |
| 656 | −static netdev_tx_t sdla_transmit(struct sk_buff *skb, | |
| 657 | − struct net_device *dev) | |
| 658 | −{ | |
| 659 | − struct frad_local *flp; | |
| 660 | − int ret, addr, accept, i; | |
| 661 | − short size; | |
| 662 | − unsigned long flags; | |
| 663 | − struct buf_entry *pbuf; | |
| 664 | − | |
| 665 | − flp = netdev_priv(dev); | |
| 666 | − ret = 0; | |
| 667 | − accept = 1; | |
| 668 | − | |
| 669 | − netif_stop_queue(dev); | |
| 670 | − | |
| 671 | − /* | |
| 672 | − * stupid GateD insists on setting up the multicast router thru us | |
| 673 | − * and we're ill equipped to handle a non Frame Relay packet at this | |
| 674 | − * time! | |
| 675 | − */ | |
| 676 | − | |
| 677 | − accept = 1; | |
| 678 | − switch (dev->type) | |
| 679 | − { | |
| 680 | − case ARPHRD_FRAD: | |
| 681 | − if (skb->dev->type != ARPHRD_DLCI) | |
| 682 | − { | |
| 683 | − netdev_warn(dev, "Non DLCI device, type %i, tried to send on FRAD module\n", | |
| 684 | − skb->dev->type); | |
| 685 | − accept = 0; | |
| 686 | − } | |
| 687 | − break; | |
| 688 | − default: | |
| 689 | − netdev_warn(dev, "unknown firmware type 0x%04X\n", | |
| 690 | − dev->type); | |
| 691 | − accept = 0; | |
| 692 | − break; | |
| 693 | − } | |
| 694 | − if (accept) | |
| 695 | − { | |
| 696 | − /* this is frame specific, but till there's a PPP module, it's the default */ | |
| 697 | − switch (flp->type) | |
| 698 | − { | |
| 699 | − case SDLA_S502A: | |
| 700 | − case SDLA_S502E: | |
| 701 | − ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL); | |
| 702 | − break; | |
| 703 | − case SDLA_S508: | |
| 704 | − size = sizeof(addr); | |
| 705 | − ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size); | |
| 706 | − if (ret == SDLA_RET_OK) | |
| 707 | − { | |
| 708 | − | |
| 709 | − spin_lock_irqsave(&sdla_lock, flags); | |
| 710 | − SDLA_WINDOW(dev, addr); | |
| 711 | − pbuf = (void *)(dev->mem_start + (addr & SDLA_ADDR_MASK)); | |
| 712 | − __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); | |
| 713 | − SDLA_WINDOW(dev, addr); | |
| 714 | − pbuf->opp_flag = 1; | |
| 715 | − spin_unlock_irqrestore(&sdla_lock, flags); | |
| 716 | − } | |
| 717 | − break; | |
| 718 | − } | |
| 719 | − | |
| 720 | − switch (ret) | |
| 721 | − { | |
| 722 | − case SDLA_RET_OK: | |
| 723 | − dev->stats.tx_packets++; | |
| 724 | − break; | |
| 725 | − | |
| 726 | − case SDLA_RET_CIR_OVERFLOW: | |
| 727 | − case SDLA_RET_BUF_OVERSIZE: | |
| 728 | − case SDLA_RET_NO_BUFS: | |
| 729 | − dev->stats.tx_dropped++; | |
| 730 | − break; | |
| 731 | − | |
| 732 | − default: | |
| 733 | − dev->stats.tx_errors++; | |
| 734 | − break; | |
| 735 | − } | |
| 736 | − } | |
| 737 | − netif_wake_queue(dev); | |
| 738 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 739 | − { | |
| 740 | − if(flp->master[i]!=NULL) | |
| 741 | − netif_wake_queue(flp->master[i]); | |
| 742 | − } | |
| 743 | − | |
| 744 | − dev_kfree_skb(skb); | |
| 745 | − return NETDEV_TX_OK; | |
| 746 | −} | |
| 747 | − | |
| 748 | −static void sdla_receive(struct net_device *dev) | |
| 749 | −{ | |
| 750 | − struct net_device *master; | |
| 751 | − struct frad_local *flp; | |
| 752 | − struct dlci_local *dlp; | |
| 753 | − struct sk_buff *skb; | |
| 754 | − | |
| 755 | − struct sdla_cmd *cmd; | |
| 756 | − struct buf_info *pbufi; | |
| 757 | − struct buf_entry *pbuf; | |
| 758 | − | |
| 759 | − unsigned long flags; | |
| 760 | − int i=0, received, success, addr, buf_base, buf_top; | |
| 761 | − short dlci, len, len2, split; | |
| 762 | − | |
| 763 | − flp = netdev_priv(dev); | |
| 764 | − success = 1; | |
| 765 | − received = addr = buf_top = buf_base = 0; | |
| 766 | − len = dlci = 0; | |
| 767 | − skb = NULL; | |
| 768 | − master = NULL; | |
| 769 | − cmd = NULL; | |
| 770 | − pbufi = NULL; | |
| 771 | − pbuf = NULL; | |
| 772 | − | |
| 773 | − spin_lock_irqsave(&sdla_lock, flags); | |
| 774 | − | |
| 775 | − switch (flp->type) | |
| 776 | − { | |
| 777 | − case SDLA_S502A: | |
| 778 | − case SDLA_S502E: | |
| 779 | − cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & SDLA_ADDR_MASK)); | |
| 780 | − SDLA_WINDOW(dev, SDLA_502_RCV_BUF); | |
| 781 | − success = cmd->opp_flag; | |
| 782 | − if (!success) | |
| 783 | − break; | |
| 784 | − | |
| 785 | − dlci = cmd->dlci; | |
| 786 | − len = cmd->length; | |
| 787 | − break; | |
| 788 | − | |
| 789 | − case SDLA_S508: | |
| 790 | − pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & SDLA_ADDR_MASK)); | |
| 791 | − SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO); | |
| 792 | − pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & SDLA_ADDR_MASK)); | |
| 793 | − success = pbuf->opp_flag; | |
| 794 | − if (!success) | |
| 795 | − break; | |
| 796 | − | |
| 797 | − buf_top = pbufi->buf_top; | |
| 798 | − buf_base = pbufi->buf_base; | |
| 799 | − dlci = pbuf->dlci; | |
| 800 | − len = pbuf->length; | |
| 801 | − addr = pbuf->buf_addr; | |
| 802 | − break; | |
| 803 | − } | |
| 804 | − | |
| 805 | − /* common code, find the DLCI and get the SKB */ | |
| 806 | − if (success) | |
| 807 | − { | |
| 808 | − for (i=0;i<CONFIG_DLCI_MAX;i++) | |
| 809 | − if (flp->dlci[i] == dlci) | |
| 810 | − break; | |
| 811 | − | |
| 812 | − if (i == CONFIG_DLCI_MAX) | |
| 813 | − { | |
| 814 | − netdev_notice(dev, "Received packet from invalid DLCI %i, ignoring\n", | |
| 815 | − dlci); | |
| 816 | − dev->stats.rx_errors++; | |
| 817 | − success = 0; | |
| 818 | − } | |
| 819 | − } | |
| 820 | − | |
| 821 | − if (success) | |
| 822 | − { | |
| 823 | − master = flp->master[i]; | |
| 824 | − skb = dev_alloc_skb(len + sizeof(struct frhdr)); | |
| 825 | − if (skb == NULL) | |
| 826 | − { | |
| 827 | − netdev_notice(dev, "Memory squeeze, dropping packet\n"); | |
| 828 | − dev->stats.rx_dropped++; | |
| 829 | − success = 0; | |
| 830 | − } | |
| 831 | − else | |
| 832 | − skb_reserve(skb, sizeof(struct frhdr)); | |
| 833 | − } | |
| 834 | − | |
| 835 | − /* pick up the data */ | |
| 836 | − switch (flp->type) | |
| 837 | − { | |
| 838 | − case SDLA_S502A: | |
| 839 | − case SDLA_S502E: | |
| 840 | − if (success) | |
| 841 | − __sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len); | |
| 842 | − | |
| 843 | − SDLA_WINDOW(dev, SDLA_502_RCV_BUF); | |
| 844 | − cmd->opp_flag = 0; | |
| 845 | − break; | |
| 846 | − | |
| 847 | − case SDLA_S508: | |
| 848 | − if (success) | |
| 849 | − { | |
| 850 | − /* is this buffer split off the end of the internal ring buffer */ | |
| 851 | − split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0; | |
| 852 | − len2 = len - split; | |
| 853 | − | |
| 854 | − __sdla_read(dev, addr, skb_put(skb, len2), len2); | |
| 855 | − if (split) | |
| 856 | − __sdla_read(dev, buf_base, skb_put(skb, split), split); | |
| 857 | − } | |
| 858 | − | |
| 859 | − /* increment the buffer we're looking at */ | |
| 860 | − SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO); | |
| 861 | − flp->buffer = (flp->buffer + 1) % pbufi->rse_num; | |
| 862 | − pbuf->opp_flag = 0; | |
| 863 | − break; | |
| 864 | − } | |
| 865 | − | |
| 866 | − if (success) | |
| 867 | − { | |
| 868 | − dev->stats.rx_packets++; | |
| 869 | − dlp = netdev_priv(master); | |
| 870 | − (*dlp->receive)(skb, master); | |
| 871 | − } | |
| 872 | − | |
| 873 | − spin_unlock_irqrestore(&sdla_lock, flags); | |
| 874 | −} | |
| 875 | − | |
| 876 | −static irqreturn_t sdla_isr(int dummy, void *dev_id) | |
| 877 | −{ | |
| 878 | − struct net_device *dev; | |
| 879 | − struct frad_local *flp; | |
| 880 | − char byte; | |
| 881 | − | |
| 882 | − dev = dev_id; | |
| 883 | − | |
| 884 | − flp = netdev_priv(dev); | |
| 885 | − | |
| 886 | − if (!flp->initialized) | |
| 887 | − { | |
| 888 | − netdev_warn(dev, "irq %d for uninitialized device\n", dev->irq); | |
| 889 | − return IRQ_NONE; | |
| 890 | − } | |
| 891 | − | |
| 892 | − byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE); | |
| 893 | − switch (byte) | |
| 894 | − { | |
| 895 | − case SDLA_INTR_RX: | |
| 896 | − sdla_receive(dev); | |
| 897 | − break; | |
| 898 | − | |
| 899 | − /* the command will get an error return, which is processed above */ | |
| 900 | − case SDLA_INTR_MODEM: | |
| 901 | − case SDLA_INTR_STATUS: | |
| 902 | − sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL); | |
| 903 | − break; | |
| 904 | − | |
| 905 | − case SDLA_INTR_TX: | |
| 906 | − case SDLA_INTR_COMPLETE: | |
| 907 | − case SDLA_INTR_TIMER: | |
| 908 | − netdev_warn(dev, "invalid irq flag 0x%02X\n", byte); | |
| 909 | − break; | |
| 910 | − } | |
| 911 | − | |
| 912 | − /* the S502E requires a manual acknowledgement of the interrupt */ | |
| 913 | − if (flp->type == SDLA_S502E) | |
| 914 | − { | |
| 915 | − flp->state &= ~SDLA_S502E_INTACK; | |
| 916 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 917 | − flp->state |= SDLA_S502E_INTACK; | |
| 918 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 919 | − } | |
| 920 | − | |
| 921 | − /* this clears the byte, informing the Z80 we're done */ | |
| 922 | − byte = 0; | |
| 923 | − sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte)); | |
| 924 | − return IRQ_HANDLED; | |
| 925 | −} | |
| 926 | − | |
| 927 | −static void sdla_poll(struct timer_list *t) | |
| 928 | −{ | |
| 929 | − struct frad_local *flp = from_timer(flp, t, timer); | |
| 930 | − struct net_device *dev = flp->dev; | |
| 931 | − | |
| 932 | − if (sdla_byte(dev, SDLA_502_RCV_BUF)) | |
| 933 | − sdla_receive(dev); | |
| 934 | − | |
| 935 | − flp->timer.expires = 1; | |
| 936 | − add_timer(&flp->timer); | |
| 937 | −} | |
| 938 | − | |
| 939 | −static int sdla_close(struct net_device *dev) | |
| 940 | −{ | |
| 941 | − struct frad_local *flp; | |
| 942 | − struct intr_info intr; | |
| 943 | − int len, i; | |
| 944 | − short dlcis[CONFIG_DLCI_MAX]; | |
| 945 | − | |
| 946 | − flp = netdev_priv(dev); | |
| 947 | − | |
| 948 | − len = 0; | |
| 949 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 950 | − if (flp->dlci[i]) | |
| 951 | − dlcis[len++] = abs(flp->dlci[i]); | |
| 952 | − len *= 2; | |
| 953 | − | |
| 954 | − if (flp->config.station == FRAD_STATION_NODE) | |
| 955 | − { | |
| 956 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 957 | − if (flp->dlci[i] > 0) | |
| 958 | − sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL); | |
| 959 | − sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL); | |
| 960 | − } | |
| 961 | − | |
| 962 | − memset(&intr, 0, sizeof(intr)); | |
| 963 | − /* let's start up the reception */ | |
| 964 | − switch(flp->type) | |
| 965 | − { | |
| 966 | − case SDLA_S502A: | |
| 967 | − del_timer(&flp->timer); | |
| 968 | − break; | |
| 969 | − | |
| 970 | − case SDLA_S502E: | |
| 971 | − sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL); | |
| 972 | − flp->state &= ~SDLA_S502E_INTACK; | |
| 973 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 974 | − break; | |
| 975 | − | |
| 976 | − case SDLA_S507: | |
| 977 | − break; | |
| 978 | − | |
| 979 | − case SDLA_S508: | |
| 980 | − sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL); | |
| 981 | − flp->state &= ~SDLA_S508_INTEN; | |
| 982 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 983 | − break; | |
| 984 | − } | |
| 985 | − | |
| 986 | − sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); | |
| 987 | − | |
| 988 | − netif_stop_queue(dev); | |
| 989 | − | |
| 990 | − return 0; | |
| 991 | −} | |
| 992 | − | |
| 993 | −struct conf_data { | |
| 994 | − struct frad_conf config; | |
| 995 | − short dlci[CONFIG_DLCI_MAX]; | |
| 996 | −}; | |
| 997 | − | |
| 998 | −static int sdla_open(struct net_device *dev) | |
| 999 | −{ | |
| 1000 | − struct frad_local *flp; | |
| 1001 | − struct dlci_local *dlp; | |
| 1002 | − struct conf_data data; | |
| 1003 | − struct intr_info intr; | |
| 1004 | − int len, i; | |
| 1005 | − char byte; | |
| 1006 | − | |
| 1007 | − flp = netdev_priv(dev); | |
| 1008 | − | |
| 1009 | − if (!flp->initialized) | |
| 1010 | − return -EPERM; | |
| 1011 | − | |
| 1012 | − if (!flp->configured) | |
| 1013 | − return -EPERM; | |
| 1014 | − | |
| 1015 | − /* time to send in the configuration */ | |
| 1016 | − len = 0; | |
| 1017 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 1018 | − if (flp->dlci[i]) | |
| 1019 | − data.dlci[len++] = abs(flp->dlci[i]); | |
| 1020 | − len *= 2; | |
| 1021 | − | |
| 1022 | − memcpy(&data.config, &flp->config, sizeof(struct frad_conf)); | |
| 1023 | − len += sizeof(struct frad_conf); | |
| 1024 | − | |
| 1025 | − sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); | |
| 1026 | − sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL); | |
| 1027 | − | |
| 1028 | − if (flp->type == SDLA_S508) | |
| 1029 | − flp->buffer = 0; | |
| 1030 | − | |
| 1031 | − sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); | |
| 1032 | − | |
| 1033 | − /* let's start up the reception */ | |
| 1034 | − memset(&intr, 0, sizeof(intr)); | |
| 1035 | − switch(flp->type) | |
| 1036 | − { | |
| 1037 | − case SDLA_S502A: | |
| 1038 | − flp->timer.expires = 1; | |
| 1039 | − add_timer(&flp->timer); | |
| 1040 | − break; | |
| 1041 | − | |
| 1042 | − case SDLA_S502E: | |
| 1043 | − flp->state |= SDLA_S502E_ENABLE; | |
| 1044 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 1045 | − flp->state |= SDLA_S502E_INTACK; | |
| 1046 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 1047 | − byte = 0; | |
| 1048 | − sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte)); | |
| 1049 | − intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM; | |
| 1050 | − sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL); | |
| 1051 | − break; | |
| 1052 | − | |
| 1053 | − case SDLA_S507: | |
| 1054 | − break; | |
| 1055 | − | |
| 1056 | − case SDLA_S508: | |
| 1057 | − flp->state |= SDLA_S508_INTEN; | |
| 1058 | − outb(flp->state, dev->base_addr + SDLA_REG_CONTROL); | |
| 1059 | − byte = 0; | |
| 1060 | − sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte)); | |
| 1061 | − intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM; | |
| 1062 | − intr.irq = dev->irq; | |
| 1063 | − sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL); | |
| 1064 | − break; | |
| 1065 | − } | |
| 1066 | − | |
| 1067 | − if (flp->config.station == FRAD_STATION_CPE) | |
| 1068 | − { | |
| 1069 | − byte = SDLA_ICS_STATUS_ENQ; | |
| 1070 | − sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL); | |
| 1071 | − } | |
| 1072 | − else | |
| 1073 | − { | |
| 1074 | − sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL); | |
| 1075 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 1076 | − if (flp->dlci[i] > 0) | |
| 1077 | − sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL); | |
| 1078 | − } | |
| 1079 | − | |
| 1080 | − /* configure any specific DLCI settings */ | |
| 1081 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 1082 | − if (flp->dlci[i]) | |
| 1083 | − { | |
| 1084 | − dlp = netdev_priv(flp->master[i]); | |
| 1085 | − if (dlp->configured) | |
| 1086 | − sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL); | |
| 1087 | − } | |
| 1088 | − | |
| 1089 | − netif_start_queue(dev); | |
| 1090 | − | |
| 1091 | − return 0; | |
| 1092 | −} | |
| 1093 | − | |
| 1094 | −static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get) | |
| 1095 | −{ | |
| 1096 | − struct frad_local *flp; | |
| 1097 | − struct conf_data data; | |
| 1098 | − int i; | |
| 1099 | − short size; | |
| 1100 | − | |
| 1101 | − if (dev->type == 0xFFFF) | |
| 1102 | − return -EUNATCH; | |
| 1103 | − | |
| 1104 | − flp = netdev_priv(dev); | |
| 1105 | − | |
| 1106 | − if (!get) | |
| 1107 | − { | |
| 1108 | − if (netif_running(dev)) | |
| 1109 | − return -EBUSY; | |
| 1110 | − | |
| 1111 | − if(copy_from_user(&data.config, conf, sizeof(struct frad_conf))) | |
| 1112 | − return -EFAULT; | |
| 1113 | − | |
| 1114 | − if (data.config.station & ~FRAD_STATION_NODE) | |
| 1115 | − return -EINVAL; | |
| 1116 | − | |
| 1117 | − if (data.config.flags & ~FRAD_VALID_FLAGS) | |
| 1118 | − return -EINVAL; | |
| 1119 | − | |
| 1120 | − if ((data.config.kbaud < 0) || | |
| 1121 | − ((data.config.kbaud > 128) && (flp->type != SDLA_S508))) | |
| 1122 | − return -EINVAL; | |
| 1123 | − | |
| 1124 | − if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232)) | |
| 1125 | − return -EINVAL; | |
| 1126 | − | |
| 1127 | − if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU)) | |
| 1128 | − return -EINVAL; | |
| 1129 | − | |
| 1130 | − if ((data.config.T391 < 5) || (data.config.T391 > 30)) | |
| 1131 | − return -EINVAL; | |
| 1132 | − | |
| 1133 | − if ((data.config.T392 < 5) || (data.config.T392 > 30)) | |
| 1134 | − return -EINVAL; | |
| 1135 | − | |
| 1136 | − if ((data.config.N391 < 1) || (data.config.N391 > 255)) | |
| 1137 | − return -EINVAL; | |
| 1138 | − | |
| 1139 | − if ((data.config.N392 < 1) || (data.config.N392 > 10)) | |
| 1140 | − return -EINVAL; | |
| 1141 | − | |
| 1142 | − if ((data.config.N393 < 1) || (data.config.N393 > 10)) | |
| 1143 | − return -EINVAL; | |
| 1144 | − | |
| 1145 | − memcpy(&flp->config, &data.config, sizeof(struct frad_conf)); | |
| 1146 | − flp->config.flags |= SDLA_DIRECT_RECV; | |
| 1147 | − | |
| 1148 | − if (flp->type == SDLA_S508) | |
| 1149 | − flp->config.flags |= SDLA_TX70_RX30; | |
| 1150 | − | |
| 1151 | − if (dev->mtu != flp->config.mtu) | |
| 1152 | − { | |
| 1153 | − /* this is required to change the MTU */ | |
| 1154 | − dev->mtu = flp->config.mtu; | |
| 1155 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 1156 | − if (flp->master[i]) | |
| 1157 | − flp->master[i]->mtu = flp->config.mtu; | |
| 1158 | − } | |
| 1159 | − | |
| 1160 | − flp->config.mtu += sizeof(struct frhdr); | |
| 1161 | − | |
| 1162 | − /* off to the races! */ | |
| 1163 | − if (!flp->configured) | |
| 1164 | − sdla_start(dev); | |
| 1165 | − | |
| 1166 | − flp->configured = 1; | |
| 1167 | − } | |
| 1168 | − else | |
| 1169 | − { | |
| 1170 | − /* no sense reading if the CPU isn't started */ | |
| 1171 | − if (netif_running(dev)) | |
| 1172 | − { | |
| 1173 | − size = sizeof(data); | |
| 1174 | − if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK) | |
| 1175 | − return -EIO; | |
| 1176 | − } | |
| 1177 | − else | |
| 1178 | − if (flp->configured) | |
| 1179 | − memcpy(&data.config, &flp->config, sizeof(struct frad_conf)); | |
| 1180 | − else | |
| 1181 | − memset(&data.config, 0, sizeof(struct frad_conf)); | |
| 1182 | − | |
| 1183 | − memcpy(&flp->config, &data.config, sizeof(struct frad_conf)); | |
| 1184 | − data.config.flags &= FRAD_VALID_FLAGS; | |
| 1185 | − data.config.mtu -= data.config.mtu > sizeof(struct frhdr) ? sizeof(struct frhdr) : data.config.mtu; | |
| 1186 | − return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0; | |
| 1187 | − } | |
| 1188 | − | |
| 1189 | − return 0; | |
| 1190 | −} | |
| 1191 | − | |
| 1192 | −static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read) | |
| 1193 | −{ | |
| 1194 | − struct sdla_mem mem; | |
| 1195 | − char *temp; | |
| 1196 | − | |
| 1197 | − if(copy_from_user(&mem, info, sizeof(mem))) | |
| 1198 | − return -EFAULT; | |
| 1199 | − | |
| 1200 | − if (read) | |
| 1201 | − { | |
| 1202 | − temp = kzalloc(mem.len, GFP_KERNEL); | |
| 1203 | − if (!temp) | |
| 1204 | − return -ENOMEM; | |
| 1205 | − sdla_read(dev, mem.addr, temp, mem.len); | |
| 1206 | − if(copy_to_user(mem.data, temp, mem.len)) | |
| 1207 | − { | |
| 1208 | − kfree(temp); | |
| 1209 | − return -EFAULT; | |
| 1210 | − } | |
| 1211 | − kfree(temp); | |
| 1212 | − } | |
| 1213 | − else | |
| 1214 | − { | |
| 1215 | − temp = memdup_user(mem.data, mem.len); | |
| 1216 | − if (IS_ERR(temp)) | |
| 1217 | − return PTR_ERR(temp); | |
| 1218 | − sdla_write(dev, mem.addr, temp, mem.len); | |
| 1219 | − kfree(temp); | |
| 1220 | − } | |
| 1221 | − return 0; | |
| 1222 | −} | |
| 1223 | − | |
| 1224 | −static int sdla_reconfig(struct net_device *dev) | |
| 1225 | −{ | |
| 1226 | − struct frad_local *flp; | |
| 1227 | − struct conf_data data; | |
| 1228 | − int i, len; | |
| 1229 | − | |
| 1230 | − flp = netdev_priv(dev); | |
| 1231 | − | |
| 1232 | − len = 0; | |
| 1233 | − for(i=0;i<CONFIG_DLCI_MAX;i++) | |
| 1234 | − if (flp->dlci[i]) | |
| 1235 | − data.dlci[len++] = flp->dlci[i]; | |
| 1236 | − len *= 2; | |
| 1237 | − | |
| 1238 | − memcpy(&data, &flp->config, sizeof(struct frad_conf)); | |
| 1239 | − len += sizeof(struct frad_conf); | |
| 1240 | − | |
| 1241 | − sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); | |
| 1242 | − sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL); | |
| 1243 | − sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); | |
| 1244 | − | |
| 1245 | − return 0; | |
| 1246 | −} | |
| 1247 | − | |
| 1248 | −static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |
| 1249 | −{ | |
| 1250 | − struct frad_local *flp; | |
| 1251 | − | |
| 1252 | − if(!capable(CAP_NET_ADMIN)) | |
| 1253 | − return -EPERM; | |
| 1254 | − | |
| 1255 | − flp = netdev_priv(dev); | |
| 1256 | − | |
| 1257 | − if (!flp->initialized) | |
| 1258 | − return -EINVAL; | |
| 1259 | − | |
| 1260 | − switch (cmd) | |
| 1261 | − { | |
| 1262 | − case FRAD_GET_CONF: | |
| 1263 | − case FRAD_SET_CONF: | |
| 1264 | − return sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF); | |
| 1265 | − | |
| 1266 | − case SDLA_IDENTIFY: | |
| 1267 | − ifr->ifr_flags = flp->type; | |
| 1268 | − break; | |
| 1269 | − | |
| 1270 | − case SDLA_CPUSPEED: | |
| 1271 | − return sdla_cpuspeed(dev, ifr); | |
| 1272 | − | |
| 1273 | −/* ========================================================== | |
| 1274 | −NOTE: This is rather a useless action right now, as the | |
| 1275 | − current driver does not support protocols other than | |
| 1276 | − FR. However, Sangoma has modules for a number of | |
| 1277 | − other protocols in the works. | |
| 1278 | −============================================================*/ | |
| 1279 | − case SDLA_PROTOCOL: | |
| 1280 | − if (flp->configured) | |
| 1281 | − return -EALREADY; | |
| 1282 | − | |
| 1283 | − switch (ifr->ifr_flags) | |
| 1284 | − { | |
| 1285 | − case ARPHRD_FRAD: | |
| 1286 | − dev->type = ifr->ifr_flags; | |
| 1287 | − break; | |
| 1288 | − default: | |
| 1289 | − return -ENOPROTOOPT; | |
| 1290 | − } | |
| 1291 | − break; | |
| 1292 | − | |
| 1293 | − case SDLA_CLEARMEM: | |
| 1294 | − sdla_clear(dev); | |
| 1295 | − break; | |
| 1296 | − | |
| 1297 | − case SDLA_WRITEMEM: | |
| 1298 | − case SDLA_READMEM: | |
| 1299 | − if(!capable(CAP_SYS_RAWIO)) | |
| 1300 | − return -EPERM; | |
| 1301 | − return sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM); | |
| 1302 | − | |
| 1303 | − case SDLA_START: | |
| 1304 | − sdla_start(dev); | |
| 1305 | − break; | |
| 1306 | − | |
| 1307 | − case SDLA_STOP: | |
| 1308 | − sdla_stop(dev); | |
| 1309 | − break; | |
| 1310 | − | |
| 1311 | − default: | |
| 1312 | − return -EOPNOTSUPP; | |
| 1313 | − } | |
| 1314 | − return 0; | |
| 1315 | −} | |
| 1316 | − | |
| 1317 | −static int sdla_change_mtu(struct net_device *dev, int new_mtu) | |
| 1318 | −{ | |
| 1319 | − if (netif_running(dev)) | |
| 1320 | − return -EBUSY; | |
| 1321 | − | |
| 1322 | − /* for now, you can't change the MTU! */ | |
| 1323 | − return -EOPNOTSUPP; | |
| 1324 | −} | |
| 1325 | − | |
| 1326 | −static int sdla_set_config(struct net_device *dev, struct ifmap *map) | |
| 1327 | −{ | |
| 1328 | − struct frad_local *flp; | |
| 1329 | − int i; | |
| 1330 | − char byte; | |
| 1331 | − unsigned base; | |
| 1332 | − int err = -EINVAL; | |
| 1333 | − | |
| 1334 | − flp = netdev_priv(dev); | |
| 1335 | − | |
| 1336 | − if (flp->initialized) | |
| 1337 | − return -EINVAL; | |
| 1338 | − | |
| 1339 | − for(i=0; i < ARRAY_SIZE(valid_port); i++) | |
| 1340 | − if (valid_port[i] == map->base_addr) | |
| 1341 | − break; | |
| 1342 | − | |
| 1343 | − if (i == ARRAY_SIZE(valid_port)) | |
| 1344 | − return -EINVAL; | |
| 1345 | − | |
| 1346 | − if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){ | |
| 1347 | − pr_warn("io-port 0x%04lx in use\n", dev->base_addr); | |
| 1348 | − return -EINVAL; | |
| 1349 | − } | |
| 1350 | − base = map->base_addr; | |
| 1351 | − | |
| 1352 | − /* test for card types, S502A, S502E, S507, S508 */ | |
| 1353 | − /* these tests shut down the card completely, so clear the state */ | |
| 1354 | − flp->type = SDLA_UNKNOWN; | |
| 1355 | − flp->state = 0; | |
| 1356 | − | |
| 1357 | − for(i=1;i<SDLA_IO_EXTENTS;i++) | |
| 1358 | − if (inb(base + i) != 0xFF) | |
| 1359 | − break; | |
| 1360 | − | |
| 1361 | − if (i == SDLA_IO_EXTENTS) { | |
| 1362 | − outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL); | |
| 1363 | − if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) { | |
| 1364 | − outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL); | |
| 1365 | − if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) { | |
| 1366 | − outb(SDLA_HALT, base + SDLA_REG_CONTROL); | |
| 1367 | − flp->type = SDLA_S502E; | |
| 1368 | − goto got_type; | |
| 1369 | − } | |
| 1370 | − } | |
| 1371 | − } | |
| 1372 | − | |
| 1373 | − for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++) | |
| 1374 | − if (inb(base + i) != byte) | |
| 1375 | − break; | |
| 1376 | − | |
| 1377 | − if (i == SDLA_IO_EXTENTS) { | |
| 1378 | − outb(SDLA_HALT, base + SDLA_REG_CONTROL); | |
| 1379 | − if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) { | |
| 1380 | − outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL); | |
| 1381 | − if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) { | |
| 1382 | − outb(SDLA_HALT, base + SDLA_REG_CONTROL); | |
| 1383 | − flp->type = SDLA_S507; | |
| 1384 | − goto got_type; | |
| 1385 | − } | |
| 1386 | − } | |
| 1387 | − } | |
| 1388 | − | |
| 1389 | − outb(SDLA_HALT, base + SDLA_REG_CONTROL); | |
| 1390 | − if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) { | |
| 1391 | − outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL); | |
| 1392 | − if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) { | |
| 1393 | − outb(SDLA_HALT, base + SDLA_REG_CONTROL); | |
| 1394 | − flp->type = SDLA_S508; | |
| 1395 | − goto got_type; | |
| 1396 | − } | |
| 1397 | − } | |
| 1398 | − | |
| 1399 | − outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL); | |
| 1400 | − if (inb(base + SDLA_S502_STS) == 0x40) { | |
| 1401 | − outb(SDLA_S502A_START, base + SDLA_REG_CONTROL); | |
| 1402 | − if (inb(base + SDLA_S502_STS) == 0x40) { | |
| 1403 | − outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL); | |
| 1404 | − if (inb(base + SDLA_S502_STS) == 0x44) { | |
| 1405 | − outb(SDLA_S502A_START, base + SDLA_REG_CONTROL); | |
| 1406 | − flp->type = SDLA_S502A; | |
| 1407 | − goto got_type; | |
| 1408 | − } | |
| 1409 | − } | |
| 1410 | − } | |
| 1411 | − | |
| 1412 | − netdev_notice(dev, "Unknown card type\n"); | |
| 1413 | − err = -ENODEV; | |
| 1414 | − goto fail; | |
| 1415 | − | |
| 1416 | −got_type: | |
| 1417 | − switch(base) { | |
| 1418 | − case 0x270: | |
| 1419 | − case 0x280: | |
| 1420 | − case 0x380: | |
| 1421 | − case 0x390: | |
| 1422 | − if (flp->type != SDLA_S508 && flp->type != SDLA_S507) | |
| 1423 | − goto fail; | |
| 1424 | − } | |
| 1425 | − | |
| 1426 | − switch (map->irq) { | |
| 1427 | − case 2: | |
| 1428 | − if (flp->type != SDLA_S502E) | |
| 1429 | − goto fail; | |
| 1430 | − break; | |
| 1431 | − | |
| 1432 | − case 10: | |
| 1433 | − case 11: | |
| 1434 | − case 12: | |
| 1435 | − case 15: | |
| 1436 | − case 4: | |
| 1437 | − if (flp->type != SDLA_S508 && flp->type != SDLA_S507) | |
| 1438 | − goto fail; | |
| 1439 | − break; | |
| 1440 | − case 3: | |
| 1441 | − case 5: | |
| 1442 | − case 7: | |
| 1443 | − if (flp->type == SDLA_S502A) | |
| 1444 | − goto fail; | |
| 1445 | − break; | |
| 1446 | − | |
| 1447 | − default: | |
| 1448 | − goto fail; | |
| 1449 | − } | |
| 1450 | − | |
| 1451 | − err = -EAGAIN; | |
| 1452 | − if (request_irq(dev->irq, sdla_isr, 0, dev->name, dev)) | |
| 1453 | − goto fail; | |
| 1454 | − | |
| 1455 | − if (flp->type == SDLA_S507) { | |
| 1456 | − switch(dev->irq) { | |
| 1457 | − case 3: | |
| 1458 | − flp->state = SDLA_S507_IRQ3; | |
| 1459 | − break; | |
| 1460 | − case 4: | |
| 1461 | − flp->state = SDLA_S507_IRQ4; | |
| 1462 | − break; | |
| 1463 | − case 5: | |
| 1464 | − flp->state = SDLA_S507_IRQ5; | |
| 1465 | − break; | |
| 1466 | − case 7: | |
| 1467 | − flp->state = SDLA_S507_IRQ7; | |
| 1468 | − break; | |
| 1469 | − case 10: | |
| 1470 | − flp->state = SDLA_S507_IRQ10; | |
| 1471 | − break; | |
| 1472 | − case 11: | |
| 1473 | − flp->state = SDLA_S507_IRQ11; | |
| 1474 | − break; | |
| 1475 | − case 12: | |
| 1476 | − flp->state = SDLA_S507_IRQ12; | |
| 1477 | − break; | |
| 1478 | − case 15: | |
| 1479 | − flp->state = SDLA_S507_IRQ15; | |
| 1480 | − break; | |
| 1481 | − } | |
| 1482 | − } | |
| 1483 | − | |
| 1484 | − for(i=0; i < ARRAY_SIZE(valid_mem); i++) | |
| 1485 | − if (valid_mem[i] == map->mem_start) | |
| 1486 | − break; | |
| 1487 | − | |
| 1488 | − err = -EINVAL; | |
| 1489 | − if (i == ARRAY_SIZE(valid_mem)) | |
| 1490 | − goto fail2; | |
| 1491 | − | |
| 1492 | − if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E) | |
| 1493 | − goto fail2; | |
| 1494 | − | |
| 1495 | − if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B) | |
| 1496 | − goto fail2; | |
| 1497 | − | |
| 1498 | − if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D) | |
| 1499 | − goto fail2; | |
| 1500 | − | |
| 1501 | − byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0; | |
| 1502 | − byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0)); | |
| 1503 | − switch(flp->type) { | |
| 1504 | − case SDLA_S502A: | |
| 1505 | − case SDLA_S502E: | |
| 1506 | − switch (map->mem_start >> 16) { | |
| 1507 | − case 0x0A: | |
| 1508 | − byte |= SDLA_S502_SEG_A; | |
| 1509 | − break; | |
| 1510 | − case 0x0C: | |
| 1511 | − byte |= SDLA_S502_SEG_C; | |
| 1512 | − break; | |
| 1513 | − case 0x0D: | |
| 1514 | − byte |= SDLA_S502_SEG_D; | |
| 1515 | − break; | |
| 1516 | − case 0x0E: | |
| 1517 | − byte |= SDLA_S502_SEG_E; | |
| 1518 | − break; | |
| 1519 | − } | |
| 1520 | − break; | |
| 1521 | − case SDLA_S507: | |
| 1522 | − switch (map->mem_start >> 16) { | |
| 1523 | − case 0x0A: | |
| 1524 | − byte |= SDLA_S507_SEG_A; | |
| 1525 | − break; | |
| 1526 | − case 0x0B: | |
| 1527 | − byte |= SDLA_S507_SEG_B; | |
| 1528 | − break; | |
| 1529 | − case 0x0C: | |
| 1530 | − byte |= SDLA_S507_SEG_C; | |
| 1531 | − break; | |
| 1532 | − case 0x0E: | |
| 1533 | − byte |= SDLA_S507_SEG_E; | |
| 1534 | − break; | |
| 1535 | − } | |
| 1536 | − break; | |
| 1537 | − case SDLA_S508: | |
| 1538 | − switch (map->mem_start >> 16) { | |
| 1539 | − case 0x0A: | |
| 1540 | − byte |= SDLA_S508_SEG_A; | |
| 1541 | − break; | |
| 1542 | − case 0x0C: | |
| 1543 | − byte |= SDLA_S508_SEG_C; | |
| 1544 | − break; | |
| 1545 | − case 0x0D: | |
| 1546 | − byte |= SDLA_S508_SEG_D; | |
| 1547 | − break; | |
| 1548 | − case 0x0E: | |
| 1549 | − byte |= SDLA_S508_SEG_E; | |
| 1550 | − break; | |
| 1551 | − } | |
| 1552 | − break; | |
| 1553 | − } | |
| 1554 | − | |
| 1555 | − /* set the memory bits, and enable access */ | |
| 1556 | − outb(byte, base + SDLA_REG_PC_WINDOW); | |
| 1557 | − | |
| 1558 | − switch(flp->type) | |
| 1559 | − { | |
| 1560 | − case SDLA_S502E: | |
| 1561 | − flp->state = SDLA_S502E_ENABLE; | |
| 1562 | − break; | |
| 1563 | − case SDLA_S507: | |
| 1564 | − flp->state |= SDLA_MEMEN; | |
| 1565 | − break; | |
| 1566 | − case SDLA_S508: | |
| 1567 | − flp->state = SDLA_MEMEN; | |
| 1568 | − break; | |
| 1569 | − } | |
| 1570 | − outb(flp->state, base + SDLA_REG_CONTROL); | |
| 1571 | − | |
| 1572 | − dev->irq = map->irq; | |
| 1573 | − dev->base_addr = base; | |
| 1574 | − dev->mem_start = map->mem_start; | |
| 1575 | − dev->mem_end = dev->mem_start + 0x2000; | |
| 1576 | − flp->initialized = 1; | |
| 1577 | − return 0; | |
| 1578 | − | |
| 1579 | −fail2: | |
| 1580 | − free_irq(map->irq, dev); | |
| 1581 | −fail: | |
| 1582 | − release_region(base, SDLA_IO_EXTENTS); | |
| 1583 | − return err; | |
| 1584 | −} | |
| 1585 | − | |
| 1586 | −static const struct net_device_ops sdla_netdev_ops = { | |
| 1587 | − .ndo_open = sdla_open, | |
| 1588 | − .ndo_stop = sdla_close, | |
| 1589 | − .ndo_do_ioctl = sdla_ioctl, | |
| 1590 | − .ndo_set_config = sdla_set_config, | |
| 1591 | − .ndo_start_xmit = sdla_transmit, | |
| 1592 | − .ndo_change_mtu = sdla_change_mtu, | |
| 1593 | −}; | |
| 1594 | − | |
| 1595 | −static void setup_sdla(struct net_device *dev) | |
| 1596 | −{ | |
| 1597 | − struct frad_local *flp = netdev_priv(dev); | |
| 1598 | − | |
| 1599 | − netdev_boot_setup_check(dev); | |
| 1600 | − | |
| 1601 | − dev->netdev_ops = &sdla_netdev_ops; | |
| 1602 | − dev->flags = 0; | |
| 1603 | − dev->type = 0xFFFF; | |
| 1604 | − dev->hard_header_len = 0; | |
| 1605 | − dev->addr_len = 0; | |
| 1606 | − dev->mtu = SDLA_MAX_MTU; | |
| 1607 | − | |
| 1608 | − flp->activate = sdla_activate; | |
| 1609 | − flp->deactivate = sdla_deactivate; | |
| 1610 | − flp->assoc = sdla_assoc; | |
| 1611 | − flp->deassoc = sdla_deassoc; | |
| 1612 | − flp->dlci_conf = sdla_dlci_conf; | |
| 1613 | − flp->dev = dev; | |
| 1614 | − | |
| 1615 | − timer_setup(&flp->timer, sdla_poll, 0); | |
| 1616 | − flp->timer.expires = 1; | |
| 1617 | −} | |
| 1618 | − | |
| 1619 | −static struct net_device *sdla; | |
| 1620 | − | |
| 1621 | −static int __init init_sdla(void) | |
| 1622 | −{ | |
| 1623 | − int err; | |
| 1624 | − | |
| 1625 | − printk("%s.\n", version); | |
| 1626 | − | |
| 1627 | − sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", | |
| 1628 | − NET_NAME_UNKNOWN, setup_sdla); | |
| 1629 | − if (!sdla) | |
| 1630 | − return -ENOMEM; | |
| 1631 | − | |
| 1632 | − err = register_netdev(sdla); | |
| 1633 | − if (err) | |
| 1634 | − free_netdev(sdla); | |
| 1635 | − | |
| 1636 | − return err; | |
| 1637 | −} | |
| 1638 | − | |
| 1639 | −static void __exit exit_sdla(void) | |
| 1640 | −{ | |
| 1641 | − struct frad_local *flp = netdev_priv(sdla); | |
| 1642 | − | |
| 1643 | − unregister_netdev(sdla); | |
| 1644 | − if (flp->initialized) { | |
| 1645 | − free_irq(sdla->irq, sdla); | |
| 1646 | − release_region(sdla->base_addr, SDLA_IO_EXTENTS); | |
| 1647 | − } | |
| 1648 | − del_timer_sync(&flp->timer); | |
| 1649 | − free_netdev(sdla); | |
| 1650 | −} | |
| 1651 | − | |
| 1652 | −MODULE_LICENSE("GPL"); | |
| 1653 | − | |
| 1654 | −module_init(init_sdla); | |
| 1655 | −module_exit(exit_sdla); | |
| @@ -1,92 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| 2 | −/* | |
| 3 | − * DLCI/FRAD Definitions for Frame Relay Access Devices. DLCI devices are | |
| 4 | − * created for each DLCI associated with a FRAD. The FRAD driver | |
| 5 | − * is not truly a network device, but the lower level device | |
| 6 | − * handler. This allows other FRAD manufacturers to use the DLCI | |
| 7 | − * code, including its RFC1490 encapsulation alongside the current | |
| 8 | − * implementation for the Sangoma cards. | |
| 9 | − * | |
| 10 | − * Version: @(#)if_ifrad.h 0.15 31 Mar 96 | |
| 11 | − * | |
| 12 | − * Author: Mike McLagan <mike.mclagan@linux.org> | |
| 13 | − * | |
| 14 | − * Changes: | |
| 15 | − * 0.15 Mike McLagan changed structure defs (packed) | |
| 16 | − * re-arranged flags | |
| 17 | − * added DLCI_RET vars | |
| 18 | − */ | |
| 19 | −#ifndef _FRAD_H_ | |
| 20 | −#define _FRAD_H_ | |
| 21 | − | |
| 22 | −#include <uapi/linux/if_frad.h> | |
| 23 | − | |
| 24 | − | |
| 25 | −#if defined(CONFIG_DLCI) || defined(CONFIG_DLCI_MODULE) | |
| 26 | − | |
| 27 | −/* these are the fields of an RFC 1490 header */ | |
| 28 | −struct frhdr | |
| 29 | −{ | |
| 30 | − unsigned char control; | |
| 31 | − | |
| 32 | − /* for IP packets, this can be the NLPID */ | |
| 33 | − unsigned char pad; | |
| 34 | − | |
| 35 | − unsigned char NLPID; | |
| 36 | − unsigned char OUI[3]; | |
| 37 | − __be16 PID; | |
| 38 | − | |
| 39 | −#define IP_NLPID pad | |
| 40 | −} __packed; | |
| 41 | − | |
| 42 | −/* see RFC 1490 for the definition of the following */ | |
| 43 | −#define FRAD_I_UI 0x03 | |
| 44 | − | |
| 45 | −#define FRAD_P_PADDING 0x00 | |
| 46 | −#define FRAD_P_Q933 0x08 | |
| 47 | −#define FRAD_P_SNAP 0x80 | |
| 48 | −#define FRAD_P_CLNP 0x81 | |
| 49 | −#define FRAD_P_IP 0xCC | |
| 50 | − | |
| 51 | −struct dlci_local | |
| 52 | −{ | |
| 53 | − struct net_device *master; | |
| 54 | − struct net_device *slave; | |
| 55 | − struct dlci_conf config; | |
| 56 | − int configured; | |
| 57 | − struct list_head list; | |
| 58 | − | |
| 59 | − /* callback function */ | |
| 60 | − void (*receive)(struct sk_buff *skb, struct net_device *); | |
| 61 | −}; | |
| 62 | − | |
| 63 | −struct frad_local | |
| 64 | −{ | |
| 65 | − /* devices which this FRAD is slaved to */ | |
| 66 | − struct net_device *master[CONFIG_DLCI_MAX]; | |
| 67 | − short dlci[CONFIG_DLCI_MAX]; | |
| 68 | − | |
| 69 | − struct frad_conf config; | |
| 70 | − int configured; /* has this device been configured */ | |
| 71 | − int initialized; /* mem_start, port, irq set ? */ | |
| 72 | − | |
| 73 | − /* callback functions */ | |
| 74 | − int (*activate)(struct net_device *, struct net_device *); | |
| 75 | − int (*deactivate)(struct net_device *, struct net_device *); | |
| 76 | − int (*assoc)(struct net_device *, struct net_device *); | |
| 77 | − int (*deassoc)(struct net_device *, struct net_device *); | |
| 78 | − int (*dlci_conf)(struct net_device *, struct net_device *, int get); | |
| 79 | − | |
| 80 | − /* fields that are used by the Sangoma SDLA cards */ | |
| 81 | − struct timer_list timer; | |
| 82 | − struct net_device *dev; | |
| 83 | − int type; /* adapter type */ | |
| 84 | − int state; /* state of the S502/8 control latch */ | |
| 85 | − int buffer; /* current buffer for S508 firmware */ | |
| 86 | −}; | |
| 87 | − | |
| 88 | −#endif /* CONFIG_DLCI || CONFIG_DLCI_MODULE */ | |
| 89 | − | |
| 90 | −extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *)); | |
| 91 | − | |
| 92 | −#endif | |
| @@ -1,240 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| 2 | −/* | |
| 3 | − * INET An implementation of the TCP/IP protocol suite for the LINUX | |
| 4 | − * operating system. INET is implemented using the BSD Socket | |
| 5 | − * interface as the means of communication with the user level. | |
| 6 | − * | |
| 7 | − * Global definitions for the Frame relay interface. | |
| 8 | − * | |
| 9 | − * Version: @(#)if_ifrad.h 0.20 13 Apr 96 | |
| 10 | − * | |
| 11 | − * Author: Mike McLagan <mike.mclagan@linux.org> | |
| 12 | − * | |
| 13 | − * Changes: | |
| 14 | − * 0.15 Mike McLagan Structure packing | |
| 15 | − * | |
| 16 | − * 0.20 Mike McLagan New flags for S508 buffer handling | |
| 17 | − */ | |
| 18 | −#ifndef SDLA_H | |
| 19 | −#define SDLA_H | |
| 20 | − | |
| 21 | −#include <uapi/linux/sdla.h> | |
| 22 | − | |
| 23 | − | |
| 24 | −/* important Z80 window addresses */ | |
| 25 | −#define SDLA_CONTROL_WND 0xE000 | |
| 26 | − | |
| 27 | −#define SDLA_502_CMD_BUF 0xEF60 | |
| 28 | −#define SDLA_502_RCV_BUF 0xA900 | |
| 29 | −#define SDLA_502_TXN_AVAIL 0xFFF1 | |
| 30 | −#define SDLA_502_RCV_AVAIL 0xFFF2 | |
| 31 | −#define SDLA_502_EVENT_FLAGS 0xFFF3 | |
| 32 | −#define SDLA_502_MDM_STATUS 0xFFF4 | |
| 33 | −#define SDLA_502_IRQ_INTERFACE 0xFFFD | |
| 34 | −#define SDLA_502_IRQ_PERMISSION 0xFFFE | |
| 35 | −#define SDLA_502_DATA_OFS 0x0010 | |
| 36 | − | |
| 37 | −#define SDLA_508_CMD_BUF 0xE000 | |
| 38 | −#define SDLA_508_TXBUF_INFO 0xF100 | |
| 39 | −#define SDLA_508_RXBUF_INFO 0xF120 | |
| 40 | −#define SDLA_508_EVENT_FLAGS 0xF003 | |
| 41 | −#define SDLA_508_MDM_STATUS 0xF004 | |
| 42 | −#define SDLA_508_IRQ_INTERFACE 0xF010 | |
| 43 | −#define SDLA_508_IRQ_PERMISSION 0xF011 | |
| 44 | −#define SDLA_508_TSE_OFFSET 0xF012 | |
| 45 | − | |
| 46 | −/* Event flags */ | |
| 47 | −#define SDLA_EVENT_STATUS 0x01 | |
| 48 | −#define SDLA_EVENT_DLCI_STATUS 0x02 | |
| 49 | −#define SDLA_EVENT_BAD_DLCI 0x04 | |
| 50 | −#define SDLA_EVENT_LINK_DOWN 0x40 | |
| 51 | − | |
| 52 | −/* IRQ Trigger flags */ | |
| 53 | −#define SDLA_INTR_RX 0x01 | |
| 54 | −#define SDLA_INTR_TX 0x02 | |
| 55 | −#define SDLA_INTR_MODEM 0x04 | |
| 56 | −#define SDLA_INTR_COMPLETE 0x08 | |
| 57 | −#define SDLA_INTR_STATUS 0x10 | |
| 58 | −#define SDLA_INTR_TIMER 0x20 | |
| 59 | − | |
| 60 | −/* DLCI status bits */ | |
| 61 | −#define SDLA_DLCI_DELETED 0x01 | |
| 62 | −#define SDLA_DLCI_ACTIVE 0x02 | |
| 63 | −#define SDLA_DLCI_WAITING 0x04 | |
| 64 | −#define SDLA_DLCI_NEW 0x08 | |
| 65 | −#define SDLA_DLCI_INCLUDED 0x40 | |
| 66 | − | |
| 67 | −/* valid command codes */ | |
| 68 | −#define SDLA_INFORMATION_WRITE 0x01 | |
| 69 | −#define SDLA_INFORMATION_READ 0x02 | |
| 70 | −#define SDLA_ISSUE_IN_CHANNEL_SIGNAL 0x03 | |
| 71 | −#define SDLA_SET_DLCI_CONFIGURATION 0x10 | |
| 72 | −#define SDLA_READ_DLCI_CONFIGURATION 0x11 | |
| 73 | −#define SDLA_DISABLE_COMMUNICATIONS 0x12 | |
| 74 | −#define SDLA_ENABLE_COMMUNICATIONS 0x13 | |
| 75 | −#define SDLA_READ_DLC_STATUS 0x14 | |
| 76 | −#define SDLA_READ_DLC_STATISTICS 0x15 | |
| 77 | −#define SDLA_FLUSH_DLC_STATISTICS 0x16 | |
| 78 | −#define SDLA_LIST_ACTIVE_DLCI 0x17 | |
| 79 | −#define SDLA_FLUSH_INFORMATION_BUFFERS 0x18 | |
| 80 | −#define SDLA_ADD_DLCI 0x20 | |
| 81 | −#define SDLA_DELETE_DLCI 0x21 | |
| 82 | −#define SDLA_ACTIVATE_DLCI 0x22 | |
| 83 | −#define SDLA_DEACTIVATE_DLCI 0x23 | |
| 84 | −#define SDLA_READ_MODEM_STATUS 0x30 | |
| 85 | −#define SDLA_SET_MODEM_STATUS 0x31 | |
| 86 | −#define SDLA_READ_COMMS_ERR_STATS 0x32 | |
| 87 | −#define SDLA_FLUSH_COMMS_ERR_STATS 0x33 | |
| 88 | −#define SDLA_READ_CODE_VERSION 0x40 | |
| 89 | −#define SDLA_SET_IRQ_TRIGGER 0x50 | |
| 90 | −#define SDLA_GET_IRQ_TRIGGER 0x51 | |
| 91 | − | |
| 92 | −/* In channel signal types */ | |
| 93 | −#define SDLA_ICS_LINK_VERIFY 0x02 | |
| 94 | −#define SDLA_ICS_STATUS_ENQ 0x03 | |
| 95 | − | |
| 96 | −/* modem status flags */ | |
| 97 | −#define SDLA_MODEM_DTR_HIGH 0x01 | |
| 98 | −#define SDLA_MODEM_RTS_HIGH 0x02 | |
| 99 | −#define SDLA_MODEM_DCD_HIGH 0x08 | |
| 100 | −#define SDLA_MODEM_CTS_HIGH 0x20 | |
| 101 | − | |
| 102 | −/* used for RET_MODEM interpretation */ | |
| 103 | −#define SDLA_MODEM_DCD_LOW 0x01 | |
| 104 | −#define SDLA_MODEM_CTS_LOW 0x02 | |
| 105 | − | |
| 106 | −/* return codes */ | |
| 107 | −#define SDLA_RET_OK 0x00 | |
| 108 | −#define SDLA_RET_COMMUNICATIONS 0x01 | |
| 109 | −#define SDLA_RET_CHANNEL_INACTIVE 0x02 | |
| 110 | −#define SDLA_RET_DLCI_INACTIVE 0x03 | |
| 111 | −#define SDLA_RET_DLCI_CONFIG 0x04 | |
| 112 | −#define SDLA_RET_BUF_TOO_BIG 0x05 | |
| 113 | −#define SDLA_RET_NO_DATA 0x05 | |
| 114 | −#define SDLA_RET_BUF_OVERSIZE 0x06 | |
| 115 | −#define SDLA_RET_CIR_OVERFLOW 0x07 | |
| 116 | −#define SDLA_RET_NO_BUFS 0x08 | |
| 117 | −#define SDLA_RET_TIMEOUT 0x0A | |
| 118 | −#define SDLA_RET_MODEM 0x10 | |
| 119 | −#define SDLA_RET_CHANNEL_OFF 0x11 | |
| 120 | −#define SDLA_RET_CHANNEL_ON 0x12 | |
| 121 | −#define SDLA_RET_DLCI_STATUS 0x13 | |
| 122 | −#define SDLA_RET_DLCI_UNKNOWN 0x14 | |
| 123 | −#define SDLA_RET_COMMAND_INVALID 0x1F | |
| 124 | − | |
| 125 | −/* Configuration flags */ | |
| 126 | −#define SDLA_DIRECT_RECV 0x0080 | |
| 127 | −#define SDLA_TX_NO_EXCEPT 0x0020 | |
| 128 | −#define SDLA_NO_ICF_MSGS 0x1000 | |
| 129 | −#define SDLA_TX50_RX50 0x0000 | |
| 130 | −#define SDLA_TX70_RX30 0x2000 | |
| 131 | −#define SDLA_TX30_RX70 0x4000 | |
| 132 | − | |
| 133 | −/* IRQ selection flags */ | |
| 134 | −#define SDLA_IRQ_RECEIVE 0x01 | |
| 135 | −#define SDLA_IRQ_TRANSMIT 0x02 | |
| 136 | −#define SDLA_IRQ_MODEM_STAT 0x04 | |
| 137 | −#define SDLA_IRQ_COMMAND 0x08 | |
| 138 | −#define SDLA_IRQ_CHANNEL 0x10 | |
| 139 | −#define SDLA_IRQ_TIMER 0x20 | |
| 140 | − | |
| 141 | −/* definitions for PC memory mapping */ | |
| 142 | −#define SDLA_8K_WINDOW 0x01 | |
| 143 | −#define SDLA_S502_SEG_A 0x10 | |
| 144 | −#define SDLA_S502_SEG_C 0x20 | |
| 145 | −#define SDLA_S502_SEG_D 0x00 | |
| 146 | −#define SDLA_S502_SEG_E 0x30 | |
| 147 | −#define SDLA_S507_SEG_A 0x00 | |
| 148 | −#define SDLA_S507_SEG_B 0x40 | |
| 149 | −#define SDLA_S507_SEG_C 0x80 | |
| 150 | −#define SDLA_S507_SEG_E 0xC0 | |
| 151 | −#define SDLA_S508_SEG_A 0x00 | |
| 152 | −#define SDLA_S508_SEG_C 0x10 | |
| 153 | −#define SDLA_S508_SEG_D 0x08 | |
| 154 | −#define SDLA_S508_SEG_E 0x18 | |
| 155 | − | |
| 156 | −/* SDLA adapter port constants */ | |
| 157 | −#define SDLA_IO_EXTENTS 0x04 | |
| 158 | − | |
| 159 | −#define SDLA_REG_CONTROL 0x00 | |
| 160 | −#define SDLA_REG_PC_WINDOW 0x01 /* offset for PC window select latch */ | |
| 161 | −#define SDLA_REG_Z80_WINDOW 0x02 /* offset for Z80 window select latch */ | |
| 162 | −#define SDLA_REG_Z80_CONTROL 0x03 /* offset for Z80 control latch */ | |
| 163 | − | |
| 164 | −#define SDLA_S502_STS 0x00 /* status reg for 502, 502E, 507 */ | |
| 165 | −#define SDLA_S508_GNRL 0x00 /* general purp. reg for 508 */ | |
| 166 | −#define SDLA_S508_STS 0x01 /* status reg for 508 */ | |
| 167 | −#define SDLA_S508_IDR 0x02 /* ID reg for 508 */ | |
| 168 | − | |
| 169 | −/* control register flags */ | |
| 170 | −#define SDLA_S502A_START 0x00 /* start the CPU */ | |
| 171 | −#define SDLA_S502A_INTREQ 0x02 | |
| 172 | −#define SDLA_S502A_INTEN 0x04 | |
| 173 | −#define SDLA_S502A_HALT 0x08 /* halt the CPU */ | |
| 174 | −#define SDLA_S502A_NMI 0x10 /* issue an NMI to the CPU */ | |
| 175 | − | |
| 176 | −#define SDLA_S502E_CPUEN 0x01 | |
| 177 | −#define SDLA_S502E_ENABLE 0x02 | |
| 178 | −#define SDLA_S502E_INTACK 0x04 | |
| 179 | − | |
| 180 | −#define SDLA_S507_ENABLE 0x01 | |
| 181 | −#define SDLA_S507_IRQ3 0x00 | |
| 182 | −#define SDLA_S507_IRQ4 0x20 | |
| 183 | −#define SDLA_S507_IRQ5 0x40 | |
| 184 | −#define SDLA_S507_IRQ7 0x60 | |
| 185 | −#define SDLA_S507_IRQ10 0x80 | |
| 186 | −#define SDLA_S507_IRQ11 0xA0 | |
| 187 | −#define SDLA_S507_IRQ12 0xC0 | |
| 188 | −#define SDLA_S507_IRQ15 0xE0 | |
| 189 | − | |
| 190 | −#define SDLA_HALT 0x00 | |
| 191 | −#define SDLA_CPUEN 0x02 | |
| 192 | −#define SDLA_MEMEN 0x04 | |
| 193 | −#define SDLA_S507_EPROMWR 0x08 | |
| 194 | −#define SDLA_S507_EPROMCLK 0x10 | |
| 195 | −#define SDLA_S508_INTRQ 0x08 | |
| 196 | −#define SDLA_S508_INTEN 0x10 | |
| 197 | − | |
| 198 | −struct sdla_cmd { | |
| 199 | − char opp_flag; | |
| 200 | − char cmd; | |
| 201 | − short length; | |
| 202 | − char retval; | |
| 203 | − short dlci; | |
| 204 | − char flags; | |
| 205 | − short rxlost_int; | |
| 206 | − long rxlost_app; | |
| 207 | − char reserve[2]; | |
| 208 | − char data[SDLA_MAX_DATA]; /* transfer data buffer */ | |
| 209 | −} __attribute__((packed)); | |
| 210 | − | |
| 211 | −struct intr_info { | |
| 212 | − char flags; | |
| 213 | − short txlen; | |
| 214 | − char irq; | |
| 215 | − char flags2; | |
| 216 | − short timeout; | |
| 217 | −} __attribute__((packed)); | |
| 218 | − | |
| 219 | −/* found in the 508's control window at RXBUF_INFO */ | |
| 220 | −struct buf_info { | |
| 221 | − unsigned short rse_num; | |
| 222 | − unsigned long rse_base; | |
| 223 | − unsigned long rse_next; | |
| 224 | − unsigned long buf_base; | |
| 225 | − unsigned short reserved; | |
| 226 | − unsigned long buf_top; | |
| 227 | −} __attribute__((packed)); | |
| 228 | − | |
| 229 | −/* structure pointed to by rse_base in RXBUF_INFO struct */ | |
| 230 | −struct buf_entry { | |
| 231 | − char opp_flag; | |
| 232 | − short length; | |
| 233 | − short dlci; | |
| 234 | − char flags; | |
| 235 | − short timestamp; | |
| 236 | − short reserved[2]; | |
| 237 | − long buf_addr; | |
| 238 | −} __attribute__((packed)); | |
| 239 | − | |
| 240 | −#endif | |
| @@ -1,123 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ | |
| 2 | −/* | |
| 3 | − * DLCI/FRAD Definitions for Frame Relay Access Devices. DLCI devices are | |
| 4 | − * created for each DLCI associated with a FRAD. The FRAD driver | |
| 5 | − * is not truly a network device, but the lower level device | |
| 6 | − * handler. This allows other FRAD manufacturers to use the DLCI | |
| 7 | − * code, including its RFC1490 encapsulation alongside the current | |
| 8 | − * implementation for the Sangoma cards. | |
| 9 | − * | |
| 10 | − * Version: @(#)if_ifrad.h 0.15 31 Mar 96 | |
| 11 | − * | |
| 12 | − * Author: Mike McLagan <mike.mclagan@linux.org> | |
| 13 | − * | |
| 14 | − * Changes: | |
| 15 | − * 0.15 Mike McLagan changed structure defs (packed) | |
| 16 | − * re-arranged flags | |
| 17 | − * added DLCI_RET vars | |
| 18 | − * | |
| 19 | − * This program is free software; you can redistribute it and/or | |
| 20 | − * modify it under the terms of the GNU General Public License | |
| 21 | − * as published by the Free Software Foundation; either version | |
| 22 | − * 2 of the License, or (at your option) any later version. | |
| 23 | − */ | |
| 24 | − | |
| 25 | −#ifndef _UAPI_FRAD_H_ | |
| 26 | −#define _UAPI_FRAD_H_ | |
| 27 | − | |
| 28 | −#include <linux/if.h> | |
| 29 | − | |
| 30 | −/* Structures and constants associated with the DLCI device driver */ | |
| 31 | − | |
| 32 | −struct dlci_add | |
| 33 | −{ | |
| 34 | − char devname[IFNAMSIZ]; | |
| 35 | − short dlci; | |
| 36 | −}; | |
| 37 | − | |
| 38 | −#define DLCI_GET_CONF (SIOCDEVPRIVATE + 2) | |
| 39 | −#define DLCI_SET_CONF (SIOCDEVPRIVATE + 3) | |
| 40 | − | |
| 41 | −/* | |
| 42 | − * These are related to the Sangoma SDLA and should remain in order. | |
| 43 | − * Code within the SDLA module is based on the specifics of this | |
| 44 | − * structure. Change at your own peril. | |
| 45 | − */ | |
| 46 | −struct dlci_conf { | |
| 47 | − short flags; | |
| 48 | − short CIR_fwd; | |
| 49 | − short Bc_fwd; | |
| 50 | − short Be_fwd; | |
| 51 | − short CIR_bwd; | |
| 52 | − short Bc_bwd; | |
| 53 | − short Be_bwd; | |
| 54 | − | |
| 55 | −/* these are part of the status read */ | |
| 56 | − short Tc_fwd; | |
| 57 | − short Tc_bwd; | |
| 58 | − short Tf_max; | |
| 59 | − short Tb_max; | |
| 60 | − | |
| 61 | −/* add any new fields here above is a mirror of sdla_dlci_conf */ | |
| 62 | −}; | |
| 63 | − | |
| 64 | −#define DLCI_GET_SLAVE (SIOCDEVPRIVATE + 4) | |
| 65 | − | |
| 66 | −/* configuration flags for DLCI */ | |
| 67 | −#define DLCI_IGNORE_CIR_OUT 0x0001 | |
| 68 | −#define DLCI_ACCOUNT_CIR_IN 0x0002 | |
| 69 | −#define DLCI_BUFFER_IF 0x0008 | |
| 70 | − | |
| 71 | −#define DLCI_VALID_FLAGS 0x000B | |
| 72 | − | |
| 73 | −/* defines for the actual Frame Relay hardware */ | |
| 74 | −#define FRAD_GET_CONF (SIOCDEVPRIVATE) | |
| 75 | −#define FRAD_SET_CONF (SIOCDEVPRIVATE + 1) | |
| 76 | − | |
| 77 | −#define FRAD_LAST_IOCTL FRAD_SET_CONF | |
| 78 | − | |
| 79 | −/* | |
| 80 | − * Based on the setup for the Sangoma SDLA. If changes are | |
| 81 | − * necessary to this structure, a routine will need to be | |
| 82 | − * added to that module to copy fields. | |
| 83 | − */ | |
| 84 | −struct frad_conf | |
| 85 | −{ | |
| 86 | − short station; | |
| 87 | − short flags; | |
| 88 | − short kbaud; | |
| 89 | − short clocking; | |
| 90 | − short mtu; | |
| 91 | − short T391; | |
| 92 | − short T392; | |
| 93 | − short N391; | |
| 94 | − short N392; | |
| 95 | − short N393; | |
| 96 | − short CIR_fwd; | |
| 97 | − short Bc_fwd; | |
| 98 | − short Be_fwd; | |
| 99 | − short CIR_bwd; | |
| 100 | − short Bc_bwd; | |
| 101 | − short Be_bwd; | |
| 102 | − | |
| 103 | −/* Add new fields here, above is a mirror of the sdla_conf */ | |
| 104 | − | |
| 105 | −}; | |
| 106 | − | |
| 107 | −#define FRAD_STATION_CPE 0x0000 | |
| 108 | −#define FRAD_STATION_NODE 0x0001 | |
| 109 | − | |
| 110 | −#define FRAD_TX_IGNORE_CIR 0x0001 | |
| 111 | −#define FRAD_RX_ACCOUNT_CIR 0x0002 | |
| 112 | −#define FRAD_DROP_ABORTED 0x0004 | |
| 113 | −#define FRAD_BUFFERIF 0x0008 | |
| 114 | −#define FRAD_STATS 0x0010 | |
| 115 | −#define FRAD_MCI 0x0100 | |
| 116 | −#define FRAD_AUTODLCI 0x8000 | |
| 117 | −#define FRAD_VALID_FLAGS 0x811F | |
| 118 | − | |
| 119 | −#define FRAD_CLOCK_INT 0x0001 | |
| 120 | −#define FRAD_CLOCK_EXT 0x0000 | |
| 121 | − | |
| 122 | − | |
| 123 | −#endif /* _UAPI_FRAD_H_ */ | |
| @@ -1,117 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ | |
| 2 | −/* | |
| 3 | − * INET An implementation of the TCP/IP protocol suite for the LINUX | |
| 4 | − * operating system. INET is implemented using the BSD Socket | |
| 5 | − * interface as the means of communication with the user level. | |
| 6 | − * | |
| 7 | − * Global definitions for the Frame relay interface. | |
| 8 | − * | |
| 9 | − * Version: @(#)if_ifrad.h 0.20 13 Apr 96 | |
| 10 | − * | |
| 11 | − * Author: Mike McLagan <mike.mclagan@linux.org> | |
| 12 | − * | |
| 13 | − * Changes: | |
| 14 | − * 0.15 Mike McLagan Structure packing | |
| 15 | − * | |
| 16 | − * 0.20 Mike McLagan New flags for S508 buffer handling | |
| 17 | − * | |
| 18 | − * This program is free software; you can redistribute it and/or | |
| 19 | − * modify it under the terms of the GNU General Public License | |
| 20 | − * as published by the Free Software Foundation; either version | |
| 21 | − * 2 of the License, or (at your option) any later version. | |
| 22 | − */ | |
| 23 | − | |
| 24 | −#ifndef _UAPISDLA_H | |
| 25 | −#define _UAPISDLA_H | |
| 26 | − | |
| 27 | −/* adapter type */ | |
| 28 | −#define SDLA_TYPES | |
| 29 | −#define SDLA_S502A 5020 | |
| 30 | −#define SDLA_S502E 5021 | |
| 31 | −#define SDLA_S503 5030 | |
| 32 | −#define SDLA_S507 5070 | |
| 33 | −#define SDLA_S508 5080 | |
| 34 | −#define SDLA_S509 5090 | |
| 35 | −#define SDLA_UNKNOWN -1 | |
| 36 | − | |
| 37 | −/* port selection flags for the S508 */ | |
| 38 | −#define SDLA_S508_PORT_V35 0x00 | |
| 39 | −#define SDLA_S508_PORT_RS232 0x02 | |
| 40 | − | |
| 41 | −/* Z80 CPU speeds */ | |
| 42 | −#define SDLA_CPU_3M 0x00 | |
| 43 | −#define SDLA_CPU_5M 0x01 | |
| 44 | −#define SDLA_CPU_7M 0x02 | |
| 45 | −#define SDLA_CPU_8M 0x03 | |
| 46 | −#define SDLA_CPU_10M 0x04 | |
| 47 | −#define SDLA_CPU_16M 0x05 | |
| 48 | −#define SDLA_CPU_12M 0x06 | |
| 49 | − | |
| 50 | −/* some private IOCTLs */ | |
| 51 | −#define SDLA_IDENTIFY (FRAD_LAST_IOCTL + 1) | |
| 52 | −#define SDLA_CPUSPEED (FRAD_LAST_IOCTL + 2) | |
| 53 | −#define SDLA_PROTOCOL (FRAD_LAST_IOCTL + 3) | |
| 54 | − | |
| 55 | −#define SDLA_CLEARMEM (FRAD_LAST_IOCTL + 4) | |
| 56 | −#define SDLA_WRITEMEM (FRAD_LAST_IOCTL + 5) | |
| 57 | −#define SDLA_READMEM (FRAD_LAST_IOCTL + 6) | |
| 58 | − | |
| 59 | −struct sdla_mem { | |
| 60 | − int addr; | |
| 61 | − int len; | |
| 62 | − void __user *data; | |
| 63 | −}; | |
| 64 | − | |
| 65 | −#define SDLA_START (FRAD_LAST_IOCTL + 7) | |
| 66 | −#define SDLA_STOP (FRAD_LAST_IOCTL + 8) | |
| 67 | − | |
| 68 | −/* some offsets in the Z80's memory space */ | |
| 69 | −#define SDLA_NMIADDR 0x0000 | |
| 70 | −#define SDLA_CONF_ADDR 0x0010 | |
| 71 | −#define SDLA_S502A_NMIADDR 0x0066 | |
| 72 | −#define SDLA_CODE_BASEADDR 0x0100 | |
| 73 | −#define SDLA_WINDOW_SIZE 0x2000 | |
| 74 | −#define SDLA_ADDR_MASK 0x1FFF | |
| 75 | − | |
| 76 | −/* largest handleable block of data */ | |
| 77 | −#define SDLA_MAX_DATA 4080 | |
| 78 | −#define SDLA_MAX_MTU 4072 /* MAX_DATA - sizeof(fradhdr) */ | |
| 79 | −#define SDLA_MAX_DLCI 24 | |
| 80 | − | |
| 81 | −/* this should be the same as frad_conf */ | |
| 82 | −struct sdla_conf { | |
| 83 | − short station; | |
| 84 | − short config; | |
| 85 | − short kbaud; | |
| 86 | − short clocking; | |
| 87 | − short max_frm; | |
| 88 | − short T391; | |
| 89 | − short T392; | |
| 90 | − short N391; | |
| 91 | − short N392; | |
| 92 | − short N393; | |
| 93 | − short CIR_fwd; | |
| 94 | − short Bc_fwd; | |
| 95 | − short Be_fwd; | |
| 96 | − short CIR_bwd; | |
| 97 | − short Bc_bwd; | |
| 98 | − short Be_bwd; | |
| 99 | −}; | |
| 100 | − | |
| 101 | −/* this should be the same as dlci_conf */ | |
| 102 | −struct sdla_dlci_conf { | |
| 103 | − short config; | |
| 104 | − short CIR_fwd; | |
| 105 | − short Bc_fwd; | |
| 106 | − short Be_fwd; | |
| 107 | − short CIR_bwd; | |
| 108 | − short Bc_bwd; | |
| 109 | − short Be_bwd; | |
| 110 | − short Tc_fwd; | |
| 111 | − short Tc_bwd; | |
| 112 | − short Tf_max; | |
| 113 | − short Tb_max; | |
| 114 | −}; | |
| 115 | − | |
| 116 | − | |
| 117 | −#endif /* _UAPISDLA_H */ | |
| @@ -64,7 +64,6 @@ · 63 unmodified lines | ||
| 64 | 64 | #include <linux/seq_file.h> |
| 65 | 65 | #include <linux/mutex.h> |
| 66 | 66 | #include <linux/if_bridge.h> |
| 67 | −#include <linux/if_frad.h> | |
| 68 | 67 | #include <linux/if_vlan.h> |
| 69 | 68 | #include <linux/ptp_classify.h> |
| 70 | 69 | #include <linux/init.h> |
| @@ -1027,17 +1026,6 @@ void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) · 956 unmodified lines | ||
| 1027 | 1026 | } |
| 1028 | 1027 | EXPORT_SYMBOL(vlan_ioctl_set); |
| 1029 | 1028 | |
| 1030 | −static DEFINE_MUTEX(dlci_ioctl_mutex); | |
| 1031 | −static int (*dlci_ioctl_hook) (unsigned int, void __user *); | |
| 1032 | − | |
| 1033 | −void dlci_ioctl_set(int (*hook) (unsigned int, void __user *)) | |
| 1034 | −{ | |
| 1035 | − mutex_lock(&dlci_ioctl_mutex); | |
| 1036 | − dlci_ioctl_hook = hook; | |
| 1037 | − mutex_unlock(&dlci_ioctl_mutex); | |
| 1038 | −} | |
| 1039 | −EXPORT_SYMBOL(dlci_ioctl_set); | |
| 1040 | − | |
| 1041 | 1029 | static long sock_do_ioctl(struct net *net, struct socket *sock, |
| 1042 | 1030 | unsigned int cmd, unsigned long arg) |
| 1043 | 1031 | { |
| @@ -1156,17 +1144,6 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) · 112 unmodified lines | ||
| 1156 | 1144 | err = vlan_ioctl_hook(net, argp); |
| 1157 | 1145 | mutex_unlock(&vlan_ioctl_mutex); |
| 1158 | 1146 | break; |
| 1159 | − case SIOCADDDLCI: | |
| 1160 | − case SIOCDELDLCI: | |
| 1161 | − err = -ENOPKG; | |
| 1162 | − if (!dlci_ioctl_hook) | |
| 1163 | − request_module("dlci"); | |
| 1164 | − | |
| 1165 | − mutex_lock(&dlci_ioctl_mutex); | |
| 1166 | − if (dlci_ioctl_hook) | |
| 1167 | − err = dlci_ioctl_hook(cmd, argp); | |
| 1168 | − mutex_unlock(&dlci_ioctl_mutex); | |
| 1169 | − break; | |
| 1170 | 1147 | case SIOCGSKNS: |
| 1171 | 1148 | err = -EPERM; |
| 1172 | 1149 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) |
| @@ -3427,8 +3404,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, · 2254 unmodified lines | ||
| 3427 | 3404 | case SIOCBRDELBR: |
| 3428 | 3405 | case SIOCGIFVLAN: |
| 3429 | 3406 | case SIOCSIFVLAN: |
| 3430 | − case SIOCADDDLCI: | |
| 3431 | − case SIOCDELDLCI: | |
| 3432 | 3407 | case SIOCGSKNS: |
| 3433 | 3408 | case SIOCGSTAMP_NEW: |
| 3434 | 3409 | case SIOCGSTAMPNS_NEW: |