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
27 * $FreeBSD: src/sys/dev/sbni/if_sbni.c,v 1.1.2.4 2002/08/11 09:32:00 fjoe Exp $
28 * $DragonFly: src/sys/dev/netif/sbni/if_sbni.c,v 1.21 2005/06/14 11:41:37 joerg Exp $
32 * Device driver for Granch SBNI12 leased line adapters
34 * Revision 2.0.0 1997/08/06
35 * Initial revision by Alexey Zverev
37 * Revision 2.0.1 1997/08/11
38 * Additional internal statistics support (tx statistics)
40 * Revision 2.0.2 1997/11/05
41 * if_bpf bug has been fixed
43 * Revision 2.0.3 1998/12/20
44 * Memory leakage has been eliminated in
45 * the sbni_st and sbni_timeout routines.
47 * Revision 3.0 2000/08/10 by Yaroslav Polyakov
48 * Support for PCI cards. 4.1 modification.
50 * Revision 3.1 2000/09/12
51 * Removed extra #defines around bpf functions
53 * Revision 4.0 2000/11/23 by Denis Timofeev
54 * Completely redesigned the buffer management
56 * Revision 4.1 2001/01/21
57 * Support for PCI Dual cards and new SBNI12D-10, -11 Dual/ISA cards
59 * Written with reference to NE2000 driver developed by David Greenman.
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/socket.h>
66 #include <sys/sockio.h>
68 #include <sys/kernel.h>
70 #include <sys/callout.h>
71 #include <sys/syslog.h>
72 #include <sys/random.h>
73 #include <sys/thread2.h>
75 #include <machine/bus.h>
77 #include <machine/resource.h>
80 #include <net/ifq_var.h>
81 #include <net/ethernet.h>
82 #include <net/if_arp.h>
85 #include "if_sbnireg.h"
86 #include "if_sbnivar.h"
90 static void sbni_init(void *);
91 static void sbni_start(struct ifnet *);
92 static int sbni_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
93 static void sbni_watchdog(struct ifnet *);
94 static void sbni_stop(struct sbni_softc *);
95 static void handle_channel(struct sbni_softc *);
97 static void card_start(struct sbni_softc *);
98 static int recv_frame(struct sbni_softc *);
99 static void send_frame(struct sbni_softc *);
100 static int upload_data(struct sbni_softc *, u_int, u_int, u_int, u_int32_t);
101 static int skip_tail(struct sbni_softc *, u_int, u_int32_t);
102 static void interpret_ack(struct sbni_softc *, u_int);
103 static void download_data(struct sbni_softc *, u_int32_t *);
104 static void prepare_to_send(struct sbni_softc *);
105 static void drop_xmit_queue(struct sbni_softc *);
106 static int get_rx_buf(struct sbni_softc *);
107 static void indicate_pkt(struct sbni_softc *);
108 static void change_level(struct sbni_softc *);
109 static int check_fhdr(struct sbni_softc *, u_int *, u_int *,
110 u_int *, u_int *, u_int32_t *);
111 static int append_frame_to_pkt(struct sbni_softc *, u_int, u_int32_t);
112 static void timeout_change_level(struct sbni_softc *);
113 static void send_frame_header(struct sbni_softc *, u_int32_t *);
114 static void set_initial_values(struct sbni_softc *, struct sbni_flags);
116 static u_int32_t calc_crc32(u_int32_t, caddr_t, u_int);
117 static timeout_t sbni_timeout;
119 static __inline u_char sbni_inb(struct sbni_softc *, enum sbni_reg);
120 static __inline void sbni_outb(struct sbni_softc *, enum sbni_reg, u_char);
121 static __inline void sbni_insb(struct sbni_softc *, u_char *, u_int);
122 static __inline void sbni_outsb(struct sbni_softc *, u_char *, u_int);
124 DECLARE_DUMMY_MODULE(if_sbni);
126 static u_int32_t crc32tab[];
128 #ifdef SBNI_DUAL_COMPOUND
129 struct sbni_softc *sbni_headlist;
132 u_int32_t next_sbni_unit;
134 /* -------------------------------------------------------------------------- */
136 static __inline u_char
137 sbni_inb(struct sbni_softc *sc, enum sbni_reg reg)
139 return bus_space_read_1(
140 rman_get_bustag(sc->io_res),
141 rman_get_bushandle(sc->io_res),
146 sbni_outb(struct sbni_softc *sc, enum sbni_reg reg, u_char value)
149 rman_get_bustag(sc->io_res),
150 rman_get_bushandle(sc->io_res),
151 sc->io_off + reg, value);
155 sbni_insb(struct sbni_softc *sc, u_char *to, u_int len)
157 bus_space_read_multi_1(
158 rman_get_bustag(sc->io_res),
159 rman_get_bushandle(sc->io_res),
160 sc->io_off + DAT, to, len);
164 sbni_outsb(struct sbni_softc *sc, u_char *from, u_int len)
166 bus_space_write_multi_1(
167 rman_get_bustag(sc->io_res),
168 rman_get_bushandle(sc->io_res),
169 sc->io_off + DAT, from, len);
174 Valid combinations in CSR0 (for probing):
176 VALID_DECODER 0000,0011,1011,1010
181 TR_RDY TR_REQ ; 3 ; +
183 BU_EMP TR_REQ ; 5 ; +
184 BU_EMP TR_RDY ; 6 ; -
185 BU_EMP TR_RDY TR_REQ ; 7 ; +
187 RC_RDY TR_REQ ; 9 ; +
188 RC_RDY TR_RDY ; 10 ; -
189 RC_RDY TR_RDY TR_REQ ; 11 ; -
190 RC_RDY BU_EMP ; 12 ; -
191 RC_RDY BU_EMP TR_REQ ; 13 ; -
192 RC_RDY BU_EMP TR_RDY ; 14 ; -
193 RC_RDY BU_EMP TR_RDY TR_REQ ; 15 ; -
196 #define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200)
200 sbni_probe(struct sbni_softc *sc)
204 csr0 = sbni_inb(sc, CSR0);
205 if (csr0 != 0xff && csr0 != 0x00) {
210 if (VALID_DECODER & (1 << (csr0 >> 4)))
219 * Install interface into kernel networking data structures
222 sbni_attach(struct sbni_softc *sc, int unit, struct sbni_flags flags)
227 ifp = &sc->arpcom.ac_if;
228 sbni_outb(sc, CSR0, 0);
229 set_initial_values(sc, flags);
231 callout_init(&sc->sbni_stat_timer);
232 /* Initialize ifnet structure */
234 if_initname(ifp, "sbni", unit);
235 ifp->if_init = sbni_init;
236 ifp->if_start = sbni_start;
237 ifp->if_ioctl = sbni_ioctl;
238 ifp->if_watchdog = sbni_watchdog;
239 ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
240 ifq_set_ready(&ifp->if_snd);
242 /* report real baud rate */
243 csr0 = sbni_inb(sc, CSR0);
245 (csr0 & 0x01 ? 500000 : 2000000) / (1 << flags.rate);
247 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
248 ether_ifattach(ifp, sc->arpcom.ac_enaddr);
250 /* device attach does transition from UNCONFIGURED to IDLE state */
252 if_printf(ifp, "speed %ld, rxl ", ifp->if_baudrate);
256 printf("%d (fixed)\n", sc->cur_rxl_index);
259 /* -------------------------------------------------------------------------- */
264 struct sbni_softc *sc =xsc;
265 struct ifnet *ifp = &sc->arpcom.ac_if;
270 * kludge to avoid multiple initialization when more than once
271 * protocols configured
273 if (ifp->if_flags & IFF_RUNNING)
277 callout_reset(&sc->sbni_stat_timer,hz / SBNI_HZ, sbni_timeout, sc);
279 ifp->if_flags |= IFF_RUNNING;
280 ifp->if_flags &= ~IFF_OACTIVE;
282 /* attempt to start output */
290 sbni_start(struct ifnet *ifp)
292 struct sbni_softc *sc = ifp->if_softc;
293 if (sc->tx_frameno == 0)
299 sbni_stop(struct sbni_softc *sc)
301 sbni_outb(sc, CSR0, 0);
305 m_freem(sc->rx_buf_p);
309 callout_stop(&sc->sbni_stat_timer);
312 /* -------------------------------------------------------------------------- */
314 /* interrupt handler */
317 * SBNI12D-10, -11/ISA boards within "common interrupt" mode could not
318 * be looked as two independent single-channel devices. Every channel seems
319 * as Ethernet interface but interrupt handler must be common. Really, first
320 * channel ("master") driver only registers the handler. In it's struct softc
321 * it has got pointer to "slave" channel's struct softc and handles that's
323 * softc of successfully attached ISA SBNI boards is linked to list.
324 * While next board driver is initialized, it scans this list. If one
325 * has found softc with same irq and ioaddr different by 4 then it assumes
326 * this board to be "master".
332 struct sbni_softc *sc;
335 sc = (struct sbni_softc *)arg;
339 if (sbni_inb(sc, CSR0) & (RC_RDY | TR_RDY)) {
343 if (sc->slave_sc && /* second channel present */
344 (sbni_inb(sc->slave_sc, CSR0) & (RC_RDY | TR_RDY))) {
345 handle_channel(sc->slave_sc);
353 handle_channel(struct sbni_softc *sc)
358 sbni_outb(sc, CSR0, (sbni_inb(sc, CSR0) & ~EN_INT) | TR_REQ);
360 sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
362 csr0 = sbni_inb(sc, CSR0);
363 if ((csr0 & (RC_RDY | TR_RDY)) == 0)
366 req_ans = !(sc->state & FL_PREV_OK);
369 req_ans = recv_frame(sc);
372 * TR_RDY always equals 1 here because we have owned the marker,
373 * and we set TR_REQ when disabled interrupts
375 csr0 = sbni_inb(sc, CSR0);
376 if ((csr0 & TR_RDY) == 0 || (csr0 & RC_RDY) != 0)
377 printf("sbni: internal error!\n");
379 /* if state & FL_NEED_RESEND != 0 then tx_frameno != 0 */
380 if (req_ans || sc->tx_frameno != 0)
383 /* send the marker without any data */
384 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) & ~TR_REQ);
388 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | EN_INT);
393 * Routine returns 1 if it need to acknoweledge received frame.
394 * Empty frame received without errors won't be acknoweledged.
398 recv_frame(struct sbni_softc *sc)
401 u_int framelen, frameno, ack;
402 u_int is_first, frame_ok;
405 if (check_fhdr(sc, &framelen, &frameno, &ack, &is_first, &crc)) {
406 frame_ok = framelen > 4 ?
407 upload_data(sc, framelen, frameno, is_first, crc) :
408 skip_tail(sc, framelen, crc);
410 interpret_ack(sc, ack);
414 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) ^ CT_ZER);
416 sc->state |= FL_PREV_OK;
418 sc->in_stats.all_rx_number++;
420 sc->state &= ~FL_PREV_OK;
422 sc->in_stats.all_rx_number++;
423 sc->in_stats.bad_rx_number++;
426 return (!frame_ok || framelen > 4);
431 send_frame(struct sbni_softc *sc)
437 if (sc->state & FL_NEED_RESEND) {
439 /* if frame was sended but not ACK'ed - resend it */
440 if (sc->trans_errors) {
442 if (sc->framelen != 0)
443 sc->in_stats.resend_tx_number++;
445 /* cannot xmit with many attempts */
450 sc->trans_errors = TR_ERROR_COUNT;
452 send_frame_header(sc, &crc);
453 sc->state |= FL_NEED_RESEND;
455 * FL_NEED_RESEND will be cleared after ACK, but if empty
456 * frame sended then in prepare_to_send next frame
461 download_data(sc, &crc);
462 sc->in_stats.all_tx_number++;
463 sc->state |= FL_WAIT_ACK;
466 sbni_outsb(sc, (u_char *)&crc, sizeof crc);
469 csr0 = sbni_inb(sc, CSR0);
470 sbni_outb(sc, CSR0, csr0 & ~TR_REQ);
472 if (sc->tx_frameno) {
473 /* next frame exists - request to send */
474 sbni_outb(sc, CSR0, csr0 | TR_REQ);
480 download_data(struct sbni_softc *sc, u_int32_t *crc_p)
484 u_int data_len, pos, slice;
486 data_p = NULL; /* initialized to avoid warn */
489 for (m = sc->tx_buf_p; m != NULL && pos < sc->pktlen; m = m->m_next) {
490 if (pos + m->m_len > sc->outpos) {
491 data_len = m->m_len - (sc->outpos - pos);
492 data_p = mtod(m, caddr_t) + (sc->outpos - pos);
505 slice = min(data_len, sc->framelen - pos);
506 sbni_outsb(sc, data_p, slice);
507 *crc_p = calc_crc32(*crc_p, data_p, slice);
510 if (data_len -= slice)
515 } while (m != NULL && m->m_len == 0);
519 data_p = mtod(m, caddr_t);
523 /* frame too short - zero padding */
525 pos = sc->framelen - pos;
527 sbni_outb(sc, DAT, 0);
528 *crc_p = CRC32(0, *crc_p);
532 } while (pos < sc->framelen);
537 upload_data(struct sbni_softc *sc, u_int framelen, u_int frameno,
538 u_int is_first, u_int32_t crc)
543 sc->wait_frameno = frameno;
547 if (sc->wait_frameno == frameno) {
549 if (sc->inppos + framelen <= ETHER_MAX_LEN) {
550 frame_ok = append_frame_to_pkt(sc, framelen, crc);
553 * if CRC is right but framelen incorrect then transmitter
554 * error was occured... drop entire packet
556 } else if ((frame_ok = skip_tail(sc, framelen, crc)) != 0) {
557 sc->wait_frameno = 0;
559 sc->arpcom.ac_if.if_ierrors++;
560 /* now skip all frames until is_first != 0 */
563 frame_ok = skip_tail(sc, framelen, crc);
565 if (is_first && !frame_ok) {
567 * Frame has been violated, but we have stored
568 * is_first already... Drop entire packet.
570 sc->wait_frameno = 0;
571 sc->arpcom.ac_if.if_ierrors++;
578 static __inline void send_complete(struct sbni_softc *);
581 send_complete(struct sbni_softc *sc)
583 m_freem(sc->tx_buf_p);
585 sc->arpcom.ac_if.if_opackets++;
590 interpret_ack(struct sbni_softc *sc, u_int ack)
592 if (ack == FRAME_SENT_OK) {
593 sc->state &= ~FL_NEED_RESEND;
595 if (sc->state & FL_WAIT_ACK) {
596 sc->outpos += sc->framelen;
598 if (--sc->tx_frameno) {
600 sc->maxframe, sc->pktlen - sc->outpos);
608 sc->state &= ~FL_WAIT_ACK;
613 * Glue received frame with previous fragments of packet.
614 * Indicate packet when last frame would be accepted.
618 append_frame_to_pkt(struct sbni_softc *sc, u_int framelen, u_int32_t crc)
622 if (sc->inppos + framelen > ETHER_MAX_LEN)
625 if (!sc->rx_buf_p && !get_rx_buf(sc))
628 p = sc->rx_buf_p->m_data + sc->inppos;
629 sbni_insb(sc, p, framelen);
630 if (calc_crc32(crc, p, framelen) != CRC32_REMAINDER)
633 sc->inppos += framelen - 4;
634 if (--sc->wait_frameno == 0) { /* last frame received */
636 sc->arpcom.ac_if.if_ipackets++;
644 * Prepare to start output on adapter.
645 * Transmitter will be actually activated when marker has been accepted.
649 prepare_to_send(struct sbni_softc *sc)
654 /* sc->tx_buf_p == NULL here! */
656 printf("sbni: memory leak!\n");
659 sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
662 sc->tx_buf_p = ifq_dequeue(&sc->arpcom.ac_if.if_snd);
663 if (sc->tx_buf_p == NULL) {
664 /* nothing to transmit... */
668 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
672 for (len = 0, m = sc->tx_buf_p; m; m = m->m_next)
677 m_freem(sc->tx_buf_p);
680 if (len < SBNI_MIN_LEN)
684 sc->tx_frameno = (len + sc->maxframe - 1) / sc->maxframe;
685 sc->framelen = min(len, sc->maxframe);
687 sbni_outb(sc, CSR0, sbni_inb(sc, CSR0) | TR_REQ);
688 sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
689 BPF_MTAP(&sc->arpcom.ac_if, sc->tx_buf_p);
694 drop_xmit_queue(struct sbni_softc *sc)
697 m_freem(sc->tx_buf_p);
699 sc->arpcom.ac_if.if_oerrors++;
702 ifq_purge(&sc->arpcom.ac_if.if_snd);
707 sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
708 sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
713 send_frame_header(struct sbni_softc *sc, u_int32_t *crc_p)
720 len_field = sc->framelen + 6; /* CRC + frameno + reserved */
722 if (sc->state & FL_NEED_RESEND)
723 len_field |= FRAME_RETRY; /* non-first attempt... */
726 len_field |= FRAME_FIRST;
728 len_field |= (sc->state & FL_PREV_OK) ? FRAME_SENT_OK : FRAME_SENT_BAD;
729 sbni_outb(sc, DAT, SBNI_SIG);
731 value = (u_char)len_field;
732 sbni_outb(sc, DAT, value);
733 crc = CRC32(value, crc);
734 value = (u_char)(len_field >> 8);
735 sbni_outb(sc, DAT, value);
736 crc = CRC32(value, crc);
738 sbni_outb(sc, DAT, sc->tx_frameno);
739 crc = CRC32(sc->tx_frameno, crc);
740 sbni_outb(sc, DAT, 0);
747 * if frame tail not needed (incorrect number or received twice),
748 * it won't store, but CRC will be calculated
752 skip_tail(struct sbni_softc *sc, u_int tail_len, u_int32_t crc)
755 crc = CRC32(sbni_inb(sc, DAT), crc);
757 return (crc == CRC32_REMAINDER);
762 check_fhdr(struct sbni_softc *sc, u_int *framelen, u_int *frameno,
763 u_int *ack, u_int *is_first, u_int32_t *crc_p)
769 if (sbni_inb(sc, DAT) != SBNI_SIG)
772 value = sbni_inb(sc, DAT);
773 *framelen = (u_int)value;
774 crc = CRC32(value, crc);
775 value = sbni_inb(sc, DAT);
776 *framelen |= ((u_int)value) << 8;
777 crc = CRC32(value, crc);
779 *ack = *framelen & FRAME_ACK_MASK;
780 *is_first = (*framelen & FRAME_FIRST) != 0;
782 if ((*framelen &= FRAME_LEN_MASK) < 6 || *framelen > SBNI_MAX_FRAME - 3)
785 value = sbni_inb(sc, DAT);
786 *frameno = (u_int)value;
787 crc = CRC32(value, crc);
789 crc = CRC32(sbni_inb(sc, DAT), crc); /* reserved byte */
798 get_rx_buf(struct sbni_softc *sc)
802 MGETHDR(m, MB_DONTWAIT, MT_DATA);
804 printf("%s: cannot allocate header mbuf\n",
805 sc->arpcom.ac_if.if_xname);
810 * We always put the received packet in a single buffer -
811 * either with just an mbuf header or in a cluster attached
812 * to the header. The +2 is to compensate for the alignment
815 if (ETHER_MAX_LEN + 2 > MHLEN) {
816 /* Attach an mbuf cluster */
817 MCLGET(m, MB_DONTWAIT);
818 if ((m->m_flags & M_EXT) == 0) {
823 m->m_pkthdr.len = m->m_len = ETHER_MAX_LEN + 2;
826 * The +2 is to longword align the start of the real packet.
827 * (sizeof ether_header == 14)
828 * This is important for NFS.
837 indicate_pkt(struct sbni_softc *sc)
839 struct ifnet *ifp = &sc->arpcom.ac_if;
843 m->m_pkthdr.rcvif = ifp;
844 m->m_pkthdr.len = m->m_len = sc->inppos;
846 (*ifp->if_input)(ifp, m);
850 /* -------------------------------------------------------------------------- */
853 * Routine checks periodically wire activity and regenerates marker if
854 * connect was inactive for a long time.
858 sbni_timeout(void *xsc)
860 struct sbni_softc *sc = xsc;
865 csr0 = sbni_inb(sc, CSR0);
868 if (sc->timer_ticks) {
869 if (csr0 & (RC_RDY | BU_EMP))
870 /* receiving not active */
873 sc->in_stats.timeout_number++;
875 timeout_change_level(sc);
877 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1 | PR_RES);
878 csr0 = sbni_inb(sc, CSR0);
882 sbni_outb(sc, CSR0, csr0 | RC_CHK);
883 callout_reset(&sc->sbni_stat_timer, hz / SBNI_HZ, sbni_timeout, sc);
888 /* -------------------------------------------------------------------------- */
891 card_start(struct sbni_softc *sc)
893 sc->timer_ticks = CHANGE_LEVEL_START_TICKS;
894 sc->state &= ~(FL_WAIT_ACK | FL_NEED_RESEND);
895 sc->state |= FL_PREV_OK;
898 sc->wait_frameno = 0;
900 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1 | PR_RES);
901 sbni_outb(sc, CSR0, EN_INT);
904 /* -------------------------------------------------------------------------- */
907 * Device timeout/watchdog routine. Entered if the device neglects to
908 * generate an interrupt after a transmit has been started on it.
912 sbni_watchdog(struct ifnet *ifp)
914 log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
919 static u_char rxl_tab[] = {
920 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
921 0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f
924 #define SIZE_OF_TIMEOUT_RXL_TAB 4
925 static u_char timeout_rxl_tab[] = {
926 0x03, 0x05, 0x08, 0x0b
930 set_initial_values(struct sbni_softc *sc, struct sbni_flags flags)
932 if (flags.fixed_rxl) {
933 sc->delta_rxl = 0; /* disable receive level autodetection */
934 sc->cur_rxl_index = flags.rxl;
936 sc->delta_rxl = DEF_RXL_DELTA;
937 sc->cur_rxl_index = DEF_RXL;
940 sc->csr1.rate = flags.fixed_rate ? flags.rate : DEFAULT_RATE;
941 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
942 sc->maxframe = DEFAULT_FRAME_LEN;
945 * generate Ethernet address (0x00ff01xxxxxx)
947 *(u_int16_t *) sc->arpcom.ac_enaddr = htons(0x00ff);
948 if (flags.mac_addr) {
949 *(u_int32_t *) (sc->arpcom.ac_enaddr + 2) =
950 htonl(flags.mac_addr | 0x01000000);
952 *(u_char *) (sc->arpcom.ac_enaddr + 2) = 0x01;
953 read_random_unlimited(sc->arpcom.ac_enaddr + 3, 3);
958 #ifdef SBNI_DUAL_COMPOUND
961 connect_to_master(struct sbni_softc *sc)
963 struct sbni_softc *p, *p_prev;
965 for (p = sbni_headlist, p_prev = NULL; p; p_prev = p, p = p->link) {
966 if (rman_get_start(p->io_res) == rman_get_start(sc->io_res) + 4 ||
967 rman_get_start(p->io_res) == rman_get_start(sc->io_res) - 4) {
970 p_prev->link = p->link;
972 sbni_headlist = p->link;
980 #endif /* SBNI_DUAL_COMPOUND */
983 /* Receive level auto-selection */
986 change_level(struct sbni_softc *sc)
988 if (sc->delta_rxl == 0) /* do not auto-negotiate RxL */
991 if (sc->cur_rxl_index == 0)
993 else if (sc->cur_rxl_index == 15)
995 else if (sc->cur_rxl_rcvd < sc->prev_rxl_rcvd)
996 sc->delta_rxl = -sc->delta_rxl;
998 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index += sc->delta_rxl];
999 sbni_inb(sc, CSR0); /* it needed for PCI cards */
1000 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1);
1002 sc->prev_rxl_rcvd = sc->cur_rxl_rcvd;
1003 sc->cur_rxl_rcvd = 0;
1008 timeout_change_level(struct sbni_softc *sc)
1010 sc->cur_rxl_index = timeout_rxl_tab[sc->timeout_rxl];
1011 if (++sc->timeout_rxl >= 4)
1012 sc->timeout_rxl = 0;
1014 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
1016 sbni_outb(sc, CSR1, *(u_char *)&sc->csr1);
1018 sc->prev_rxl_rcvd = sc->cur_rxl_rcvd;
1019 sc->cur_rxl_rcvd = 0;
1022 /* -------------------------------------------------------------------------- */
1025 * Process an ioctl request. This code needs some work - it looks
1030 sbni_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
1032 struct sbni_softc *sc;
1034 struct sbni_in_stats *in_stats;
1035 struct sbni_flags flags;
1039 ifr = (struct ifreq *)data;
1047 * If the interface is marked up and stopped, then start it.
1048 * If it is marked down and running, then stop it.
1050 if (ifp->if_flags & IFF_UP) {
1051 if (!(ifp->if_flags & IFF_RUNNING))
1054 if (ifp->if_flags & IFF_RUNNING) {
1056 ifp->if_flags &= ~IFF_RUNNING;
1064 * Multicast list has changed; set the hardware filter
1069 error = EAFNOSUPPORT; */
1073 if (ifr->ifr_mtu > ETHERMTU)
1076 ifp->if_mtu = ifr->ifr_mtu;
1080 * SBNI specific ioctl
1082 case SIOCGHWFLAGS: /* get flags */
1083 bcopy((caddr_t) sc->arpcom.ac_enaddr+3, (caddr_t) &flags, 3);
1084 flags.rxl = sc->cur_rxl_index;
1085 flags.rate = sc->csr1.rate;
1086 flags.fixed_rxl = (sc->delta_rxl == 0);
1087 flags.fixed_rate = 1;
1088 ifr->ifr_data = *(caddr_t*) &flags;
1092 in_stats = (struct sbni_in_stats *)ifr->ifr_data;
1093 bcopy((void *)(&(sc->in_stats)), (void *)in_stats,
1094 sizeof(struct sbni_in_stats));
1097 case SIOCSHWFLAGS: /* set flags */
1099 error = suser_cred(cr, NULL_CRED_OKAY);
1100 /* NOTE: returns EPERM if no proc */
1103 flags = *(struct sbni_flags*)&ifr->ifr_data;
1104 if (flags.fixed_rxl) {
1106 sc->cur_rxl_index = flags.rxl;
1108 sc->delta_rxl = DEF_RXL_DELTA;
1109 sc->cur_rxl_index = DEF_RXL;
1111 sc->csr1.rxl = rxl_tab[sc->cur_rxl_index];
1112 sc->csr1.rate = flags.fixed_rate ? flags.rate : DEFAULT_RATE;
1114 bcopy((caddr_t) &flags,
1115 (caddr_t) sc->arpcom.ac_enaddr+3, 3);
1117 /* Don't be afraid... */
1118 sbni_outb(sc, CSR1, *(char*)(&sc->csr1) | PR_RES);
1122 if (!(error = suser_cred(cr, NULL_CRED_OKAY))) /* root only */
1123 bzero(&sc->in_stats, sizeof(struct sbni_in_stats));
1127 error = ether_ioctl(ifp, command, data);
1136 /* -------------------------------------------------------------------------- */
1141 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
1147 "xorl %%ebx, %%ebx\n"
1150 "movl $crc32tab, %%edi\n"
1157 "movl (%%esi), %%edx\n"
1161 "xorl (%%edi,%%ebx,4), %%eax\n"
1167 "xorl (%%edi,%%ebx,4), %%eax\n"
1173 "xorl (%%edi,%%ebx,4), %%eax\n"
1179 "xorl (%%edi,%%ebx,4), %%eax\n"
1191 "xorb (%%esi), %%bl\n"
1192 "xorl (%%edi,%%ebx,4), %%eax\n"
1199 "xorb 1(%%esi), %%bl\n"
1200 "xorl (%%edi,%%ebx,4), %%eax\n"
1207 "xorb 2(%%esi), %%bl\n"
1208 "xorl (%%edi,%%ebx,4), %%eax\n"
1211 : "a" (_crc), "g" (p), "g" (len)
1212 : "bx", "cx", "dx", "si", "di"
1221 calc_crc32(u_int32_t crc, caddr_t p, u_int len)
1224 crc = CRC32(*p++, crc);
1229 #endif /* ASM_CRC */
1232 static u_int32_t crc32tab[] __attribute__ ((aligned(8))) = {
1233 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37,
1234 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E,
1235 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605,
1236 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C,
1237 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53,
1238 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A,
1239 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661,
1240 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278,
1241 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF,
1242 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6,
1243 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD,
1244 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4,
1245 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B,
1246 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82,
1247 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9,
1248 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0,
1249 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7,
1250 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE,
1251 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795,
1252 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C,
1253 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3,
1254 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA,
1255 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1,
1256 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8,
1257 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F,
1258 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76,
1259 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D,
1260 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344,
1261 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B,
1262 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12,
1263 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739,
1264 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320,
1265 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17,
1266 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E,
1267 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525,
1268 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C,
1269 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73,
1270 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A,
1271 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541,
1272 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158,
1273 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF,
1274 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6,
1275 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED,
1276 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4,
1277 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB,
1278 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2,
1279 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589,
1280 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190,
1281 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87,
1282 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E,
1283 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5,
1284 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC,
1285 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3,
1286 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA,
1287 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1,
1288 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8,
1289 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F,
1290 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856,
1291 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D,
1292 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064,
1293 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B,
1294 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832,
1295 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419,
1296 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000