if_cs.c revision 179591
1/*-
2 * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko.
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
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
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.
14 *
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 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 179591 2008-06-06 04:56:27Z imp $");
31
32/*
33 *
34 * Device driver for Crystal Semiconductor CS8920 based ethernet
35 *   adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997
36 */
37
38/*
39#define	 CS_DEBUG
40 */
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/malloc.h>
45#include <sys/mbuf.h>
46#include <sys/socket.h>
47#include <sys/sockio.h>
48#include <sys/kernel.h>
49#include <sys/sysctl.h>
50#include <sys/syslog.h>
51
52#include <sys/module.h>
53#include <sys/bus.h>
54#include <machine/bus.h>
55#include <sys/rman.h>
56#include <machine/resource.h>
57
58#include <net/if.h>
59#include <net/if_arp.h>
60#include <net/if_dl.h>
61#include <net/if_media.h>
62#include <net/if_types.h>
63#include <net/ethernet.h>
64#include <net/bpf.h>
65
66#include <dev/cs/if_csvar.h>
67#include <dev/cs/if_csreg.h>
68
69#ifdef  CS_USE_64K_DMA
70#define CS_DMA_BUFFER_SIZE 65536
71#else
72#define CS_DMA_BUFFER_SIZE 16384
73#endif
74
75static void	cs_init(void *);
76static void	cs_init_locked(struct cs_softc *);
77static int	cs_ioctl(struct ifnet *, u_long, caddr_t);
78static void	cs_start(struct ifnet *);
79static void	cs_start_locked(struct ifnet *);
80static void	cs_stop(struct cs_softc *);
81static void	cs_reset(struct cs_softc *);
82static void	cs_watchdog(void *);
83
84static int	cs_mediachange(struct ifnet *);
85static void	cs_mediastatus(struct ifnet *, struct ifmediareq *);
86static int      cs_mediaset(struct cs_softc *, int);
87
88static void	cs_write_mbufs(struct cs_softc*, struct mbuf*);
89static void	cs_xmit_buf(struct cs_softc*);
90static int	cs_get_packet(struct cs_softc*);
91static void	cs_setmode(struct cs_softc*);
92
93static int	get_eeprom_data(struct cs_softc *sc, int, int, uint16_t *);
94static int	get_eeprom_cksum(int, int, uint16_t *);
95static int	wait_eeprom_ready( struct cs_softc *);
96static void	control_dc_dc( struct cs_softc *, int );
97static int	send_test_pkt( struct cs_softc * );
98static int	enable_tp(struct cs_softc *);
99static int	enable_aui(struct cs_softc *);
100static int	enable_bnc(struct cs_softc *);
101static int      cs_duplex_auto(struct cs_softc *);
102
103devclass_t cs_devclass;
104
105/* sysctl vars */
106SYSCTL_NODE(_hw, OID_AUTO, cs, CTLFLAG_RD, 0, "cs device parameters");
107
108int	cs_debug = 0;
109TUNABLE_INT("hw.cs.debug", &cs_debug);
110SYSCTL_INT(_hw_cs, OID_AUTO, debug, CTLFLAG_RW,
111    &cs_debug, 0,
112  "cs debug");
113
114int	cs_ignore_cksum_failure = 0;
115TUNABLE_INT("hw.cs.ignore_checksum_failure", &cs_ignore_cksum_failure);
116SYSCTL_INT(_hw_cs, OID_AUTO, ignore_checksum_failure, CTLFLAG_RW,
117    &cs_ignore_cksum_failure, 0,
118  "ignore checksum errors in cs card EEPROM");
119
120static int	cs_recv_delay = 570;
121TUNABLE_INT("hw.cs.recv_delay", &cs_recv_delay);
122SYSCTL_INT(_hw_cs, OID_AUTO, recv_delay, CTLFLAG_RW, &cs_recv_delay, 570, "");
123
124static int cs8900_eeint2irq[16] = {
125	 10,  11,  12,   5, 255, 255, 255, 255,
126	255, 255, 255, 255, 255, 255, 255, 255
127};
128
129static int cs8900_irq2eeint[16] = {
130	255, 255, 255, 255, 255,   3, 255, 255,
131	255,   0,   1,   2, 255, 255, 255, 255
132};
133
134static int
135get_eeprom_data(struct cs_softc *sc, int off, int len, uint16_t *buffer)
136{
137	int i;
138
139#ifdef CS_DEBUG
140	device_printf(sc->sc_dev, "EEPROM data from %x for %x:\n", off, len);
141#endif
142
143	for (i=0; i < len; i++) {
144		if (wait_eeprom_ready(sc) < 0)
145			return (-1);
146		/* Send command to EEPROM to read */
147		cs_writereg(sc, PP_EECMD, (off + i) | EEPROM_READ_CMD);
148		if (wait_eeprom_ready(sc) < 0)
149			return (-1);
150		buffer[i] = cs_readreg(sc, PP_EEData);
151
152#ifdef CS_DEBUG
153		printf("%04x ",buffer[i]);
154#endif
155	}
156
157#ifdef CS_DEBUG
158	printf("\n");
159#endif
160	return (0);
161}
162
163static int
164get_eeprom_cksum(int off, int len, uint16_t *buffer)
165{
166	int i;
167	uint16_t cksum=0;
168
169	for (i = 0; i < len; i++)
170		cksum += buffer[i];
171	cksum &= 0xffff;
172	if (cksum == 0 || cs_ignore_cksum_failure)
173		return (0);
174	return (-1);
175}
176
177static int
178wait_eeprom_ready(struct cs_softc *sc)
179{
180	DELAY(30000);	/* XXX should we do some checks here ? */
181	return (0);
182}
183
184static void
185control_dc_dc(struct cs_softc *sc, int on_not_off)
186{
187	unsigned int self_control = HCB1_ENBL;
188
189	if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0) ^ on_not_off)
190		self_control |= HCB1;
191	else
192		self_control &= ~HCB1;
193	cs_writereg(sc, PP_SelfCTL, self_control);
194	DELAY(500000);
195}
196
197
198static int
199cs_duplex_auto(struct cs_softc *sc)
200{
201	int i, error=0;
202
203	cs_writereg(sc, PP_AutoNegCTL,
204	    RE_NEG_NOW | ALLOW_FDX | AUTO_NEG_ENABLE);
205	for (i=0; cs_readreg(sc, PP_AutoNegST) & AUTO_NEG_BUSY; i++) {
206		if (i > 40000) {
207			device_printf(sc->dev,
208			    "full/half duplex auto negotiation timeout\n");
209			error = ETIMEDOUT;
210			break;
211		}
212		DELAY(1000);
213	}
214	return (error);
215}
216
217static int
218enable_tp(struct cs_softc *sc)
219{
220
221	cs_writereg(sc, PP_LineCTL, sc->line_ctl & ~AUI_ONLY);
222	control_dc_dc(sc, 0);
223	return (0);
224}
225
226/*
227 * XXX This was rewritten from Linux driver without any tests.
228 */
229static int
230send_test_pkt(struct cs_softc *sc)
231{
232	char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
233				0, 46,  /* A 46 in network order */
234				0, 0,   /* DSAP=0 & SSAP=0 fields */
235				0xf3, 0 /* Control (Test Req + P bit set) */ };
236	int i;
237	u_char ether_address_backup[ETHER_ADDR_LEN];
238
239	for (i = 0; i < ETHER_ADDR_LEN; i++)
240		ether_address_backup[i] = sc->enaddr[i];
241
242	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_TX_ON);
243	bcopy(test_packet, sc->enaddr, ETHER_ADDR_LEN);
244	bcopy(test_packet+ETHER_ADDR_LEN,
245	    sc->enaddr, ETHER_ADDR_LEN);
246	cs_outw(sc, TX_CMD_PORT, sc->send_cmd);
247	cs_outw(sc, TX_LEN_PORT, sizeof(test_packet));
248
249	/* Wait for chip to allocate memory */
250	DELAY(50000);
251	if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) {
252		for (i = 0; i < ETHER_ADDR_LEN; i++)
253			sc->enaddr[i] = ether_address_backup[i];
254		return (0);
255	}
256
257	outsw(sc->nic_addr + TX_FRAME_PORT, test_packet, sizeof(test_packet));
258
259	DELAY(30000);
260
261	for (i = 0; i < ETHER_ADDR_LEN; i++)
262		sc->enaddr[i] = ether_address_backup[i];
263	if ((cs_readreg(sc, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK)
264		return (1);
265	return (0);
266}
267
268/*
269 * XXX This was rewritten from Linux driver without any tests.
270 */
271static int
272enable_aui(struct cs_softc *sc)
273{
274
275	control_dc_dc(sc, 0);
276	cs_writereg(sc, PP_LineCTL,
277	    (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY);
278
279	if (!send_test_pkt(sc))
280		return (EINVAL);
281	return (0);
282}
283
284/*
285 * XXX This was rewritten from Linux driver without any tests.
286 */
287static int
288enable_bnc(struct cs_softc *sc)
289{
290
291	control_dc_dc(sc, 1);
292	cs_writereg(sc, PP_LineCTL,
293	    (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY);
294
295	if (!send_test_pkt(sc))
296		return (EINVAL);
297	return (0);
298}
299
300int
301cs_cs89x0_probe(device_t dev)
302{
303	int i;
304	int error;
305	u_long irq, junk;
306	struct cs_softc *sc = device_get_softc(dev);
307	unsigned rev_type = 0;
308	uint16_t id;
309	char chip_revision;
310	uint16_t eeprom_buff[CHKSUM_LEN];
311	int chip_type, pp_isaint, pp_isadma;
312
313	error = cs_alloc_port(dev, 0, CS_89x0_IO_PORTS);
314	if (error)
315		return (error);
316
317	sc->nic_addr = rman_get_start(sc->port_res);
318
319	if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG) {
320		/* Chip not detected. Let's try to reset it */
321		if (bootverbose)
322			device_printf(dev, "trying to reset the chip.\n");
323		cs_outw(sc, ADD_PORT, PP_SelfCTL);
324		i = cs_inw(sc, DATA_PORT);
325		cs_outw(sc, ADD_PORT, PP_SelfCTL);
326		cs_outw(sc, DATA_PORT, i | POWER_ON_RESET);
327		if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG)
328			return (ENXIO);
329	}
330
331	for (i = 0; i < 10000; i++) {
332		id = cs_readreg(sc, PP_ChipID);
333		if (id == CHIP_EISA_ID_SIG)
334			break;
335	}
336	if (i == 10000)
337		return (ENXIO);
338
339	rev_type = cs_readreg(sc, PRODUCT_ID_ADD);
340	chip_type = rev_type & ~REVISON_BITS;
341	chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
342
343	sc->chip_type = chip_type;
344
345	if (chip_type == CS8900) {
346		pp_isaint = PP_CS8900_ISAINT;
347		pp_isadma = PP_CS8900_ISADMA;
348		sc->send_cmd = TX_CS8900_AFTER_ALL;
349	} else {
350		pp_isaint = PP_CS8920_ISAINT;
351		pp_isadma = PP_CS8920_ISADMA;
352		sc->send_cmd = TX_CS8920_AFTER_ALL;
353	}
354
355	/*
356	 * Clear some fields so that fail of EEPROM will left them clean
357	 */
358	sc->auto_neg_cnf = 0;
359	sc->adapter_cnf  = 0;
360	sc->isa_config   = 0;
361
362	/*
363	 * If no interrupt specified, use what the board tells us.
364	 */
365	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk);
366
367	/*
368	 * Get data from EEPROM
369	 */
370	if((cs_readreg(sc, PP_SelfST) & EEPROM_PRESENT) == 0) {
371		device_printf(dev, "No EEPROM, assuming defaults.\n");
372	} else if (get_eeprom_data(sc,START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) {
373		device_printf(dev, "EEPROM read failed, assuming defaults.\n");
374	} else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) {
375		device_printf(dev, "EEPROM cheksum bad, assuming defaults.\n");
376	} else {
377		sc->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
378		sc->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
379		sc->isa_config = eeprom_buff[ISA_CNF_OFFSET/2];
380		for (i=0; i<ETHER_ADDR_LEN/2; i++) {
381			sc->enaddr[i*2] = eeprom_buff[i];
382			sc->enaddr[i*2+1] = eeprom_buff[i] >> 8;
383		}
384		/*
385		 * If no interrupt specified, use what the
386		 * board tells us.
387		 */
388		if (error) {
389			irq = sc->isa_config & INT_NO_MASK;
390			error = 0;
391			if (chip_type == CS8900) {
392				irq = cs8900_eeint2irq[irq];
393			} else {
394				if (irq > CS8920_NO_INTS)
395					irq = 255;
396			}
397			if (irq == 255) {
398				device_printf(dev, "invalid irq in EEPROM.\n");
399				error = EINVAL;
400			}
401			if (!error)
402				bus_set_resource(dev, SYS_RES_IRQ, 0,
403				    irq, 1);
404		}
405	}
406
407	if (!error && !(sc->flags & CS_NO_IRQ)) {
408		if (chip_type == CS8900) {
409			if (irq >= 0 || irq < 16)
410				irq = cs8900_irq2eeint[irq];
411			else
412				irq = 255;
413		} else {
414			if (irq > CS8920_NO_INTS)
415				irq = 255;
416		}
417		if (irq == 255)
418			error = EINVAL;
419	}
420
421	if (error) {
422	       	device_printf(dev, "Unknown or invalid irq\n");
423		return (error);
424	}
425
426	if (!(sc->flags & CS_NO_IRQ))
427		cs_writereg(sc, pp_isaint, irq);
428
429	/*
430	 * Temporary disabled
431	 *
432	if (drq>0)
433		cs_writereg(sc, pp_isadma, drq);
434	else {
435		device_printf(dev, "incorrect drq\n",);
436		return (0);
437	}
438	*/
439
440	if (bootverbose)
441		 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n",
442			chip_type == CS8900 ? '0' : '2',
443			chip_type == CS8920M ? "M" : "",
444			chip_revision,
445			(sc->adapter_cnf & A_CNF_10B_T) ? " TP"  : "",
446			(sc->adapter_cnf & A_CNF_AUI)   ? " AUI" : "",
447			(sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : "");
448
449	if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) &&
450	    (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
451		sc->line_ctl = LOW_RX_SQUELCH;
452	else
453		sc->line_ctl = 0;
454
455	return (0);
456}
457
458/*
459 * Allocate a port resource with the given resource id.
460 */
461int
462cs_alloc_port(device_t dev, int rid, int size)
463{
464	struct cs_softc *sc = device_get_softc(dev);
465	struct resource *res;
466
467	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
468	    0ul, ~0ul, size, RF_ACTIVE);
469	if (res == NULL)
470		return (ENOENT);
471	sc->port_rid = rid;
472	sc->port_res = res;
473	return (0);
474}
475
476/*
477 * Allocate a memory resource with the given resource id.
478 */
479int
480cs_alloc_memory(device_t dev, int rid, int size)
481{
482	struct cs_softc *sc = device_get_softc(dev);
483	struct resource *res;
484
485	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
486	    0ul, ~0ul, size, RF_ACTIVE);
487	if (res == NULL)
488		return (ENOENT);
489	return (0);
490}
491
492/*
493 * Allocate an irq resource with the given resource id.
494 */
495int
496cs_alloc_irq(device_t dev, int rid, int flags)
497{
498	struct cs_softc *sc = device_get_softc(dev);
499	struct resource *res;
500
501	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
502	    (RF_ACTIVE | flags));
503	if (res == NULL)
504		return (ENOENT);
505	sc->irq_rid = rid;
506	sc->irq_res = res;
507	return (0);
508}
509
510/*
511 * Release all resources
512 */
513void
514cs_release_resources(device_t dev)
515{
516	struct cs_softc *sc = device_get_softc(dev);
517
518	if (sc->port_res) {
519		bus_release_resource(dev, SYS_RES_IOPORT,
520		    sc->port_rid, sc->port_res);
521		sc->port_res = 0;
522	}
523	if (sc->irq_res) {
524		bus_release_resource(dev, SYS_RES_IRQ,
525		    sc->irq_rid, sc->irq_res);
526		sc->irq_res = 0;
527	}
528}
529
530/*
531 * Install the interface into kernel networking data structures
532 */
533int
534cs_attach(device_t dev)
535{
536	int error, media=0;
537	struct cs_softc *sc = device_get_softc(dev);;
538	struct ifnet *ifp;
539
540	sc->dev = dev;
541
542	ifp = sc->ifp = if_alloc(IFT_ETHER);
543	if (ifp == NULL) {
544		device_printf(dev, "can not if_alloc()\n");
545		cs_release_resources(dev);
546		return (ENOMEM);
547	}
548
549	mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
550	    MTX_DEF);
551	callout_init_mtx(&sc->timer, &sc->lock, 0);
552
553	CS_LOCK(sc);
554	cs_stop(sc);
555	CS_UNLOCK(sc);
556
557	ifp->if_softc=sc;
558	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
559	ifp->if_start=cs_start;
560	ifp->if_ioctl=cs_ioctl;
561	ifp->if_init=cs_init;
562	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
563	/*
564	 *  MIB DATA
565	 */
566	/*
567	ifp->if_linkmib=&sc->mibdata;
568	ifp->if_linkmiblen=sizeof sc->mibdata;
569	*/
570
571	ifp->if_flags=(IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
572
573	/*
574	 * this code still in progress (DMA support)
575	 *
576
577	sc->recv_ring=malloc(CS_DMA_BUFFER_SIZE<<1, M_DEVBUF, M_NOWAIT);
578	if (sc->recv_ring == NULL) {
579		log(LOG_ERR,
580		"%s: Couldn't allocate memory for NIC\n", ifp->if_xname);
581		return(0);
582	}
583	if ((sc->recv_ring-(sc->recv_ring & 0x1FFFF))
584	    < (128*1024-CS_DMA_BUFFER_SIZE))
585	    sc->recv_ring+=16*1024;
586
587	*/
588
589	sc->buffer=malloc(ETHER_MAX_LEN-ETHER_CRC_LEN,M_DEVBUF,M_NOWAIT);
590	if (sc->buffer == NULL) {
591		device_printf(sc->dev, "Couldn't allocate memory for NIC\n");
592		if_free(ifp);
593		mtx_destroy(&sc->lock);
594		cs_release_resources(dev);
595		return(ENOMEM);
596	}
597
598	/*
599	 * Initialize the media structures.
600	 */
601	ifmedia_init(&sc->media, 0, cs_mediachange, cs_mediastatus);
602
603	if (sc->adapter_cnf & A_CNF_10B_T) {
604		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL);
605		if (sc->chip_type != CS8900) {
606			ifmedia_add(&sc->media,
607				IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
608			ifmedia_add(&sc->media,
609				IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
610		}
611	}
612
613	if (sc->adapter_cnf & A_CNF_10B_2)
614		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_2, 0, NULL);
615
616	if (sc->adapter_cnf & A_CNF_AUI)
617		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_5, 0, NULL);
618
619	if (sc->adapter_cnf & A_CNF_MEDIA)
620		ifmedia_add(&sc->media, IFM_ETHER|IFM_AUTO, 0, NULL);
621
622	/* Set default media from EEPROM */
623	switch (sc->adapter_cnf & A_CNF_MEDIA_TYPE) {
624	case A_CNF_MEDIA_AUTO:  media = IFM_ETHER|IFM_AUTO; break;
625	case A_CNF_MEDIA_10B_T: media = IFM_ETHER|IFM_10_T; break;
626	case A_CNF_MEDIA_10B_2: media = IFM_ETHER|IFM_10_2; break;
627	case A_CNF_MEDIA_AUI:   media = IFM_ETHER|IFM_10_5; break;
628	default:
629		device_printf(sc->dev, "no media, assuming 10baseT\n");
630		sc->adapter_cnf |= A_CNF_10B_T;
631		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL);
632		if (sc->chip_type != CS8900) {
633			ifmedia_add(&sc->media,
634			    IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
635			ifmedia_add(&sc->media,
636			    IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
637		}
638		media = IFM_ETHER | IFM_10_T;
639		break;
640	}
641	ifmedia_set(&sc->media, media);
642	cs_mediaset(sc, media);
643
644	ether_ifattach(ifp, sc->enaddr);
645
646  	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
647	    NULL, csintr, sc, &sc->irq_handle);
648	if (error) {
649		ether_ifdetach(ifp);
650		free(sc->buffer, M_DEVBUF);
651		if_free(ifp);
652		mtx_destroy(&sc->lock);
653		cs_release_resources(dev);
654		return (error);
655	}
656
657	return (0);
658}
659
660int
661cs_detach(device_t dev)
662{
663	struct cs_softc *sc;
664	struct ifnet *ifp;
665
666	sc = device_get_softc(dev);
667	ifp = sc->ifp;
668
669	CS_LOCK(sc);
670	cs_stop(sc);
671	CS_UNLOCK(sc);
672	callout_drain(&sc->timer);
673	ether_ifdetach(ifp);
674	bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
675	cs_release_resources(dev);
676	free(sc->buffer, M_DEVBUF);
677	if_free(ifp);
678	mtx_destroy(&sc->lock);
679	return (0);
680}
681
682/*
683 * Initialize the board
684 */
685static void
686cs_init(void *xsc)
687{
688	struct cs_softc *sc=(struct cs_softc *)xsc;
689
690	CS_LOCK(sc);
691	cs_init_locked(sc);
692	CS_UNLOCK(sc);
693}
694
695static void
696cs_init_locked(struct cs_softc *sc)
697{
698	struct ifnet *ifp = sc->ifp;
699	int i, rx_cfg;
700
701	/*
702	 * reset watchdog timer
703	 */
704	sc->tx_timeout = 0;
705	sc->buf_len = 0;
706
707	/*
708	 * Hardware initialization of cs
709	 */
710
711	/* Enable receiver and transmitter */
712	cs_writereg(sc, PP_LineCTL,
713		cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
714
715	/* Configure the receiver mode */
716	cs_setmode(sc);
717
718	/*
719	 * This defines what type of frames will cause interrupts
720	 * Bad frames should generate interrupts so that the driver
721	 * could track statistics of discarded packets
722	 */
723	rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL | RX_RUNT_ENBL |
724		 RX_EXTRA_DATA_ENBL;
725	if (sc->isa_config & STREAM_TRANSFER)
726		rx_cfg |= RX_STREAM_ENBL;
727	cs_writereg(sc, PP_RxCFG, rx_cfg);
728	cs_writereg(sc, PP_TxCFG, TX_LOST_CRS_ENBL |
729		    TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL |
730		    TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
731	cs_writereg(sc, PP_BufCFG, READY_FOR_TX_ENBL |
732		    RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL |
733		    TX_UNDERRUN_ENBL /*| RX_DMA_ENBL*/);
734
735	/* Write MAC address into IA filter */
736	for (i=0; i<ETHER_ADDR_LEN/2; i++)
737		cs_writereg(sc, PP_IA + i * 2,
738		    sc->enaddr[i * 2] |
739		    (sc->enaddr[i * 2 + 1] << 8) );
740
741	/*
742	 * Now enable everything
743	 */
744/*
745#ifdef	CS_USE_64K_DMA
746	cs_writereg(sc, PP_BusCTL, ENABLE_IRQ | RX_DMA_SIZE_64K);
747#else
748	cs_writereg(sc, PP_BusCTL, ENABLE_IRQ);
749#endif
750*/
751	cs_writereg(sc, PP_BusCTL, ENABLE_IRQ);
752
753	/*
754	 * Set running and clear output active flags
755	 */
756	sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
757	sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
758	callout_reset(&sc->timer, hz, cs_watchdog, sc);
759
760	/*
761	 * Start sending process
762	 */
763	cs_start_locked(ifp);
764}
765
766/*
767 * Get the packet from the board and send it to the upper layer.
768 */
769static int
770cs_get_packet(struct cs_softc *sc)
771{
772	struct ifnet *ifp = sc->ifp;
773	int iobase = sc->nic_addr, status, length;
774	struct ether_header *eh;
775	struct mbuf *m;
776
777#ifdef CS_DEBUG
778	int i;
779#endif
780
781	status = cs_inw(sc, RX_FRAME_PORT);
782	length = cs_inw(sc, RX_FRAME_PORT);
783
784#ifdef CS_DEBUG
785	device_printf(sc->dev, "rcvd: stat %x, len %d\n",
786		status, length);
787#endif
788
789	if (!(status & RX_OK)) {
790#ifdef CS_DEBUG
791		device_printf(sc->dev, "bad pkt stat %x\n", status);
792#endif
793		ifp->if_ierrors++;
794		return (-1);
795	}
796
797	MGETHDR(m, M_DONTWAIT, MT_DATA);
798	if (m==NULL)
799		return (-1);
800
801	if (length > MHLEN) {
802		MCLGET(m, M_DONTWAIT);
803		if (!(m->m_flags & M_EXT)) {
804			m_freem(m);
805			return (-1);
806		}
807	}
808
809	/* Initialize packet's header info */
810	m->m_pkthdr.rcvif = ifp;
811	m->m_pkthdr.len = length;
812	m->m_len = length;
813
814	/* Get the data */
815	insw(iobase + RX_FRAME_PORT, m->m_data, (length+1)>>1);
816
817	eh = mtod(m, struct ether_header *);
818
819#ifdef CS_DEBUG
820	for (i=0;i<length;i++)
821	     printf(" %02x",(unsigned char)*((char *)(m->m_data+i)));
822	printf( "\n" );
823#endif
824
825	if (status & (RX_IA | RX_BROADCAST) ||
826	    (ifp->if_flags & IFF_MULTICAST && status & RX_HASHED)) {
827		/* Feed the packet to the upper layer */
828		(*ifp->if_input)(ifp, m);
829		ifp->if_ipackets++;
830		if (length == ETHER_MAX_LEN-ETHER_CRC_LEN)
831			DELAY(cs_recv_delay);
832	} else {
833		m_freem(m);
834	}
835
836	return (0);
837}
838
839/*
840 * Handle interrupts
841 */
842void
843csintr(void *arg)
844{
845	struct cs_softc *sc = (struct cs_softc*) arg;
846	struct ifnet *ifp = sc->ifp;
847	int status;
848
849#ifdef CS_DEBUG
850	device_printf(sc->dev, "Interrupt.\n");
851#endif
852
853	CS_LOCK(sc);
854	while ((status=cs_inw(sc, ISQ_PORT))) {
855
856#ifdef CS_DEBUG
857		device_printf(sc->dev, "from ISQ: %04x\n", status);
858#endif
859
860		switch (status & ISQ_EVENT_MASK) {
861		case ISQ_RECEIVER_EVENT:
862			cs_get_packet(sc);
863			break;
864
865		case ISQ_TRANSMITTER_EVENT:
866			if (status & TX_OK)
867				ifp->if_opackets++;
868			else
869				ifp->if_oerrors++;
870			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
871			sc->tx_timeout = 0;
872			break;
873
874		case ISQ_BUFFER_EVENT:
875			if (status & READY_FOR_TX) {
876				ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
877				sc->tx_timeout = 0;
878			}
879
880			if (status & TX_UNDERRUN) {
881				ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
882				sc->tx_timeout = 0;
883				ifp->if_oerrors++;
884			}
885			break;
886
887		case ISQ_RX_MISS_EVENT:
888			ifp->if_ierrors+=(status>>6);
889			break;
890
891		case ISQ_TX_COL_EVENT:
892			ifp->if_collisions+=(status>>6);
893			break;
894		}
895	}
896
897	if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
898		cs_start_locked(ifp);
899	}
900	CS_UNLOCK(sc);
901}
902
903/*
904 * Save the data in buffer
905 */
906
907static void
908cs_write_mbufs( struct cs_softc *sc, struct mbuf *m )
909{
910	int len;
911	struct mbuf *mp;
912	unsigned char *data, *buf;
913
914	for (mp=m, buf=sc->buffer, sc->buf_len=0; mp != NULL; mp=mp->m_next) {
915		len = mp->m_len;
916
917		/*
918		 * Ignore empty parts
919		 */
920		if (!len)
921		continue;
922
923		/*
924		 * Find actual data address
925		 */
926		data = mtod(mp, caddr_t);
927
928		bcopy((caddr_t) data, (caddr_t) buf, len);
929		buf += len;
930		sc->buf_len += len;
931	}
932}
933
934
935static void
936cs_xmit_buf( struct cs_softc *sc )
937{
938	outsw(sc->nic_addr+TX_FRAME_PORT, sc->buffer, (sc->buf_len+1)>>1);
939	sc->buf_len = 0;
940}
941
942static void
943cs_start(struct ifnet *ifp)
944{
945	struct cs_softc *sc = ifp->if_softc;
946
947	CS_LOCK(sc);
948	cs_start_locked(ifp);
949	CS_UNLOCK(sc);
950}
951
952static void
953cs_start_locked(struct ifnet *ifp)
954{
955	int length;
956	struct mbuf *m, *mp;
957	struct cs_softc *sc = ifp->if_softc;
958
959	for (;;) {
960		if (sc->buf_len)
961			length = sc->buf_len;
962		else {
963			IF_DEQUEUE( &ifp->if_snd, m );
964
965			if (m==NULL) {
966				return;
967			}
968
969			for (length=0, mp=m; mp != NULL; mp=mp->m_next)
970				length += mp->m_len;
971
972			/* Skip zero-length packets */
973			if (length == 0) {
974				m_freem(m);
975				continue;
976			}
977
978			cs_write_mbufs(sc, m);
979
980			BPF_MTAP(ifp, m);
981
982			m_freem(m);
983		}
984
985		/*
986		 * Issue a SEND command
987		 */
988		cs_outw(sc, TX_CMD_PORT, sc->send_cmd);
989		cs_outw(sc, TX_LEN_PORT, length );
990
991		/*
992		 * If there's no free space in the buffer then leave
993		 * this packet for the next time: indicate output active
994		 * and return.
995		 */
996		if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) {
997			sc->tx_timeout = sc->buf_len;
998			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
999			return;
1000		}
1001
1002		cs_xmit_buf(sc);
1003
1004		/*
1005		 * Set the watchdog timer in case we never hear
1006		 * from board again. (I don't know about correct
1007		 * value for this timeout)
1008		 */
1009		sc->tx_timeout = length;
1010
1011		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1012		return;
1013	}
1014}
1015
1016/*
1017 * Stop everything on the interface
1018 */
1019static void
1020cs_stop(struct cs_softc *sc)
1021{
1022
1023	CS_ASSERT_LOCKED(sc);
1024	cs_writereg(sc, PP_RxCFG, 0);
1025	cs_writereg(sc, PP_TxCFG, 0);
1026	cs_writereg(sc, PP_BufCFG, 0);
1027	cs_writereg(sc, PP_BusCTL, 0);
1028
1029	sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1030	sc->tx_timeout = 0;
1031	callout_stop(&sc->timer);
1032}
1033
1034/*
1035 * Reset the interface
1036 */
1037static void
1038cs_reset(struct cs_softc *sc)
1039{
1040
1041	CS_ASSERT_LOCKED(sc);
1042	cs_stop(sc);
1043	cs_init_locked(sc);
1044}
1045
1046static uint16_t
1047cs_hash_index(struct sockaddr_dl *addr)
1048{
1049	uint32_t crc;
1050	uint16_t idx;
1051	caddr_t lla;
1052
1053	lla = LLADDR(addr);
1054	crc = ether_crc32_le(lla, ETHER_ADDR_LEN);
1055	idx = crc >> 26;
1056
1057	return (idx);
1058}
1059
1060static void
1061cs_setmode(struct cs_softc *sc)
1062{
1063	int rx_ctl;
1064	uint16_t af[4];
1065	uint16_t port, mask, index;
1066	struct ifnet *ifp = sc->ifp;
1067	struct ifmultiaddr *ifma;
1068
1069	/* Stop the receiver while changing filters */
1070	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & ~SERIAL_RX_ON);
1071
1072	if (ifp->if_flags & IFF_PROMISC) {
1073		/* Turn on promiscuous mode. */
1074		rx_ctl = RX_OK_ACCEPT | RX_PROM_ACCEPT;
1075	} else if (ifp->if_flags & IFF_MULTICAST) {
1076		/* Allow receiving frames with multicast addresses */
1077		rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT |
1078			 RX_OK_ACCEPT | RX_MULTCAST_ACCEPT;
1079
1080		/* Start with an empty filter */
1081		af[0] = af[1] = af[2] = af[3] = 0x0000;
1082
1083		if (ifp->if_flags & IFF_ALLMULTI) {
1084			/* Accept all multicast frames */
1085			af[0] = af[1] = af[2] = af[3] = 0xffff;
1086		} else {
1087			/*
1088			 * Set up the filter to only accept multicast
1089			 * frames we're interested in.
1090			 */
1091			IF_ADDR_LOCK(ifp);
1092			TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1093				struct sockaddr_dl *dl =
1094				    (struct sockaddr_dl *)ifma->ifma_addr;
1095
1096				index = cs_hash_index(dl);
1097				port = (u_int16_t) (index >> 4);
1098				mask = (u_int16_t) (1 << (index & 0xf));
1099				af[port] |= mask;
1100			}
1101			IF_ADDR_UNLOCK(ifp);
1102		}
1103
1104		cs_writereg(sc, PP_LAF + 0, af[0]);
1105		cs_writereg(sc, PP_LAF + 2, af[1]);
1106		cs_writereg(sc, PP_LAF + 4, af[2]);
1107		cs_writereg(sc, PP_LAF + 6, af[3]);
1108	} else {
1109		/*
1110		 * Receive only good frames addressed for us and
1111		 * good broadcasts.
1112		 */
1113		rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT |
1114			 RX_OK_ACCEPT;
1115	}
1116
1117	/* Set up the filter */
1118	cs_writereg(sc, PP_RxCTL, RX_DEF_ACCEPT | rx_ctl);
1119
1120	/* Turn on receiver */
1121	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON);
1122}
1123
1124static int
1125cs_ioctl(register struct ifnet *ifp, u_long command, caddr_t data)
1126{
1127	struct cs_softc *sc=ifp->if_softc;
1128	struct ifreq *ifr = (struct ifreq *)data;
1129	int error=0;
1130
1131#ifdef CS_DEBUG
1132	if_printf(ifp, "%s command=%lx\n", __func__, command);
1133#endif
1134
1135	switch (command) {
1136	case SIOCSIFFLAGS:
1137		/*
1138		 * Switch interface state between "running" and
1139		 * "stopped", reflecting the UP flag.
1140		 */
1141		CS_LOCK(sc);
1142		if (sc->ifp->if_flags & IFF_UP) {
1143			if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)==0) {
1144				cs_init_locked(sc);
1145			}
1146		} else {
1147			if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)!=0) {
1148				cs_stop(sc);
1149			}
1150		}
1151		/*
1152		 * Promiscuous and/or multicast flags may have changed,
1153		 * so reprogram the multicast filter and/or receive mode.
1154		 *
1155		 * See note about multicasts in cs_setmode
1156		 */
1157		cs_setmode(sc);
1158		CS_UNLOCK(sc);
1159		break;
1160
1161	case SIOCADDMULTI:
1162	case SIOCDELMULTI:
1163	    /*
1164	     * Multicast list has changed; set the hardware filter
1165	     * accordingly.
1166	     *
1167	     * See note about multicasts in cs_setmode
1168	     */
1169	    CS_LOCK(sc);
1170	    cs_setmode(sc);
1171	    CS_UNLOCK(sc);
1172	    error = 0;
1173	    break;
1174
1175	case SIOCSIFMEDIA:
1176	case SIOCGIFMEDIA:
1177		error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
1178		break;
1179
1180	default:
1181		error = ether_ioctl(ifp, command, data);
1182		break;
1183	}
1184
1185	return (error);
1186}
1187
1188/*
1189 * Device timeout/watchdog routine. Entered if the device neglects to
1190 * generate an interrupt after a transmit has been started on it.
1191 */
1192static void
1193cs_watchdog(void *arg)
1194{
1195	struct cs_softc *sc = arg;
1196	struct ifnet *ifp = sc->ifp;
1197
1198	CS_ASSERT_LOCKED(sc);
1199	if (sc->tx_timeout && --sc->tx_timeout == 0) {
1200		ifp->if_oerrors++;
1201		log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
1202
1203		/* Reset the interface */
1204		if (ifp->if_flags & IFF_UP)
1205			cs_reset(sc);
1206		else
1207			cs_stop(sc);
1208	}
1209	callout_reset(&sc->timer, hz, cs_watchdog, sc);
1210}
1211
1212static int
1213cs_mediachange(struct ifnet *ifp)
1214{
1215	struct cs_softc *sc = ifp->if_softc;
1216	struct ifmedia *ifm = &sc->media;
1217	int error;
1218
1219	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1220		return (EINVAL);
1221
1222	CS_LOCK(sc);
1223	error = cs_mediaset(sc, ifm->ifm_media);
1224	CS_UNLOCK(sc);
1225	return (error);
1226}
1227
1228static void
1229cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1230{
1231	int line_status;
1232	struct cs_softc *sc = ifp->if_softc;
1233
1234	CS_LOCK(sc);
1235	ifmr->ifm_active = IFM_ETHER;
1236	line_status = cs_readreg(sc, PP_LineST);
1237	if (line_status & TENBASET_ON) {
1238		ifmr->ifm_active |= IFM_10_T;
1239		if (sc->chip_type != CS8900) {
1240			if (cs_readreg(sc, PP_AutoNegST) & FDX_ACTIVE)
1241				ifmr->ifm_active |= IFM_FDX;
1242			if (cs_readreg(sc, PP_AutoNegST) & HDX_ACTIVE)
1243				ifmr->ifm_active |= IFM_HDX;
1244		}
1245		ifmr->ifm_status = IFM_AVALID;
1246		if (line_status & LINK_OK)
1247			ifmr->ifm_status |= IFM_ACTIVE;
1248	} else {
1249		if (line_status & AUI_ON) {
1250			cs_writereg(sc, PP_SelfCTL, cs_readreg(sc, PP_SelfCTL) |
1251			    HCB1_ENBL);
1252			if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0)^
1253			    (cs_readreg(sc, PP_SelfCTL) & HCB1))
1254				ifmr->ifm_active |= IFM_10_2;
1255			else
1256				ifmr->ifm_active |= IFM_10_5;
1257		}
1258	}
1259	CS_UNLOCK(sc);
1260}
1261
1262static int
1263cs_mediaset(struct cs_softc *sc, int media)
1264{
1265	int error = 0;
1266
1267	/* Stop the receiver & transmitter */
1268	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) &
1269	    ~(SERIAL_RX_ON | SERIAL_TX_ON));
1270
1271#ifdef CS_DEBUG
1272	device_printf(sc->dev, "%s media=%x\n", __func__, media);
1273#endif
1274
1275	switch (IFM_SUBTYPE(media)) {
1276	default:
1277	case IFM_AUTO:
1278		/*
1279		 * This chip makes it a little hard to support this, so treat
1280		 * it as IFM_10_T, auto duplex.
1281		 */
1282		enable_tp(sc);
1283		cs_duplex_auto(sc);
1284		break;
1285	case IFM_10_T:
1286		enable_tp(sc);
1287		if (media & IFM_FDX)
1288			cs_duplex_full(sc);
1289		else if (media & IFM_HDX)
1290			cs_duplex_half(sc);
1291		else
1292			error = cs_duplex_auto(sc);
1293		break;
1294	case IFM_10_2:
1295		error = enable_bnc(sc);
1296		break;
1297	case IFM_10_5:
1298		error = enable_aui(sc);
1299		break;
1300	}
1301
1302	/*
1303	 * Turn the transmitter & receiver back on
1304	 */
1305	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) |
1306	    SERIAL_RX_ON | SERIAL_TX_ON);
1307
1308	return (error);
1309}
1310