Deleted Added
full compact
if_plip.c (51646) if_plip.c (55939)
1/*-
2 * Copyright (c) 1997 Poul-Henning Kamp
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 10 unchanged lines hidden (view full) ---

19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp
1/*-
2 * Copyright (c) 1997 Poul-Henning Kamp
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 10 unchanged lines hidden (view full) ---

19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * From Id: lpt.c,v 1.55.2.1 1996/11/12 09:08:38 phk Exp
27 * $FreeBSD: head/sys/dev/ppbus/if_plip.c 51646 1999-09-25 12:06:01Z phk $
27 * $FreeBSD: head/sys/dev/ppbus/if_plip.c 55939 2000-01-14 00:18:06Z nsouch $
28 */
29
30/*
31 * Parallel port TCP/IP interfaces added. I looked at the driver from
32 * MACH but this is a complete rewrite, and btw. incompatible, and it
33 * should perform better too. I have never run the MACH driver though.
34 *
35 * This driver sends two bytes (0x08, 0x00) in front of each packet,

--- 36 unchanged lines hidden (view full) ---

72 * the code would be cleaner
73 *
74 * Poul-Henning Kamp <phk@freebsd.org>
75 */
76
77/*
78 * Update for ppbus, PLIP support only - Nicolas Souchu
79 */
28 */
29
30/*
31 * Parallel port TCP/IP interfaces added. I looked at the driver from
32 * MACH but this is a complete rewrite, and btw. incompatible, and it
33 * should perform better too. I have never run the MACH driver though.
34 *
35 * This driver sends two bytes (0x08, 0x00) in front of each packet,

--- 36 unchanged lines hidden (view full) ---

72 * the code would be cleaner
73 *
74 * Poul-Henning Kamp <phk@freebsd.org>
75 */
76
77/*
78 * Update for ppbus, PLIP support only - Nicolas Souchu
79 */
80#include "plip.h"
80
81
82#if NPLIP > 0
83
84#include "opt_plip.h"
85
81#include <sys/param.h>
82#include <sys/systm.h>
86#include <sys/param.h>
87#include <sys/systm.h>
88#include <sys/module.h>
89#include <sys/bus.h>
90#include <sys/conf.h>
83#include <sys/mbuf.h>
84#include <sys/socket.h>
85#include <sys/sockio.h>
86#include <sys/kernel.h>
87#include <sys/malloc.h>
88
91#include <sys/mbuf.h>
92#include <sys/socket.h>
93#include <sys/sockio.h>
94#include <sys/kernel.h>
95#include <sys/malloc.h>
96
97#include <machine/clock.h>
98#include <machine/bus.h>
99#include <machine/resource.h>
100#include <sys/rman.h>
101
89#include <net/if.h>
90#include <net/if_types.h>
91#include <net/netisr.h>
92
93#include <netinet/in.h>
94#include <netinet/in_var.h>
95
96#include <net/bpf.h>
97
98#include <dev/ppbus/ppbconf.h>
102#include <net/if.h>
103#include <net/if_types.h>
104#include <net/netisr.h>
105
106#include <netinet/in.h>
107#include <netinet/in_var.h>
108
109#include <net/bpf.h>
110
111#include <dev/ppbus/ppbconf.h>
112#include "ppbus_if.h"
113#include <dev/ppbus/ppbio.h>
99
114
100#include "opt_plip.h"
101
102#ifndef LPMTU /* MTU for the lp# interfaces */
103#define LPMTU 1500
104#endif
105
106#ifndef LPMAXSPIN1 /* DELAY factor for the lp# interfaces */
107#define LPMAXSPIN1 8000 /* Spinning for remote intr to happen */
108#endif
109

--- 20 unchanged lines hidden (view full) ---

130#define lprintf if (lptflag) printf
131
132#ifdef PLIP_DEBUG
133static int volatile lptflag = 1;
134#else
135static int volatile lptflag = 0;
136#endif
137
115#ifndef LPMTU /* MTU for the lp# interfaces */
116#define LPMTU 1500
117#endif
118
119#ifndef LPMAXSPIN1 /* DELAY factor for the lp# interfaces */
120#define LPMAXSPIN1 8000 /* Spinning for remote intr to happen */
121#endif
122

--- 20 unchanged lines hidden (view full) ---

