History

net: wan: Delete the DLCI / SDLA drivers

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.)

Xie He committed 6 years ago

Commit f7365911 parent fccf11115 files · +0 −2902Browse files

Unified · Split

15 files
  1. CREDITS +0 −9
  2. Documentation/networking/framerelay.rst +0 −44
  3. MAINTAINERS +0 −6
  4. arch/arm/configs/ixp4xx_defconfig +0 −1
  5. arch/mips/configs/gpr_defconfig +0 −1
  6. arch/mips/configs/mtx1_defconfig +0 −1
  7. drivers/net/wan/Kconfig +0 −45
  8. drivers/net/wan/Makefile +0 −2
  9. drivers/net/wan/dlci.c +0 −541
  10. drivers/net/wan/sdla.c +0 −1655
  11. include/linux/if_frad.h +0 −92
  12. include/linux/sdla.h +0 −240
  13. include/uapi/linux/if_frad.h +0 −123
  14. include/uapi/linux/sdla.h +0 −117
  15. net/socket.c +0 −25
CREDITS+0−9
@@ -2499,15 +2499,6 @@ W: http://www.rdrop.com/users/paulmck/ · 2498 unmodified lines
2499D: RCU and variants2499D: RCU and variants
2500D: rcutorture module2500D: rcutorture module
2501 2501
2502N: Mike McLagan
2503E: mike.mclagan@linux.org
2504W: http://www.invlogic.com/~mmclagan
2505D: DLCI/FRAD drivers for Sangoma SDLAs
2506S: Innovative Logic Corp
2507S: Post Office Box 1068
2508S: Laurel, Maryland 20732
2509S: USA
2510
2511N: Bradley McLean2502N: Bradley McLean
2512E: brad@bradpc.gaylord.com2503E: brad@bradpc.gaylord.com
2513D: Device driver hacker2504D: Device driver hacker
Documentation/networking/framerelay.rst+0−44
@@ -1,44 +0,0 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3================
4Frame Relay (FR)
5================
6
7Frame Relay (FR) support for linux is built into a two tiered system of device
8drivers. The upper layer implements RFC1490 FR specification, and uses the
9Data Link Connection Identifier (DLCI) as its hardware address. Usually these
10are assigned by your network supplier, they give you the number/numbers of
11the Virtual Connections (VC) assigned to you.
12
13Each DLCI is a point-to-point link between your machine and a remote one.
14As such, a separate device is needed to accommodate the routing. Within the
15net-tools archives is 'dlcicfg'. This program will communicate with the
16base "DLCI" device, and create new net devices named 'dlci00', 'dlci01'...
17The configuration script will ask you how many DLCIs you need, as well as
18how many DLCIs you want to assign to each Frame Relay Access Device (FRAD).
19
20The DLCI uses a number of function calls to communicate with the FRAD, all
21of which are stored in the FRAD's private data area. assoc/deassoc,
22activate/deactivate and dlci_config. The DLCI supplies a receive function
23to the FRAD to accept incoming packets.
24
25With this initial offering, only 1 FRAD driver is available. With many thanks
26to Sangoma Technologies, David Mandelstam & Gene Kozin, the S502A, S502E &
27S508 are supported. This driver is currently set up for only FR, but as
28Sangoma makes more firmware modules available, it can be updated to provide
29them as well.
30
31Configuration of the FRAD makes use of another net-tools program, 'fradcfg'.
32This program makes use of a configuration file (which dlcicfg can also read)
33to specify the types of boards to be configured as FRADs, as well as perform
34any board specific configuration. The Sangoma module of fradcfg loads the
35FR firmware into the card, sets the irq/port/memory information, and provides
36an initial configuration.
37
38Additional FRAD device drivers can be added as hardware is available.
39
40At this time, the dlcicfg and fradcfg programs have not been incorporated into
41the 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
43use 'cd linux'. v0.10 is for use on pre-2.0.3 and earlier, v0.15 is for
44pre-2.0.4 and later.
MAINTAINERS+0−6
@@ -6905,12 +6905,6 @@ S: Maintained · 6904 unmodified lines
6905W: http://floatingpoint.sourceforge.net/emulator/index.html6905W: http://floatingpoint.sourceforge.net/emulator/index.html
6906F: arch/x86/math-emu/6906F: arch/x86/math-emu/
6907 6907
6908FRAME RELAY DLCI/FRAD (Sangoma drivers too)
6909L: netdev@vger.kernel.org
6910S: Orphan
6911F: drivers/net/wan/dlci.c
6912F: drivers/net/wan/sdla.c
6913
6914FRAMEBUFFER LAYER6908FRAMEBUFFER LAYER
6915M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>6909M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
6916L: dri-devel@lists.freedesktop.org6910L: dri-devel@lists.freedesktop.org
arch/arm/configs/ixp4xx_defconfig+0−1
@@ -141,7 +141,6 @@ CONFIG_HDLC_CISCO=m · 140 unmodified lines
141CONFIG_HDLC_FR=m141CONFIG_HDLC_FR=m
142CONFIG_HDLC_PPP=m142CONFIG_HDLC_PPP=m
143CONFIG_HDLC_X25=m143CONFIG_HDLC_X25=m
144CONFIG_DLCI=m
145CONFIG_WAN_ROUTER_DRIVERS=m144CONFIG_WAN_ROUTER_DRIVERS=m
146CONFIG_ATM_TCP=m145CONFIG_ATM_TCP=m
147# CONFIG_INPUT_KEYBOARD is not set146# CONFIG_INPUT_KEYBOARD is not set
arch/mips/configs/gpr_defconfig+0−1
@@ -228,7 +228,6 @@ CONFIG_FARSYNC=m · 227 unmodified lines
228CONFIG_DSCC4=m228CONFIG_DSCC4=m
229CONFIG_DSCC4_PCISYNC=y229CONFIG_DSCC4_PCISYNC=y
230CONFIG_DSCC4_PCI_RST=y230CONFIG_DSCC4_PCI_RST=y
231CONFIG_DLCI=m
232CONFIG_LAPBETHER=m231CONFIG_LAPBETHER=m
233# CONFIG_INPUT_KEYBOARD is not set232# CONFIG_INPUT_KEYBOARD is not set
234# CONFIG_INPUT_MOUSE is not set233# CONFIG_INPUT_MOUSE is not set
arch/mips/configs/mtx1_defconfig+0−1
@@ -378,7 +378,6 @@ CONFIG_FARSYNC=m · 377 unmodified lines
378CONFIG_DSCC4=m378CONFIG_DSCC4=m
379CONFIG_DSCC4_PCISYNC=y379CONFIG_DSCC4_PCISYNC=y
380CONFIG_DSCC4_PCI_RST=y380CONFIG_DSCC4_PCI_RST=y
381CONFIG_DLCI=m
382CONFIG_LAPBETHER=m381CONFIG_LAPBETHER=m
383# CONFIG_KEYBOARD_ATKBD is not set382# CONFIG_KEYBOARD_ATKBD is not set
384CONFIG_KEYBOARD_GPIO=y383CONFIG_KEYBOARD_GPIO=y
drivers/net/wan/Kconfig+0−45
@@ -321,51 +321,6 @@ config IXP4XX_HSS · 320 unmodified lines
321 Say Y here if you want to use built-in HSS ports321 Say Y here if you want to use built-in HSS ports
322 on IXP4xx processor.322 on IXP4xx processor.
323 323
324config 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
344config 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
355config 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# X.25 network drivers324# X.25 network drivers
370config LAPBETHER325config LAPBETHER
371 tristate "LAPB over Ethernet driver"326 tristate "LAPB over Ethernet driver"
drivers/net/wan/Makefile+0−2
@@ -21,8 +21,6 @@ obj-$(CONFIG_FARSYNC) += farsync.o · 20 unmodified lines
21 21
22obj-$(CONFIG_LANMEDIA) += lmc/22obj-$(CONFIG_LANMEDIA) += lmc/
23 23
24obj-$(CONFIG_DLCI) += dlci.o
25obj-$(CONFIG_SDLA) += sdla.o
26obj-$(CONFIG_LAPBETHER) += lapbether.o24obj-$(CONFIG_LAPBETHER) += lapbether.o
27obj-$(CONFIG_SBNI) += sbni.o25obj-$(CONFIG_SBNI) += sbni.o
28obj-$(CONFIG_N2) += n2.o26obj-$(CONFIG_N2) += n2.o
drivers/net/wan/dlci.c+0−541
@@ -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
53static const char version[] = "DLCI driver v0.35, 4 Jan 1997, mike.mclagan@linux.org";
54
55static LIST_HEAD(dlci_devs);
56
57static 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
65static 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
101static 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
187static 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
198static 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
232static 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
263static 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
270static 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
294static 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
309static 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
372static 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 }
417out:
418 rtnl_unlock();
419 return err;
420}
421
422static 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
454static const struct header_ops dlci_header_ops = {
455 .create = dlci_header,
456};
457
458static 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
466static 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 */
484static 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
507static struct notifier_block dlci_notifier = {
508 .notifier_call = dlci_dev_event,
509};
510
511static 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
521static 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
536module_init(init_dlci);
537module_exit(dlci_exit);
538
539MODULE_AUTHOR("Mike McLagan");
540MODULE_DESCRIPTION("Frame Relay DLCI layer");
541MODULE_LICENSE("GPL");
drivers/net/wan/sdla.c+0−1655
@@ -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
57static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org";
58
59static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
60
61static 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
68static 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
78static 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
100static 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
108static 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
131static 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
142static 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
166static 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
181static 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
208static 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
246static 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
276static 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
326struct _dlci_stat
327{
328 short dlci;
329 char flags;
330} __packed;
331
332struct _frad_stat
333{
334 char flags;
335 struct _dlci_stat dlcis[SDLA_MAX_DLCI];
336};
337
338static 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
426static 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
507static int sdla_reconfig(struct net_device *dev);
508
509static 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
531static 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
553static 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
589static 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
617static 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!! */
656static 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
748static 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
876static 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
927static 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
939static 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
993struct conf_data {
994 struct frad_conf config;
995 short dlci[CONFIG_DLCI_MAX];
996};
997
998static 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
1094static 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
1192static 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
1224static 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
1248static 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/* ==========================================================
1274NOTE: 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
1317static 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
1326static 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
1416got_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
1579fail2:
1580 free_irq(map->irq, dev);
1581fail:
1582 release_region(base, SDLA_IO_EXTENTS);
1583 return err;
1584}
1585
1586static 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
1595static 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
1619static struct net_device *sdla;
1620
1621static 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
1639static 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
1652MODULE_LICENSE("GPL");
1653
1654module_init(init_sdla);
1655module_exit(exit_sdla);
include/linux/if_frad.h+0−92
@@ -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 */
28struct 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
51struct 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
63struct 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
90extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
91
92#endif
include/linux/sdla.h+0−240
@@ -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
198struct 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
211struct 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 */
220struct 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 */
230struct 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
include/uapi/linux/if_frad.h+0−123
@@ -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
32struct 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 */
46struct 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 */
84struct 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_ */
include/uapi/linux/sdla.h+0−117
@@ -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
59struct 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 */
82struct 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 */
102struct 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 */
net/socket.c+0−25
@@ -64,7 +64,6 @@ · 63 unmodified lines
64#include <linux/seq_file.h>64#include <linux/seq_file.h>
65#include <linux/mutex.h>65#include <linux/mutex.h>
66#include <linux/if_bridge.h>66#include <linux/if_bridge.h>
67#include <linux/if_frad.h>
68#include <linux/if_vlan.h>67#include <linux/if_vlan.h>
69#include <linux/ptp_classify.h>68#include <linux/ptp_classify.h>
70#include <linux/init.h>69#include <linux/init.h>
@@ -1027,17 +1026,6 @@ void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) · 956 unmodified lines
1027}1026}
1028EXPORT_SYMBOL(vlan_ioctl_set);1027EXPORT_SYMBOL(vlan_ioctl_set);
1029 1028
1030static DEFINE_MUTEX(dlci_ioctl_mutex);
1031static int (*dlci_ioctl_hook) (unsigned int, void __user *);
1032
1033void 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}
1039EXPORT_SYMBOL(dlci_ioctl_set);
1040
1041static long sock_do_ioctl(struct net *net, struct socket *sock,1029static long sock_do_ioctl(struct net *net, struct socket *sock,
1042 unsigned int cmd, unsigned long arg)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 err = vlan_ioctl_hook(net, argp);1144 err = vlan_ioctl_hook(net, argp);
1157 mutex_unlock(&vlan_ioctl_mutex);1145 mutex_unlock(&vlan_ioctl_mutex);
1158 break;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 case SIOCGSKNS:1147 case SIOCGSKNS:
1171 err = -EPERM;1148 err = -EPERM;
1172 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))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 case SIOCBRDELBR:3404 case SIOCBRDELBR:
3428 case SIOCGIFVLAN:3405 case SIOCGIFVLAN:
3429 case SIOCSIFVLAN:3406 case SIOCSIFVLAN:
3430 case SIOCADDDLCI:
3431 case SIOCDELDLCI:
3432 case SIOCGSKNS:3407 case SIOCGSKNS:
3433 case SIOCGSTAMP_NEW:3408 case SIOCGSTAMP_NEW:
3434 case SIOCGSTAMPNS_NEW:3409 case SIOCGSTAMPNS_NEW: