Mercurial > nand-ecoscentric
changeset 2019:ec659f224fe7
* src/if_dp83816.c: Use CYG_CPU_TO_LE32 and CYG_LE32_TO_CPU macros
instead of the _h2le and _le2h functions.
* src/dp83816.h: #define's for MEAR (EEPROM access) register.
* src/dp83816.c [CYGHWR_NS_DP83186_USE_EEPROM]: Read MAC address
from EEPROM.
| author | asl |
|---|---|
| date | Thu, 21 Jul 2005 18:10:55 +0000 |
| parents | 975b261a7619 |
| children | 6d5deacbe8fd |
| files | packages/devs/eth/ns/dp83816/current/ChangeLog packages/devs/eth/ns/dp83816/current/src/dp83816.h packages/devs/eth/ns/dp83816/current/src/if_dp83816.c |
| diffstat | 3 files changed, 127 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/eth/ns/dp83816/current/ChangeLog +++ b/packages/devs/eth/ns/dp83816/current/ChangeLog @@ -1,3 +1,13 @@ +2005-07-18 David Vrabel <dvrabel@arcom.com> + + * src/if_dp83816.c: Use CYG_CPU_TO_LE32 and CYG_LE32_TO_CPU macros + instead of the _h2le and _le2h functions. + + * src/dp83816.h: #define's for MEAR (EEPROM access) register. + + * src/dp83816.c [CYGHWR_NS_DP83186_USE_EEPROM]: Read MAC address + from EEPROM. + 2004-08-24 Gary Thomas <gary@mlbassoc.com> * src/if_dp83816.c: Enable start/stop functions (device was always
--- a/packages/devs/eth/ns/dp83816/current/src/dp83816.h +++ b/packages/devs/eth/ns/dp83816/current/src/dp83816.h @@ -152,6 +152,11 @@ static void dp83816_poll(struct eth_drv_ #define _CFG_FDUP (1<<29) // Full duplex #define _CFG_POL (1<<28) // 10Mb polarity #define _CFG_ANDONE (1<<27) // Auto-negotiation done +#define DP_MEAR 0x08 // EEPROM access +#define _MEAR_EESEL (1<<3) // EEPROM chip select +#define _MEAR_EECLK (1<<2) // EEPROM serial clock +#define _MEAR_EEDO (1<<1) // EEPROM data out +#define _MEAR_EEDI (1<<0) // EEPROM data in #define DP_ISR 0x10 // Interrupt status #define _ISR_TXRCMP (1<<25) // Tx reset complete #define _ISR_RXRCMP (1<<24) // Rx reset complete
--- a/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c +++ b/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c @@ -56,6 +56,7 @@ #include <cyg/infra/cyg_type.h> #include <cyg/hal/hal_arch.h> +#include <cyg/hal/hal_endian.h> #include <cyg/infra/diag.h> #include <cyg/hal/drv_api.h> #include <cyg/hal/hal_if.h> @@ -65,6 +66,10 @@ #include "dp83816.h" #include CYGDAT_DEVS_ETH_NS_DP83816_INL +#ifdef CYGHWR_NS_DP83816_USE_EEPROM +static cyg_uint16 dp83816_eeprom_read(struct dp83816_priv_data *dp, int location); +#endif + #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED // This ISR is called when the ethernet interrupt occurs static cyg_uint32 @@ -120,24 +125,24 @@ dp83816_reset(dp83816_priv_data_t *dp) bdp = dp->rxnext = CYGARC_UNCACHED_ADDRESS(dp->rxd); bp = dp->rxbuf; for (i = 0; i < dp->rxnum; i++, bdp++) { - bdp->next = (dp83816_bd_t *)_h2le(CYGARC_PHYSICAL_ADDRESS(bdp+1)); - bdp->stat = _h2le(BD_INTR | _DP83816_BUFSIZE); // Max buffer - bdp->buf = (unsigned char *)_h2le(CYGARC_PHYSICAL_ADDRESS(bp)); + bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bdp+1)); + bdp->stat = CYG_CPU_TO_LE32(BD_INTR | _DP83816_BUFSIZE); // Max buffer + bdp->buf = (unsigned char *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bp)); bp += _DP83816_BUFSIZE; } - bdp--; bdp->next = (dp83816_bd_t *)_h2le(CYGARC_PHYSICAL_ADDRESS(dp->rxd)); + bdp--; bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(dp->rxd)); DP_OUT(dp->base, DP_RXCFG, _RXCFG_MXDMA_128 | ((64/32)<<_RXCFG_DRTH_SHIFT)); DP_OUT(dp->base, DP_RXDP, CYGARC_PHYSICAL_ADDRESS(dp->rxd)); // Tx ring bdp = dp->txfill = dp->txint = CYGARC_UNCACHED_ADDRESS(dp->txd); bp = dp->txbuf; for (i = 0; i < dp->txnum; i++, bdp++) { - bdp->next = (dp83816_bd_t *)_h2le(CYGARC_PHYSICAL_ADDRESS(bdp+1)); + bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bdp+1)); bdp->stat = 0; // Driver owns buffer for now - bdp->buf = (unsigned char *)_h2le(CYGARC_PHYSICAL_ADDRESS(bp)); + bdp->buf = (unsigned char *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bp)); bp += _DP83816_BUFSIZE; } - bdp--; bdp->next = (dp83816_bd_t *)_h2le(CYGARC_PHYSICAL_ADDRESS(dp->txd)); + bdp--; bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(dp->txd)); DP_OUT(dp->base, DP_TXCFG, _TXCFG_ATP | _TXCFG_MXDMA_128 | ((256/32)<<_TXCFG_FLTH_SHIFT) | @@ -167,7 +172,33 @@ dp83816_init(struct cyg_netdevtab_entry bool esa_ok; unsigned char enaddr[6]; + DEBUG_FUNCTION(); + + CYGHWR_NS_DP83816_PLF_INIT(dp); + base = dp->base; + if (!base) return false; // No device found + // Get physical device address +#ifdef CYGHWR_NS_DP83816_USE_EEPROM + { + cyg_uint16 t; + + t = (dp83816_eeprom_read(dp, 0x0006) >> 15) + | (dp83816_eeprom_read(dp, 0x0007) << 1); + enaddr[0] = t & 0xFF; + enaddr[1] = t >> 8; + t = (dp83816_eeprom_read(dp, 0x0007) >> 15) + | (dp83816_eeprom_read(dp, 0x0008) << 1); + enaddr[2] = t & 0xFF; + enaddr[3] = t >> 8; + t = (dp83816_eeprom_read(dp, 0x0008) >> 15) + | (dp83816_eeprom_read(dp, 0x0009) << 1); + enaddr[4] = t & 0xFF; + enaddr[5] = t >> 8; + + esa_ok = true; + } +#else #ifdef CYGPKG_REDBOOT #ifdef CYGSEM_REDBOOT_FLASH_CONFIG esa_ok = flash_get_config(dp->esa_key, enaddr, CONFIG_ESA); @@ -178,6 +209,7 @@ dp83816_init(struct cyg_netdevtab_entry esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, dp->esa_key, enaddr, CONFIG_ESA); #endif +#endif if (esa_ok) { memcpy(dp->enaddr, enaddr, sizeof(enaddr)); } else { @@ -185,18 +217,8 @@ dp83816_init(struct cyg_netdevtab_entry diag_printf("DP83816 - Warning! ESA unknown\n"); } - DEBUG_FUNCTION(); - - CYGHWR_NS_DP83816_PLF_INIT(dp); - base = dp->base; - if (!base) return false; // No device found - if (!dp83816_reset(dp)) return false; - diag_printf("DP83816 - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", - dp->enaddr[0], dp->enaddr[1], dp->enaddr[2], - dp->enaddr[3], dp->enaddr[4], dp->enaddr[5] ); - #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED cyg_drv_interrupt_create( dp->interrupt, @@ -290,15 +312,15 @@ dp83816_send(struct eth_drv_sc *sc, stru len = total_len; if (len < IEEE_8023_MIN_FRAME) len = IEEE_8023_MIN_FRAME; - data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(_le2h((unsigned long)bdp->buf)); + data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->buf)); for (i = 0; i < sg_len; i++) { memcpy(data, (unsigned char *)sg_list[i].buf, sg_list[i].len); data += sg_list[i].len; } bdp->key = key; - bdp->stat = _h2le(len | BD_OWN | BD_INTR); + bdp->stat = CYG_CPU_TO_LE32(len | BD_OWN | BD_INTR); dp->txbusy++; - bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(_le2h((unsigned long)bdp->next))); + bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next))); dp->txfill = bdp; // Kick the device, in case it went idle DP_OUT(dp->base, DP_CR, _CR_TXE); @@ -311,13 +333,13 @@ dp83816_TxEvent(struct eth_drv_sc *sc) dp83816_bd_t *bdp = dp->txint; DEBUG_FUNCTION(); - while ((_le2h(bdp->stat) & (BD_OWN|BD_INTR)) == BD_INTR) { + while ((CYG_LE32_TO_CPU(bdp->stat) & (BD_OWN|BD_INTR)) == BD_INTR) { // Tell higher level we sent this packet (sc->funs->eth_drv->tx_done)(sc, bdp->key, 0); bdp->stat = 0; // retake buffer bdp->key = 0; dp->txbusy--; - bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(_le2h((unsigned long)bdp->next))); + bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next))); } dp->txint = bdp; } @@ -340,17 +362,17 @@ dp83816_RxEvent(struct eth_drv_sc *sc) DEBUG_FUNCTION(); while (true) { - if ((_le2h(bdp->stat) & BD_OWN) != 0) { - err = _le2h(bdp->stat) & (BD_RXA|BD_RXO|BD_LONG|BD_RUNT|BD_ISE|BD_CRCE|BD_FAE|BD_COL); + if ((CYG_LE32_TO_CPU(bdp->stat) & BD_OWN) != 0) { + err = CYG_LE32_TO_CPU(bdp->stat) & (BD_RXA|BD_RXO|BD_LONG|BD_RUNT|BD_ISE|BD_CRCE|BD_FAE|BD_COL); if (err != 0) { diag_printf("RxError: %x\n", err); } - len = _le2h(bdp->stat) & BD_LENGTH_MASK; + len = CYG_LE32_TO_CPU(bdp->stat) & BD_LENGTH_MASK; dp->rxnext = bdp; (sc->funs->eth_drv->recv)(sc, len); - bdp->stat = _h2le(BD_INTR | _DP83816_BUFSIZE); // Give back buffer + bdp->stat = CYG_CPU_TO_LE32(BD_INTR | _DP83816_BUFSIZE); // Give back buffer } - bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(_le2h((unsigned long)bdp->next))); + bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next))); if (bdp == bdfirst) { break; } @@ -372,7 +394,7 @@ dp83816_recv(struct eth_drv_sc *sc, stru unsigned char *data; int i; - data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(_le2h((unsigned long)bdp->buf)); + data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->buf)); for (i = 0; i < sg_len; i++) { memcpy((void *)sg_list[i].buf, data, sg_list[i].len); data += sg_list[i].len; @@ -442,3 +464,65 @@ dp83816_int_vector(struct eth_drv_sc *sc struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private; return dp->interrupt; } + +/* EEPROM Functions */ +#ifdef CYGHWR_NS_DP83816_USE_EEPROM + +#define EEPROM_READ(dp, x) DP_IN((dp)->base, DP_MEAR, (x)) +#define EEPROM_WRITE(dp, x) DP_OUT((dp)->base, DP_MEAR, (x)) +#define EEPROM_DELAY(dp) CYG_MACRO_START cyg_uint16 t; EEPROM_READ((dp), t); CYG_MACRO_END + +#define DP83816_EEPROM_ADDR_LEN 6 +#define DP83816_EE_READ_CMD (6 << DP83816_EEPROM_ADDR_LEN) + + +/* EEPROM data is bit-swapped. */ +static cyg_uint16 dp83816_eeprom_fixup_data(cyg_uint16 input) +{ + cyg_uint16 output = 0; + int i; + + for (i = 0; i < 16; i++) { + output = (output << 1) | (input & 0x0001); + input >>= 1; + } + return output; +} + +static cyg_uint16 dp83816_eeprom_command(struct dp83816_priv_data *dp, int cmd, int cmd_len) +{ + int d = 0; + + EEPROM_WRITE(dp, _MEAR_EESEL); + + do { + cyg_uint32 c = (cmd & (1 << cmd_len)) ? _MEAR_EEDI : 0; + cyg_uint8 t; + + EEPROM_WRITE(dp, c | _MEAR_EESEL); + EEPROM_DELAY(dp); + EEPROM_WRITE(dp, c | _MEAR_EESEL | _MEAR_EECLK); + EEPROM_DELAY(dp); + + EEPROM_READ(dp, t); + d <<= 1; + d |= (t & _MEAR_EEDO) ? 1 : 0; + } while (cmd_len--); + + EEPROM_WRITE(dp, _MEAR_EESEL); + EEPROM_WRITE(dp, 0); + + return d & 0xffff; +} + +static cyg_uint16 dp83816_eeprom_read(struct dp83816_priv_data *dp, int loc) +{ + cyg_uint16 d; + + d = dp83816_eeprom_command(dp, (loc | DP83816_EE_READ_CMD) << 16, + 3 + DP83816_EEPROM_ADDR_LEN + 16); + + return dp83816_eeprom_fixup_data(d); +} + +#endif /* CYGHWR_NS_DP83816_USE_EEPROM */