143#define lprintf if (lptflag) printf
144
145#ifdef PLIP_DEBUG
146static int volatile lptflag = 1;
147#else
148static int volatile lptflag = 0;
149#endif
150
138struct lpt_softc {
151struct lp_data {
139 unsigned short lp_unit;
140
152 unsigned short lp_unit;
153
141 struct ppb_device lp_dev;
142
143 struct ifnet sc_if;
144 u_char *sc_ifbuf;
145 int sc_iferrs;
154 struct ifnet sc_if;
155 u_char *sc_ifbuf;
156 int sc_iferrs;
157
158 struct resource *res_irq;
146};
147
159};
160
148static int nlp = 0;
149#define MAXPLIP 8 /* XXX not much better! */
150static struct lpt_softc *lpdata[MAXPLIP];
151
152
153/* Tables for the lp# interface */
154static u_char *txmith;
155#define txmitl (txmith+(1*LPIPTBLSIZE))
156#define trecvh (txmith+(2*LPIPTBLSIZE))
157#define trecvl (txmith+(3*LPIPTBLSIZE))
158
159static u_char *ctxmith;
160#define ctxmitl (ctxmith+(1*LPIPTBLSIZE))
161#define ctrecvh (ctxmith+(2*LPIPTBLSIZE))
162#define ctrecvl (ctxmith+(3*LPIPTBLSIZE))
163
164/* Functions for the lp# interface */
161/* Tables for the lp# interface */
162static u_char *txmith;
163#define txmitl (txmith+(1*LPIPTBLSIZE))
164#define trecvh (txmith+(2*LPIPTBLSIZE))
165#define trecvl (txmith+(3*LPIPTBLSIZE))
166
167static u_char *ctxmith;
168#define ctxmitl (ctxmith+(1*LPIPTBLSIZE))
169#define ctrecvh (ctxmith+(2*LPIPTBLSIZE))
170#define ctrecvl (ctxmith+(3*LPIPTBLSIZE))
171
172/* Functions for the lp# interface */
165static struct ppb_device *lpprobe(struct ppb_data *);
166static int lpattach(struct ppb_device *);
173static int lp_probe(device_t dev);
174static int lp_attach(device_t dev);
167
168static int lpinittables(void);
169static int lpioctl(struct ifnet *, u_long, caddr_t);
170static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
171 struct rtentry *);
175
176static int lpinittables(void);
177static int lpioctl(struct ifnet *, u_long, caddr_t);
178static int lpoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
179 struct rtentry *);
172static void lpintr(int);
180static void lp_intr(void *);
173
181
174/*
175 * Make ourselves visible as a ppbus driver
176 */
182#define DEVTOSOFTC(dev) \
183 ((struct lp_data *)device_get_softc(dev))
184#define UNITOSOFTC(unit) \
185 ((struct lp_data *)devclass_get_softc(lp_devclass, (unit)))
186#define UNITODEVICE(unit) \
187 (devclass_get_device(lp_devclass, (unit)))
177
188
178static struct ppb_driver lpdriver = {
179 lpprobe, lpattach, "lp"
189static devclass_t lp_devclass;
190
191static device_method_t lp_methods[] = {
192 /* device interface */
193 DEVMETHOD(device_probe, lp_probe),
194 DEVMETHOD(device_attach, lp_attach),
195
196 { 0, 0 }
180};
197};
181DATA_SET(ppbdriver_set, lpdriver);
182
198
199static driver_t lp_driver = {
200 "plip",
201 lp_methods,
202 sizeof(struct lp_data),
203};
183
184/*
185 * lpprobe()
186 */
204
205/*
206 * lpprobe()
207 */
187static struct ppb_device *
188lpprobe(struct ppb_data *ppb)
208static int
209lp_probe(device_t dev)
189{
210{
190 struct lpt_softc *lp;
211 device_t ppbus = device_get_parent(dev);
212 struct lp_data *lp;
213 int irq, zero = 0;
191
214
215 lp = DEVTOSOFTC(dev);
216 bzero(lp, sizeof(struct lp_data));
217
218 /* retrieve the ppbus irq */
219 BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
220
192 /* if we haven't interrupts, the probe fails */
221 /* if we haven't interrupts, the probe fails */
193 if (!ppb->ppb_link->id_irq) {
194 printf("plip: not an interrupt driven port, failed.\n");
195 return (0);
222 if (irq == -1) {
223 device_printf(dev, "not an interrupt driven port, failed.\n");
224 return (ENXIO);
196 }
197
225 }
226
198 lp = (struct lpt_softc *) malloc(sizeof(struct lpt_softc),
199 M_TEMP, M_NOWAIT);
200 if (!lp) {
201 printf("lp: cannot malloc!\n");
202 return (0);
227 /* reserve the interrupt resource, expecting irq is available to continue */
228 lp->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1,
229 RF_SHAREABLE);
230 if (lp->res_irq == 0) {
231 device_printf(dev, "cannot reserve interrupt, failed.\n");
232 return (ENXIO);
203 }
233 }
204 bzero(lp, sizeof(struct lpt_softc));
205
234
206 lpdata[nlp] = lp;
207
208 /*
209 * lp dependent initialisation.
210 */
235 /*
236 * lp dependent initialisation.
237 */
211 lp->lp_unit = nlp;
238 lp->lp_unit = device_get_unit(dev);
212
239
213 if (bootverbose)
214 printf("plip: irq %d\n", ppb->ppb_link->id_irq);
240 device_set_desc(dev, "PLIP network interface");
215
241
216 /*
217 * ppbus dependent initialisation.
218 */
219 lp->lp_dev.id_unit = lp->lp_unit;
220 lp->lp_dev.name = lpdriver.name;
221 lp->lp_dev.ppb = ppb;
222 lp->lp_dev.intr = lpintr;
223
224 /* Ok, go to next device on next probe */
225 nlp ++;
226
227 return (&lp->lp_dev);
242 return (0);
228}
229
230static int
243}
244
245static int
231lpattach (struct ppb_device *dev)
246lp_attach (device_t dev)
232{
247{
233 int unit = dev->id_unit;
234 struct lpt_softc *sc = lpdata[unit];
235 struct ifnet *ifp = &sc->sc_if;
248 struct lp_data *lp = DEVTOSOFTC(dev);
249 struct ifnet *ifp = &lp->sc_if;
236
250
237 /*
238 * Report ourselves
239 */
240 printf("plip%d: <PLIP network interface> on ppbus %d\n",
241 dev->id_unit, dev->ppb->ppb_link->adapter_unit);
242
243 ifp->if_softc = sc;
251 ifp->if_softc = lp;
244 ifp->if_name = "lp";
252 ifp->if_name = "lp";
245 ifp->if_unit = unit;
253 ifp->if_unit = device_get_unit(dev);
246 ifp->if_mtu = LPMTU;
247 ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
248 ifp->if_ioctl = lpioctl;
249 ifp->if_output = lpoutput;
250 ifp->if_type = IFT_PARA;
251 ifp->if_hdrlen = 0;
252 ifp->if_addrlen = 0;
253 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
254 if_attach(ifp);
255
256 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
257
254 ifp->if_mtu = LPMTU;
255 ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT | IFF_MULTICAST;
256 ifp->if_ioctl = lpioctl;
257 ifp->if_output = lpoutput;
258 ifp->if_type = IFT_PARA;
259 ifp->if_hdrlen = 0;
260 ifp->if_addrlen = 0;
261 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
262 if_attach(ifp);
263
264 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
265
258 return (1);
266 return (0);
259}
260/*
261 * Build the translation tables for the LPIP (BSD unix) protocol.
262 * We don't want to calculate these nasties in our tight loop, so we
263 * precalculate them when we initialize.
264 */
265static int
266lpinittables (void)

--- 31 unchanged lines hidden (view full) ---

298
299/*
300 * Process an ioctl request.
301 */
302
303static int
304lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
305{
267}
268/*
269 * Build the translation tables for the LPIP (BSD unix) protocol.
270 * We don't want to calculate these nasties in our tight loop, so we
271 * precalculate them when we initialize.
272 */
273static int
274lpinittables (void)

--- 31 unchanged lines hidden (view full) ---

306
307/*
308 * Process an ioctl request.
309 */
310
311static int
312lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
313{
306 struct lpt_softc *sc = lpdata[ifp->if_unit];
314 device_t dev = UNITODEVICE(ifp->if_unit);
315 device_t ppbus = device_get_parent(dev);
316 struct lp_data *sc = DEVTOSOFTC(dev);
307 struct ifaddr *ifa = (struct ifaddr *)data;
308 struct ifreq *ifr = (struct ifreq *)data;
309 u_char *ptr;
317 struct ifaddr *ifa = (struct ifaddr *)data;
318 struct ifreq *ifr = (struct ifreq *)data;
319 u_char *ptr;
320 void *ih;
310 int error;
311
312 switch (cmd) {
313
314 case SIOCSIFDSTADDR:
315 case SIOCAIFADDR:
316 case SIOCSIFADDR:
317 if (ifa->ifa_addr->sa_family != AF_INET)
318 return EAFNOSUPPORT;
319
320 ifp->if_flags |= IFF_UP;
321 /* FALLTHROUGH */
322 case SIOCSIFFLAGS:
323 if ((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) {
324
321 int error;
322
323 switch (cmd) {
324
325 case SIOCSIFDSTADDR:
326 case SIOCAIFADDR:
327 case SIOCSIFADDR:
328 if (ifa->ifa_addr->sa_family != AF_INET)
329 return EAFNOSUPPORT;
330
331 ifp->if_flags |= IFF_UP;
332 /* FALLTHROUGH */
333 case SIOCSIFFLAGS:
334 if ((!(ifp->if_flags & IFF_UP)) && (ifp->if_flags & IFF_RUNNING)) {
335
325 ppb_wctr(&sc->lp_dev, 0x00);
336 ppb_wctr(ppbus, 0x00);
326 ifp->if_flags &= ~IFF_RUNNING;
327
328 /* IFF_UP is not set, try to release the bus anyway */
337 ifp->if_flags &= ~IFF_RUNNING;
338
339 /* IFF_UP is not set, try to release the bus anyway */
329 ppb_release_bus(&sc->lp_dev);
340 ppb_release_bus(ppbus, dev);
330 break;
331 }
332 if (((ifp->if_flags & IFF_UP)) && (!(ifp->if_flags & IFF_RUNNING))) {
333
334 /* XXX
335 * Should the request be interruptible?
336 */
341 break;
342 }
343 if (((ifp->if_flags & IFF_UP)) && (!(ifp->if_flags & IFF_RUNNING))) {
344
345 /* XXX
346 * Should the request be interruptible?
347 */
337 if ((error = ppb_request_bus(&sc->lp_dev, PPB_WAIT|PPB_INTR)))
348 if ((error = ppb_request_bus(ppbus, dev, PPB_WAIT|PPB_INTR)))
338 return (error);
339
340 /* Now IFF_UP means that we own the bus */
341
349 return (error);
350
351 /* Now IFF_UP means that we own the bus */
352
342 ppb_set_mode(&sc->lp_dev, PPB_COMPATIBLE);
353 ppb_set_mode(ppbus, PPB_COMPATIBLE);
343
344 if (lpinittables()) {
354
355 if (lpinittables()) {
345 ppb_release_bus(&sc->lp_dev);
356 ppb_release_bus(ppbus, dev);
346 return ENOBUFS;
347 }
348
349 sc->sc_ifbuf = malloc(sc->sc_if.if_mtu + MLPIPHDRLEN,
350 M_DEVBUF, M_WAITOK);
351 if (!sc->sc_ifbuf) {
357 return ENOBUFS;
358 }
359
360 sc->sc_ifbuf = malloc(sc->sc_if.if_mtu + MLPIPHDRLEN,
361 M_DEVBUF, M_WAITOK);
362 if (!sc->sc_ifbuf) {
352 ppb_release_bus(&sc->lp_dev);
363 ppb_release_bus(ppbus, dev);
353 return ENOBUFS;
354 }
355
364 return ENOBUFS;
365 }
366
356 ppb_wctr(&sc->lp_dev, IRQENABLE);
367 /* attach our interrupt handler, later detached when the bus is released */
368 if ((error = BUS_SETUP_INTR(ppbus, dev, sc->res_irq,
369 INTR_TYPE_NET, lp_intr, dev, &ih))) {
370 ppb_release_bus(ppbus, dev);
371 return (error);
372 }
373
374 ppb_wctr(ppbus, IRQENABLE);
357 ifp->if_flags |= IFF_RUNNING;
358 }
359 break;
360
361 case SIOCSIFMTU:
362 ptr = sc->sc_ifbuf;
363 sc->sc_ifbuf = malloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_NOWAIT);
364 if (!sc->sc_ifbuf) {

--- 34 unchanged lines hidden (view full) ---

399 default:
400 lprintf("LP:ioctl(0x%lx)\n", cmd);
401 return EINVAL;
402 }
403 return 0;
404}
405
406static __inline int
375 ifp->if_flags |= IFF_RUNNING;
376 }
377 break;
378
379 case SIOCSIFMTU:
380 ptr = sc->sc_ifbuf;
381 sc->sc_ifbuf = malloc(ifr->ifr_mtu+MLPIPHDRLEN, M_DEVBUF, M_NOWAIT);
382 if (!sc->sc_ifbuf) {

--- 34 unchanged lines hidden (view full) ---

417 default:
418 lprintf("LP:ioctl(0x%lx)\n", cmd);
419 return EINVAL;
420 }
421 return 0;
422}
423
424static __inline int
407clpoutbyte (u_char byte, int spin, struct ppb_device *dev)
425clpoutbyte (u_char byte, int spin, device_t ppbus)
408{
426{
409 ppb_wdtr(dev, ctxmitl[byte]);
410 while (ppb_rstr(dev) & CLPIP_SHAKE)
427 ppb_wdtr(ppbus, ctxmitl[byte]);
428 while (ppb_rstr(ppbus) & CLPIP_SHAKE)
411 if (--spin == 0) {
412 return 1;
413 }
429 if (--spin == 0) {
430 return 1;
431 }
414 ppb_wdtr(dev, ctxmith[byte]);
415 while (!(ppb_rstr(dev) & CLPIP_SHAKE))
432 ppb_wdtr(ppbus, ctxmith[byte]);
433 while (!(ppb_rstr(ppbus) & CLPIP_SHAKE))
416 if (--spin == 0) {
417 return 1;
418 }
419 return 0;
420}
421
422static __inline int
434 if (--spin == 0) {
435 return 1;
436 }
437 return 0;
438}
439
440static __inline int
423clpinbyte (int spin, struct ppb_device *dev)
441clpinbyte (int spin, device_t ppbus)
424{
425 u_char c, cl;
426
442{
443 u_char c, cl;
444
427 while((ppb_rstr(dev) & CLPIP_SHAKE))
445 while((ppb_rstr(ppbus) & CLPIP_SHAKE))
428 if(!--spin) {
429 return -1;
430 }
446 if(!--spin) {
447 return -1;
448 }
431 cl = ppb_rstr(dev);
432 ppb_wdtr(dev, 0x10);
449 cl = ppb_rstr(ppbus);
450 ppb_wdtr(ppbus, 0x10);
433
451
434 while(!(ppb_rstr(dev) & CLPIP_SHAKE))
452 while(!(ppb_rstr(ppbus) & CLPIP_SHAKE))
435 if(!--spin) {
436 return -1;
437 }
453 if(!--spin) {
454 return -1;
455 }
438 c = ppb_rstr(dev);
439 ppb_wdtr(dev, 0x00);
456 c = ppb_rstr(ppbus);
457 ppb_wdtr(ppbus, 0x00);
440
441 return (ctrecvl[cl] | ctrecvh[c]);
442}
443
444static void
445lptap(struct ifnet *ifp, struct mbuf *m)
446{
447 /*

--- 7 unchanged lines hidden (view full) ---

455
456 m0.m_next = m;
457 m0.m_len = sizeof(u_int32_t);
458 m0.m_data = (char *)&af;
459 bpf_mtap(ifp, &m0);
460}
461
462static void
458
459 return (ctrecvl[cl] | ctrecvh[c]);
460}
461
462static void
463lptap(struct ifnet *ifp, struct mbuf *m)
464{
465 /*

--- 7 unchanged lines hidden (view full) ---

473
474 m0.m_next = m;
475 m0.m_len = sizeof(u_int32_t);
476 m0.m_data = (char *)&af;
477 bpf_mtap(ifp, &m0);
478}
479
480static void
463lpintr (int unit)
481lp_intr (void *arg)
464{
482{
465 struct lpt_softc *sc = lpdata[unit];
483 device_t dev = (device_t)arg;
484 device_t ppbus = device_get_parent(dev);
485 struct lp_data *sc = DEVTOSOFTC(dev);
466 int len, s, j;
467 u_char *bp;
468 u_char c, cl;
469 struct mbuf *top;
470
471 s = splhigh();
472
473 if (sc->sc_if.if_flags & IFF_LINK0) {
474
475 /* Ack. the request */
486 int len, s, j;
487 u_char *bp;
488 u_char c, cl;
489 struct mbuf *top;
490
491 s = splhigh();
492
493 if (sc->sc_if.if_flags & IFF_LINK0) {
494
495 /* Ack. the request */
476 ppb_wdtr(&sc->lp_dev, 0x01);
496 ppb_wdtr(ppbus, 0x01);
477
478 /* Get the packet length */
497
498 /* Get the packet length */
479 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
499 j = clpinbyte(LPMAXSPIN2, ppbus);
480 if (j == -1)
481 goto err;
482 len = j;
500 if (j == -1)
501 goto err;
502 len = j;
483 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
503 j = clpinbyte(LPMAXSPIN2, ppbus);
484 if (j == -1)
485 goto err;
486 len = len + (j << 8);
487 if (len > sc->sc_if.if_mtu + MLPIPHDRLEN)
488 goto err;
489
490 bp = sc->sc_ifbuf;
491
492 while (len--) {
504 if (j == -1)
505 goto err;
506 len = len + (j << 8);
507 if (len > sc->sc_if.if_mtu + MLPIPHDRLEN)
508 goto err;
509
510 bp = sc->sc_ifbuf;
511
512 while (len--) {
493 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
513 j = clpinbyte(LPMAXSPIN2, ppbus);
494 if (j == -1) {
495 goto err;
496 }
497 *bp++ = j;
498 }
499 /* Get and ignore checksum */
514 if (j == -1) {
515 goto err;
516 }
517 *bp++ = j;
518 }
519 /* Get and ignore checksum */
500 j = clpinbyte(LPMAXSPIN2, &sc->lp_dev);
520 j = clpinbyte(LPMAXSPIN2, ppbus);
501 if (j == -1) {
502 goto err;
503 }
504
505 len = bp - sc->sc_ifbuf;
506 if (len <= CLPIPHDRLEN)
507 goto err;
508

--- 11 unchanged lines hidden (view full) ---

520 if (top) {
521 if (sc->sc_if.if_bpf)
522 lptap(&sc->sc_if, top);
523 IF_ENQUEUE(&ipintrq, top);
524 schednetisr(NETISR_IP);
525 }
526 goto done;
527 }
521 if (j == -1) {
522 goto err;
523 }
524
525 len = bp - sc->sc_ifbuf;
526 if (len <= CLPIPHDRLEN)
527 goto err;
528

--- 11 unchanged lines hidden (view full) ---

540 if (top) {
541 if (sc->sc_if.if_bpf)
542 lptap(&sc->sc_if, top);
543 IF_ENQUEUE(&ipintrq, top);
544 schednetisr(NETISR_IP);
545 }
546 goto done;
547 }
528 while ((ppb_rstr(&sc->lp_dev) & LPIP_SHAKE)) {
548 while ((ppb_rstr(ppbus) & LPIP_SHAKE)) {
529 len = sc->sc_if.if_mtu + LPIPHDRLEN;
530 bp = sc->sc_ifbuf;
531 while (len--) {
532
549 len = sc->sc_if.if_mtu + LPIPHDRLEN;
550 bp = sc->sc_ifbuf;
551 while (len--) {
552
533 cl = ppb_rstr(&sc->lp_dev);
534 ppb_wdtr(&sc->lp_dev, 8);
553 cl = ppb_rstr(ppbus);
554 ppb_wdtr(ppbus, 8);
535
536 j = LPMAXSPIN2;
555
556 j = LPMAXSPIN2;
537 while((ppb_rstr(&sc->lp_dev) & LPIP_SHAKE))
557 while((ppb_rstr(ppbus) & LPIP_SHAKE))
538 if(!--j) goto err;
539
558 if(!--j) goto err;
559
540 c = ppb_rstr(&sc->lp_dev);
541 ppb_wdtr(&sc->lp_dev, 0);
560 c = ppb_rstr(ppbus);
561 ppb_wdtr(ppbus, 0);
542
543 *bp++= trecvh[cl] | trecvl[c];
544
545 j = LPMAXSPIN2;
562
563 *bp++= trecvh[cl] | trecvl[c];
564
565 j = LPMAXSPIN2;
546 while (!((cl=ppb_rstr(&sc->lp_dev)) & LPIP_SHAKE)) {
566 while (!((cl=ppb_rstr(ppbus)) & LPIP_SHAKE)) {
547 if (cl != c &&
567 if (cl != c &&
548 (((cl = ppb_rstr(&sc->lp_dev)) ^ 0xb8) & 0xf8) ==
568 (((cl = ppb_rstr(ppbus)) ^ 0xb8) & 0xf8) ==
549 (c & 0xf8))
550 goto end;
551 if (!--j) goto err;
552 }
553 }
554
555 end:
556 len = bp - sc->sc_ifbuf;

--- 16 unchanged lines hidden (view full) ---

573 lptap(&sc->sc_if, top);
574 IF_ENQUEUE(&ipintrq, top);
575 schednetisr(NETISR_IP);
576 }
577 }
578 goto done;
579
580 err:
569 (c & 0xf8))
570 goto end;
571 if (!--j) goto err;
572 }
573 }
574
575 end:
576 len = bp - sc->sc_ifbuf;

--- 16 unchanged lines hidden (view full) ---

593 lptap(&sc->sc_if, top);
594 IF_ENQUEUE(&ipintrq, top);
595 schednetisr(NETISR_IP);
596 }
597 }
598 goto done;
599
600 err:
581 ppb_wdtr(&sc->lp_dev, 0);
601 ppb_wdtr(ppbus, 0);
582 lprintf("R");
583 sc->sc_if.if_ierrors++;
584 sc->sc_iferrs++;
585
586 /*
587 * We are not able to send receive anything for now,
588 * so stop wasting our time
589 */
590 if (sc->sc_iferrs > LPMAXERRS) {
602 lprintf("R");
603 sc->sc_if.if_ierrors++;
604 sc->sc_iferrs++;
605
606 /*
607 * We are not able to send receive anything for now,
608 * so stop wasting our time
609 */
610 if (sc->sc_iferrs > LPMAXERRS) {
591 printf("lp%d: Too many errors, Going off-line.\n", unit);
592 ppb_wctr(&sc->lp_dev, 0x00);
611 printf("lp%d: Too many errors, Going off-line.\n", device_get_unit(dev));
612 ppb_wctr(ppbus, 0x00);
593 sc->sc_if.if_flags &= ~IFF_RUNNING;
594 sc->sc_iferrs=0;
595 }
596
597 done:
598 splx(s);
599 return;
600}
601
602static __inline int
613 sc->sc_if.if_flags &= ~IFF_RUNNING;
614 sc->sc_iferrs=0;
615 }
616
617 done:
618 splx(s);
619 return;
620}
621
622static __inline int
603lpoutbyte (u_char byte, int spin, struct ppb_device *dev)
623lpoutbyte (u_char byte, int spin, device_t ppbus)
604{
624{
605 ppb_wdtr(dev, txmith[byte]);
606 while (!(ppb_rstr(dev) & LPIP_SHAKE))
625 ppb_wdtr(ppbus, txmith[byte]);
626 while (!(ppb_rstr(ppbus) & LPIP_SHAKE))
607 if (--spin == 0)
608 return 1;
627 if (--spin == 0)
628 return 1;
609 ppb_wdtr(dev, txmitl[byte]);
610 while (ppb_rstr(dev) & LPIP_SHAKE)
629 ppb_wdtr(ppbus, txmitl[byte]);
630 while (ppb_rstr(ppbus) & LPIP_SHAKE)
611 if (--spin == 0)
612 return 1;
613 return 0;
614}
615
616static int
617lpoutput (struct ifnet *ifp, struct mbuf *m,
618 struct sockaddr *dst, struct rtentry *rt)
619{
631 if (--spin == 0)
632 return 1;
633 return 0;
634}
635
636static int
637lpoutput (struct ifnet *ifp, struct mbuf *m,
638 struct sockaddr *dst, struct rtentry *rt)
639{
620 struct lpt_softc *sc = lpdata[ifp->if_unit];
640 device_t dev = UNITODEVICE(ifp->if_unit);
641 device_t ppbus = device_get_parent(dev);
621 int s, err;
622 struct mbuf *mm;
623 u_char *cp = "\0\0";
624 u_char chksum = 0;
625 int count = 0;
626 int i, len, spin;
627
628 /* We need a sensible value if we abort */
629 cp++;
630 ifp->if_flags |= IFF_RUNNING;
631
632 err = 1; /* assume we're aborting because of an error */
633
634 s = splhigh();
635
636 /* Suspend (on laptops) or receive-errors might have taken us offline */
642 int s, err;
643 struct mbuf *mm;
644 u_char *cp = "\0\0";
645 u_char chksum = 0;
646 int count = 0;
647 int i, len, spin;
648
649 /* We need a sensible value if we abort */
650 cp++;
651 ifp->if_flags |= IFF_RUNNING;
652
653 err = 1; /* assume we're aborting because of an error */
654
655 s = splhigh();
656
657 /* Suspend (on laptops) or receive-errors might have taken us offline */
637 ppb_wctr(&sc->lp_dev, IRQENABLE);
658 ppb_wctr(ppbus, IRQENABLE);
638
639 if (ifp->if_flags & IFF_LINK0) {
640
659
660 if (ifp->if_flags & IFF_LINK0) {
661
641 if (!(ppb_rstr(&sc->lp_dev) & CLPIP_SHAKE)) {
662 if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) {
642 lprintf("&");
663 lprintf("&");
643 lpintr(ifp->if_unit);
664 lp_intr(dev);
644 }
645
646 /* Alert other end to pending packet */
647 spin = LPMAXSPIN1;
665 }
666
667 /* Alert other end to pending packet */
668 spin = LPMAXSPIN1;
648 ppb_wdtr(&sc->lp_dev, 0x08);
649 while ((ppb_rstr(&sc->lp_dev) & 0x08) == 0)
669 ppb_wdtr(ppbus, 0x08);
670 while ((ppb_rstr(ppbus) & 0x08) == 0)
650 if (--spin == 0) {
651 goto nend;
652 }
653
654 /* Calculate length of packet, then send that */
655
656 count += 14; /* Ethernet header len */
657
658 mm = m;
659 for (mm = m; mm; mm = mm->m_next) {
660 count += mm->m_len;
661 }
671 if (--spin == 0) {
672 goto nend;
673 }
674
675 /* Calculate length of packet, then send that */
676
677 count += 14; /* Ethernet header len */
678
679 mm = m;
680 for (mm = m; mm; mm = mm->m_next) {
681 count += mm->m_len;
682 }
662 if (clpoutbyte(count & 0xFF, LPMAXSPIN1, &sc->lp_dev))
683 if (clpoutbyte(count & 0xFF, LPMAXSPIN1, ppbus))
663 goto nend;
684 goto nend;
664 if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, &sc->lp_dev))
685 if (clpoutbyte((count >> 8) & 0xFF, LPMAXSPIN1, ppbus))
665 goto nend;
666
667 /* Send dummy ethernet header */
668 for (i = 0; i < 12; i++) {
686 goto nend;
687
688 /* Send dummy ethernet header */
689 for (i = 0; i < 12; i++) {
669 if (clpoutbyte(i, LPMAXSPIN1, &sc->lp_dev))
690 if (clpoutbyte(i, LPMAXSPIN1, ppbus))
670 goto nend;
671 chksum += i;
672 }
673
691 goto nend;
692 chksum += i;
693 }
694
674 if (clpoutbyte(0x08, LPMAXSPIN1, &sc->lp_dev))
695 if (clpoutbyte(0x08, LPMAXSPIN1, ppbus))
675 goto nend;
696 goto nend;
676 if (clpoutbyte(0x00, LPMAXSPIN1, &sc->lp_dev))
697 if (clpoutbyte(0x00, LPMAXSPIN1, ppbus))
677 goto nend;
678 chksum += 0x08 + 0x00; /* Add into checksum */
679
680 mm = m;
681 do {
682 cp = mtod(mm, u_char *);
683 len = mm->m_len;
684 while (len--) {
685 chksum += *cp;
698 goto nend;
699 chksum += 0x08 + 0x00; /* Add into checksum */
700
701 mm = m;
702 do {
703 cp = mtod(mm, u_char *);
704 len = mm->m_len;
705 while (len--) {
706 chksum += *cp;
686 if (clpoutbyte(*cp++, LPMAXSPIN2, &sc->lp_dev))
707 if (clpoutbyte(*cp++, LPMAXSPIN2, ppbus))
687 goto nend;
688 }
689 } while ((mm = mm->m_next));
690
691 /* Send checksum */
708 goto nend;
709 }
710 } while ((mm = mm->m_next));
711
712 /* Send checksum */
692 if (clpoutbyte(chksum, LPMAXSPIN2, &sc->lp_dev))
713 if (clpoutbyte(chksum, LPMAXSPIN2, ppbus))
693 goto nend;
694
695 /* Go quiescent */
714 goto nend;
715
716 /* Go quiescent */
696 ppb_wdtr(&sc->lp_dev, 0);
717 ppb_wdtr(ppbus, 0);
697
698 err = 0; /* No errors */
699
700 nend:
701 if (err) { /* if we didn't timeout... */
702 ifp->if_oerrors++;
703 lprintf("X");
704 } else {
705 ifp->if_opackets++;
706 ifp->if_obytes += m->m_pkthdr.len;
707 if (ifp->if_bpf)
708 lptap(ifp, m);
709 }
710
711 m_freem(m);
712
718
719 err = 0; /* No errors */
720
721 nend:
722 if (err) { /* if we didn't timeout... */
723 ifp->if_oerrors++;
724 lprintf("X");
725 } else {
726 ifp->if_opackets++;
727 ifp->if_obytes += m->m_pkthdr.len;
728 if (ifp->if_bpf)
729 lptap(ifp, m);
730 }
731
732 m_freem(m);
733
713 if (!(ppb_rstr(&sc->lp_dev) & CLPIP_SHAKE)) {
734 if (!(ppb_rstr(ppbus) & CLPIP_SHAKE)) {
714 lprintf("^");
735 lprintf("^");
715 lpintr(ifp->if_unit);
736 lp_intr(dev);
716 }
717 (void) splx(s);
718 return 0;
719 }
720
737 }
738 (void) splx(s);
739 return 0;
740 }
741
721 if (ppb_rstr(&sc->lp_dev) & LPIP_SHAKE) {
742 if (ppb_rstr(ppbus) & LPIP_SHAKE) {
722 lprintf("&");
743 lprintf("&");
723 lpintr(ifp->if_unit);
744 lp_intr(dev);
724 }
725
745 }
746
726 if (lpoutbyte(0x08, LPMAXSPIN1, &sc->lp_dev))
747 if (lpoutbyte(0x08, LPMAXSPIN1, ppbus))
727 goto end;
748 goto end;
728 if (lpoutbyte(0x00, LPMAXSPIN2, &sc->lp_dev))
749 if (lpoutbyte(0x00, LPMAXSPIN2, ppbus))
729 goto end;
730
731 mm = m;
732 do {
733 cp = mtod(mm,u_char *);
734 len = mm->m_len;
735 while (len--)
750 goto end;
751
752 mm = m;
753 do {
754 cp = mtod(mm,u_char *);
755 len = mm->m_len;
756 while (len--)
736 if (lpoutbyte(*cp++, LPMAXSPIN2, &sc->lp_dev))
757 if (lpoutbyte(*cp++, LPMAXSPIN2, ppbus))
737 goto end;
738 } while ((mm = mm->m_next));
739
740 err = 0; /* no errors were encountered */
741
742 end:
743 --cp;
758 goto end;
759 } while ((mm = mm->m_next));
760
761 err = 0; /* no errors were encountered */
762
763 end:
764 --cp;
744 ppb_wdtr(&sc->lp_dev, txmitl[*cp] ^ 0x17);
765 ppb_wdtr(ppbus, txmitl[*cp] ^ 0x17);
745
746 if (err) { /* if we didn't timeout... */
747 ifp->if_oerrors++;
748 lprintf("X");
749 } else {
750 ifp->if_opackets++;
751 ifp->if_obytes += m->m_pkthdr.len;
752 if (ifp->if_bpf)
753 lptap(ifp, m);
754 }
755
756 m_freem(m);
757
766
767 if (err) { /* if we didn't timeout... */
768 ifp->if_oerrors++;
769 lprintf("X");
770 } else {
771 ifp->if_opackets++;
772 ifp->if_obytes += m->m_pkthdr.len;
773 if (ifp->if_bpf)
774 lptap(ifp, m);
775 }
776
777 m_freem(m);
778
758 if (ppb_rstr(&sc->lp_dev) & LPIP_SHAKE) {
779 if (ppb_rstr(ppbus) & LPIP_SHAKE) {
759 lprintf("^");
780 lprintf("^");
760 lpintr(ifp->if_unit);
781 lp_intr(dev);
761 }
762
763 (void) splx(s);
764 return 0;
765}
782 }
783
784 (void) splx(s);
785 return 0;
786}
787
788DRIVER_MODULE(plip, ppbus, lp_driver, lp_devclass, 0, 0);
789
790#endif /* NPLIP > 0 */