if_cs.c revision 257176
1255767Sdes/*-
276259Sgreen * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko.
3124208Sdes * All rights reserved.
476259Sgreen *
5124208Sdes * Redistribution and use in source and binary forms, with or without
6124208Sdes * modification, are permitted provided that the following conditions
7124208Sdes * are met:
876259Sgreen * 1. Redistributions of source code must retain the above copyright
9124208Sdes *    notice unmodified, this list of conditions, and the following
10124208Sdes *    disclaimer.
11124208Sdes * 2. Redistributions in binary form must reproduce the above copyright
12124208Sdes *    notice, this list of conditions and the following disclaimer in the
13124208Sdes *    documentation and/or other materials provided with the distribution.
14124208Sdes *
15124208Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1676259Sgreen * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17162852Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1876259Sgreen * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1976259Sgreen * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20162852Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21162852Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2276259Sgreen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2376259Sgreen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2476259Sgreen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25162852Sdes * SUCH DAMAGE.
26162852Sdes *
27162852Sdes */
2876259Sgreen
2976259Sgreen#include <sys/cdefs.h>
3076259Sgreen__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 257176 2013-10-26 17:58:36Z glebius $");
3176259Sgreen
3276259Sgreen/*
33215116Sdes *
3498675Sdes * Device driver for Crystal Semiconductor CS8920 based ethernet
3576259Sgreen *   adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997
36113908Sdes */
37106121Sdes
3876259Sgreen/*
3976259Sgreen#define	 CS_DEBUG
40126274Sdes */
41126274Sdes
4276259Sgreen#include <sys/param.h>
4376259Sgreen#include <sys/systm.h>
4476259Sgreen#include <sys/malloc.h>
45106121Sdes#include <sys/mbuf.h>
4676259Sgreen#include <sys/socket.h>
4776259Sgreen#include <sys/sockio.h>
4876259Sgreen#include <sys/kernel.h>
4976259Sgreen#include <sys/sysctl.h>
50215116Sdes#include <sys/syslog.h>
51215116Sdes
5276259Sgreen#include <sys/module.h>
5376259Sgreen#include <sys/bus.h>
5476259Sgreen#include <machine/bus.h>
5576259Sgreen#include <sys/rman.h>
5676259Sgreen#include <machine/resource.h>
5776259Sgreen
5876259Sgreen#include <net/if.h>
5976259Sgreen#include <net/if_var.h>
6076259Sgreen#include <net/if_arp.h>
6176259Sgreen#include <net/if_dl.h>
6292555Sdes#include <net/if_media.h>
6376259Sgreen#include <net/if_types.h>
6476259Sgreen#include <net/ethernet.h>
6576259Sgreen#include <net/bpf.h>
6676259Sgreen
6776259Sgreen#include <dev/cs/if_csvar.h>
6892555Sdes#include <dev/cs/if_csreg.h>
6976259Sgreen
7076259Sgreen#ifdef  CS_USE_64K_DMA
7176259Sgreen#define CS_DMA_BUFFER_SIZE 65536
72162852Sdes#else
7399060Sdes#define CS_DMA_BUFFER_SIZE 16384
7499060Sdes#endif
75255767Sdes
7676259Sgreenstatic void	cs_init(void *);
7776259Sgreenstatic void	cs_init_locked(struct cs_softc *);
7876259Sgreenstatic int	cs_ioctl(struct ifnet *, u_long, caddr_t);
79106121Sdesstatic void	cs_start(struct ifnet *);
8099060Sdesstatic void	cs_start_locked(struct ifnet *);
8176259Sgreenstatic void	cs_stop(struct cs_softc *);
8276259Sgreenstatic void	cs_reset(struct cs_softc *);
8376259Sgreenstatic void	cs_watchdog(void *);
8499060Sdes
85255767Sdesstatic int	cs_mediachange(struct ifnet *);
8676259Sgreenstatic void	cs_mediastatus(struct ifnet *, struct ifmediareq *);
8776259Sgreenstatic int      cs_mediaset(struct cs_softc *, int);
8876259Sgreen
8976259Sgreenstatic void	cs_write_mbufs(struct cs_softc*, struct mbuf*);
9076259Sgreenstatic void	cs_xmit_buf(struct cs_softc*);
9176259Sgreenstatic int	cs_get_packet(struct cs_softc*);
9276259Sgreenstatic void	cs_setmode(struct cs_softc*);
93106121Sdes
94106121Sdesstatic int	get_eeprom_data(struct cs_softc *sc, int, int, uint16_t *);
95106121Sdesstatic int	get_eeprom_cksum(int, int, uint16_t *);
96106121Sdesstatic int	wait_eeprom_ready( struct cs_softc *);
97106121Sdesstatic void	control_dc_dc( struct cs_softc *, int );
98106121Sdesstatic int	enable_tp(struct cs_softc *);
9976259Sgreenstatic int	enable_aui(struct cs_softc *);
10076259Sgreenstatic int	enable_bnc(struct cs_softc *);
101255767Sdesstatic int      cs_duplex_auto(struct cs_softc *);
10276259Sgreen
10376259Sgreendevclass_t cs_devclass;
10476259Sgreendriver_intr_t	csintr;
10576259Sgreen
10676259Sgreen/* sysctl vars */
107126274Sdesstatic SYSCTL_NODE(_hw, OID_AUTO, cs, CTLFLAG_RD, 0, "cs device parameters");
108126274Sdes
10976259Sgreenint	cs_ignore_cksum_failure = 0;
11076259SgreenTUNABLE_INT("hw.cs.ignore_checksum_failure", &cs_ignore_cksum_failure);
11176259SgreenSYSCTL_INT(_hw_cs, OID_AUTO, ignore_checksum_failure, CTLFLAG_RW,
11276259Sgreen    &cs_ignore_cksum_failure, 0,
11376259Sgreen  "ignore checksum errors in cs card EEPROM");
11492555Sdes
11598675Sdesstatic int	cs_recv_delay = 570;
11676259SgreenTUNABLE_INT("hw.cs.recv_delay", &cs_recv_delay);
11776259SgreenSYSCTL_INT(_hw_cs, OID_AUTO, recv_delay, CTLFLAG_RW, &cs_recv_delay, 570, "");
118215116Sdes
119215116Sdesstatic int cs8900_eeint2irq[16] = {
12076259Sgreen	 10,  11,  12,   5, 255, 255, 255, 255,
12176259Sgreen	255, 255, 255, 255, 255, 255, 255, 255
12276259Sgreen};
12398675Sdes
12498675Sdesstatic int cs8900_irq2eeint[16] = {
12598675Sdes	255, 255, 255, 255, 255,   3, 255, 255,
12692555Sdes	255,   0,   1,   2, 255, 255, 255, 255
12792555Sdes};
12876259Sgreen
12992555Sdesstatic int
130221420Sdesget_eeprom_data(struct cs_softc *sc, int off, int len, uint16_t *buffer)
13176259Sgreen{
13276259Sgreen	int i;
13376259Sgreen
134255767Sdes#ifdef CS_DEBUG
13576259Sgreen	device_printf(sc->dev, "EEPROM data from %x for %x:\n", off, len);
13676259Sgreen#endif
137255767Sdes	for (i=0; i < len; i++) {
13892555Sdes		if (wait_eeprom_ready(sc) < 0)
13976259Sgreen			return (-1);
14076259Sgreen		/* Send command to EEPROM to read */
14192555Sdes		cs_writereg(sc, PP_EECMD, (off + i) | EEPROM_READ_CMD);
14292555Sdes		if (wait_eeprom_ready(sc) < 0)
143255767Sdes			return (-1);
14476259Sgreen		buffer[i] = cs_readreg(sc, PP_EEData);
14576259Sgreen
14698675Sdes#ifdef CS_DEBUG
14798675Sdes		printf("%04x ",buffer[i]);
14898675Sdes#endif
14999060Sdes	}
150255767Sdes
15198675Sdes#ifdef CS_DEBUG
15298675Sdes	printf("\n");
153106121Sdes#endif
15499060Sdes	return (0);
15598675Sdes}
156162852Sdes
15798675Sdesstatic int
15898675Sdesget_eeprom_cksum(int off, int len, uint16_t *buffer)
15998675Sdes{
16098675Sdes	int i;
16176259Sgreen	uint16_t cksum=0;
16276259Sgreen
16392555Sdes	for (i = 0; i < len; i++)
164255767Sdes		cksum += buffer[i];
16576259Sgreen	cksum &= 0xffff;
16676259Sgreen	if (cksum == 0 || cs_ignore_cksum_failure)
16776259Sgreen		return (0);
16876259Sgreen	return (-1);
16992555Sdes}
17076259Sgreen
171106121Sdesstatic int
17292555Sdeswait_eeprom_ready(struct cs_softc *sc)
17376259Sgreen{
174255767Sdes	int i;
17576259Sgreen
17676259Sgreen	/*
17776259Sgreen	 * From the CS8900A datasheet, section 3.5.2:
178106121Sdes	 * "Before issuing any command to the EEPROM, the host must wait
179106121Sdes	 * for the SIBUSY bit (Register 16, SelfST, bit 8) to clear.  After
180106121Sdes	 * each command has been issued, the host must wait again for SIBUSY
181106121Sdes	 * to clear."
182106121Sdes	 *
183106121Sdes	 * Before we issue the command, we should be !busy, so that will
184106121Sdes	 * be fast.  The datasheet suggests that clock out from the part
185106121Sdes	 * per word will be on the order of 25us, which is consistant with
186106121Sdes	 * the 1MHz serial clock and 16bits...  We should never hit 100,
187106121Sdes	 * let alone 15,000 here.  The original code did an unconditional
188106121Sdes	 * 30ms DELAY here.  Bad Kharma.  cs_readreg takes ~2us.
189106121Sdes	 */
190106121Sdes	for (i = 0; i < 15000; i++)	/* 30ms max */
191106121Sdes		if (!(cs_readreg(sc, PP_SelfST) & SI_BUSY))
192106121Sdes			return (0);
193106121Sdes	return (1);
194106121Sdes}
195106121Sdes
196106121Sdesstatic void
197106121Sdescontrol_dc_dc(struct cs_softc *sc, int on_not_off)
198106121Sdes{
199106121Sdes	unsigned int self_control = HCB1_ENBL;
200106121Sdes
201106121Sdes	if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0) ^ on_not_off)
202106121Sdes		self_control |= HCB1;
203106121Sdes	else
204106121Sdes		self_control &= ~HCB1;
205106121Sdes	cs_writereg(sc, PP_SelfCTL, self_control);
206106121Sdes	DELAY(500000);	/* Bad! */
207106121Sdes}
208106121Sdes
209106121Sdes
210106121Sdesstatic int
211106121Sdescs_duplex_auto(struct cs_softc *sc)
212106121Sdes{
213106121Sdes	int i, error=0;
214215116Sdes
215106121Sdes	cs_writereg(sc, PP_AutoNegCTL,
216106121Sdes	    RE_NEG_NOW | ALLOW_FDX | AUTO_NEG_ENABLE);
217106121Sdes	for (i=0; cs_readreg(sc, PP_AutoNegST) & AUTO_NEG_BUSY; i++) {
218106121Sdes		if (i > 4000) {
219106121Sdes			device_printf(sc->dev,
220106121Sdes			    "full/half duplex auto negotiation timeout\n");
221106121Sdes			error = ETIMEDOUT;
222106121Sdes			break;
223106121Sdes		}
224106121Sdes		DELAY(1000);
225106121Sdes	}
226106121Sdes	return (error);
227106121Sdes}
228106121Sdes
229106121Sdesstatic int
230106121Sdesenable_tp(struct cs_softc *sc)
231106121Sdes{
232106121Sdes
233106121Sdes	cs_writereg(sc, PP_LineCTL, sc->line_ctl & ~AUI_ONLY);
234106121Sdes	control_dc_dc(sc, 0);
235106121Sdes	return (0);
236106121Sdes}
237106121Sdes
238106121Sdesstatic int
239106121Sdesenable_aui(struct cs_softc *sc)
240106121Sdes{
241106121Sdes
242106121Sdes	cs_writereg(sc, PP_LineCTL,
243106121Sdes	    (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY);
244106121Sdes	control_dc_dc(sc, 0);
245106121Sdes	return (0);
246106121Sdes}
247106121Sdes
248106121Sdesstatic int
249149749Sdesenable_bnc(struct cs_softc *sc)
250106121Sdes{
251106121Sdes
252106121Sdes	cs_writereg(sc, PP_LineCTL,
253215116Sdes	    (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY);
254215116Sdes	control_dc_dc(sc, 1);
255215116Sdes	return (0);
256106121Sdes}
257106121Sdes
258106121Sdesint
259215116Sdescs_cs89x0_probe(device_t dev)
260106121Sdes{
261106121Sdes	int i;
262106121Sdes	int error;
263106121Sdes	u_long irq, junk;
264106121Sdes	struct cs_softc *sc = device_get_softc(dev);
265255767Sdes	unsigned rev_type = 0;
266106121Sdes	uint16_t id;
267106121Sdes	char chip_revision;
268	uint16_t eeprom_buff[CHKSUM_LEN];
269	int chip_type, pp_isaint, pp_isadma;
270
271	sc->dev = dev;
272	error = cs_alloc_port(dev, 0, CS_89x0_IO_PORTS);
273	if (error)
274		return (error);
275
276	if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG) {
277		/* Chip not detected. Let's try to reset it */
278		if (bootverbose)
279			device_printf(dev, "trying to reset the chip.\n");
280		cs_outw(sc, ADD_PORT, PP_SelfCTL);
281		i = cs_inw(sc, DATA_PORT);
282		cs_outw(sc, ADD_PORT, PP_SelfCTL);
283		cs_outw(sc, DATA_PORT, i | POWER_ON_RESET);
284		if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG)
285			return (ENXIO);
286	}
287
288	for (i = 0; i < 10000; i++) {
289		id = cs_readreg(sc, PP_ChipID);
290		if (id == CHIP_EISA_ID_SIG)
291			break;
292	}
293	if (i == 10000)
294		return (ENXIO);
295
296	rev_type = cs_readreg(sc, PRODUCT_ID_ADD);
297	chip_type = rev_type & ~REVISON_BITS;
298	chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
299
300	sc->chip_type = chip_type;
301
302	if (chip_type == CS8900) {
303		pp_isaint = PP_CS8900_ISAINT;
304		pp_isadma = PP_CS8900_ISADMA;
305		sc->send_cmd = TX_CS8900_AFTER_ALL;
306	} else {
307		pp_isaint = PP_CS8920_ISAINT;
308		pp_isadma = PP_CS8920_ISADMA;
309		sc->send_cmd = TX_CS8920_AFTER_ALL;
310	}
311
312	/*
313	 * Clear some fields so that fail of EEPROM will left them clean
314	 */
315	sc->auto_neg_cnf = 0;
316	sc->adapter_cnf  = 0;
317	sc->isa_config   = 0;
318
319	/*
320	 * If no interrupt specified, use what the board tells us.
321	 */
322	error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk);
323
324	/*
325	 * Get data from EEPROM
326	 */
327	if((cs_readreg(sc, PP_SelfST) & EEPROM_PRESENT) == 0) {
328		device_printf(dev, "No EEPROM, assuming defaults.\n");
329	} else if (get_eeprom_data(sc,START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) {
330		device_printf(dev, "EEPROM read failed, assuming defaults.\n");
331	} else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) {
332		device_printf(dev, "EEPROM cheksum bad, assuming defaults.\n");
333	} else {
334		sc->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET];
335		sc->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET];
336		sc->isa_config = eeprom_buff[ISA_CNF_OFFSET];
337		for (i=0; i<ETHER_ADDR_LEN/2; i++) {
338			sc->enaddr[i*2] = eeprom_buff[i];
339			sc->enaddr[i*2+1] = eeprom_buff[i] >> 8;
340		}
341		/*
342		 * If no interrupt specified, use what the
343		 * board tells us.
344		 */
345		if (error) {
346			irq = sc->isa_config & INT_NO_MASK;
347			error = 0;
348			if (chip_type == CS8900) {
349				irq = cs8900_eeint2irq[irq];
350			} else {
351				if (irq > CS8920_NO_INTS)
352					irq = 255;
353			}
354			if (irq == 255) {
355				device_printf(dev, "invalid irq in EEPROM.\n");
356				error = EINVAL;
357			}
358			if (!error)
359				bus_set_resource(dev, SYS_RES_IRQ, 0,
360				    irq, 1);
361		}
362	}
363
364	if (!error && !(sc->flags & CS_NO_IRQ)) {
365		if (chip_type == CS8900) {
366			if (irq < 16)
367				irq = cs8900_irq2eeint[irq];
368			else
369				irq = 255;
370		} else {
371			if (irq > CS8920_NO_INTS)
372				irq = 255;
373		}
374		if (irq == 255)
375			error = EINVAL;
376	}
377
378	if (error) {
379	       	device_printf(dev, "Unknown or invalid irq\n");
380		return (error);
381	}
382
383	if (!(sc->flags & CS_NO_IRQ))
384		cs_writereg(sc, pp_isaint, irq);
385
386	/*
387	 * Temporary disabled
388	 *
389	if (drq>0)
390		cs_writereg(sc, pp_isadma, drq);
391	else {
392		device_printf(dev, "incorrect drq\n",);
393		return (0);
394	}
395	*/
396
397	if (bootverbose)
398		 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n",
399			chip_type == CS8900 ? '0' : '2',
400			chip_type == CS8920M ? "M" : "",
401			chip_revision,
402			(sc->adapter_cnf & A_CNF_10B_T) ? " TP"  : "",
403			(sc->adapter_cnf & A_CNF_AUI)   ? " AUI" : "",
404			(sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : "");
405
406	if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) &&
407	    (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
408		sc->line_ctl = LOW_RX_SQUELCH;
409	else
410		sc->line_ctl = 0;
411
412	return (0);
413}
414
415/*
416 * Allocate a port resource with the given resource id.
417 */
418int
419cs_alloc_port(device_t dev, int rid, int size)
420{
421	struct cs_softc *sc = device_get_softc(dev);
422	struct resource *res;
423
424	res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
425	    0ul, ~0ul, size, RF_ACTIVE);
426	if (res == NULL)
427		return (ENOENT);
428	sc->port_rid = rid;
429	sc->port_res = res;
430	return (0);
431}
432
433/*
434 * Allocate an irq resource with the given resource id.
435 */
436int
437cs_alloc_irq(device_t dev, int rid)
438{
439	struct cs_softc *sc = device_get_softc(dev);
440	struct resource *res;
441
442	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
443	if (res == NULL)
444		return (ENOENT);
445	sc->irq_rid = rid;
446	sc->irq_res = res;
447	return (0);
448}
449
450/*
451 * Release all resources
452 */
453void
454cs_release_resources(device_t dev)
455{
456	struct cs_softc *sc = device_get_softc(dev);
457
458	if (sc->port_res) {
459		bus_release_resource(dev, SYS_RES_IOPORT,
460		    sc->port_rid, sc->port_res);
461		sc->port_res = 0;
462	}
463	if (sc->irq_res) {
464		bus_release_resource(dev, SYS_RES_IRQ,
465		    sc->irq_rid, sc->irq_res);
466		sc->irq_res = 0;
467	}
468}
469
470/*
471 * Install the interface into kernel networking data structures
472 */
473int
474cs_attach(device_t dev)
475{
476	int error, media=0;
477	struct cs_softc *sc = device_get_softc(dev);
478	struct ifnet *ifp;
479
480	sc->dev = dev;
481
482	ifp = sc->ifp = if_alloc(IFT_ETHER);
483	if (ifp == NULL) {
484		device_printf(dev, "can not if_alloc()\n");
485		cs_release_resources(dev);
486		return (ENOMEM);
487	}
488
489	mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
490	    MTX_DEF);
491	callout_init_mtx(&sc->timer, &sc->lock, 0);
492
493	CS_LOCK(sc);
494	cs_stop(sc);
495	CS_UNLOCK(sc);
496
497	ifp->if_softc=sc;
498	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
499	ifp->if_start=cs_start;
500	ifp->if_ioctl=cs_ioctl;
501	ifp->if_init=cs_init;
502	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
503
504	ifp->if_flags=(IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
505
506	/*
507	 * this code still in progress (DMA support)
508	 *
509
510	sc->recv_ring=malloc(CS_DMA_BUFFER_SIZE<<1, M_DEVBUF, M_NOWAIT);
511	if (sc->recv_ring == NULL) {
512		log(LOG_ERR,
513		"%s: Couldn't allocate memory for NIC\n", ifp->if_xname);
514		return(0);
515	}
516	if ((sc->recv_ring-(sc->recv_ring & 0x1FFFF))
517	    < (128*1024-CS_DMA_BUFFER_SIZE))
518	    sc->recv_ring+=16*1024;
519
520	*/
521
522	sc->buffer=malloc(ETHER_MAX_LEN-ETHER_CRC_LEN,M_DEVBUF,M_NOWAIT);
523	if (sc->buffer == NULL) {
524		device_printf(sc->dev, "Couldn't allocate memory for NIC\n");
525		if_free(ifp);
526		mtx_destroy(&sc->lock);
527		cs_release_resources(dev);
528		return(ENOMEM);
529	}
530
531	/*
532	 * Initialize the media structures.
533	 */
534	ifmedia_init(&sc->media, 0, cs_mediachange, cs_mediastatus);
535
536	if (sc->adapter_cnf & A_CNF_10B_T) {
537		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL);
538		if (sc->chip_type != CS8900) {
539			ifmedia_add(&sc->media,
540				IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
541			ifmedia_add(&sc->media,
542				IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
543		}
544	}
545
546	if (sc->adapter_cnf & A_CNF_10B_2)
547		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_2, 0, NULL);
548
549	if (sc->adapter_cnf & A_CNF_AUI)
550		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_5, 0, NULL);
551
552	if (sc->adapter_cnf & A_CNF_MEDIA)
553		ifmedia_add(&sc->media, IFM_ETHER|IFM_AUTO, 0, NULL);
554
555	/* Set default media from EEPROM */
556	switch (sc->adapter_cnf & A_CNF_MEDIA_TYPE) {
557	case A_CNF_MEDIA_AUTO:  media = IFM_ETHER|IFM_AUTO; break;
558	case A_CNF_MEDIA_10B_T: media = IFM_ETHER|IFM_10_T; break;
559	case A_CNF_MEDIA_10B_2: media = IFM_ETHER|IFM_10_2; break;
560	case A_CNF_MEDIA_AUI:   media = IFM_ETHER|IFM_10_5; break;
561	default:
562		device_printf(sc->dev, "no media, assuming 10baseT\n");
563		sc->adapter_cnf |= A_CNF_10B_T;
564		ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL);
565		if (sc->chip_type != CS8900) {
566			ifmedia_add(&sc->media,
567			    IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
568			ifmedia_add(&sc->media,
569			    IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
570		}
571		media = IFM_ETHER | IFM_10_T;
572		break;
573	}
574	ifmedia_set(&sc->media, media);
575	cs_mediaset(sc, media);
576
577	ether_ifattach(ifp, sc->enaddr);
578
579  	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
580	    NULL, csintr, sc, &sc->irq_handle);
581	if (error) {
582		ether_ifdetach(ifp);
583		free(sc->buffer, M_DEVBUF);
584		if_free(ifp);
585		mtx_destroy(&sc->lock);
586		cs_release_resources(dev);
587		return (error);
588	}
589
590	return (0);
591}
592
593int
594cs_detach(device_t dev)
595{
596	struct cs_softc *sc;
597	struct ifnet *ifp;
598
599	sc = device_get_softc(dev);
600	ifp = sc->ifp;
601
602	CS_LOCK(sc);
603	cs_stop(sc);
604	CS_UNLOCK(sc);
605	callout_drain(&sc->timer);
606	ether_ifdetach(ifp);
607	bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
608	cs_release_resources(dev);
609	free(sc->buffer, M_DEVBUF);
610	if_free(ifp);
611	mtx_destroy(&sc->lock);
612	return (0);
613}
614
615/*
616 * Initialize the board
617 */
618static void
619cs_init(void *xsc)
620{
621	struct cs_softc *sc=(struct cs_softc *)xsc;
622
623	CS_LOCK(sc);
624	cs_init_locked(sc);
625	CS_UNLOCK(sc);
626}
627
628static void
629cs_init_locked(struct cs_softc *sc)
630{
631	struct ifnet *ifp = sc->ifp;
632	int i, rx_cfg;
633
634	/*
635	 * reset watchdog timer
636	 */
637	sc->tx_timeout = 0;
638	sc->buf_len = 0;
639
640	/*
641	 * Hardware initialization of cs
642	 */
643
644	/* Enable receiver and transmitter */
645	cs_writereg(sc, PP_LineCTL,
646		cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
647
648	/* Configure the receiver mode */
649	cs_setmode(sc);
650
651	/*
652	 * This defines what type of frames will cause interrupts
653	 * Bad frames should generate interrupts so that the driver
654	 * could track statistics of discarded packets
655	 */
656	rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL | RX_RUNT_ENBL |
657		 RX_EXTRA_DATA_ENBL;
658	if (sc->isa_config & STREAM_TRANSFER)
659		rx_cfg |= RX_STREAM_ENBL;
660	cs_writereg(sc, PP_RxCFG, rx_cfg);
661	cs_writereg(sc, PP_TxCFG, TX_LOST_CRS_ENBL |
662		    TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL |
663		    TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
664	cs_writereg(sc, PP_BufCFG, READY_FOR_TX_ENBL |
665		    RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL |
666		    TX_UNDERRUN_ENBL /*| RX_DMA_ENBL*/);
667
668	/* Write MAC address into IA filter */
669	for (i=0; i<ETHER_ADDR_LEN/2; i++)
670		cs_writereg(sc, PP_IA + i * 2,
671		    sc->enaddr[i * 2] |
672		    (sc->enaddr[i * 2 + 1] << 8) );
673
674	/*
675	 * Now enable everything
676	 */
677/*
678#ifdef	CS_USE_64K_DMA
679	cs_writereg(sc, PP_BusCTL, ENABLE_IRQ | RX_DMA_SIZE_64K);
680#else
681	cs_writereg(sc, PP_BusCTL, ENABLE_IRQ);
682#endif
683*/
684	cs_writereg(sc, PP_BusCTL, ENABLE_IRQ);
685
686	/*
687	 * Set running and clear output active flags
688	 */
689	sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
690	sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
691	callout_reset(&sc->timer, hz, cs_watchdog, sc);
692
693	/*
694	 * Start sending process
695	 */
696	cs_start_locked(ifp);
697}
698
699/*
700 * Get the packet from the board and send it to the upper layer.
701 */
702static int
703cs_get_packet(struct cs_softc *sc)
704{
705	struct ifnet *ifp = sc->ifp;
706	int status, length;
707	struct ether_header *eh;
708	struct mbuf *m;
709
710#ifdef CS_DEBUG
711	int i;
712#endif
713
714	status = cs_inw(sc, RX_FRAME_PORT);
715	length = cs_inw(sc, RX_FRAME_PORT);
716
717#ifdef CS_DEBUG
718	device_printf(sc->dev, "rcvd: stat %x, len %d\n",
719		status, length);
720#endif
721
722	if (!(status & RX_OK)) {
723#ifdef CS_DEBUG
724		device_printf(sc->dev, "bad pkt stat %x\n", status);
725#endif
726		ifp->if_ierrors++;
727		return (-1);
728	}
729
730	MGETHDR(m, M_NOWAIT, MT_DATA);
731	if (m==NULL)
732		return (-1);
733
734	if (length > MHLEN) {
735		MCLGET(m, M_NOWAIT);
736		if (!(m->m_flags & M_EXT)) {
737			m_freem(m);
738			return (-1);
739		}
740	}
741
742	/* Initialize packet's header info */
743	m->m_pkthdr.rcvif = ifp;
744	m->m_pkthdr.len = length;
745	m->m_len = length;
746
747	/* Get the data */
748	bus_read_multi_2(sc->port_res, RX_FRAME_PORT, mtod(m, uint16_t *),
749	    (length + 1) >> 1);
750
751	eh = mtod(m, struct ether_header *);
752
753#ifdef CS_DEBUG
754	for (i=0;i<length;i++)
755	     printf(" %02x",(unsigned char)*((char *)(m->m_data+i)));
756	printf( "\n" );
757#endif
758
759	if (status & (RX_IA | RX_BROADCAST) ||
760	    (ifp->if_flags & IFF_MULTICAST && status & RX_HASHED)) {
761		/* Feed the packet to the upper layer */
762		(*ifp->if_input)(ifp, m);
763		ifp->if_ipackets++;
764		if (length == ETHER_MAX_LEN-ETHER_CRC_LEN)
765			DELAY(cs_recv_delay);
766	} else {
767		m_freem(m);
768	}
769
770	return (0);
771}
772
773/*
774 * Handle interrupts
775 */
776void
777csintr(void *arg)
778{
779	struct cs_softc *sc = (struct cs_softc*) arg;
780	struct ifnet *ifp = sc->ifp;
781	int status;
782
783#ifdef CS_DEBUG
784	device_printf(sc->dev, "Interrupt.\n");
785#endif
786
787	CS_LOCK(sc);
788	while ((status=cs_inw(sc, ISQ_PORT))) {
789
790#ifdef CS_DEBUG
791		device_printf(sc->dev, "from ISQ: %04x\n", status);
792#endif
793
794		switch (status & ISQ_EVENT_MASK) {
795		case ISQ_RECEIVER_EVENT:
796			cs_get_packet(sc);
797			break;
798
799		case ISQ_TRANSMITTER_EVENT:
800			if (status & TX_OK)
801				ifp->if_opackets++;
802			else
803				ifp->if_oerrors++;
804			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
805			sc->tx_timeout = 0;
806			break;
807
808		case ISQ_BUFFER_EVENT:
809			if (status & READY_FOR_TX) {
810				ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
811				sc->tx_timeout = 0;
812			}
813
814			if (status & TX_UNDERRUN) {
815				ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
816				sc->tx_timeout = 0;
817				ifp->if_oerrors++;
818			}
819			break;
820
821		case ISQ_RX_MISS_EVENT:
822			ifp->if_ierrors+=(status>>6);
823			break;
824
825		case ISQ_TX_COL_EVENT:
826			ifp->if_collisions+=(status>>6);
827			break;
828		}
829	}
830
831	if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
832		cs_start_locked(ifp);
833	}
834	CS_UNLOCK(sc);
835}
836
837/*
838 * Save the data in buffer
839 */
840
841static void
842cs_write_mbufs( struct cs_softc *sc, struct mbuf *m )
843{
844	int len;
845	struct mbuf *mp;
846	unsigned char *data, *buf;
847
848	for (mp=m, buf=sc->buffer, sc->buf_len=0; mp != NULL; mp=mp->m_next) {
849		len = mp->m_len;
850
851		/*
852		 * Ignore empty parts
853		 */
854		if (!len)
855			continue;
856
857		/*
858		 * Find actual data address
859		 */
860		data = mtod(mp, caddr_t);
861
862		bcopy((caddr_t) data, (caddr_t) buf, len);
863		buf += len;
864		sc->buf_len += len;
865	}
866}
867
868
869static void
870cs_xmit_buf( struct cs_softc *sc )
871{
872	bus_write_multi_2(sc->port_res, TX_FRAME_PORT, (uint16_t *)sc->buffer,
873	    (sc->buf_len + 1) >> 1);
874	sc->buf_len = 0;
875}
876
877static void
878cs_start(struct ifnet *ifp)
879{
880	struct cs_softc *sc = ifp->if_softc;
881
882	CS_LOCK(sc);
883	cs_start_locked(ifp);
884	CS_UNLOCK(sc);
885}
886
887static void
888cs_start_locked(struct ifnet *ifp)
889{
890	int length;
891	struct mbuf *m, *mp;
892	struct cs_softc *sc = ifp->if_softc;
893
894	for (;;) {
895		if (sc->buf_len)
896			length = sc->buf_len;
897		else {
898			IF_DEQUEUE( &ifp->if_snd, m );
899
900			if (m==NULL) {
901				return;
902			}
903
904			for (length=0, mp=m; mp != NULL; mp=mp->m_next)
905				length += mp->m_len;
906
907			/* Skip zero-length packets */
908			if (length == 0) {
909				m_freem(m);
910				continue;
911			}
912
913			cs_write_mbufs(sc, m);
914
915			BPF_MTAP(ifp, m);
916
917			m_freem(m);
918		}
919
920		/*
921		 * Issue a SEND command
922		 */
923		cs_outw(sc, TX_CMD_PORT, sc->send_cmd);
924		cs_outw(sc, TX_LEN_PORT, length );
925
926		/*
927		 * If there's no free space in the buffer then leave
928		 * this packet for the next time: indicate output active
929		 * and return.
930		 */
931		if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) {
932			sc->tx_timeout = sc->buf_len;
933			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
934			return;
935		}
936
937		cs_xmit_buf(sc);
938
939		/*
940		 * Set the watchdog timer in case we never hear
941		 * from board again. (I don't know about correct
942		 * value for this timeout)
943		 */
944		sc->tx_timeout = length;
945
946		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
947		return;
948	}
949}
950
951/*
952 * Stop everything on the interface
953 */
954static void
955cs_stop(struct cs_softc *sc)
956{
957
958	CS_ASSERT_LOCKED(sc);
959	cs_writereg(sc, PP_RxCFG, 0);
960	cs_writereg(sc, PP_TxCFG, 0);
961	cs_writereg(sc, PP_BufCFG, 0);
962	cs_writereg(sc, PP_BusCTL, 0);
963
964	sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
965	sc->tx_timeout = 0;
966	callout_stop(&sc->timer);
967}
968
969/*
970 * Reset the interface
971 */
972static void
973cs_reset(struct cs_softc *sc)
974{
975
976	CS_ASSERT_LOCKED(sc);
977	cs_stop(sc);
978	cs_init_locked(sc);
979}
980
981static uint16_t
982cs_hash_index(struct sockaddr_dl *addr)
983{
984	uint32_t crc;
985	uint16_t idx;
986	caddr_t lla;
987
988	lla = LLADDR(addr);
989	crc = ether_crc32_le(lla, ETHER_ADDR_LEN);
990	idx = crc >> 26;
991
992	return (idx);
993}
994
995static void
996cs_setmode(struct cs_softc *sc)
997{
998	int rx_ctl;
999	uint16_t af[4];
1000	uint16_t port, mask, index;
1001	struct ifnet *ifp = sc->ifp;
1002	struct ifmultiaddr *ifma;
1003
1004	/* Stop the receiver while changing filters */
1005	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & ~SERIAL_RX_ON);
1006
1007	if (ifp->if_flags & IFF_PROMISC) {
1008		/* Turn on promiscuous mode. */
1009		rx_ctl = RX_OK_ACCEPT | RX_PROM_ACCEPT;
1010	} else if (ifp->if_flags & IFF_MULTICAST) {
1011		/* Allow receiving frames with multicast addresses */
1012		rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT |
1013			 RX_OK_ACCEPT | RX_MULTCAST_ACCEPT;
1014
1015		/* Start with an empty filter */
1016		af[0] = af[1] = af[2] = af[3] = 0x0000;
1017
1018		if (ifp->if_flags & IFF_ALLMULTI) {
1019			/* Accept all multicast frames */
1020			af[0] = af[1] = af[2] = af[3] = 0xffff;
1021		} else {
1022			/*
1023			 * Set up the filter to only accept multicast
1024			 * frames we're interested in.
1025			 */
1026			if_maddr_rlock(ifp);
1027			TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1028				struct sockaddr_dl *dl =
1029				    (struct sockaddr_dl *)ifma->ifma_addr;
1030
1031				index = cs_hash_index(dl);
1032				port = (u_int16_t) (index >> 4);
1033				mask = (u_int16_t) (1 << (index & 0xf));
1034				af[port] |= mask;
1035			}
1036			if_maddr_runlock(ifp);
1037		}
1038
1039		cs_writereg(sc, PP_LAF + 0, af[0]);
1040		cs_writereg(sc, PP_LAF + 2, af[1]);
1041		cs_writereg(sc, PP_LAF + 4, af[2]);
1042		cs_writereg(sc, PP_LAF + 6, af[3]);
1043	} else {
1044		/*
1045		 * Receive only good frames addressed for us and
1046		 * good broadcasts.
1047		 */
1048		rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT |
1049			 RX_OK_ACCEPT;
1050	}
1051
1052	/* Set up the filter */
1053	cs_writereg(sc, PP_RxCTL, RX_DEF_ACCEPT | rx_ctl);
1054
1055	/* Turn on receiver */
1056	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON);
1057}
1058
1059static int
1060cs_ioctl(register struct ifnet *ifp, u_long command, caddr_t data)
1061{
1062	struct cs_softc *sc=ifp->if_softc;
1063	struct ifreq *ifr = (struct ifreq *)data;
1064	int error=0;
1065
1066#ifdef CS_DEBUG
1067	if_printf(ifp, "%s command=%lx\n", __func__, command);
1068#endif
1069
1070	switch (command) {
1071	case SIOCSIFFLAGS:
1072		/*
1073		 * Switch interface state between "running" and
1074		 * "stopped", reflecting the UP flag.
1075		 */
1076		CS_LOCK(sc);
1077		if (sc->ifp->if_flags & IFF_UP) {
1078			if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)==0) {
1079				cs_init_locked(sc);
1080			}
1081		} else {
1082			if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)!=0) {
1083				cs_stop(sc);
1084			}
1085		}
1086		/*
1087		 * Promiscuous and/or multicast flags may have changed,
1088		 * so reprogram the multicast filter and/or receive mode.
1089		 *
1090		 * See note about multicasts in cs_setmode
1091		 */
1092		cs_setmode(sc);
1093		CS_UNLOCK(sc);
1094		break;
1095
1096	case SIOCADDMULTI:
1097	case SIOCDELMULTI:
1098	    /*
1099	     * Multicast list has changed; set the hardware filter
1100	     * accordingly.
1101	     *
1102	     * See note about multicasts in cs_setmode
1103	     */
1104	    CS_LOCK(sc);
1105	    cs_setmode(sc);
1106	    CS_UNLOCK(sc);
1107	    error = 0;
1108	    break;
1109
1110	case SIOCSIFMEDIA:
1111	case SIOCGIFMEDIA:
1112		error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
1113		break;
1114
1115	default:
1116		error = ether_ioctl(ifp, command, data);
1117		break;
1118	}
1119
1120	return (error);
1121}
1122
1123/*
1124 * Device timeout/watchdog routine. Entered if the device neglects to
1125 * generate an interrupt after a transmit has been started on it.
1126 */
1127static void
1128cs_watchdog(void *arg)
1129{
1130	struct cs_softc *sc = arg;
1131	struct ifnet *ifp = sc->ifp;
1132
1133	CS_ASSERT_LOCKED(sc);
1134	if (sc->tx_timeout && --sc->tx_timeout == 0) {
1135		ifp->if_oerrors++;
1136		log(LOG_ERR, "%s: device timeout\n", ifp->if_xname);
1137
1138		/* Reset the interface */
1139		if (ifp->if_flags & IFF_UP)
1140			cs_reset(sc);
1141		else
1142			cs_stop(sc);
1143	}
1144	callout_reset(&sc->timer, hz, cs_watchdog, sc);
1145}
1146
1147static int
1148cs_mediachange(struct ifnet *ifp)
1149{
1150	struct cs_softc *sc = ifp->if_softc;
1151	struct ifmedia *ifm = &sc->media;
1152	int error;
1153
1154	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
1155		return (EINVAL);
1156
1157	CS_LOCK(sc);
1158	error = cs_mediaset(sc, ifm->ifm_media);
1159	CS_UNLOCK(sc);
1160	return (error);
1161}
1162
1163static void
1164cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1165{
1166	int line_status;
1167	struct cs_softc *sc = ifp->if_softc;
1168
1169	CS_LOCK(sc);
1170	ifmr->ifm_active = IFM_ETHER;
1171	line_status = cs_readreg(sc, PP_LineST);
1172	if (line_status & TENBASET_ON) {
1173		ifmr->ifm_active |= IFM_10_T;
1174		if (sc->chip_type != CS8900) {
1175			if (cs_readreg(sc, PP_AutoNegST) & FDX_ACTIVE)
1176				ifmr->ifm_active |= IFM_FDX;
1177			if (cs_readreg(sc, PP_AutoNegST) & HDX_ACTIVE)
1178				ifmr->ifm_active |= IFM_HDX;
1179		}
1180		ifmr->ifm_status = IFM_AVALID;
1181		if (line_status & LINK_OK)
1182			ifmr->ifm_status |= IFM_ACTIVE;
1183	} else {
1184		if (line_status & AUI_ON) {
1185			cs_writereg(sc, PP_SelfCTL, cs_readreg(sc, PP_SelfCTL) |
1186			    HCB1_ENBL);
1187			if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0)^
1188			    (cs_readreg(sc, PP_SelfCTL) & HCB1))
1189				ifmr->ifm_active |= IFM_10_2;
1190			else
1191				ifmr->ifm_active |= IFM_10_5;
1192		}
1193	}
1194	CS_UNLOCK(sc);
1195}
1196
1197static int
1198cs_mediaset(struct cs_softc *sc, int media)
1199{
1200	int error = 0;
1201
1202	/* Stop the receiver & transmitter */
1203	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) &
1204	    ~(SERIAL_RX_ON | SERIAL_TX_ON));
1205
1206#ifdef CS_DEBUG
1207	device_printf(sc->dev, "%s media=%x\n", __func__, media);
1208#endif
1209
1210	switch (IFM_SUBTYPE(media)) {
1211	default:
1212	case IFM_AUTO:
1213		/*
1214		 * This chip makes it a little hard to support this, so treat
1215		 * it as IFM_10_T, auto duplex.
1216		 */
1217		enable_tp(sc);
1218		cs_duplex_auto(sc);
1219		break;
1220	case IFM_10_T:
1221		enable_tp(sc);
1222		if (media & IFM_FDX)
1223			cs_duplex_full(sc);
1224		else if (media & IFM_HDX)
1225			cs_duplex_half(sc);
1226		else
1227			error = cs_duplex_auto(sc);
1228		break;
1229	case IFM_10_2:
1230		enable_bnc(sc);
1231		break;
1232	case IFM_10_5:
1233		enable_aui(sc);
1234		break;
1235	}
1236
1237	/*
1238	 * Turn the transmitter & receiver back on
1239	 */
1240	cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) |
1241	    SERIAL_RX_ON | SERIAL_TX_ON);
1242
1243	return (error);
1244}
1245