1 /* $NetBSD: if_se.c,v 1.78 2009/05/12 14:44:31 cegger Exp $ */
4 * Copyright (c) 1997 Ian W. Dall <ian.dall@dsto.defence.gov.au>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Ian W. Dall.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Driver for Cabletron EA41x scsi ethernet adaptor.
36 * Written by Ian Dall <ian.dall@dsto.defence.gov.au> Feb 3, 1997
38 * Acknowledgement: Thanks are due to Philip L. Budne <budd@cs.bu.edu>
39 * who reverse engineered the EA41x. In developing this code,
40 * Phil's userland daemon "etherd", was refered to extensively in lieu
41 * of accurate documentation for the device.
43 * This is a weird device! It doesn't conform to the scsi spec in much
44 * at all. About the only standard command supported is inquiry. Most
45 * commands are 6 bytes long, but the recv data is only 1 byte. Data
46 * must be received by periodically polling the device with the recv
49 * This driver is also a bit unusual. It must look like a network
50 * interface and it must also appear to be a scsi device to the scsi
51 * system. Hence there are cases where there are two entry points. eg
52 * sestart is to be called from the scsi subsytem and se_ifstart from
53 * the network interface subsystem. In addition, to facilitate scsi
54 * commands issued by userland programs, there are open, close and
55 * ioctl entry points. This allows a user program to, for example,
56 * display the ea41x stats and download new code into the adaptor ---
57 * functions which can't be performed through the ifconfig interface.
58 * Normal operation does not require any special userland program.
61 #include <sys/cdefs.h>
62 __KERNEL_RCSID(0, "$NetBSD: if_se.c,v 1.78 2009/05/12 14:44:31 cegger Exp $");
65 #include "opt_atalk.h"
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/callout.h>
71 #include <sys/syslog.h>
72 #include <sys/kernel.h>
75 #include <sys/ioctl.h>
78 #include <sys/malloc.h>
79 #include <sys/errno.h>
80 #include <sys/device.h>
81 #include <sys/disklabel.h>
86 #include <dev/scsipi/scsipi_all.h>
87 #include <dev/scsipi/scsi_ctron_ether.h>
88 #include <dev/scsipi/scsiconf.h>
92 #include <sys/socket.h>
94 #include <net/if_dl.h>
95 #include <net/if_ether.h>
96 #include <net/if_media.h>
99 #include <netinet/in.h>
100 #include <netinet/if_inarp.h>
105 #include <netatalk/at.h>
111 #include <net/bpfdesc.h>
114 #define SETIMEOUT 1000
115 #define SEOUTSTANDING 4
121 /* Make this big enough for an ETHERMTU packet in promiscuous mode. */
122 #define MAX_SNAP (ETHERMTU + sizeof(struct ether_header) + \
123 SE_PREFIX + ETHER_CRC)
125 /* 10 full length packets appears to be the max ever returned. 16k is OK */
126 #define RBUF_LEN (16 * 1024)
128 /* Tuning parameters:
129 * The EA41x only returns a maximum of 10 packets (regardless of size).
130 * We will attempt to adapt to polling fast enough to get RDATA_GOAL packets
136 /* se_poll and se_poll0 are the normal polling rate and the minimum
137 * polling rate respectively. se_poll0 should be chosen so that at
138 * maximum ethernet speed, we will read nearly RDATA_MAX packets. se_poll
139 * should be chosen for reasonable maximum latency.
140 * In practice, if we are being saturated with min length packets, we
141 * can't poll fast enough. Polling with zero delay actually
142 * worsens performance. se_poll0 is enforced to be always at least 1
144 #define SE_POLL 40 /* default in milliseconds */
145 #define SE_POLL0 10 /* default in milliseconds */
146 int se_poll
= 0; /* Delay in ticks set at attach time */
148 int se_max_received
= 0; /* Instrumentation */
150 #define PROTOCMD(p, d) \
153 #define PROTOCMD_DECL(name) \
154 static const struct scsi_ctron_ether_generic name
156 #define PROTOCMD_DECL_SPECIAL(name) \
157 static const struct __CONCAT(scsi_,name) name
159 /* Command initializers for commands using scsi_ctron_ether_generic */
160 PROTOCMD_DECL(ctron_ether_send
) = {CTRON_ETHER_SEND
, 0, {0,0}, 0};
161 PROTOCMD_DECL(ctron_ether_add_proto
) = {CTRON_ETHER_ADD_PROTO
, 0, {0,0}, 0};
162 PROTOCMD_DECL(ctron_ether_get_addr
) = {CTRON_ETHER_GET_ADDR
, 0, {0,0}, 0};
163 PROTOCMD_DECL(ctron_ether_set_media
) = {CTRON_ETHER_SET_MEDIA
, 0, {0,0}, 0};
164 PROTOCMD_DECL(ctron_ether_set_addr
) = {CTRON_ETHER_SET_ADDR
, 0, {0,0}, 0};
165 PROTOCMD_DECL(ctron_ether_set_multi
) = {CTRON_ETHER_SET_MULTI
, 0, {0,0}, 0};
166 PROTOCMD_DECL(ctron_ether_remove_multi
) =
167 {CTRON_ETHER_REMOVE_MULTI
, 0, {0,0}, 0};
169 /* Command initializers for commands using their own structures */
170 PROTOCMD_DECL_SPECIAL(ctron_ether_recv
) = {CTRON_ETHER_RECV
};
171 PROTOCMD_DECL_SPECIAL(ctron_ether_set_mode
) =
172 {CTRON_ETHER_SET_MODE
, 0, {0,0}, 0};
175 struct device sc_dev
;
176 struct ethercom sc_ethercom
; /* Ethernet common part */
177 struct scsipi_periph
*sc_periph
;/* contains our targ, lun, etc. */
179 struct callout sc_ifstart_ch
;
180 struct callout sc_recv_ch
;
185 #define PROTO_IP 0x01
186 #define PROTO_ARP 0x02
187 #define PROTO_REVARP 0x04
188 #define PROTO_AT 0x08
189 #define PROTO_AARP 0x10
192 #define SE_NEED_RECV 0x1
197 static int sematch(device_t
, cfdata_t
, void *);
198 static void seattach(device_t
, device_t
, void *);
200 static void se_ifstart(struct ifnet
*);
201 static void sestart(struct scsipi_periph
*);
203 static void sedone(struct scsipi_xfer
*, int);
204 static int se_ioctl(struct ifnet
*, u_long
, void *);
205 static void sewatchdog(struct ifnet
*);
207 static inline u_int16_t
ether_cmp(void *, void *);
208 static void se_recv(void *);
209 static struct mbuf
*se_get(struct se_softc
*, char *, int);
210 static int se_read(struct se_softc
*, char *, int);
211 static int se_reset(struct se_softc
*);
212 static int se_add_proto(struct se_softc
*, int);
213 static int se_get_addr(struct se_softc
*, u_int8_t
*);
214 static int se_set_media(struct se_softc
*, int);
215 static int se_init(struct se_softc
*);
216 static int se_set_multi(struct se_softc
*, u_int8_t
*);
217 static int se_remove_multi(struct se_softc
*, u_int8_t
*);
219 static int sc_set_all_multi(struct se_softc
*, int);
221 static void se_stop(struct se_softc
*);
222 static inline int se_scsipi_cmd(struct scsipi_periph
*periph
,
223 struct scsipi_generic
*scsipi_cmd
,
224 int cmdlen
, u_char
*data_addr
, int datalen
,
225 int retries
, int timeout
, struct buf
*bp
,
227 static void se_delayed_ifstart(void *);
228 static int se_set_mode(struct se_softc
*, int, int);
230 int se_enable(struct se_softc
*);
231 void se_disable(struct se_softc
*);
233 CFATTACH_DECL(se
, sizeof(struct se_softc
),
234 sematch
, seattach
, NULL
, NULL
);
236 extern struct cfdriver se_cd
;
238 dev_type_open(seopen
);
239 dev_type_close(seclose
);
240 dev_type_ioctl(seioctl
);
242 const struct cdevsw se_cdevsw
= {
243 seopen
, seclose
, noread
, nowrite
, seioctl
,
244 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
247 const struct scsipi_periphsw se_switch
= {
248 NULL
, /* Use default error handler */
249 sestart
, /* have a queue, served by this */
250 NULL
, /* have no async handler */
251 sedone
, /* deal with stats at interrupt time */
254 const struct scsipi_inquiry_pattern se_patterns
[] = {
255 {T_PROCESSOR
, T_FIXED
,
256 "CABLETRN", "EA412", ""},
257 {T_PROCESSOR
, T_FIXED
,
258 "Cabletrn", "EA412", ""},
262 * Compare two Ether/802 addresses for equality, inlined and
263 * unrolled for speed.
264 * Note: use this like memcmp()
266 static inline u_int16_t
267 ether_cmp(void *one
, void *two
)
269 u_int16_t
*a
= (u_int16_t
*) one
;
270 u_int16_t
*b
= (u_int16_t
*) two
;
273 diff
= (a
[0] - b
[0]) | (a
[1] - b
[1]) | (a
[2] - b
[2]);
278 #define ETHER_CMP ether_cmp
281 sematch(device_t parent
, cfdata_t match
, void *aux
)
283 struct scsipibus_attach_args
*sa
= aux
;
286 (void)scsipi_inqmatch(&sa
->sa_inqbuf
,
287 se_patterns
, sizeof(se_patterns
) / sizeof(se_patterns
[0]),
288 sizeof(se_patterns
[0]), &priority
);
293 * The routine called by the low level scsi routine when it discovers
294 * a device suitable for this driver.
297 seattach(device_t parent
, device_t self
, void *aux
)
299 struct se_softc
*sc
= device_private(self
);
300 struct scsipibus_attach_args
*sa
= aux
;
301 struct scsipi_periph
*periph
= sa
->sa_periph
;
302 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
303 u_int8_t myaddr
[ETHER_ADDR_LEN
];
306 SC_DEBUG(periph
, SCSIPI_DB2
, ("seattach: "));
308 callout_init(&sc
->sc_ifstart_ch
, 0);
309 callout_init(&sc
->sc_recv_ch
, 0);
313 * Store information needed to contact our base driver
315 sc
->sc_periph
= periph
;
316 periph
->periph_dev
= &sc
->sc_dev
;
317 periph
->periph_switch
= &se_switch
;
319 /* XXX increase openings? */
321 se_poll
= (SE_POLL
* hz
) / 1000;
322 se_poll
= se_poll
? se_poll
: 1;
323 se_poll0
= (SE_POLL0
* hz
) / 1000;
324 se_poll0
= se_poll0
? se_poll0
: 1;
327 * Initialize and attach a buffer
329 sc
->sc_tbuf
= malloc(ETHERMTU
+ sizeof(struct ether_header
),
331 if (sc
->sc_tbuf
== 0)
332 panic("seattach: can't allocate transmit buffer");
334 sc
->sc_rbuf
= malloc(RBUF_LEN
, M_DEVBUF
, M_NOWAIT
);/* A Guess */
335 if (sc
->sc_rbuf
== 0)
336 panic("seattach: can't allocate receive buffer");
338 se_get_addr(sc
, myaddr
);
340 /* Initialize ifnet structure. */
341 strlcpy(ifp
->if_xname
, device_xname(&sc
->sc_dev
), sizeof(ifp
->if_xname
));
343 ifp
->if_start
= se_ifstart
;
344 ifp
->if_ioctl
= se_ioctl
;
345 ifp
->if_watchdog
= sewatchdog
;
347 IFF_BROADCAST
| IFF_SIMPLEX
| IFF_NOTRAILERS
| IFF_MULTICAST
;
348 IFQ_SET_READY(&ifp
->if_snd
);
350 /* Attach the interface. */
352 ether_ifattach(ifp
, myaddr
);
357 se_scsipi_cmd(periph
, cmd
, cmdlen
, data_addr
, datalen
,
358 retries
, timeout
, bp
, flags
)
359 struct scsipi_periph
*periph
;
360 struct scsipi_generic
*cmd
;
372 error
= scsipi_command(periph
, cmd
, cmdlen
, data_addr
,
373 datalen
, retries
, timeout
, bp
, flags
);
378 /* Start routine for calling from scsi sub system */
380 sestart(struct scsipi_periph
*periph
)
382 struct se_softc
*sc
= (void *)periph
->periph_dev
;
383 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
391 se_delayed_ifstart(void *v
)
393 struct ifnet
*ifp
= v
;
394 struct se_softc
*sc
= ifp
->if_softc
;
398 if (sc
->sc_enabled
) {
399 ifp
->if_flags
&= ~IFF_OACTIVE
;
406 * Start transmission on the interface.
407 * Always called at splnet().
410 se_ifstart(struct ifnet
*ifp
)
412 struct se_softc
*sc
= ifp
->if_softc
;
413 struct scsi_ctron_ether_generic send_cmd
;
418 /* Don't transmit if interface is busy or not running */
419 if ((ifp
->if_flags
& (IFF_RUNNING
|IFF_OACTIVE
)) != IFF_RUNNING
)
422 IFQ_DEQUEUE(&ifp
->if_snd
, m0
);
426 /* If BPF is listening on this interface, let it see the
427 * packet before we commit it to the wire.
430 bpf_mtap(ifp
->if_bpf
, m0
);
433 /* We need to use m->m_pkthdr.len, so require the header */
434 if ((m0
->m_flags
& M_PKTHDR
) == 0)
435 panic("ctscstart: no header mbuf");
436 len
= m0
->m_pkthdr
.len
;
438 /* Mark the interface busy. */
439 ifp
->if_flags
|= IFF_OACTIVE
;
441 /* Chain; copy into linear buffer we allocated at attach time. */
443 for (m
= m0
; m
!= NULL
; ) {
444 memcpy(cp
, mtod(m
, u_char
*), m
->m_len
);
449 if (len
< SEMINSIZE
) {
452 printf("se: packet size %d (%d) < %d\n", len
,
453 cp
- (u_char
*)sc
->sc_tbuf
, SEMINSIZE
);
455 memset(cp
, 0, SEMINSIZE
- len
);
459 /* Fill out SCSI command. */
460 PROTOCMD(ctron_ether_send
, send_cmd
);
461 _lto2b(len
, send_cmd
.length
);
463 /* Send command to device. */
464 error
= se_scsipi_cmd(sc
->sc_periph
,
465 (void *)&send_cmd
, sizeof(send_cmd
),
466 sc
->sc_tbuf
, len
, SERETRIES
,
467 SETIMEOUT
, NULL
, XS_CTL_NOSLEEP
|XS_CTL_ASYNC
|XS_CTL_DATA_OUT
);
469 aprint_error_dev(&sc
->sc_dev
, "not queued, error %d\n", error
);
471 ifp
->if_flags
&= ~IFF_OACTIVE
;
474 if (sc
->sc_flags
& SE_NEED_RECV
) {
475 sc
->sc_flags
&= ~SE_NEED_RECV
;
476 se_recv((void *) sc
);
482 * Called from the scsibus layer via our scsi device switch.
485 sedone(struct scsipi_xfer
*xs
, int error
)
487 struct se_softc
*sc
= (void *)xs
->xs_periph
->periph_dev
;
488 struct scsipi_generic
*cmd
= xs
->cmd
;
489 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
494 if (xs
->error
== XS_BUSY
) {
495 printf("se: busy, retry txmit\n");
496 callout_reset(&sc
->sc_ifstart_ch
, hz
,
497 se_delayed_ifstart
, ifp
);
499 ifp
->if_flags
&= ~IFF_OACTIVE
;
500 /* the generic scsipi_done will call
501 * sestart (through scsipi_free_xs).
504 } else if(IS_RECV(cmd
)) {
506 /* pass data up. reschedule a recv */
507 /* scsipi_free_xs will call start. Harmless. */
509 /* Reschedule after a delay */
510 callout_reset(&sc
->sc_recv_ch
, se_poll
,
511 se_recv
, (void *)sc
);
514 n
= se_read(sc
, xs
->data
, xs
->datalen
- xs
->resid
);
515 if (n
> se_max_received
)
519 else if (n
>= RDATA_MAX
)
522 ntimeo
= sc
->sc_last_timeout
;
523 ntimeo
= (ntimeo
* RDATA_GOAL
)/n
;
524 ntimeo
= (ntimeo
< se_poll0
?
526 ntimeo
= (ntimeo
> se_poll
?
529 sc
->sc_last_timeout
= ntimeo
;
530 if (ntimeo
== se_poll0
&&
531 IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
532 /* Output is pending. Do next recv
533 * after the next send. */
534 sc
->sc_flags
|= SE_NEED_RECV
;
536 callout_reset(&sc
->sc_recv_ch
, ntimeo
,
537 se_recv
, (void *)sc
);
547 /* do a recv command */
548 struct se_softc
*sc
= (struct se_softc
*) v
;
549 struct scsi_ctron_ether_recv recv_cmd
;
552 if (sc
->sc_enabled
== 0)
555 PROTOCMD(ctron_ether_recv
, recv_cmd
);
557 error
= se_scsipi_cmd(sc
->sc_periph
,
558 (void *)&recv_cmd
, sizeof(recv_cmd
),
559 sc
->sc_rbuf
, RBUF_LEN
, SERETRIES
, SETIMEOUT
, NULL
,
560 XS_CTL_NOSLEEP
|XS_CTL_ASYNC
|XS_CTL_DATA_IN
);
562 callout_reset(&sc
->sc_recv_ch
, se_poll
, se_recv
, (void *)sc
);
566 * We copy the data into mbufs. When full cluster sized units are present
567 * we copy into clusters.
570 se_get(struct se_softc
*sc
, char *data
, int totlen
)
572 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
573 struct mbuf
*m
, *m0
, *newm
;
576 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
579 m0
->m_pkthdr
.rcvif
= ifp
;
580 m0
->m_pkthdr
.len
= totlen
;
585 if (totlen
>= MINCLSIZE
) {
586 MCLGET(m
, M_DONTWAIT
);
587 if ((m
->m_flags
& M_EXT
) == 0)
593 char *newdata
= (char *)
594 ALIGN(m
->m_data
+ sizeof(struct ether_header
)) -
595 sizeof(struct ether_header
);
596 len
-= newdata
- m
->m_data
;
600 m
->m_len
= len
= min(totlen
, len
);
601 memcpy(mtod(m
, void *), data
, len
);
606 MGET(newm
, M_DONTWAIT
, MT_DATA
);
610 m
= m
->m_next
= newm
;
622 * Pass packets to higher levels.
625 se_read(struct se_softc
*sc
, char *data
, int datalen
)
628 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
632 while (datalen
>= 2) {
633 int len
= _2btol(data
);
641 printf("se_read: datalen = %d, packetlen = %d, proto = 0x%04x\n", datalen
, len
,
642 ntohs(((struct ether_header
*)data
)->ether_type
));
645 if (len
<= sizeof(struct ether_header
) ||
648 printf("%s: invalid packet size %d; dropping\n",
649 device_xname(&sc
->sc_dev
), len
);
655 /* Don't need crc. Must keep ether header for BPF */
656 m
= se_get(sc
, data
, len
- ETHER_CRC
);
660 printf("se_read: se_get returned null\n");
665 if ((ifp
->if_flags
& IFF_PROMISC
) != 0) {
672 * Check if there's a BPF listener on this interface.
673 * If so, hand off the raw packet to BPF.
676 bpf_mtap(ifp
->if_bpf
, m
);
679 /* Pass the packet up. */
680 (*ifp
->if_input
)(ifp
, m
);
692 sewatchdog(struct ifnet
*ifp
)
694 struct se_softc
*sc
= ifp
->if_softc
;
696 log(LOG_ERR
, "%s: device timeout\n", device_xname(&sc
->sc_dev
));
703 se_reset(struct se_softc
*sc
)
708 /* Maybe we don't *really* want to reset the entire bus
709 * because the ctron isn't working. We would like to send a
710 * "BUS DEVICE RESET" message, but don't think the ctron
713 error
= se_scsipi_cmd(sc
->sc_periph
, 0, 0, 0, 0, SERETRIES
, 2000, NULL
,
722 se_add_proto(struct se_softc
*sc
, int proto
)
725 struct scsi_ctron_ether_generic add_proto_cmd
;
730 printf("se: adding proto 0x%02x%02x\n", data
[0], data
[1]);
733 PROTOCMD(ctron_ether_add_proto
, add_proto_cmd
);
734 _lto2b(sizeof(data
), add_proto_cmd
.length
);
735 error
= se_scsipi_cmd(sc
->sc_periph
,
736 (void *)&add_proto_cmd
, sizeof(add_proto_cmd
),
737 data
, sizeof(data
), SERETRIES
, SETIMEOUT
, NULL
,
743 se_get_addr(struct se_softc
*sc
, u_int8_t
*myaddr
)
746 struct scsi_ctron_ether_generic get_addr_cmd
;
748 PROTOCMD(ctron_ether_get_addr
, get_addr_cmd
);
749 _lto2b(ETHER_ADDR_LEN
, get_addr_cmd
.length
);
750 error
= se_scsipi_cmd(sc
->sc_periph
,
751 (void *)&get_addr_cmd
, sizeof(get_addr_cmd
),
752 myaddr
, ETHER_ADDR_LEN
, SERETRIES
, SETIMEOUT
, NULL
,
754 printf("%s: ethernet address %s\n", device_xname(&sc
->sc_dev
),
755 ether_sprintf(myaddr
));
761 se_set_media(struct se_softc
*sc
, int type
)
764 struct scsi_ctron_ether_generic set_media_cmd
;
766 PROTOCMD(ctron_ether_set_media
, set_media_cmd
);
767 set_media_cmd
.byte3
= type
;
768 error
= se_scsipi_cmd(sc
->sc_periph
,
769 (void *)&set_media_cmd
, sizeof(set_media_cmd
),
770 0, 0, SERETRIES
, SETIMEOUT
, NULL
, 0);
775 se_set_mode(struct se_softc
*sc
, int len
, int mode
)
778 struct scsi_ctron_ether_set_mode set_mode_cmd
;
780 PROTOCMD(ctron_ether_set_mode
, set_mode_cmd
);
781 set_mode_cmd
.mode
= mode
;
782 _lto2b(len
, set_mode_cmd
.length
);
783 error
= se_scsipi_cmd(sc
->sc_periph
,
784 (void *)&set_mode_cmd
, sizeof(set_mode_cmd
),
785 0, 0, SERETRIES
, SETIMEOUT
, NULL
, 0);
791 se_init(struct se_softc
*sc
)
793 struct ifnet
*ifp
= &sc
->sc_ethercom
.ec_if
;
794 struct scsi_ctron_ether_generic set_addr_cmd
;
795 uint8_t enaddr
[ETHER_ADDR_LEN
];
799 if (ifp
->if_flags
& IFF_PROMISC
) {
800 error
= se_set_mode(sc
, MAX_SNAP
, 1);
804 error
= se_set_mode(sc
, ETHERMTU
+ sizeof(struct ether_header
),
809 PROTOCMD(ctron_ether_set_addr
, set_addr_cmd
);
810 _lto2b(ETHER_ADDR_LEN
, set_addr_cmd
.length
);
811 memcpy(enaddr
, CLLADDR(ifp
->if_sadl
), sizeof(enaddr
));
812 error
= se_scsipi_cmd(sc
->sc_periph
,
813 (void *)&set_addr_cmd
, sizeof(set_addr_cmd
),
814 enaddr
, ETHER_ADDR_LEN
, SERETRIES
, SETIMEOUT
, NULL
,
819 if ((sc
->protos
& PROTO_IP
) &&
820 (error
= se_add_proto(sc
, ETHERTYPE_IP
)) != 0)
822 if ((sc
->protos
& PROTO_ARP
) &&
823 (error
= se_add_proto(sc
, ETHERTYPE_ARP
)) != 0)
825 if ((sc
->protos
& PROTO_REVARP
) &&
826 (error
= se_add_proto(sc
, ETHERTYPE_REVARP
)) != 0)
829 if ((sc
->protos
& PROTO_AT
) &&
830 (error
= se_add_proto(sc
, ETHERTYPE_ATALK
)) != 0)
832 if ((sc
->protos
& PROTO_AARP
) &&
833 (error
= se_add_proto(sc
, ETHERTYPE_AARP
)) != 0)
837 if ((ifp
->if_flags
& (IFF_RUNNING
|IFF_UP
)) == IFF_UP
) {
838 ifp
->if_flags
|= IFF_RUNNING
;
840 ifp
->if_flags
&= ~IFF_OACTIVE
;
847 se_set_multi(struct se_softc
*sc
, u_int8_t
*addr
)
849 struct scsi_ctron_ether_generic set_multi_cmd
;
853 printf("%s: set_set_multi: %s\n", device_xname(&sc
->sc_dev
),
854 ether_sprintf(addr
));
856 PROTOCMD(ctron_ether_set_multi
, set_multi_cmd
);
857 _lto2b(sizeof(addr
), set_multi_cmd
.length
);
858 /* XXX sizeof(addr) is the size of the pointer. Surely it
859 * is too small? --dyoung
861 error
= se_scsipi_cmd(sc
->sc_periph
,
862 (void *)&set_multi_cmd
, sizeof(set_multi_cmd
),
863 addr
, sizeof(addr
), SERETRIES
, SETIMEOUT
, NULL
, XS_CTL_DATA_OUT
);
868 se_remove_multi(struct se_softc
*sc
, u_int8_t
*addr
)
870 struct scsi_ctron_ether_generic remove_multi_cmd
;
874 printf("%s: se_remove_multi: %s\n", device_xname(&sc
->sc_dev
),
875 ether_sprintf(addr
));
877 PROTOCMD(ctron_ether_remove_multi
, remove_multi_cmd
);
878 _lto2b(sizeof(addr
), remove_multi_cmd
.length
);
879 /* XXX sizeof(addr) is the size of the pointer. Surely it
880 * is too small? --dyoung
882 error
= se_scsipi_cmd(sc
->sc_periph
,
883 (void *)&remove_multi_cmd
, sizeof(remove_multi_cmd
),
884 addr
, sizeof(addr
), SERETRIES
, SETIMEOUT
, NULL
, XS_CTL_DATA_OUT
);
888 #if 0 /* not used --thorpej */
890 sc_set_all_multi(struct se_softc
*sc
, int set
)
894 struct ethercom
*ac
= &sc
->sc_ethercom
;
895 struct ether_multi
*enm
;
896 struct ether_multistep step
;
898 ETHER_FIRST_MULTI(step
, ac
, enm
);
899 while (enm
!= NULL
) {
900 if (ETHER_CMP(enm
->enm_addrlo
, enm
->enm_addrhi
)) {
902 * We must listen to a range of multicast addresses.
903 * For now, just accept all multicasts, rather than
904 * trying to set only those filter bits needed to match
905 * the range. (At this time, the only use of address
906 * ranges is for IP multicast routing, for which the
907 * range is big enough to require all bits set.)
909 /* We have no way of adding a range to this device.
910 * stepping through all addresses in the range is
911 * typically not possible. The only real alternative
912 * is to go into promicuous mode and filter by hand.
918 addr
= enm
->enm_addrlo
;
919 if ((error
= set
? se_set_multi(sc
, addr
) :
920 se_remove_multi(sc
, addr
)) != 0)
922 ETHER_NEXT_MULTI(step
, enm
);
926 #endif /* not used */
929 se_stop(struct se_softc
*sc
)
932 /* Don't schedule any reads */
933 callout_stop(&sc
->sc_recv_ch
);
935 /* How can we abort any scsi cmds in progress? */
940 * Process an ioctl request.
943 se_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
945 struct se_softc
*sc
= ifp
->if_softc
;
946 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
947 struct ifreq
*ifr
= (struct ifreq
*)data
;
956 if ((error
= se_enable(sc
)) != 0)
958 ifp
->if_flags
|= IFF_UP
;
960 if ((error
= se_set_media(sc
, CMEDIA_AUTOSENSE
) != 0))
963 switch (ifa
->ifa_addr
->sa_family
) {
966 sc
->protos
|= (PROTO_IP
| PROTO_ARP
| PROTO_REVARP
);
967 if ((error
= se_init(sc
)) != 0)
969 arp_ifinit(ifp
, ifa
);
974 sc
->protos
|= (PROTO_AT
| PROTO_AARP
);
975 if ((error
= se_init(sc
)) != 0)
987 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
989 /* XXX re-use ether_ioctl() */
990 switch (ifp
->if_flags
& (IFF_UP
|IFF_RUNNING
)) {
993 * If interface is marked down and it is running, then
997 ifp
->if_flags
&= ~IFF_RUNNING
;
1002 * If interface is marked up and it is stopped, then
1005 if ((error
= se_enable(sc
)) != 0)
1007 error
= se_init(sc
);
1011 * Reset the interface to pick up changes in any other
1012 * flags that affect hardware registers.
1015 error
= se_init(sc
);
1019 if (ifp
->if_flags
& IFF_DEBUG
)
1028 sa
= sockaddr_dup(ifreq_getaddr(cmd
, ifr
), M_NOWAIT
);
1033 if ((error
= ether_ioctl(ifp
, cmd
, data
)) == ENETRESET
) {
1034 if (ifp
->if_flags
& IFF_RUNNING
) {
1035 error
= (cmd
== SIOCADDMULTI
) ?
1036 se_set_multi(sc
, sa
->sa_data
) :
1037 se_remove_multi(sc
, sa
->sa_data
);
1046 error
= ether_ioctl(ifp
, cmd
, data
);
1055 * Enable the network interface.
1058 se_enable(struct se_softc
*sc
)
1060 struct scsipi_periph
*periph
= sc
->sc_periph
;
1061 struct scsipi_adapter
*adapt
= periph
->periph_channel
->chan_adapter
;
1064 if (sc
->sc_enabled
== 0 &&
1065 (error
= scsipi_adapter_addref(adapt
)) == 0)
1068 aprint_error_dev(&sc
->sc_dev
, "device enable failed\n");
1074 * Disable the network interface.
1077 se_disable(struct se_softc
*sc
)
1079 struct scsipi_periph
*periph
= sc
->sc_periph
;
1080 struct scsipi_adapter
*adapt
= periph
->periph_channel
->chan_adapter
;
1082 if (sc
->sc_enabled
!= 0) {
1083 scsipi_adapter_delref(adapt
);
1088 #define SEUNIT(z) (minor(z))
1093 seopen(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
1096 struct se_softc
*sc
;
1097 struct scsipi_periph
*periph
;
1098 struct scsipi_adapter
*adapt
;
1101 sc
= device_lookup_private(&se_cd
, unit
);
1105 periph
= sc
->sc_periph
;
1106 adapt
= periph
->periph_channel
->chan_adapter
;
1108 if ((error
= scsipi_adapter_addref(adapt
)) != 0)
1111 SC_DEBUG(periph
, SCSIPI_DB1
,
1112 ("scopen: dev=0x%"PRIx64
" (unit %d (of %d))\n", dev
, unit
,
1115 periph
->periph_flags
|= PERIPH_OPEN
;
1117 SC_DEBUG(periph
, SCSIPI_DB3
, ("open complete\n"));
1122 * close the device.. only called if we are the LAST
1123 * occurence of an open device
1126 seclose(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
1128 struct se_softc
*sc
= device_lookup_private(&se_cd
, SEUNIT(dev
));
1129 struct scsipi_periph
*periph
= sc
->sc_periph
;
1130 struct scsipi_adapter
*adapt
= periph
->periph_channel
->chan_adapter
;
1132 SC_DEBUG(sc
->sc_periph
, SCSIPI_DB1
, ("closing\n"));
1134 scsipi_wait_drain(periph
);
1136 scsipi_adapter_delref(adapt
);
1137 periph
->periph_flags
&= ~PERIPH_OPEN
;
1143 * Perform special action on behalf of the user
1144 * Only does generic scsi ioctls.
1147 seioctl(dev_t dev
, u_long cmd
, void *addr
, int flag
, struct lwp
*l
)
1149 struct se_softc
*sc
= device_lookup_private(&se_cd
, SEUNIT(dev
));
1151 return (scsipi_do_ioctl(sc
->sc_periph
, dev
, cmd
, addr
, flag
, l
));