2 * Copyright (c) 1997-2001 Granch, Ltd. All rights reserved.
3 * Author: Denis I.Timofeev <timofeev@granch.ru>
5 * Redistributon and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
33 * Device driver for Granch SBNI12 leased line adapters
35 * Revision 2.0.0 1997/08/06
36 * Initial revision by Alexey Zverev
38 * Revision 2.0.1 1997/08/11
39 * Additional internal statistics support (tx statistics)
41 * Revision 2.0.2 1997/11/05
42 * if_bpf bug has been fixed
44 * Revision 2.0.3 1998/12/20
45 * Memory leakage has been eliminated in
46 * the sbni_st and sbni_timeout routines.
48 * Revision 3.0 2000/08/10 by Yaroslav Polyakov
49 * Support for PCI cards. 4.1 modification.
51 * Revision 3.1 2000/09/12
52 * Removed extra #defines around bpf functions
54 * Revision 4.0 2000/11/23 by Denis Timofeev
55 * Completely redesigned the buffer management
57 * Revision 4.1 2001/01/21
58 * Support for PCI Dual cards and new SBNI12D-10, -11 Dual/ISA cards
60 * Written with reference to NE2000 driver developed by David Greenman.
63 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
69 #include <sys/kernel.h>
72 #include <sys/callout.h>
73 #include <sys/syslog.h>
74 #include <sys/random.h>
76 #include <machine/bus.h>
78 #include <machine/resource.h>
81 #include <net/if_var.h>
82 #include <net/if_dl.h>
83 #include <net/ethernet.h>
85 #include <net/if_types.h>
87 #include <dev/sbni/if_sbnireg.h>
88 #include <dev/sbni/if_sbnivar.h>
90 static void sbni_init(void *);
91 static void sbni_init_locked(struct sbni_softc *);
92 static void sbni_start(struct ifnet *);
93 static void sbni_start_locked(struct ifnet *);
94 static int sbni_ioctl(struct ifnet *, u_long, caddr_t);
95 static void sbni_stop(struct sbni_softc *);
96 static void handle_channel(struct sbni_softc *);
98 static void card_start(struct sbni_softc *);
99 static int recv_frame(struct sbni_softc *);
100 static void send_frame(struct sbni_softc *);
101 static int upload_data(struct sbni_softc *, u_int, u_int, u_int, u_int32_t);
102 static int skip_tail(struct sbni_softc *, u_int, u_int32_t);
103 static void interpret_ack(struct sbni_softc *, u_int);
104 static void download_data(struct sbni_softc *, u_int32_t *);
105 static void prepare_to_send(struct sbni_softc *);
106 static void drop_xmit_queue(struct sbni_softc *);
107 static int get_rx_buf(struct sbni_softc *);
108 static void indicate_pkt(struct sbni_softc *);
109 static void change_level(struct sbni_softc *);
110 static int check_fhdr(struct sbni_softc *, u_int *, u_int *,
111 u_int *, u_int *, u_int32_t *);
112 static int append_frame_to_pkt(struct sbni_softc *, u_int, u_int32_t);
113 static void timeout_change_level(struct sbni_softc *);
114 static void send_frame_header(struct sbni_softc *, u_int32_t *);
115 static void set_initial_values(struct sbni_softc *, struct sbni_flags);
117 static u_int32_t calc_crc32(u_int32_t, caddr_t, u_int);
118 static callout_func_t sbni_timeout;
120 static __inline u_char sbni_inb(struct sbni_softc *, enum sbni_reg);
121 static __inline void sbni_outb(struct sbni_softc *, enum sbni_reg, u_char);
122 static __inline void sbni_insb(struct sbni_softc *, u_char *, u_int);
123 static __inline void sbni_outsb(struct sbni_softc *, u_char *, u_int);
125 static u_int32_t crc32tab[];
127 #ifdef SBNI_DUAL_COMPOUND
128 static struct mtx headlist_lock;
129 MTX_SYSINIT(headlist_lock, &headlist_lock, "sbni headlist", MTX_DEF);
130 static struct sbni_softc *sbni_headlist;
133 /* -------------------------------------------------------------------------- */
135 static __inline u_char
136 sbni_inb(struct sbni_softc *sc, enum sbni_reg reg)
138 return bus_space_read_1(
139 rman_get_bustag(sc->io_res),
140 rman_get_bushandle(sc->io_res),
145 sbni_outb(struct sbni_softc *sc, enum sbni_reg reg, u_char value)
148 rman_get_bustag(sc->io_res),
149 rman_get_bushandle(sc->io_res),
150 sc->io_off + reg, value);
154 sbni_insb(struct sbni_softc *sc, u_char *to, u_int len)
156 bus_space_read_multi_1(
157 rman_get_bustag(sc->io_res),
158 rman_get_bushandle(sc->io_res),
159 sc->io_off + DAT, to, len);
163 sbni_outsb(struct sbni_softc *sc, u_char *from, u_int len)
165 bus_space_write_multi_1(
166 rman_get_bustag(sc->io_res),
167 rman_get_bushandle(sc->io_res),
168 sc->io_off + DAT, from, len);
172 Valid combinations in CSR0 (for probing):
174 VALID_DECODER 0000,0011,1011,1010
179 TR_RDY TR_REQ ; 3 ; +
181 BU_EMP TR_REQ ; 5 ; +
182 BU_EMP TR_RDY ; 6 ; -
183 BU_EMP TR_RDY TR_REQ ; 7 ; +
185 RC_RDY TR_REQ ; 9 ; +
186 RC_RDY TR_RDY ; 10 ; -
187 RC_RDY TR_RDY TR_REQ ; 11 ; -
188 RC_RDY BU_EMP ; 12 ; -
189 RC_RDY BU_EMP TR_REQ ; 13 ; -
190 RC_RDY BU_EMP TR_RDY ; 14 ; -
191 RC_RDY BU_EMP TR_RDY TR_REQ ; 15 ; -
194 #define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)
197 sbni_probe(struct sbni_softc *sc)
201 csr0 = sbni_inb(sc, CSR0);
202 if (csr0 != 0xff && csr0 != 0x00) {
207 if (VALID_DECODER & (1 << (csr0 >> 4)))
215 * Install interface into kernel networking data structures
218 sbni_attach(struct sbni_softc *sc, int unit, struct sbni_flags flags)
223 ifp = sc->ifp = if_alloc(IFT_ETHER);
226 sbni_outb(sc, CSR0, 0);
227 set_initial_values(sc, flags);
229 /* Initialize ifnet structure */
231 if_initname(ifp, "sbni", unit);
232 ifp->if_init = sbni_init;
233 ifp->if_start = sbni_start;
234 ifp->if_ioctl = sbni_ioctl;
235 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
237 /* report real baud rate */
238 csr0 = sbni_inb(sc, CSR0);
240 (csr0 & 0x01 ? 500000 : 2000000) / (1 << flags.rate);
242 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
244 mtx_init(&sc->lock, ifp->if_xname, MTX_NETWORK_LOCK, MTX_DEF);
245 callout_init_mtx(&sc->wch, &sc->lock, 0);
246 ether_ifattach(ifp, sc->enaddr);
247 /* device attach does transition from UNCONFIGURED to IDLE state */
249 if_printf(ifp, "speed %ju, rxl ", (uintmax_t)ifp->if_baudrate);
253 printf("%d (fixed)\n", sc->cur_rxl_index);
258 sbni_detach(struct sbni_softc *sc)
264 callout_drain(&sc->wch);
265 ether_ifdetach(sc->ifp);
267 bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_handle);
268 mtx_destroy(&sc->lock);
273 sbni_release_resources(struct sbni_softc *sc)
277 bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
279 if (sc->io_res && sc->io_off == 0)
280 bus_release_resource(sc->dev, SYS_RES_IOPORT, sc->io_rid,
284 /* -------------------------------------------------------------------------- */
289 struct sbni_softc *sc;
291 sc = (struct sbni_softc *)xsc;
293 sbni_init_locked(sc);
298 sbni_init_locked(struct sbni_softc *sc)
305 * kludge to avoid multiple initialization when more than once
306 * protocols configured
308 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
312 callout_reset(&sc->wch, hz/SBNI_HZ, sbni_timeout, sc);
314 ifp->if_drv_flags |= IFF_DRV_RUNNING;
315 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
317 /* attempt to start output */
318 sbni_start_locked(ifp);
322 sbni_start(struct ifnet *ifp)
324 struct sbni_softc *sc = ifp->if_softc;
327 sbni_start_locked(ifp);
332 sbni_start_locked(struct ifnet *ifp)
334 struct sbni_softc *sc = ifp->if_softc;
336 if (sc->tx_frameno == 0)
341 sbni_stop(struct sbni_softc *sc)
343 sbni_outb(sc, CSR0, 0);
347 m_freem(sc->rx_buf_p);
351 callout_stop(&sc->wch);
352 sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
355 /* -------------------------------------------------------------------------- */
357 /* interrupt handler */
360 * SBNI12D-10, -11/ISA boards within "common interrupt" mode could not
361 * be looked as two independent single-channel devices. Every channel seems
362 * as Ethernet interface but interrupt handler must be common. Really, first
363 * channel ("master") driver only registers the handler. In it's struct softc
364 * it has got pointer to "slave" channel's struct softc and handles that's
366 * softc of successfully attached ISA SBNI boards is linked to list.
367 * While next board driver is initialized, it scans this list. If one
368 * has found softc with same irq and ioaddr different by 4 then it assumes
369 * this board to be "master".
375 struct sbni_softc *sc;
378 sc = (struct sbni_softc *)arg;
383 if (sbni_inb(sc, CSR0) & (RC_RDY | TR_RDY)) {
389 /* second channel present */
390 SBNI_LOCK(sc->slave_sc);
391 if (sbni_inb(sc->slave_sc, CSR0) & (RC_RDY | TR_RDY)) {
392 handle_channel(sc->slave_sc);
395 SBNI_UNLOCK(sc->slave_sc);
401 handle_channel(struct sbni_softc *sc)
406 sbni_outb(sc, CSR0, (sbni_inb(sc, CSR0) & ~EN_INT) | TR_REQ);
408 sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
410 csr0 = sbni_inb(sc, CSR0);
411 if ((csr0 & (RC_RDY | TR_RDY)) == 0)
414 req_ans = !(sc->state & FL_PREV_OK);
417 req_ans = recv_frame(sc);
420 * TR_RDY always equals 1 here because we have owned the marker,
421 * and we set TR_REQ when disabled interrupts
423 csr0 = sbni_inb(sc, CSR0);
424 if ((csr0 & TR_RDY) == 0 || (csr0 & RC_RDY) != 0)
425 if_printf(sc->ifp, "internal error!\n");
427 /* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
428 if (req_ans || sc->tx_frameno != 0)
431 /* send the marker without any data */
432 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) & ~TR_REQ);
436 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | EN_INT);
440 * Routine returns 1 if it need to acknoweledge received frame.
441 * Empty frame received without errors won't be acknoweledged.
445 recv_frame(struct sbni_softc *sc)
448 u_int framelen, frameno, ack;
449 u_int is_first, frame_ok;
452 if (check_fhdr(sc, &framelen, &frameno, &ack, &is_first, &crc)) {
453 frame_ok = framelen > 4 ?
454 upload_data(sc, framelen, frameno, is_first, crc) :
455 skip_tail(sc, framelen, crc);
457 interpret_ack(sc, ack);
463 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) ^ CT_ZER);
465 sc->state |= FL_PREV_OK;
467 sc->in_stats.all_rx_number++;
469 sc->state &= ~FL_PREV_OK;
471 sc->in_stats.all_rx_number++;
472 sc->in_stats.bad_rx_number++;
475 return (!frame_ok || framelen > 4);
479 send_frame(struct sbni_softc *sc)
485 if (sc->state & FL_NEED_RESEND) {
486 /* if frame was sended but not ACK'ed - resend it */
487 if (sc->trans_errors) {
489 if (sc->framelen != 0)
490 sc->in_stats.resend_tx_number++;
492 /* cannot xmit with many attempts */
497 sc->trans_errors = TR_ERROR_COUNT;
499 send_frame_header(sc, &crc);
500 sc->state |= FL_NEED_RESEND;
502 * FL_NEED_RESEND will be cleared after ACK, but if empty
503 * frame sended then in prepare_to_send next frame
507 download_data(sc, &crc);
508 sc->in_stats.all_tx_number++;
509 sc->state |= FL_WAIT_ACK;
512 sbni_outsb(sc, (u_char *)&crc, sizeof crc);
515 csr0 = sbni_inb(sc, CSR0);
516 sbni_outb(sc, CSR0, csr0 & ~TR_REQ);
518 if (sc->tx_frameno) {
519 /* next frame exists - request to send */
520 sbni_outb(sc, CSR0, csr0 | TR_REQ);
525 download_data(struct sbni_softc *sc, u_int32_t *crc_p)
529 u_int data_len, pos, slice;
531 data_p = NULL; /* initialized to avoid warn */
534 for (m = sc->tx_buf_p; m != NULL && pos < sc->pktlen; m = m->m_next) {
535 if (pos + m->m_len > sc->outpos) {
536 data_len = m->m_len - (sc->outpos - pos);
537 data_p = mtod(m, caddr_t) + (sc->outpos - pos);
550 slice = min(data_len, sc->framelen - pos);
551 sbni_outsb(sc, data_p, slice);
552 *crc_p = calc_crc32(*crc_p, data_p, slice);
555 if (data_len -= slice)
560 } while (m != NULL && m->m_len == 0);
564 data_p = mtod(m, caddr_t);
568 /* frame too short - zero padding */
570 pos = sc->framelen - pos;
572 sbni_outb(sc, DAT, 0);
573 *crc_p = CRC32(0, *crc_p);
577 } while (pos < sc->framelen);
581 upload_data(struct sbni_softc *sc, u_int framelen, u_int frameno,
582 u_int is_first, u_int32_t crc)
587 sc->wait_frameno = frameno;
591 if (sc->wait_frameno == frameno) {
592 if (sc->inppos + framelen <= ETHER_MAX_LEN) {
593 frame_ok = append_frame_to_pkt(sc, framelen, crc);
596 * if CRC is right but framelen incorrect then transmitter
597 * error was occurred... drop entire packet
599 } else if ((frame_ok = skip_tail(sc, framelen, crc)) != 0) {
600 sc->wait_frameno = 0;
602 if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
603 /* now skip all frames until is_first != 0 */
606 frame_ok = skip_tail(sc, framelen, crc);
608 if (is_first && !frame_ok) {
610 * Frame has been violated, but we have stored
611 * is_first already... Drop entire packet.
613 sc->wait_frameno = 0;
614 if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
620 static __inline void send_complete(struct sbni_softc *);
623 send_complete(struct sbni_softc *sc)
625 m_freem(sc->tx_buf_p);
627 if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
631 interpret_ack(struct sbni_softc *sc, u_int ack)
633 if (ack == FRAME_SENT_OK) {
634 sc->state &= ~FL_NEED_RESEND;
636 if (sc->state & FL_WAIT_ACK) {
637 sc->outpos += sc->framelen;
639 if (--sc->tx_frameno) {
641 sc->maxframe, sc->pktlen - sc->outpos);
649 sc->state &= ~FL_WAIT_ACK;
653 * Glue received frame with previous fragments of packet.
654 * Indicate packet when last frame would be accepted.
658 append_frame_to_pkt(struct sbni_softc *sc, u_int framelen, u_int32_t crc)
662 if (sc->inppos + framelen > ETHER_MAX_LEN)
665 if (!sc->rx_buf_p && !get_rx_buf(sc))
668 p = sc->rx_buf_p->m_data + sc->inppos;
669 sbni_insb(sc, p, framelen);
670 if (calc_crc32(crc, p, framelen) != CRC32_REMAINDER)
673 sc->inppos += framelen - 4;
674 if (--sc->wait_frameno == 0) { /* last frame received */
676 if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
683 * Prepare to start output on adapter. Current priority must be set to splimp
684 * before this routine is called.
685 * Transmitter will be actually activated when marker has been accepted.
689 prepare_to_send(struct sbni_softc *sc)
694 /* sc->tx_buf_p == NULL here! */
696 printf("sbni: memory leak!\n");
699 sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
702 IF_DEQUEUE(&sc->ifp->if_snd, sc->tx_buf_p);
704 /* nothing to transmit... */
708 sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
712 for (len = 0, m = sc->tx_buf_p; m; m = m->m_next)
717 m_freem(sc->tx_buf_p);
720 if (len < SBNI_MIN_LEN)
724 sc->tx_frameno = howmany(len, sc->maxframe);
725 sc->framelen = min(len, sc->maxframe);
727 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | TR_REQ);
728 sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
729 BPF_MTAP(sc->ifp, sc->tx_buf_p);
733 drop_xmit_queue(struct sbni_softc *sc)
738 m_freem(sc->tx_buf_p);
740 if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
744 IF_DEQUEUE(&sc->ifp->if_snd, m);
748 if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
754 sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
755 sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
759 send_frame_header(struct sbni_softc *sc, u_int32_t *crc_p)
766 len_field = sc->framelen + 6; /* CRC + frameno + reserved */
768 if (sc->state & FL_NEED_RESEND)
769 len_field |= FRAME_RETRY; /* non-first attempt... */
772 len_field |= FRAME_FIRST;
774 len_field |= (sc->state & FL_PREV_OK) ? FRAME_SENT_OK : FRAME_SENT_BAD;
775 sbni_outb(sc, DAT, SBNI_SIG);
777 value = (u_char)len_field;
778 sbni_outb(sc, DAT, value);
779 crc = CRC32(value, crc);
780 value = (u_char)(len_field >> 8);
781 sbni_outb(sc, DAT, value);
782 crc = CRC32(value, crc);
784 sbni_outb(sc, DAT, sc->tx_frameno);
785 crc = CRC32(sc->tx_frameno, crc);
786 sbni_outb(sc, DAT, 0);
792 * if frame tail not needed (incorrect number or received twice),
793 * it won't store, but CRC will be calculated
797 skip_tail(struct sbni_softc *sc, u_int tail_len, u_int32_t crc)
800 crc = CRC32(sbni_inb(sc, DAT), crc);
802 return (crc == CRC32_REMAINDER);
806 check_fhdr(struct sbni_softc *sc, u_int *framelen, u_int *frameno,
807 u_int *ack, u_int *is_first, u_int32_t *crc_p)
813 if (sbni_inb(sc, DAT) != SBNI_SIG)
816 value = sbni_inb(sc, DAT);
817 *framelen = (u_int)value;
818 crc = CRC32(value, crc);
819 value = sbni_inb(sc, DAT);
820 *framelen |= ((u_int)value) << 8;
821 crc = CRC32(value, crc);
823 *ack = *framelen & FRAME_ACK_MASK;
824 *is_first = (*framelen & FRAME_FIRST) != 0;
826 if ((*framelen &= FRAME_LEN_MASK) < 6 || *framelen > SBNI_MAX_FRAME - 3)
829 value = sbni_inb(sc, DAT);
830 *frameno = (u_int)value;
831 crc = CRC32(value, crc);
833 crc = CRC32(sbni_inb(sc, DAT), crc); /* reserved byte */
841 get_rx_buf(struct sbni_softc *sc)
845 MGETHDR(m, M_NOWAIT, MT_DATA);
847 if_printf(sc->ifp, "cannot allocate header mbuf\n");
852 * We always put the received packet in a single buffer -
853 * either with just an mbuf header or in a cluster attached
854 * to the header. The +2 is to compensate for the alignment
857 if (ETHER_MAX_LEN + 2 > MHLEN) {
858 /* Attach an mbuf cluster */
859 if (!(MCLGET(m, M_NOWAIT))) {
864 m->m_pkthdr.len = m->m_len = ETHER_MAX_LEN + 2;
867 * The +2 is to longword align the start of the real packet.
868 * (sizeof ether_header == 14)
869 * This is important for NFS.
877 indicate_pkt(struct sbni_softc *sc)
879 struct ifnet *ifp = sc->ifp;
883 m->m_pkthdr.rcvif = ifp;
884 m->m_pkthdr.len = m->m_len = sc->inppos;
888 (*ifp->if_input)(ifp, m);
892 /* -------------------------------------------------------------------------- */
895 * Routine checks periodically wire activity and regenerates marker if
896 * connect was inactive for a long time.
900 sbni_timeout(void *xsc)
902 struct sbni_softc *sc;
905 sc = (struct sbni_softc *)xsc;
906 SBNI_ASSERT_LOCKED(sc);
908 csr0 = sbni_inb(sc, CSR0);
910 if (sc->timer_ticks) {
911 if (csr0 & (RC_RDY | BU_EMP))
912 /* receiving not active */
915 sc->in_stats.timeout_number++;
917 timeout_change_level(sc);
919 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1 | PR_RES);
920 csr0 = sbni_inb(sc, CSR0);
924 sbni_outb(sc, CSR0, csr0 | RC_CHK);
925 callout_reset(&sc->wch, hz/SBNI_HZ, sbni_timeout, sc);
928 /* -------------------------------------------------------------------------- */
931 card_start(struct sbni_softc *sc)
933 sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
934 sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
935 sc->state |= FL_PREV_OK;
938 sc->wait_frameno = 0;
940 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1 | PR_RES);
941 sbni_outb(sc, CSR0, EN_INT);
944 /* -------------------------------------------------------------------------- */
946 static u_char rxl_tab[] = {
947 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
948 0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f
951 #define SIZE_OF_TIMEOUT_RXL_TAB 4
952 static u_char timeout_rxl_tab[] = {
953 0x03, 0x05, 0x08, 0x0b
957 set_initial_values(struct sbni_softc *sc, struct sbni_flags flags)
959 if (flags.fixed_rxl) {
960 sc->delta_rxl = 0; /* disable receive level autodetection */
961 sc->cur_rxl_index = flags.rxl;
963 sc->delta_rxl = DEF_RXL_DELTA;
964 sc->cur_rxl_index = DEF_RXL;
967 sc->csr1.rate = flags.fixed_rate ? flags.rate : DEFAULT_RATE;
968 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
969 sc->maxframe = DEFAULT_FRAME_LEN;
972 * generate Ethernet address (0x00ff01xxxxxx)
974 *(u_int16_t *) sc->enaddr = htons(0x00ff);
975 if (flags.mac_addr) {
976 *(u_int32_t *) (sc->enaddr + 2) =
977 htonl(flags.mac_addr | 0x01000000);
979 *(u_char *) (sc->enaddr + 2) = 0x01;
980 read_random(sc->enaddr + 3, 3);
984 #ifdef SBNI_DUAL_COMPOUND
986 sbni_add(struct sbni_softc *sc)
989 mtx_lock(&headlist_lock);
990 sc->link = sbni_headlist;
992 mtx_unlock(&headlist_lock);
996 connect_to_master(struct sbni_softc *sc)
998 struct sbni_softc *p, *p_prev;
1000 mtx_lock(&headlist_lock);
1001 for (p = sbni_headlist, p_prev = NULL; p; p_prev = p, p = p->link) {
1002 if (rman_get_start(p->io_res) == rman_get_start(sc->io_res) + 4 ||
1003 rman_get_start(p->io_res) == rman_get_start(sc->io_res) - 4) {
1006 p_prev->link = p->link;
1008 sbni_headlist = p->link;
1009 mtx_unlock(&headlist_lock);
1013 mtx_unlock(&headlist_lock);
1018 #endif /* SBNI_DUAL_COMPOUND */
1020 /* Receive level auto-selection */
1023 change_level(struct sbni_softc *sc)
1025 if (sc->delta_rxl == 0) /* do not auto-negotiate RxL */
1028 if (sc->cur_rxl_index == 0)
1030 else if (sc->cur_rxl_index == 15)
1032 else if (sc->cur_rxl_rcvd < sc->prev_rxl_rcvd)
1033 sc->delta_rxl = -sc->delta_rxl;
1035 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index += sc->delta_rxl];
1036 sbni_inb(sc, CSR0); /* it needed for PCI cards */
1037 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1);
1039 sc->prev_rxl_rcvd = sc->cur_rxl_rcvd;
1040 sc->cur_rxl_rcvd = 0;
1044 timeout_change_level(struct sbni_softc *sc)
1046 sc->cur_rxl_index = timeout_rxl_tab[sc->timeout_rxl];
1047 if (++sc->timeout_rxl >= 4)
1048 sc->timeout_rxl = 0;
1050 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
1052 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1);
1054 sc->prev_rxl_rcvd = sc->cur_rxl_rcvd;
1055 sc->cur_rxl_rcvd = 0;
1058 /* -------------------------------------------------------------------------- */
1061 * Process an ioctl request. This code needs some work - it looks
1066 sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1068 struct sbni_softc *sc;
1071 struct sbni_in_stats *in_stats;
1072 struct sbni_flags flags;
1076 ifr = (struct ifreq *)data;
1083 * If the interface is marked up and stopped, then start it.
1084 * If it is marked down and running, then stop it.
1087 if (ifp->if_flags & IFF_UP) {
1088 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1089 sbni_init_locked(sc);
1091 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1101 * Multicast list has changed; set the hardware filter
1106 error = EAFNOSUPPORT; */
1110 * SBNI specific ioctl
1112 case SIOCGHWFLAGS: /* get flags */
1114 bcopy((caddr_t)IF_LLADDR(sc->ifp)+3, (caddr_t) &flags, 3);
1115 flags.rxl = sc->cur_rxl_index;
1116 flags.rate = sc->csr1.rate;
1117 flags.fixed_rxl = (sc->delta_rxl == 0);
1118 flags.fixed_rate = 1;
1120 bcopy(&flags, &ifr->ifr_ifru, sizeof(flags));
1124 in_stats = malloc(sizeof(struct sbni_in_stats), M_DEVBUF,
1127 bcopy(&sc->in_stats, in_stats, sizeof(struct sbni_in_stats));
1129 error = copyout(in_stats, ifr_data_get_ptr(ifr),
1130 sizeof(struct sbni_in_stats));
1131 free(in_stats, M_DEVBUF);
1134 case SIOCSHWFLAGS: /* set flags */
1136 error = priv_check(td, PRIV_DRIVER);
1139 bcopy(&ifr->ifr_ifru, &flags, sizeof(flags));
1141 if (flags.fixed_rxl) {
1143 sc->cur_rxl_index = flags.rxl;
1145 sc->delta_rxl = DEF_RXL_DELTA;
1146 sc->cur_rxl_index = DEF_RXL;
1148 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
1149 sc->csr1.rate = flags.fixed_rate ? flags.rate : DEFAULT_RATE;
1151 bcopy((caddr_t) &flags,
1152 (caddr_t) IF_LLADDR(sc->ifp)+3, 3);
1154 /* Don't be afraid... */
1155 sbni_outb(sc, CSR1, *(char*)(&sc->csr1) | PR_RES);
1161 if (!(error = priv_check(td, PRIV_DRIVER))) /* root only */
1162 bzero(&sc->in_stats, sizeof(struct sbni_in_stats));
1167 error = ether_ioctl(ifp, command, data);
1174 /* -------------------------------------------------------------------------- */
1177 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
1180 crc = CRC32(*p++, crc);
1185 static u_int32_t crc32tab[] __aligned(8) = {
1186 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37,
1187 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E,
1188 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605,
1189 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C,
1190 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53,
1191 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A,
1192 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661,
1193 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278,
1194 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF,
1195 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6,
1196 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD,
1197 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4,
1198 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B,
1199 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82,
1200 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9,
1201 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0,
1202 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7,
1203 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE,
1204 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795,
1205 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C,
1206 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3,
1207 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA,
1208 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1,
1209 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8,
1210 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F,
1211 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76,
1212 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D,
1213 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344,
1214 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B,
1215 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12,
1216 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739,
1217 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320,
1218 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17,
1219 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E,
1220 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525,
1221 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C,
1222 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73,
1223 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A,
1224 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541,
1225 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158,
1226 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF,
1227 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6,
1228 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED,
1229 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4,
1230 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB,
1231 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2,
1232 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589,
1233 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190,
1234 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87,
1235 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E,
1236 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5,
1237 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC,
1238 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3,
1239 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA,
1240 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1,
1241 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8,
1242 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F,
1243 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856,
1244 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D,
1245 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064,
1246 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B,
1247 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832,
1248 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419,
1249 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000