Home | History | Annotate | Line # | Download | only in altboot
fxp.c revision 1.2.4.2
      1  1.2.4.2  bouyer /* $NetBSD: fxp.c,v 1.2.4.2 2011/03/06 15:07:55 bouyer Exp $ */
      2  1.2.4.2  bouyer 
      3  1.2.4.2  bouyer /*
      4  1.2.4.2  bouyer  * most of the following code was imported from dev/ic/i82557.c; the
      5  1.2.4.2  bouyer  * original copyright notice is as below.
      6  1.2.4.2  bouyer  */
      7  1.2.4.2  bouyer 
      8  1.2.4.2  bouyer /*-
      9  1.2.4.2  bouyer  * Copyright (c) 1997, 1998, 1999, 2001, 2002 The NetBSD Foundation, Inc.
     10  1.2.4.2  bouyer  * All rights reserved.
     11  1.2.4.2  bouyer  *
     12  1.2.4.2  bouyer  * This code is derived from software contributed to The NetBSD Foundation
     13  1.2.4.2  bouyer  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
     14  1.2.4.2  bouyer  * NASA Ames Research Center.
     15  1.2.4.2  bouyer  *
     16  1.2.4.2  bouyer  * Redistribution and use in source and binary forms, with or without
     17  1.2.4.2  bouyer  * modification, are permitted provided that the following conditions
     18  1.2.4.2  bouyer  * are met:
     19  1.2.4.2  bouyer  * 1. Redistributions of source code must retain the above copyright
     20  1.2.4.2  bouyer  *    notice, this list of conditions and the following disclaimer.
     21  1.2.4.2  bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     22  1.2.4.2  bouyer  *    notice, this list of conditions and the following disclaimer in the
     23  1.2.4.2  bouyer  *    documentation and/or other materials provided with the distribution.
     24  1.2.4.2  bouyer  *
     25  1.2.4.2  bouyer  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     26  1.2.4.2  bouyer  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  1.2.4.2  bouyer  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  1.2.4.2  bouyer  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     29  1.2.4.2  bouyer  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  1.2.4.2  bouyer  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  1.2.4.2  bouyer  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  1.2.4.2  bouyer  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  1.2.4.2  bouyer  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  1.2.4.2  bouyer  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  1.2.4.2  bouyer  * POSSIBILITY OF SUCH DAMAGE.
     36  1.2.4.2  bouyer  */
     37  1.2.4.2  bouyer 
     38  1.2.4.2  bouyer /*
     39  1.2.4.2  bouyer  * Copyright (c) 1995, David Greenman
     40  1.2.4.2  bouyer  * Copyright (c) 2001 Jonathan Lemon <jlemon (at) freebsd.org>
     41  1.2.4.2  bouyer  * All rights reserved.
     42  1.2.4.2  bouyer  *
     43  1.2.4.2  bouyer  * Redistribution and use in source and binary forms, with or without
     44  1.2.4.2  bouyer  * modification, are permitted provided that the following conditions
     45  1.2.4.2  bouyer  * are met:
     46  1.2.4.2  bouyer  * 1. Redistributions of source code must retain the above copyright
     47  1.2.4.2  bouyer  *    notice unmodified, this list of conditions, and the following
     48  1.2.4.2  bouyer  *    disclaimer.
     49  1.2.4.2  bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     50  1.2.4.2  bouyer  *    notice, this list of conditions and the following disclaimer in the
     51  1.2.4.2  bouyer  *    documentation and/or other materials provided with the distribution.
     52  1.2.4.2  bouyer  *
     53  1.2.4.2  bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     54  1.2.4.2  bouyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     55  1.2.4.2  bouyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     56  1.2.4.2  bouyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     57  1.2.4.2  bouyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     58  1.2.4.2  bouyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     59  1.2.4.2  bouyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     60  1.2.4.2  bouyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     61  1.2.4.2  bouyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     62  1.2.4.2  bouyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     63  1.2.4.2  bouyer  * SUCH DAMAGE.
     64  1.2.4.2  bouyer  *
     65  1.2.4.2  bouyer  *	Id: if_fxp.c,v 1.113 2001/05/17 23:50:24 jlemon
     66  1.2.4.2  bouyer  */
     67  1.2.4.2  bouyer 
     68  1.2.4.2  bouyer #include <sys/param.h>
     69  1.2.4.2  bouyer 
     70  1.2.4.2  bouyer #include <netinet/in.h>
     71  1.2.4.2  bouyer #include <netinet/in_systm.h>
     72  1.2.4.2  bouyer 
     73  1.2.4.2  bouyer #include <lib/libsa/stand.h>
     74  1.2.4.2  bouyer #include <lib/libsa/net.h>
     75  1.2.4.2  bouyer 
     76  1.2.4.2  bouyer #include <dev/ic/i82557reg.h>
     77  1.2.4.2  bouyer 
     78  1.2.4.2  bouyer #include "globals.h"
     79  1.2.4.2  bouyer 
     80  1.2.4.2  bouyer #define FRAMESIZE 1536
     81  1.2.4.2  bouyer 
     82  1.2.4.2  bouyer /*
     83  1.2.4.2  bouyer  * 82559ER 8086.1209/1229
     84  1.2.4.2  bouyer  *
     85  1.2.4.2  bouyer  * - reverse endian access for 16bit/32bit register.
     86  1.2.4.2  bouyer  * - no vtophys() translation, vaddr_t == paddr_t.
     87  1.2.4.2  bouyer  * - PIPT writeback cache aware.
     88  1.2.4.2  bouyer  */
     89  1.2.4.2  bouyer #define CSR_WRITE_1(l, r, v)	*(volatile uint8_t *)((l)->iobase+(r)) = (v)
     90  1.2.4.2  bouyer #define CSR_READ_1(l, r)	*(volatile uint8_t *)((l)->iobase+(r))
     91  1.2.4.2  bouyer #define CSR_WRITE_2(l, r, v)	out16rb((l)->iobase+(r), (v))
     92  1.2.4.2  bouyer #define CSR_READ_2(l, r)	in16rb((l)->iobase+(r))
     93  1.2.4.2  bouyer #define CSR_WRITE_4(l, r, v) 	out32rb((l)->iobase+(r), (v))
     94  1.2.4.2  bouyer #define CSR_READ_4(l, r)	in32rb((l)->iobase+(r))
     95  1.2.4.2  bouyer #define VTOPHYS(va) 		(uint32_t)(va)
     96  1.2.4.2  bouyer #define DEVTOV(pa) 		(uint32_t)(pa)
     97  1.2.4.2  bouyer #define wbinv(adr, siz)		_wbinv(VTOPHYS(adr), (uint32_t)(siz))
     98  1.2.4.2  bouyer #define inv(adr, siz)		_inv(VTOPHYS(adr), (uint32_t)(siz))
     99  1.2.4.2  bouyer #define DELAY(n)		delay(n)
    100  1.2.4.2  bouyer #define ALLOC(T,A)		(T *)allocaligned(sizeof(T),(A))
    101  1.2.4.2  bouyer 
    102  1.2.4.2  bouyer struct txdesc {
    103  1.2.4.2  bouyer 	volatile uint16_t cb_status;
    104  1.2.4.2  bouyer 	volatile uint16_t cb_command;
    105  1.2.4.2  bouyer 	volatile uint32_t link_addr;
    106  1.2.4.2  bouyer 	volatile uint32_t tbd_array_addr;
    107  1.2.4.2  bouyer 	volatile uint16_t byte_count;
    108  1.2.4.2  bouyer 	volatile uint8_t tx_threshold;
    109  1.2.4.2  bouyer 	volatile uint8_t tbd_number;
    110  1.2.4.2  bouyer 	volatile uint32_t tx_buf_addr0;
    111  1.2.4.2  bouyer 	volatile uint32_t tx_buf_size0;
    112  1.2.4.2  bouyer 	volatile uint32_t tx_buf_addr1;
    113  1.2.4.2  bouyer 	volatile uint32_t tx_buf_size1;
    114  1.2.4.2  bouyer }; /* mimic extended TxCB layout */
    115  1.2.4.2  bouyer 
    116  1.2.4.2  bouyer struct rxdesc {
    117  1.2.4.2  bouyer 	volatile uint16_t rfa_status;
    118  1.2.4.2  bouyer 	volatile uint16_t rfa_control;
    119  1.2.4.2  bouyer 	volatile uint32_t link_addr;
    120  1.2.4.2  bouyer 	volatile uint32_t rbd_addr;
    121  1.2.4.2  bouyer 	volatile uint16_t actual_size;
    122  1.2.4.2  bouyer 	volatile uint16_t size;
    123  1.2.4.2  bouyer }; /* 16B rfa */
    124  1.2.4.2  bouyer 
    125  1.2.4.2  bouyer struct local {
    126  1.2.4.2  bouyer 	struct txdesc txd;
    127  1.2.4.2  bouyer 	uint8_t store[sizeof(struct rxdesc) + FRAMESIZE];
    128  1.2.4.2  bouyer 	unsigned iobase;
    129  1.2.4.2  bouyer 	unsigned eeprom_addr;
    130  1.2.4.2  bouyer };
    131  1.2.4.2  bouyer 
    132  1.2.4.2  bouyer static void autosize_eeprom(struct local *);
    133  1.2.4.2  bouyer static int read_eeprom(struct local *, int);
    134  1.2.4.2  bouyer static void fxp_scb_wait(struct local *);
    135  1.2.4.2  bouyer #ifdef DEBUG
    136  1.2.4.2  bouyer static int fxp_mdi_read(struct local *, int, int);
    137  1.2.4.2  bouyer #endif
    138  1.2.4.2  bouyer 
    139  1.2.4.2  bouyer /*
    140  1.2.4.2  bouyer  * Template for default configuration parameters.
    141  1.2.4.2  bouyer  * See struct fxp_cb_config for the bit definitions.
    142  1.2.4.2  bouyer  */
    143  1.2.4.2  bouyer static uint8_t fxp_cb_config_template[] = {
    144  1.2.4.2  bouyer 	0x0, 0x0,		/* cb_status */
    145  1.2.4.2  bouyer 	0x80, 0x2,		/* cb_command */
    146  1.2.4.2  bouyer 	0xff, 0xff, 0xff, 0xff, /* link_addr */
    147  1.2.4.2  bouyer 	0x16,	/*  0 */
    148  1.2.4.2  bouyer 	0x8,	/*  1 */
    149  1.2.4.2  bouyer 	0x0,	/*  2 */
    150  1.2.4.2  bouyer 	0x0,	/*  3 */
    151  1.2.4.2  bouyer 	0x0,	/*  4 */
    152  1.2.4.2  bouyer 	0x80,	/*  5 */
    153  1.2.4.2  bouyer 	0xb2,	/*  6 */
    154  1.2.4.2  bouyer 	0x3,	/*  7 */
    155  1.2.4.2  bouyer 	0x1,	/*  8 */
    156  1.2.4.2  bouyer 	0x0,	/*  9 */
    157  1.2.4.2  bouyer 	0x26,	/* 10 */
    158  1.2.4.2  bouyer 	0x0,	/* 11 */
    159  1.2.4.2  bouyer 	0x60,	/* 12 */
    160  1.2.4.2  bouyer 	0x0,	/* 13 */
    161  1.2.4.2  bouyer 	0xf2,	/* 14 */
    162  1.2.4.2  bouyer 	0x48,	/* 15 */
    163  1.2.4.2  bouyer 	0x0,	/* 16 */
    164  1.2.4.2  bouyer 	0x40,	/* 17 */
    165  1.2.4.2  bouyer 	0xf3,	/* 18 */
    166  1.2.4.2  bouyer 	0x0,	/* 19 */
    167  1.2.4.2  bouyer 	0x3f,	/* 20 */
    168  1.2.4.2  bouyer 	0x5	/* 21 */
    169  1.2.4.2  bouyer };
    170  1.2.4.2  bouyer 
    171  1.2.4.2  bouyer static struct fxp_cb_config store_cbc;
    172  1.2.4.2  bouyer static struct fxp_cb_ias store_cbi;
    173  1.2.4.2  bouyer 
    174  1.2.4.2  bouyer int
    175  1.2.4.2  bouyer fxp_match(unsigned tag, void *data)
    176  1.2.4.2  bouyer {
    177  1.2.4.2  bouyer 	unsigned v;
    178  1.2.4.2  bouyer 
    179  1.2.4.2  bouyer 	v = pcicfgread(tag, PCI_ID_REG);
    180  1.2.4.2  bouyer 	switch (v) {
    181  1.2.4.2  bouyer 	case PCI_DEVICE(0x8086, 0x1209):
    182  1.2.4.2  bouyer 	case PCI_DEVICE(0x8086, 0x1229):
    183  1.2.4.2  bouyer 		return 1;
    184  1.2.4.2  bouyer 	}
    185  1.2.4.2  bouyer 	return 0;
    186  1.2.4.2  bouyer }
    187  1.2.4.2  bouyer 
    188  1.2.4.2  bouyer void *
    189  1.2.4.2  bouyer fxp_init(unsigned tag, void *data)
    190  1.2.4.2  bouyer {
    191  1.2.4.2  bouyer 	struct local *sc;
    192  1.2.4.2  bouyer 	uint8_t *en = data;
    193  1.2.4.2  bouyer 	struct fxp_cb_config *cbp = &store_cbc;
    194  1.2.4.2  bouyer 	struct fxp_cb_ias *cb_ias = &store_cbi;
    195  1.2.4.2  bouyer 	struct rxdesc *rfa;
    196  1.2.4.2  bouyer 	unsigned v, i;
    197  1.2.4.2  bouyer 
    198  1.2.4.2  bouyer 	sc = ALLOC(struct local, sizeof(struct txdesc)); /* desc alignment */
    199  1.2.4.2  bouyer 	memset(sc, 0, sizeof(struct local));
    200  1.2.4.2  bouyer 	sc->iobase = DEVTOV(pcicfgread(tag, 0x10)); /* use mem space */
    201  1.2.4.2  bouyer 
    202  1.2.4.2  bouyer 	CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
    203  1.2.4.2  bouyer 	DELAY(100);
    204  1.2.4.2  bouyer 
    205  1.2.4.2  bouyer 	autosize_eeprom(sc);
    206  1.2.4.2  bouyer 	v = read_eeprom(sc, 0); en[0] = v; en[1] = v >> 8;
    207  1.2.4.2  bouyer 	v = read_eeprom(sc, 1); en[2] = v; en[3] = v >> 8;
    208  1.2.4.2  bouyer 	v = read_eeprom(sc, 2); en[4] = v; en[5] = v >> 8;
    209  1.2.4.2  bouyer 
    210  1.2.4.2  bouyer 	printf("MAC address %02x:%02x:%02x:%02x:%02x:%02x, ",
    211  1.2.4.2  bouyer 		en[0], en[1], en[2], en[3], en[4], en[5]);
    212  1.2.4.2  bouyer 
    213  1.2.4.2  bouyer 	DPRINTF(("PHY %d (%04x.%04x)\n", fxp_mdi_read(sc, 1, 18),
    214  1.2.4.2  bouyer 	   fxp_mdi_read(sc, 1, 2), fxp_mdi_read(sc, 1, 3)));
    215  1.2.4.2  bouyer 
    216  1.2.4.2  bouyer 	/*
    217  1.2.4.2  bouyer 	 * Initialize base of CBL and RFA memory. Loading with zero
    218  1.2.4.2  bouyer 	 * sets it up for regular linear addressing.
    219  1.2.4.2  bouyer 	 */
    220  1.2.4.2  bouyer 	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
    221  1.2.4.2  bouyer 	CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_BASE);
    222  1.2.4.2  bouyer 
    223  1.2.4.2  bouyer 	fxp_scb_wait(sc);
    224  1.2.4.2  bouyer 	CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_BASE);
    225  1.2.4.2  bouyer 
    226  1.2.4.2  bouyer 	/*
    227  1.2.4.2  bouyer 	 * This memcpy is kind of disgusting, but there are a bunch of must be
    228  1.2.4.2  bouyer 	 * zero and must be one bits in this structure and this is the easiest
    229  1.2.4.2  bouyer 	 * way to initialize them all to proper values.
    230  1.2.4.2  bouyer 	 */
    231  1.2.4.2  bouyer 	memcpy(cbp, fxp_cb_config_template, sizeof(fxp_cb_config_template));
    232  1.2.4.2  bouyer 
    233  1.2.4.2  bouyer #define prm 0
    234  1.2.4.2  bouyer #define phy_10Mbps_only 0
    235  1.2.4.2  bouyer #define all_mcasts 0
    236  1.2.4.2  bouyer 	cbp->cb_status =	0;
    237  1.2.4.2  bouyer 	cbp->cb_command =	htole16(FXP_CB_COMMAND_CONFIG |
    238  1.2.4.2  bouyer 				    FXP_CB_COMMAND_EL);
    239  1.2.4.2  bouyer 	cbp->link_addr =	-1;	/* (no) next command */
    240  1.2.4.2  bouyer 	cbp->byte_count =	22;	/* (22) bytes to config */
    241  1.2.4.2  bouyer 	cbp->rx_fifo_limit =	8;	/* rx fifo threshold (32 bytes) */
    242  1.2.4.2  bouyer 	cbp->tx_fifo_limit =	0;	/* tx fifo threshold (0 bytes) */
    243  1.2.4.2  bouyer 	cbp->adaptive_ifs =	0;	/* (no) adaptive interframe spacing */
    244  1.2.4.2  bouyer 	cbp->rx_dma_bytecount = 0;	/* (no) rx DMA max */
    245  1.2.4.2  bouyer 	cbp->tx_dma_bytecount = 0;	/* (no) tx DMA max */
    246  1.2.4.2  bouyer 	cbp->dma_mbce =		0;	/* (disable) dma max counters */
    247  1.2.4.2  bouyer 	cbp->late_scb =		0;	/* (don't) defer SCB update */
    248  1.2.4.2  bouyer 	cbp->tno_int_or_tco_en = 0;	/* (disable) tx not okay interrupt */
    249  1.2.4.2  bouyer 	cbp->ci_int =		0;	/* interrupt on CU not active */
    250  1.2.4.2  bouyer 	cbp->save_bf =		prm;	/* save bad frames */
    251  1.2.4.2  bouyer 	cbp->disc_short_rx =	!prm;	/* discard short packets */
    252  1.2.4.2  bouyer 	cbp->underrun_retry =	1;	/* retry mode (1) on DMA underrun */
    253  1.2.4.2  bouyer 	cbp->mediatype =	!phy_10Mbps_only; /* interface mode */
    254  1.2.4.2  bouyer 	cbp->nsai =		1;     /* (don't) disable source addr insert */
    255  1.2.4.2  bouyer 	cbp->preamble_length =	2;	/* (7 byte) preamble */
    256  1.2.4.2  bouyer 	cbp->loopback =		0;	/* (don't) loopback */
    257  1.2.4.2  bouyer 	cbp->linear_priority =	0;	/* (normal CSMA/CD operation) */
    258  1.2.4.2  bouyer 	cbp->linear_pri_mode =	0;	/* (wait after xmit only) */
    259  1.2.4.2  bouyer 	cbp->interfrm_spacing = 6;	/* (96 bits of) interframe spacing */
    260  1.2.4.2  bouyer 	cbp->promiscuous =	prm;	/* promiscuous mode */
    261  1.2.4.2  bouyer 	cbp->bcast_disable =	0;	/* (don't) disable broadcasts */
    262  1.2.4.2  bouyer 	cbp->crscdt =		0;	/* (CRS only) */
    263  1.2.4.2  bouyer 	cbp->stripping =	!prm;	/* truncate rx packet to byte count */
    264  1.2.4.2  bouyer 	cbp->padding =		1;	/* (do) pad short tx packets */
    265  1.2.4.2  bouyer 	cbp->rcv_crc_xfer =	0;	/* (don't) xfer CRC to host */
    266  1.2.4.2  bouyer 	cbp->force_fdx =	0;	/* (don't) force full duplex */
    267  1.2.4.2  bouyer 	cbp->fdx_pin_en =	1;	/* (enable) FDX# pin */
    268  1.2.4.2  bouyer 	cbp->multi_ia =		0;	/* (don't) accept multiple IAs */
    269  1.2.4.2  bouyer 	cbp->mc_all =		all_mcasts;/* accept all multicasts */
    270  1.2.4.2  bouyer #undef prm
    271  1.2.4.2  bouyer #undef phy_10Mbps_only
    272  1.2.4.2  bouyer #undef all_mcasts
    273  1.2.4.2  bouyer 
    274  1.2.4.2  bouyer 	wbinv(cbp, sizeof(*cbp));
    275  1.2.4.2  bouyer 	fxp_scb_wait(sc);
    276  1.2.4.2  bouyer 	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, VTOPHYS(cbp));
    277  1.2.4.2  bouyer 	CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
    278  1.2.4.2  bouyer 	i = 1000;
    279  1.2.4.2  bouyer 	while (!(le16toh(cbp->cb_status) & FXP_CB_STATUS_C) && --i > 0) {
    280  1.2.4.2  bouyer 		DELAY(1);
    281  1.2.4.2  bouyer 		inv(&cbp->cb_status, sizeof(cbp->cb_status));
    282  1.2.4.2  bouyer 	}
    283  1.2.4.2  bouyer 	if (i == 0)
    284  1.2.4.2  bouyer 		printf("cbp config timeout\n");
    285  1.2.4.2  bouyer 
    286  1.2.4.2  bouyer 	/*
    287  1.2.4.2  bouyer 	 * Initialize the station address.
    288  1.2.4.2  bouyer 	 */
    289  1.2.4.2  bouyer 	cb_ias->cb_status = 0;
    290  1.2.4.2  bouyer 	cb_ias->cb_command = htole16(FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL);
    291  1.2.4.2  bouyer 	cb_ias->link_addr = -1;
    292  1.2.4.2  bouyer 	memcpy(cb_ias->macaddr, en, 6);
    293  1.2.4.2  bouyer 
    294  1.2.4.2  bouyer 	/*
    295  1.2.4.2  bouyer 	 * Start the IAS (Individual Address Setup) command/DMA.
    296  1.2.4.2  bouyer 	 */
    297  1.2.4.2  bouyer 	wbinv(cb_ias, sizeof(*cb_ias));
    298  1.2.4.2  bouyer 	fxp_scb_wait(sc);
    299  1.2.4.2  bouyer 	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, VTOPHYS(cb_ias));
    300  1.2.4.2  bouyer 	CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
    301  1.2.4.2  bouyer 
    302  1.2.4.2  bouyer 	i = 1000;
    303  1.2.4.2  bouyer 	while (!(le16toh(cb_ias->cb_status) & FXP_CB_STATUS_C) && --i > 0) {
    304  1.2.4.2  bouyer 		DELAY(1);
    305  1.2.4.2  bouyer 		inv(&cb_ias->cb_status, sizeof(cb_ias->cb_status));
    306  1.2.4.2  bouyer 	}
    307  1.2.4.2  bouyer 	if (i == 0)
    308  1.2.4.2  bouyer 		printf("ias config timeout\n");
    309  1.2.4.2  bouyer 
    310  1.2.4.2  bouyer 	rfa = (struct rxdesc *)sc->store;
    311  1.2.4.2  bouyer 	rfa->rfa_status = 0;
    312  1.2.4.2  bouyer 	rfa->rfa_control = htole16(FXP_RFA_CONTROL_S);
    313  1.2.4.2  bouyer 	rfa->link_addr = htole32(VTOPHYS(rfa));
    314  1.2.4.2  bouyer 	rfa->rbd_addr = -1;
    315  1.2.4.2  bouyer 	rfa->actual_size = 0;
    316  1.2.4.2  bouyer 	rfa->size = htole16(sizeof(sc->store) - sizeof(struct rxdesc));
    317  1.2.4.2  bouyer 	wbinv(rfa, sizeof(sc->store));
    318  1.2.4.2  bouyer 
    319  1.2.4.2  bouyer 	fxp_scb_wait(sc);
    320  1.2.4.2  bouyer 	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, VTOPHYS(rfa));
    321  1.2.4.2  bouyer 	CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_START);
    322  1.2.4.2  bouyer 
    323  1.2.4.2  bouyer 	return sc;
    324  1.2.4.2  bouyer }
    325  1.2.4.2  bouyer 
    326  1.2.4.2  bouyer int
    327  1.2.4.2  bouyer fxp_send(void *dev, char *buf, unsigned len)
    328  1.2.4.2  bouyer {
    329  1.2.4.2  bouyer 	struct local *l = dev;
    330  1.2.4.2  bouyer 	struct txdesc *txd;
    331  1.2.4.2  bouyer 	int loop;
    332  1.2.4.2  bouyer 
    333  1.2.4.2  bouyer 	if (len > 1520)
    334  1.2.4.2  bouyer 		printf("fxp_send: len > 1520 (%u)\n", len);
    335  1.2.4.2  bouyer 
    336  1.2.4.2  bouyer 	txd = &l->txd;
    337  1.2.4.2  bouyer 	txd->cb_status = 0;
    338  1.2.4.2  bouyer 	txd->cb_command =
    339  1.2.4.2  bouyer 	    htole16(FXP_CB_COMMAND_XMIT|FXP_CB_COMMAND_SF|FXP_CB_COMMAND_EL);
    340  1.2.4.2  bouyer 	txd->link_addr = -1;
    341  1.2.4.2  bouyer 	txd->tbd_array_addr = htole32(VTOPHYS(&txd->tx_buf_addr0));
    342  1.2.4.2  bouyer 	txd->tx_buf_addr0 = htole32(VTOPHYS(buf));
    343  1.2.4.2  bouyer 	txd->tx_buf_size0 = htole32(len);
    344  1.2.4.2  bouyer 	txd->byte_count = htole16(0x8000);
    345  1.2.4.2  bouyer 	txd->tx_threshold = 0x20;
    346  1.2.4.2  bouyer 	txd->tbd_number = 1;
    347  1.2.4.2  bouyer 	wbinv(buf, len);
    348  1.2.4.2  bouyer 	wbinv(txd, sizeof(*txd));
    349  1.2.4.2  bouyer 
    350  1.2.4.2  bouyer 	fxp_scb_wait(l);
    351  1.2.4.2  bouyer 	CSR_WRITE_4(l, FXP_CSR_SCB_GENERAL, VTOPHYS(txd));
    352  1.2.4.2  bouyer 	CSR_WRITE_1(l, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START);
    353  1.2.4.2  bouyer 
    354  1.2.4.2  bouyer 	loop = 10000;
    355  1.2.4.2  bouyer 	while (!(le16toh(txd->cb_status) & FXP_CB_STATUS_C) && --loop > 0) {
    356  1.2.4.2  bouyer 		DELAY(1);
    357  1.2.4.2  bouyer 		inv(txd, sizeof(struct txdesc));
    358  1.2.4.2  bouyer 	}
    359  1.2.4.2  bouyer 	if (loop == 0)
    360  1.2.4.2  bouyer 		printf("send timeout\n");
    361  1.2.4.2  bouyer 
    362  1.2.4.2  bouyer 	return len;
    363  1.2.4.2  bouyer }
    364  1.2.4.2  bouyer 
    365  1.2.4.2  bouyer int
    366  1.2.4.2  bouyer fxp_recv(void *dev, char *buf, unsigned maxlen, unsigned timo)
    367  1.2.4.2  bouyer {
    368  1.2.4.2  bouyer 	struct local *l = dev;
    369  1.2.4.2  bouyer 	struct rxdesc *rfa;
    370  1.2.4.2  bouyer 	unsigned bound, ruscus, len;
    371  1.2.4.2  bouyer 
    372  1.2.4.2  bouyer 	fxp_scb_wait(l);
    373  1.2.4.2  bouyer 	CSR_WRITE_1(l, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_RESUME);
    374  1.2.4.2  bouyer 
    375  1.2.4.2  bouyer 	bound = 1000 * timo;
    376  1.2.4.2  bouyer 	do {
    377  1.2.4.2  bouyer 		ruscus = CSR_READ_1(l, FXP_CSR_SCB_RUSCUS);
    378  1.2.4.2  bouyer 		if (((ruscus >> 2) & 0x0f) != FXP_SCB_RUS_READY
    379  1.2.4.2  bouyer 		    && (((ruscus >> 2) & 0x0f) == FXP_SCB_RUS_SUSPENDED))
    380  1.2.4.2  bouyer 			goto gotone;
    381  1.2.4.2  bouyer 		DELAY(1000);	/* 1 milli second */
    382  1.2.4.2  bouyer 	} while (--bound > 0);
    383  1.2.4.2  bouyer 	errno = 0;
    384  1.2.4.2  bouyer 	return -1;
    385  1.2.4.2  bouyer   gotone:
    386  1.2.4.2  bouyer 	rfa = (struct rxdesc *)l->store;
    387  1.2.4.2  bouyer 	inv(rfa, sizeof(l->store)); /* whole including received frame */
    388  1.2.4.2  bouyer 	if ((le16toh(rfa->rfa_status) & FXP_RFA_STATUS_C) == 0)
    389  1.2.4.2  bouyer 		return 0;
    390  1.2.4.2  bouyer 	len = le16toh(rfa->actual_size) & 0x7ff;
    391  1.2.4.2  bouyer 	if (len > maxlen)
    392  1.2.4.2  bouyer 		len = maxlen;
    393  1.2.4.2  bouyer 	memcpy(buf, &l->store[sizeof(struct rxdesc)], len);
    394  1.2.4.2  bouyer 
    395  1.2.4.2  bouyer 	rfa->rfa_status = 0;
    396  1.2.4.2  bouyer 	rfa->rfa_control = htole16(FXP_RFA_CONTROL_S);
    397  1.2.4.2  bouyer 	rfa->actual_size = 0;
    398  1.2.4.2  bouyer 	wbinv(rfa, sizeof(struct rxdesc));
    399  1.2.4.2  bouyer #if 0
    400  1.2.4.2  bouyer 	fxp_scb_wait(l);
    401  1.2.4.2  bouyer 	CSR_WRITE_1(l, FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_RESUME);
    402  1.2.4.2  bouyer #endif
    403  1.2.4.2  bouyer 	return len;
    404  1.2.4.2  bouyer }
    405  1.2.4.2  bouyer 
    406  1.2.4.2  bouyer static void
    407  1.2.4.2  bouyer eeprom_shiftin(struct local *sc, int data, int len)
    408  1.2.4.2  bouyer {
    409  1.2.4.2  bouyer 	uint16_t reg;
    410  1.2.4.2  bouyer 	int x;
    411  1.2.4.2  bouyer 
    412  1.2.4.2  bouyer 	for (x = 1 << (len - 1); x != 0; x >>= 1) {
    413  1.2.4.2  bouyer 		DELAY(40);
    414  1.2.4.2  bouyer 		if (data & x)
    415  1.2.4.2  bouyer 			reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
    416  1.2.4.2  bouyer 		else
    417  1.2.4.2  bouyer 			reg = FXP_EEPROM_EECS;
    418  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
    419  1.2.4.2  bouyer 		DELAY(40);
    420  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
    421  1.2.4.2  bouyer 		    reg | FXP_EEPROM_EESK);
    422  1.2.4.2  bouyer 		DELAY(40);
    423  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
    424  1.2.4.2  bouyer 	}
    425  1.2.4.2  bouyer 	DELAY(40);
    426  1.2.4.2  bouyer }
    427  1.2.4.2  bouyer 
    428  1.2.4.2  bouyer void
    429  1.2.4.2  bouyer autosize_eeprom(struct local *sc)
    430  1.2.4.2  bouyer {
    431  1.2.4.2  bouyer 	int x;
    432  1.2.4.2  bouyer 
    433  1.2.4.2  bouyer 	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
    434  1.2.4.2  bouyer 	DELAY(40);
    435  1.2.4.2  bouyer 
    436  1.2.4.2  bouyer 	/* Shift in read opcode. */
    437  1.2.4.2  bouyer 	eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3);
    438  1.2.4.2  bouyer 
    439  1.2.4.2  bouyer 	/*
    440  1.2.4.2  bouyer 	 * Shift in address, wait for the dummy zero following a correct
    441  1.2.4.2  bouyer 	 * address shift.
    442  1.2.4.2  bouyer 	 */
    443  1.2.4.2  bouyer 	for (x = 1; x <= 8; x++) {
    444  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
    445  1.2.4.2  bouyer 		DELAY(40);
    446  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
    447  1.2.4.2  bouyer 		    FXP_EEPROM_EECS | FXP_EEPROM_EESK);
    448  1.2.4.2  bouyer 		DELAY(40);
    449  1.2.4.2  bouyer 		if ((CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) &
    450  1.2.4.2  bouyer 		    FXP_EEPROM_EEDO) == 0)
    451  1.2.4.2  bouyer 			break;
    452  1.2.4.2  bouyer 		DELAY(40);
    453  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
    454  1.2.4.2  bouyer 		DELAY(40);
    455  1.2.4.2  bouyer 	}
    456  1.2.4.2  bouyer 	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
    457  1.2.4.2  bouyer 	DELAY(40);
    458  1.2.4.2  bouyer 	if (x != 6 && x != 8)
    459  1.2.4.2  bouyer 		printf("fxp: strange EEPROM address size (%d)\n", x);
    460  1.2.4.2  bouyer 	else
    461  1.2.4.2  bouyer 		sc->eeprom_addr = x;
    462  1.2.4.2  bouyer }
    463  1.2.4.2  bouyer 
    464  1.2.4.2  bouyer static int
    465  1.2.4.2  bouyer read_eeprom(struct local *sc, int offset)
    466  1.2.4.2  bouyer {
    467  1.2.4.2  bouyer 	uint16_t reg;
    468  1.2.4.2  bouyer 	int x, val;
    469  1.2.4.2  bouyer 
    470  1.2.4.2  bouyer 	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
    471  1.2.4.2  bouyer 
    472  1.2.4.2  bouyer 	/* Shift in read opcode. */
    473  1.2.4.2  bouyer 	eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3);
    474  1.2.4.2  bouyer 
    475  1.2.4.2  bouyer 	/* Shift in address. */
    476  1.2.4.2  bouyer 	eeprom_shiftin(sc, offset, sc->eeprom_addr);
    477  1.2.4.2  bouyer 
    478  1.2.4.2  bouyer 	reg = FXP_EEPROM_EECS;
    479  1.2.4.2  bouyer 	val = 0;
    480  1.2.4.2  bouyer 	/*
    481  1.2.4.2  bouyer 	 * Shift out data.
    482  1.2.4.2  bouyer 	 */
    483  1.2.4.2  bouyer 	for (x = 16; x > 0; x--) {
    484  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
    485  1.2.4.2  bouyer 		    reg | FXP_EEPROM_EESK);
    486  1.2.4.2  bouyer 		DELAY(1);
    487  1.2.4.2  bouyer 		if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) &
    488  1.2.4.2  bouyer 		    FXP_EEPROM_EEDO)
    489  1.2.4.2  bouyer 			val |= (1 << (x - 1));
    490  1.2.4.2  bouyer 		CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
    491  1.2.4.2  bouyer 		DELAY(1);
    492  1.2.4.2  bouyer 	}
    493  1.2.4.2  bouyer 	CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
    494  1.2.4.2  bouyer 	DELAY(1);
    495  1.2.4.2  bouyer 
    496  1.2.4.2  bouyer 	return val;
    497  1.2.4.2  bouyer }
    498  1.2.4.2  bouyer 
    499  1.2.4.2  bouyer static void
    500  1.2.4.2  bouyer fxp_scb_wait(struct local *sc)
    501  1.2.4.2  bouyer {
    502  1.2.4.2  bouyer 	int loop = 5000;
    503  1.2.4.2  bouyer 
    504  1.2.4.2  bouyer 	while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --loop > 0)
    505  1.2.4.2  bouyer 		DELAY(2);
    506  1.2.4.2  bouyer 	if (loop == 0)
    507  1.2.4.2  bouyer 		printf("SCB timeout\n");
    508  1.2.4.2  bouyer }
    509  1.2.4.2  bouyer 
    510  1.2.4.2  bouyer #ifdef DEBUG
    511  1.2.4.2  bouyer static int
    512  1.2.4.2  bouyer fxp_mdi_read(struct local *sc, int phy, int reg)
    513  1.2.4.2  bouyer {
    514  1.2.4.2  bouyer 	int count = 10000;
    515  1.2.4.2  bouyer 	int value;
    516  1.2.4.2  bouyer 
    517  1.2.4.2  bouyer 	CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
    518  1.2.4.2  bouyer 	    (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21));
    519  1.2.4.2  bouyer 
    520  1.2.4.2  bouyer 	while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) &
    521  1.2.4.2  bouyer 	    0x10000000) == 0 && count--)
    522  1.2.4.2  bouyer 		DELAY(10);
    523  1.2.4.2  bouyer 
    524  1.2.4.2  bouyer 	if (count <= 0)
    525  1.2.4.2  bouyer 		printf("fxp_mdi_read: timed out\n");
    526  1.2.4.2  bouyer 
    527  1.2.4.2  bouyer 	return (value & 0xffff);
    528  1.2.4.2  bouyer }
    529  1.2.4.2  bouyer #endif
    530