Commit a61a81967f57cb657dea9289a1b0810c668bf9ae

Authored by Reinhard Meyer
Committed by Ben Warren
1 parent f29c181cd4

NET: add ENC28J60 driver using SPI framework

V3: further refinements:
- use priv member instead of container method
- allow setting of MAC address by write_hwaddr method
- avoid shutting down link between commands

Signed-off-by: Reinhard Meyer <u-boot@emk-elektronik.de>
Signed-off-by: Ben Warren <biggerbadderben@gmail.com>

Showing 4 changed files with 1232 additions and 0 deletions Side-by-side Diff

drivers/net/Makefile
... ... @@ -39,6 +39,7 @@
39 39 COBJS-$(CONFIG_DNET) += dnet.o
40 40 COBJS-$(CONFIG_E1000) += e1000.o
41 41 COBJS-$(CONFIG_EEPRO100) += eepro100.o
  42 +COBJS-$(CONFIG_ENC28J60) += enc28j60.o
42 43 COBJS-$(CONFIG_ENC28J60_LPC2292) += enc28j60_lpc2292.o
43 44 COBJS-$(CONFIG_EP93XX) += ep93xx_eth.o
44 45 COBJS-$(CONFIG_ETHOC) += ethoc.o
drivers/net/enc28j60.c
  1 +/*
  2 + * (C) Copyright 2010
  3 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
  4 + * Martin Krause, Martin.Krause@tqs.de
  5 + * reworked original enc28j60.c
  6 + *
  7 + * This program is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU General Public License as
  9 + * published by the Free Software Foundation; either version 2 of
  10 + * the License, or (at your option) any later version.
  11 + *
  12 + * This program is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU General Public License
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 + * MA 02111-1307 USA
  21 + */
  22 +
  23 +#include <common.h>
  24 +#include <net.h>
  25 +#include <spi.h>
  26 +#include <malloc.h>
  27 +#include <netdev.h>
  28 +#include <miiphy.h>
  29 +#include "enc28j60.h"
  30 +
  31 +/*
  32 + * IMPORTANT: spi_claim_bus() and spi_release_bus()
  33 + * are called at begin and end of each of the following functions:
  34 + * enc_miiphy_read(), enc_miiphy_write(), enc_write_hwaddr(),
  35 + * enc_init(), enc_recv(), enc_send(), enc_halt()
  36 + * ALL other functions assume that the bus has already been claimed!
  37 + * Since NetReceive() might call enc_send() in return, the bus must be
  38 + * released, NetReceive() called and claimed again.
  39 + */
  40 +
  41 +/*
  42 + * Controller memory layout.
  43 + * We only allow 1 frame for transmission and reserve the rest
  44 + * for reception to handle as many broadcast packets as possible.
  45 + * Also use the memory from 0x0000 for receiver buffer. See errata pt. 5
  46 + * 0x0000 - 0x19ff 6656 bytes receive buffer
  47 + * 0x1a00 - 0x1fff 1536 bytes transmit buffer =
  48 + * control(1)+frame(1518)+status(7)+reserve(10).
  49 + */
  50 +#define ENC_RX_BUF_START 0x0000
  51 +#define ENC_RX_BUF_END 0x19ff
  52 +#define ENC_TX_BUF_START 0x1a00
  53 +#define ENC_TX_BUF_END 0x1fff
  54 +#define ENC_MAX_FRM_LEN 1518
  55 +#define RX_RESET_COUNTER 1000
  56 +
  57 +/*
  58 + * For non data transfer functions, like phy read/write, set hwaddr, init
  59 + * we do not need a full, time consuming init including link ready wait.
  60 + * This enum helps to bring the chip through the minimum necessary inits.
  61 + */
  62 +enum enc_initstate {none=0, setupdone, linkready};
  63 +typedef struct enc_device {
  64 + struct eth_device *dev; /* back pointer */
  65 + struct spi_slave *slave;
  66 + int rx_reset_counter;
  67 + u16 next_pointer;
  68 + u8 bank; /* current bank in enc28j60 */
  69 + enum enc_initstate initstate;
  70 +} enc_dev_t;
  71 +
  72 +/*
  73 + * enc_bset: set bits in a common register
  74 + * enc_bclr: clear bits in a common register
  75 + *
  76 + * making the reg parameter u8 will give a compile time warning if the
  77 + * functions are called with a register not accessible in all Banks
  78 + */
  79 +static void enc_bset(enc_dev_t *enc, const u8 reg, const u8 data)
  80 +{
  81 + u8 dout[2];
  82 +
  83 + dout[0] = CMD_BFS(reg);
  84 + dout[1] = data;
  85 + spi_xfer(enc->slave, 2 * 8, dout, NULL,
  86 + SPI_XFER_BEGIN | SPI_XFER_END);
  87 +}
  88 +
  89 +static void enc_bclr(enc_dev_t *enc, const u8 reg, const u8 data)
  90 +{
  91 + u8 dout[2];
  92 +
  93 + dout[0] = CMD_BFC(reg);
  94 + dout[1] = data;
  95 + spi_xfer(enc->slave, 2 * 8, dout, NULL,
  96 + SPI_XFER_BEGIN | SPI_XFER_END);
  97 +}
  98 +
  99 +/*
  100 + * high byte of the register contains bank number:
  101 + * 0: no bank switch necessary
  102 + * 1: switch to bank 0
  103 + * 2: switch to bank 1
  104 + * 3: switch to bank 2
  105 + * 4: switch to bank 3
  106 + */
  107 +static void enc_set_bank(enc_dev_t *enc, const u16 reg)
  108 +{
  109 + u8 newbank = reg >> 8;
  110 +
  111 + if (newbank == 0 || newbank == enc->bank)
  112 + return;
  113 + switch (newbank) {
  114 + case 1:
  115 + enc_bclr(enc, CTL_REG_ECON1,
  116 + ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1);
  117 + break;
  118 + case 2:
  119 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0);
  120 + enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1);
  121 + break;
  122 + case 3:
  123 + enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0);
  124 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1);
  125 + break;
  126 + case 4:
  127 + enc_bset(enc, CTL_REG_ECON1,
  128 + ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1);
  129 + break;
  130 + }
  131 + enc->bank = newbank;
  132 +}
  133 +
  134 +/*
  135 + * local functions to access SPI
  136 + *
  137 + * reg: register inside ENC28J60
  138 + * data: 8/16 bits to write
  139 + * c: number of retries
  140 + *
  141 + * enc_r8: read 8 bits
  142 + * enc_r16: read 16 bits
  143 + * enc_w8: write 8 bits
  144 + * enc_w16: write 16 bits
  145 + * enc_w8_retry: write 8 bits, verify and retry
  146 + * enc_rbuf: read from ENC28J60 into buffer
  147 + * enc_wbuf: write from buffer into ENC28J60
  148 + */
  149 +
  150 +/*
  151 + * MAC and MII registers need a 3 byte SPI transfer to read,
  152 + * all other registers need a 2 byte SPI transfer.
  153 + */
  154 +static int enc_reg2nbytes(const u16 reg)
  155 +{
  156 + /* check if MAC or MII register */
  157 + return ((reg >= CTL_REG_MACON1 && reg <= CTL_REG_MIRDH) ||
  158 + (reg >= CTL_REG_MAADR1 && reg <= CTL_REG_MAADR4) ||
  159 + (reg == CTL_REG_MISTAT)) ? 3 : 2;
  160 +}
  161 +
  162 +/*
  163 + * Read a byte register
  164 + */
  165 +static u8 enc_r8(enc_dev_t *enc, const u16 reg)
  166 +{
  167 + u8 dout[3];
  168 + u8 din[3];
  169 + int nbytes = enc_reg2nbytes(reg);
  170 +
  171 + enc_set_bank(enc, reg);
  172 + dout[0] = CMD_RCR(reg);
  173 + spi_xfer(enc->slave, nbytes * 8, dout, din,
  174 + SPI_XFER_BEGIN | SPI_XFER_END);
  175 + return din[nbytes-1];
  176 +}
  177 +
  178 +/*
  179 + * Read a L/H register pair and return a word.
  180 + * Must be called with the L register's address.
  181 + */
  182 +static u16 enc_r16(enc_dev_t *enc, const u16 reg)
  183 +{
  184 + u8 dout[3];
  185 + u8 din[3];
  186 + u16 result;
  187 + int nbytes = enc_reg2nbytes(reg);
  188 +
  189 + enc_set_bank(enc, reg);
  190 + dout[0] = CMD_RCR(reg);
  191 + spi_xfer(enc->slave, nbytes * 8, dout, din,
  192 + SPI_XFER_BEGIN | SPI_XFER_END);
  193 + result = din[nbytes-1];
  194 + dout[0]++; /* next register */
  195 + spi_xfer(enc->slave, nbytes * 8, dout, din,
  196 + SPI_XFER_BEGIN | SPI_XFER_END);
  197 + result |= din[nbytes-1] << 8;
  198 + return result;
  199 +}
  200 +
  201 +/*
  202 + * Write a byte register
  203 + */
  204 +static void enc_w8(enc_dev_t *enc, const u16 reg, const u8 data)
  205 +{
  206 + u8 dout[2];
  207 +
  208 + enc_set_bank(enc, reg);
  209 + dout[0] = CMD_WCR(reg);
  210 + dout[1] = data;
  211 + spi_xfer(enc->slave, 2 * 8, dout, NULL,
  212 + SPI_XFER_BEGIN | SPI_XFER_END);
  213 +}
  214 +
  215 +/*
  216 + * Write a L/H register pair.
  217 + * Must be called with the L register's address.
  218 + */
  219 +static void enc_w16(enc_dev_t *enc, const u16 reg, const u16 data)
  220 +{
  221 + u8 dout[2];
  222 +
  223 + enc_set_bank(enc, reg);
  224 + dout[0] = CMD_WCR(reg);
  225 + dout[1] = data;
  226 + spi_xfer(enc->slave, 2 * 8, dout, NULL,
  227 + SPI_XFER_BEGIN | SPI_XFER_END);
  228 + dout[0]++; /* next register */
  229 + dout[1] = data >> 8;
  230 + spi_xfer(enc->slave, 2 * 8, dout, NULL,
  231 + SPI_XFER_BEGIN | SPI_XFER_END);
  232 +}
  233 +
  234 +/*
  235 + * Write a byte register, verify and retry
  236 + */
  237 +static void enc_w8_retry(enc_dev_t *enc, const u16 reg, const u8 data, const int c)
  238 +{
  239 + u8 dout[2];
  240 + u8 readback;
  241 + int i;
  242 +
  243 + enc_set_bank(enc, reg);
  244 + for (i = 0; i < c; i++) {
  245 + dout[0] = CMD_WCR(reg);
  246 + dout[1] = data;
  247 + spi_xfer(enc->slave, 2 * 8, dout, NULL,
  248 + SPI_XFER_BEGIN | SPI_XFER_END);
  249 + readback = enc_r8(enc, reg);
  250 + if (readback == data)
  251 + break;
  252 + /* wait 1ms */
  253 + udelay(1000);
  254 + }
  255 + if (i == c) {
  256 + printf("%s: write reg 0x%03x failed\n", enc->dev->name, reg);
  257 + }
  258 +}
  259 +
  260 +/*
  261 + * Read ENC RAM into buffer
  262 + */
  263 +static void enc_rbuf(enc_dev_t *enc, const u16 length, u8 *buf)
  264 +{
  265 + u8 dout[1];
  266 +
  267 + dout[0] = CMD_RBM;
  268 + spi_xfer(enc->slave, 8, dout, NULL, SPI_XFER_BEGIN);
  269 + spi_xfer(enc->slave, length * 8, NULL, buf, SPI_XFER_END);
  270 +#ifdef DEBUG
  271 + puts("Rx:\n");
  272 + print_buffer(0, buf, 1, length, 0);
  273 +#endif
  274 +}
  275 +
  276 +/*
  277 + * Write buffer into ENC RAM
  278 + */
  279 +static void enc_wbuf(enc_dev_t *enc, const u16 length, const u8 *buf, const u8 control)
  280 +{
  281 + u8 dout[2];
  282 + dout[0] = CMD_WBM;
  283 + dout[1] = control;
  284 + spi_xfer(enc->slave, 2 * 8, dout, NULL, SPI_XFER_BEGIN);
  285 + spi_xfer(enc->slave, length * 8, buf, NULL, SPI_XFER_END);
  286 +#ifdef DEBUG
  287 + puts("Tx:\n");
  288 + print_buffer(0, buf, 1, length, 0);
  289 +#endif
  290 +}
  291 +
  292 +/*
  293 + * Try to claim the SPI bus.
  294 + * Print error message on failure.
  295 + */
  296 +static int enc_claim_bus(enc_dev_t *enc)
  297 +{
  298 + int rc = spi_claim_bus(enc->slave);
  299 + if (rc)
  300 + printf("%s: failed to claim SPI bus\n", enc->dev->name);
  301 + return rc;
  302 +}
  303 +
  304 +/*
  305 + * Release previously claimed SPI bus.
  306 + * This function is mainly for symmetry to enc_claim_bus().
  307 + * Let the toolchain decide to inline it...
  308 + */
  309 +static void enc_release_bus(enc_dev_t *enc)
  310 +{
  311 + spi_release_bus(enc->slave);
  312 +}
  313 +
  314 +/*
  315 + * Read PHY register
  316 + */
  317 +static u16 phy_read(enc_dev_t *enc, const u8 addr)
  318 +{
  319 + uint64_t etime;
  320 + u8 status;
  321 +
  322 + enc_w8(enc, CTL_REG_MIREGADR, addr);
  323 + enc_w8(enc, CTL_REG_MICMD, ENC_MICMD_MIIRD);
  324 + /* 1 second timeout - only happens on hardware problem */
  325 + etime = get_ticks() + get_tbclk();
  326 + /* poll MISTAT.BUSY bit until operation is complete */
  327 + do
  328 + {
  329 + status = enc_r8(enc, CTL_REG_MISTAT);
  330 + } while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY));
  331 + if (status & ENC_MISTAT_BUSY) {
  332 + printf("%s: timeout reading phy\n", enc->dev->name);
  333 + return 0;
  334 + }
  335 + enc_w8(enc, CTL_REG_MICMD, 0);
  336 + return enc_r16(enc, CTL_REG_MIRDL);
  337 +}
  338 +
  339 +/*
  340 + * Write PHY register
  341 + */
  342 +static void phy_write(enc_dev_t *enc, const u8 addr, const u16 data)
  343 +{
  344 + uint64_t etime;
  345 + u8 status;
  346 +
  347 + enc_w8(enc, CTL_REG_MIREGADR, addr);
  348 + enc_w16(enc, CTL_REG_MIWRL, data);
  349 + /* 1 second timeout - only happens on hardware problem */
  350 + etime = get_ticks() + get_tbclk();
  351 + /* poll MISTAT.BUSY bit until operation is complete */
  352 + do
  353 + {
  354 + status = enc_r8(enc, CTL_REG_MISTAT);
  355 + } while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY));
  356 + if (status & ENC_MISTAT_BUSY) {
  357 + printf("%s: timeout writing phy\n", enc->dev->name);
  358 + return;
  359 + }
  360 +}
  361 +
  362 +/*
  363 + * Verify link status, wait if necessary
  364 + *
  365 + * Note: with a 10 MBit/s only PHY there is no autonegotiation possible,
  366 + * half/full duplex is a pure setup matter. For the time being, this driver
  367 + * will setup in half duplex mode only.
  368 + */
  369 +static int enc_phy_link_wait(enc_dev_t *enc)
  370 +{
  371 + u16 status;
  372 + int duplex;
  373 + uint64_t etime;
  374 +
  375 +#ifdef CONFIG_ENC_SILENTLINK
  376 + /* check if we have a link, then just return */
  377 + status = phy_read(enc, PHY_REG_PHSTAT1);
  378 + if (status & ENC_PHSTAT1_LLSTAT)
  379 + return 0;
  380 +#endif
  381 +
  382 + /* wait for link with 1 second timeout */
  383 + etime = get_ticks() + get_tbclk();
  384 + while (get_ticks() <= etime) {
  385 + status = phy_read(enc, PHY_REG_PHSTAT1);
  386 + if (status & ENC_PHSTAT1_LLSTAT) {
  387 + /* now we have a link */
  388 + status = phy_read(enc, PHY_REG_PHSTAT2);
  389 + duplex = (status & ENC_PHSTAT2_DPXSTAT) ? 1 : 0;
  390 + printf("%s: link up, 10Mbps %s-duplex\n",
  391 + enc->dev->name, duplex ? "full" : "half");
  392 + return 0;
  393 + }
  394 + udelay(1000);
  395 + }
  396 +
  397 + /* timeout occured */
  398 + printf("%s: link down\n", enc->dev->name);
  399 + return 1;
  400 +}
  401 +
  402 +/*
  403 + * This function resets the receiver only.
  404 + */
  405 +static void enc_reset_rx(enc_dev_t *enc)
  406 +{
  407 + u8 econ1;
  408 +
  409 + econ1 = enc_r8(enc, CTL_REG_ECON1);
  410 + if ((econ1 & ENC_ECON1_RXRST) == 0) {
  411 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXRST);
  412 + enc->rx_reset_counter = RX_RESET_COUNTER;
  413 + }
  414 +}
  415 +
  416 +/*
  417 + * Reset receiver and reenable it.
  418 + */
  419 +static void enc_reset_rx_call(enc_dev_t *enc)
  420 +{
  421 + enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXRST);
  422 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
  423 +}
  424 +
  425 +/*
  426 + * Copy a packet from the receive ring and forward it to
  427 + * the protocol stack.
  428 + */
  429 +static void enc_receive(enc_dev_t *enc)
  430 +{
  431 + u8 *packet = (u8 *)NetRxPackets[0];
  432 + u16 pkt_len;
  433 + u16 copy_len;
  434 + u16 status;
  435 + u8 eir_reg;
  436 + u8 pkt_cnt = 0;
  437 + u16 rxbuf_rdpt;
  438 + u8 hbuf[6];
  439 +
  440 + enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer);
  441 + do {
  442 + enc_rbuf(enc, 6, hbuf);
  443 + enc->next_pointer = hbuf[0] | (hbuf[1] << 8);
  444 + pkt_len = hbuf[2] | (hbuf[3] << 8);
  445 + status = hbuf[4] | (hbuf[5] << 8);
  446 + debug("next_pointer=$%04x pkt_len=%u status=$%04x\n",
  447 + enc->next_pointer, pkt_len, status);
  448 + if (pkt_len <= ENC_MAX_FRM_LEN)
  449 + copy_len = pkt_len;
  450 + else
  451 + copy_len = 0;
  452 + if ((status & (1L << 7)) == 0) /* check Received Ok bit */
  453 + copy_len = 0;
  454 + /* check if next pointer is resonable */
  455 + if (enc->next_pointer >= ENC_TX_BUF_START)
  456 + copy_len = 0;
  457 + if (copy_len > 0) {
  458 + enc_rbuf(enc, copy_len, packet);
  459 + }
  460 + /* advance read pointer to next pointer */
  461 + enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer);
  462 + /* decrease packet counter */
  463 + enc_bset(enc, CTL_REG_ECON2, ENC_ECON2_PKTDEC);
  464 + /*
  465 + * Only odd values should be written to ERXRDPTL,
  466 + * see errata B4 pt.13
  467 + */
  468 + rxbuf_rdpt = enc->next_pointer - 1;
  469 + if ((rxbuf_rdpt < enc_r16(enc, CTL_REG_ERXSTL)) ||
  470 + (rxbuf_rdpt > enc_r16(enc, CTL_REG_ERXNDL))) {
  471 + enc_w16(enc, CTL_REG_ERXRDPTL,
  472 + enc_r16(enc, CTL_REG_ERXNDL));
  473 + } else {
  474 + enc_w16(enc, CTL_REG_ERXRDPTL, rxbuf_rdpt);
  475 + }
  476 + /* read pktcnt */
  477 + pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT);
  478 + if (copy_len == 0) {
  479 + eir_reg = enc_r8(enc, CTL_REG_EIR);
  480 + enc_reset_rx(enc);
  481 + printf("%s: receive copy_len=0\n", enc->dev->name);
  482 + continue;
  483 + }
  484 + /*
  485 + * Because NetReceive() might call enc_send(), we need to
  486 + * release the SPI bus, call NetReceive(), reclaim the bus
  487 + */
  488 + enc_release_bus(enc);
  489 + NetReceive(packet, pkt_len);
  490 + if (enc_claim_bus(enc))
  491 + return;
  492 + eir_reg = enc_r8(enc, CTL_REG_EIR);
  493 + } while (pkt_cnt);
  494 + /* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */
  495 +}
  496 +
  497 +/*
  498 + * Poll for completely received packets.
  499 + */
  500 +static void enc_poll(enc_dev_t *enc)
  501 +{
  502 + u8 eir_reg;
  503 + u8 estat_reg;
  504 + u8 pkt_cnt;
  505 +
  506 +#ifdef CONFIG_USE_IRQ
  507 + /* clear global interrupt enable bit in enc28j60 */
  508 + enc_bclr(enc, CTL_REG_EIE, ENC_EIE_INTIE);
  509 +#endif
  510 + estat_reg = enc_r8(enc, CTL_REG_ESTAT);
  511 + eir_reg = enc_r8(enc, CTL_REG_EIR);
  512 + if (eir_reg & ENC_EIR_TXIF) {
  513 + /* clear TXIF bit in EIR */
  514 + enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXIF);
  515 + }
  516 + /* We have to use pktcnt and not pktif bit, see errata pt. 6 */
  517 + pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT);
  518 + if (pkt_cnt > 0) {
  519 + if ((eir_reg & ENC_EIR_PKTIF) == 0) {
  520 + debug("enc_poll: pkt cnt > 0, but pktif not set\n");
  521 + }
  522 + enc_receive(enc);
  523 + /*
  524 + * clear PKTIF bit in EIR, this should not need to be done
  525 + * but it seems like we get problems if we do not
  526 + */
  527 + enc_bclr(enc, CTL_REG_EIR, ENC_EIR_PKTIF);
  528 + }
  529 + if (eir_reg & ENC_EIR_RXERIF) {
  530 + printf("%s: rx error\n", enc->dev->name);
  531 + enc_bclr(enc, CTL_REG_EIR, ENC_EIR_RXERIF);
  532 + }
  533 + if (eir_reg & ENC_EIR_TXERIF) {
  534 + printf("%s: tx error\n", enc->dev->name);
  535 + enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXERIF);
  536 + }
  537 +#ifdef CONFIG_USE_IRQ
  538 + /* set global interrupt enable bit in enc28j60 */
  539 + enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE);
  540 +#endif
  541 +}
  542 +
  543 +/*
  544 + * Completely Reset the ENC
  545 + */
  546 +static void enc_reset(enc_dev_t *enc)
  547 +{
  548 + u8 dout[1];
  549 +
  550 + dout[0] = CMD_SRC;
  551 + spi_xfer(enc->slave, 8, dout, NULL,
  552 + SPI_XFER_BEGIN | SPI_XFER_END);
  553 + /* sleep 1 ms. See errata pt. 2 */
  554 + udelay(1000);
  555 +}
  556 +
  557 +/*
  558 + * Initialisation data for most of the ENC registers
  559 + */
  560 +static const u16 enc_initdata[] = {
  561 + /*
  562 + * Setup the buffer space. The reset values are valid for the
  563 + * other pointers.
  564 + *
  565 + * We shall not write to ERXST, see errata pt. 5. Instead we
  566 + * have to make sure that ENC_RX_BUS_START is 0.
  567 + */
  568 + CTL_REG_ERXSTL, ENC_RX_BUF_START,
  569 + CTL_REG_ERXSTH, ENC_RX_BUF_START >> 8,
  570 + CTL_REG_ERXNDL, ENC_RX_BUF_END,
  571 + CTL_REG_ERXNDH, ENC_RX_BUF_END >> 8,
  572 + CTL_REG_ERDPTL, ENC_RX_BUF_START,
  573 + CTL_REG_ERDPTH, ENC_RX_BUF_START >> 8,
  574 + /*
  575 + * Set the filter to receive only good-CRC, unicast and broadcast
  576 + * frames.
  577 + * Note: some DHCP servers return their answers as broadcasts!
  578 + * So its unwise to remove broadcast from this. This driver
  579 + * might incur receiver overruns with packet loss on a broadcast
  580 + * flooded network.
  581 + */
  582 + CTL_REG_ERXFCON, ENC_RFR_BCEN | ENC_RFR_UCEN | ENC_RFR_CRCEN,
  583 +
  584 + /* enable MAC to receive frames */
  585 + CTL_REG_MACON1,
  586 + ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS,
  587 +
  588 + /* configure pad, tx-crc and duplex */
  589 + CTL_REG_MACON3,
  590 + ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN |
  591 + ENC_MACON3_FRMLNEN,
  592 +
  593 + /* Allow infinite deferals if the medium is continously busy */
  594 + CTL_REG_MACON4, ENC_MACON4_DEFER,
  595 +
  596 + /* Late collisions occur beyond 63 bytes */
  597 + CTL_REG_MACLCON2, 63,
  598 +
  599 + /*
  600 + * Set (low byte) Non-Back-to_Back Inter-Packet Gap.
  601 + * Recommended 0x12
  602 + */
  603 + CTL_REG_MAIPGL, 0x12,
  604 +
  605 + /*
  606 + * Set (high byte) Non-Back-to_Back Inter-Packet Gap.
  607 + * Recommended 0x0c for half-duplex. Nothing for full-duplex
  608 + */
  609 + CTL_REG_MAIPGH, 0x0C,
  610 +
  611 + /* set maximum frame length */
  612 + CTL_REG_MAMXFLL, ENC_MAX_FRM_LEN,
  613 + CTL_REG_MAMXFLH, ENC_MAX_FRM_LEN >> 8,
  614 +
  615 + /*
  616 + * Set MAC back-to-back inter-packet gap.
  617 + * Recommended 0x12 for half duplex
  618 + * and 0x15 for full duplex.
  619 + */
  620 + CTL_REG_MABBIPG, 0x12,
  621 +
  622 + /* end of table */
  623 + 0xffff
  624 +};
  625 +
  626 +/*
  627 + * Wait for the XTAL oscillator to become ready
  628 + */
  629 +static int enc_clock_wait(enc_dev_t *enc)
  630 +{
  631 + uint64_t etime;
  632 +
  633 + /* one second timeout */
  634 + etime = get_ticks() + get_tbclk();
  635 +
  636 + /*
  637 + * Wait for CLKRDY to become set (i.e., check that we can
  638 + * communicate with the ENC)
  639 + */
  640 + do
  641 + {
  642 + if (enc_r8(enc, CTL_REG_ESTAT) & ENC_ESTAT_CLKRDY)
  643 + return 0;
  644 + } while (get_ticks() <= etime);
  645 +
  646 + printf("%s: timeout waiting for CLKRDY\n", enc->dev->name);
  647 + return -1;
  648 +}
  649 +
  650 +/*
  651 + * Write the MAC address into the ENC
  652 + */
  653 +static int enc_write_macaddr(enc_dev_t *enc)
  654 +{
  655 + unsigned char *p = enc->dev->enetaddr;
  656 +
  657 + enc_w8_retry(enc, CTL_REG_MAADR5, *p++, 5);
  658 + enc_w8_retry(enc, CTL_REG_MAADR4, *p++, 5);
  659 + enc_w8_retry(enc, CTL_REG_MAADR3, *p++, 5);
  660 + enc_w8_retry(enc, CTL_REG_MAADR2, *p++, 5);
  661 + enc_w8_retry(enc, CTL_REG_MAADR1, *p++, 5);
  662 + enc_w8_retry(enc, CTL_REG_MAADR0, *p, 5);
  663 + return 0;
  664 +}
  665 +
  666 +/*
  667 + * Setup most of the ENC registers
  668 + */
  669 +static int enc_setup(enc_dev_t *enc)
  670 +{
  671 + u16 phid1 = 0;
  672 + u16 phid2 = 0;
  673 + const u16 *tp;
  674 +
  675 + /* reset enc struct values */
  676 + enc->next_pointer = ENC_RX_BUF_START;
  677 + enc->rx_reset_counter = RX_RESET_COUNTER;
  678 + enc->bank = 0xff; /* invalidate current bank in enc28j60 */
  679 +
  680 + /* verify PHY identification */
  681 + phid1 = phy_read(enc, PHY_REG_PHID1);
  682 + phid2 = phy_read(enc, PHY_REG_PHID2) & ENC_PHID2_MASK;
  683 + if (phid1 != ENC_PHID1_VALUE || phid2 != ENC_PHID2_VALUE) {
  684 + printf("%s: failed to identify PHY. Found %04x:%04x\n",
  685 + enc->dev->name, phid1, phid2);
  686 + return -1;
  687 + }
  688 +
  689 + /* now program registers */
  690 + for (tp = enc_initdata; *tp != 0xffff; tp += 2)
  691 + enc_w8_retry(enc, tp[0], tp[1], 10);
  692 +
  693 + /*
  694 + * Prevent automatic loopback of data beeing transmitted by setting
  695 + * ENC_PHCON2_HDLDIS
  696 + */
  697 + phy_write(enc, PHY_REG_PHCON2, (1<<8));
  698 +
  699 + /*
  700 + * LEDs configuration
  701 + * LEDA: LACFG = 0100 -> display link status
  702 + * LEDB: LBCFG = 0111 -> display TX & RX activity
  703 + * STRCH = 1 -> LED pulses
  704 + */
  705 + phy_write(enc, PHY_REG_PHLCON, 0x0472);
  706 +
  707 + /* Reset PDPXMD-bit => half duplex */
  708 + phy_write(enc, PHY_REG_PHCON1, 0);
  709 +
  710 +#ifdef CONFIG_USE_IRQ
  711 + /* enable interrupts */
  712 + enc_bset(enc, CTL_REG_EIE, ENC_EIE_PKTIE);
  713 + enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXIE);
  714 + enc_bset(enc, CTL_REG_EIE, ENC_EIE_RXERIE);
  715 + enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXERIE);
  716 + enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE);
  717 +#endif
  718 +
  719 + return 0;
  720 +}
  721 +
  722 +/*
  723 + * Check if ENC has been initialized.
  724 + * If not, try to initialize it.
  725 + * Remember initialized state in struct.
  726 + */
  727 +static int enc_initcheck(enc_dev_t *enc, const enum enc_initstate requiredstate)
  728 +{
  729 + if (enc->initstate >= requiredstate)
  730 + return 0;
  731 +
  732 + if (enc->initstate < setupdone) {
  733 + /* Initialize the ENC only */
  734 + enc_reset(enc);
  735 + /* if any of functions fails, skip the rest and return an error */
  736 + if (enc_clock_wait(enc) || enc_setup(enc) || enc_write_macaddr(enc)) {
  737 + return -1;
  738 + }
  739 + enc->initstate = setupdone;
  740 + }
  741 + /* if that's all we need, return here */
  742 + if (enc->initstate >= requiredstate)
  743 + return 0;
  744 +
  745 + /* now wait for link ready condition */
  746 + if (enc_phy_link_wait(enc)) {
  747 + return -1;
  748 + }
  749 + enc->initstate = linkready;
  750 + return 0;
  751 +}
  752 +
  753 +#if defined(CONFIG_CMD_MII)
  754 +/*
  755 + * Read a PHY register.
  756 + *
  757 + * This function is registered with miiphy_register().
  758 + */
  759 +int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
  760 +{
  761 + struct eth_device *dev = eth_get_dev_by_name(devname);
  762 + enc_dev_t *enc;
  763 +
  764 + if (!dev || phy_adr != 0)
  765 + return -1;
  766 +
  767 + enc = dev->priv;
  768 + if (enc_claim_bus(enc))
  769 + return -1;
  770 + if (enc_initcheck(enc, setupdone)) {
  771 + enc_release_bus(enc);
  772 + return -1;
  773 + }
  774 + *value = phy_read(enc, reg);
  775 + enc_release_bus(enc);
  776 + return 0;
  777 +}
  778 +
  779 +/*
  780 + * Write a PHY register.
  781 + *
  782 + * This function is registered with miiphy_register().
  783 + */
  784 +int enc_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
  785 +{
  786 + struct eth_device *dev = eth_get_dev_by_name(devname);
  787 + enc_dev_t *enc;
  788 +
  789 + if (!dev || phy_adr != 0)
  790 + return -1;
  791 +
  792 + enc = dev->priv;
  793 + if (enc_claim_bus(enc))
  794 + return -1;
  795 + if (enc_initcheck(enc, setupdone)) {
  796 + enc_release_bus(enc);
  797 + return -1;
  798 + }
  799 + phy_write(enc, reg, value);
  800 + enc_release_bus(enc);
  801 + return 0;
  802 +}
  803 +#endif
  804 +
  805 +/*
  806 + * Write hardware (MAC) address.
  807 + *
  808 + * This function entered into eth_device structure.
  809 + */
  810 +static int enc_write_hwaddr(struct eth_device *dev)
  811 +{
  812 + enc_dev_t *enc = dev->priv;
  813 +
  814 + if (enc_claim_bus(enc))
  815 + return -1;
  816 + if (enc_initcheck(enc, setupdone)) {
  817 + enc_release_bus(enc);
  818 + return -1;
  819 + }
  820 + enc_release_bus(enc);
  821 + return 0;
  822 +}
  823 +
  824 +/*
  825 + * Initialize ENC28J60 for use.
  826 + *
  827 + * This function entered into eth_device structure.
  828 + */
  829 +static int enc_init(struct eth_device *dev, bd_t *bis)
  830 +{
  831 + enc_dev_t *enc = dev->priv;
  832 +
  833 + if (enc_claim_bus(enc))
  834 + return -1;
  835 + if (enc_initcheck(enc, linkready)) {
  836 + enc_release_bus(enc);
  837 + return -1;
  838 + }
  839 + /* enable receive */
  840 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
  841 + enc_release_bus(enc);
  842 + return 0;
  843 +}
  844 +
  845 +/*
  846 + * Check for received packets.
  847 + *
  848 + * This function entered into eth_device structure.
  849 + */
  850 +static int enc_recv(struct eth_device *dev)
  851 +{
  852 + enc_dev_t *enc = dev->priv;
  853 +
  854 + if (enc_claim_bus(enc))
  855 + return -1;
  856 + if (enc_initcheck(enc, linkready)) {
  857 + enc_release_bus(enc);
  858 + return -1;
  859 + }
  860 + /* Check for dead receiver */
  861 + if (enc->rx_reset_counter > 0)
  862 + enc->rx_reset_counter--;
  863 + else
  864 + enc_reset_rx_call(enc);
  865 + enc_poll(enc);
  866 + enc_release_bus(enc);
  867 + return 0;
  868 +}
  869 +
  870 +/*
  871 + * Send a packet.
  872 + *
  873 + * This function entered into eth_device structure.
  874 + *
  875 + * Should we wait here until we have a Link? Or shall we leave that to
  876 + * protocol retries?
  877 + */
  878 +static int enc_send(
  879 + struct eth_device *dev,
  880 + volatile void *packet,
  881 + int length)
  882 +{
  883 + enc_dev_t *enc = dev->priv;
  884 +
  885 + if (enc_claim_bus(enc))
  886 + return -1;
  887 + if (enc_initcheck(enc, linkready)) {
  888 + enc_release_bus(enc);
  889 + return -1;
  890 + }
  891 + /* setup transmit pointers */
  892 + enc_w16(enc, CTL_REG_EWRPTL, ENC_TX_BUF_START);
  893 + enc_w16(enc, CTL_REG_ETXNDL, length + ENC_TX_BUF_START);
  894 + enc_w16(enc, CTL_REG_ETXSTL, ENC_TX_BUF_START);
  895 + /* write packet to ENC */
  896 + enc_wbuf(enc, length, (u8 *) packet, 0x00);
  897 + /*
  898 + * Check that the internal transmit logic has not been altered
  899 + * by excessive collisions. Reset transmitter if so.
  900 + * See Errata B4 12 and 14.
  901 + */
  902 + if (enc_r8(enc, CTL_REG_EIR) & ENC_EIR_TXERIF) {
  903 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRST);
  904 + enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_TXRST);
  905 + }
  906 + enc_bclr(enc, CTL_REG_EIR, (ENC_EIR_TXERIF | ENC_EIR_TXIF));
  907 + /* start transmitting */
  908 + enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRTS);
  909 + enc_release_bus(enc);
  910 + return 0;
  911 +}
  912 +
  913 +/*
  914 + * Finish use of ENC.
  915 + *
  916 + * This function entered into eth_device structure.
  917 + */
  918 +static void enc_halt(struct eth_device *dev)
  919 +{
  920 + enc_dev_t *enc = dev->priv;
  921 +
  922 + if (enc_claim_bus(enc))
  923 + return;
  924 + /* Just disable receiver */
  925 + enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
  926 + enc_release_bus(enc);
  927 +}
  928 +
  929 +/*
  930 + * This is the only exported function.
  931 + *
  932 + * It may be called several times with different bus:cs combinations.
  933 + */
  934 +int enc28j60_initialize(unsigned int bus, unsigned int cs,
  935 + unsigned int max_hz, unsigned int mode)
  936 +{
  937 + struct eth_device *dev;
  938 + enc_dev_t *enc;
  939 +
  940 + /* try to allocate, check and clear eth_device object */
  941 + dev = malloc(sizeof(*dev));
  942 + if (!dev) {
  943 + return -1;
  944 + }
  945 + memset(dev, 0, sizeof(*dev));
  946 +
  947 + /* try to allocate, check and clear enc_dev_t object */
  948 + enc = malloc(sizeof(*enc));
  949 + if (!enc) {
  950 + free(dev);
  951 + return -1;
  952 + }
  953 + memset(enc, 0, sizeof(*enc));
  954 +
  955 + /* try to setup the SPI slave */
  956 + enc->slave = spi_setup_slave(bus, cs, max_hz, mode);
  957 + if (!enc->slave) {
  958 + printf("enc28j60: invalid SPI device %i:%i\n", bus, cs);
  959 + free(enc);
  960 + free(dev);
  961 + return -1;
  962 + }
  963 +
  964 + enc->dev = dev;
  965 + /* now fill the eth_device object */
  966 + dev->priv = enc;
  967 + dev->init = enc_init;
  968 + dev->halt = enc_halt;
  969 + dev->send = enc_send;
  970 + dev->recv = enc_recv;
  971 + dev->write_hwaddr = enc_write_hwaddr;
  972 + sprintf(dev->name, "enc%i.%i", bus, cs);
  973 + eth_register(dev);
  974 +#if defined(CONFIG_CMD_MII)
  975 + miiphy_register(dev->name, enc_miiphy_read, enc_miiphy_write);
  976 +#endif
  977 + return 0;
  978 +}
drivers/net/enc28j60.h
  1 +/*
  2 + * (X) extracted from enc28j60.c
  3 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
  4 + *
  5 + * This program is free software; you can redistribute it and/or
  6 + * modify it under the terms of the GNU General Public License as
  7 + * published by the Free Software Foundation; either version 2 of
  8 + * the License, or (at your option) any later version.
  9 + *
  10 + * This program is distributed in the hope that it will be useful,
  11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 + * GNU General Public License for more details.
  14 + *
  15 + * You should have received a copy of the GNU General Public License
  16 + * along with this program; if not, write to the Free Software
  17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18 + * MA 02111-1307 USA
  19 + */
  20 +
  21 +#ifndef _enc28j60_h
  22 +#define _enc28j60_h
  23 +
  24 +/*
  25 + * SPI Commands
  26 + *
  27 + * Bits 7-5: Command
  28 + * Bits 4-0: Register
  29 + */
  30 +#define CMD_RCR(x) (0x00+((x)&0x1f)) /* Read Control Register */
  31 +#define CMD_RBM 0x3a /* Read Buffer Memory */
  32 +#define CMD_WCR(x) (0x40+((x)&0x1f)) /* Write Control Register */
  33 +#define CMD_WBM 0x7a /* Write Buffer Memory */
  34 +#define CMD_BFS(x) (0x80+((x)&0x1f)) /* Bit Field Set */
  35 +#define CMD_BFC(x) (0xa0+((x)&0x1f)) /* Bit Field Clear */
  36 +#define CMD_SRC 0xff /* System Reset Command */
  37 +
  38 +/* NEW: encode (bank number+1) in upper byte */
  39 +
  40 +/* Common Control Registers accessible in all Banks */
  41 +#define CTL_REG_EIE 0x01B
  42 +#define CTL_REG_EIR 0x01C
  43 +#define CTL_REG_ESTAT 0x01D
  44 +#define CTL_REG_ECON2 0x01E
  45 +#define CTL_REG_ECON1 0x01F
  46 +
  47 +/* Control Registers accessible in Bank 0 */
  48 +#define CTL_REG_ERDPTL 0x100
  49 +#define CTL_REG_ERDPTH 0x101
  50 +#define CTL_REG_EWRPTL 0x102
  51 +#define CTL_REG_EWRPTH 0x103
  52 +#define CTL_REG_ETXSTL 0x104
  53 +#define CTL_REG_ETXSTH 0x105
  54 +#define CTL_REG_ETXNDL 0x106
  55 +#define CTL_REG_ETXNDH 0x107
  56 +#define CTL_REG_ERXSTL 0x108
  57 +#define CTL_REG_ERXSTH 0x109
  58 +#define CTL_REG_ERXNDL 0x10A
  59 +#define CTL_REG_ERXNDH 0x10B
  60 +#define CTL_REG_ERXRDPTL 0x10C
  61 +#define CTL_REG_ERXRDPTH 0x10D
  62 +#define CTL_REG_ERXWRPTL 0x10E
  63 +#define CTL_REG_ERXWRPTH 0x10F
  64 +#define CTL_REG_EDMASTL 0x110
  65 +#define CTL_REG_EDMASTH 0x111
  66 +#define CTL_REG_EDMANDL 0x112
  67 +#define CTL_REG_EDMANDH 0x113
  68 +#define CTL_REG_EDMADSTL 0x114
  69 +#define CTL_REG_EDMADSTH 0x115
  70 +#define CTL_REG_EDMACSL 0x116
  71 +#define CTL_REG_EDMACSH 0x117
  72 +
  73 +/* Control Registers accessible in Bank 1 */
  74 +#define CTL_REG_EHT0 0x200
  75 +#define CTL_REG_EHT1 0x201
  76 +#define CTL_REG_EHT2 0x202
  77 +#define CTL_REG_EHT3 0x203
  78 +#define CTL_REG_EHT4 0x204
  79 +#define CTL_REG_EHT5 0x205
  80 +#define CTL_REG_EHT6 0x206
  81 +#define CTL_REG_EHT7 0x207
  82 +#define CTL_REG_EPMM0 0x208
  83 +#define CTL_REG_EPMM1 0x209
  84 +#define CTL_REG_EPMM2 0x20A
  85 +#define CTL_REG_EPMM3 0x20B
  86 +#define CTL_REG_EPMM4 0x20C
  87 +#define CTL_REG_EPMM5 0x20D
  88 +#define CTL_REG_EPMM6 0x20E
  89 +#define CTL_REG_EPMM7 0x20F
  90 +#define CTL_REG_EPMCSL 0x210
  91 +#define CTL_REG_EPMCSH 0x211
  92 +#define CTL_REG_EPMOL 0x214
  93 +#define CTL_REG_EPMOH 0x215
  94 +#define CTL_REG_EWOLIE 0x216
  95 +#define CTL_REG_EWOLIR 0x217
  96 +#define CTL_REG_ERXFCON 0x218
  97 +#define CTL_REG_EPKTCNT 0x219
  98 +
  99 +/* Control Registers accessible in Bank 2 */
  100 +#define CTL_REG_MACON1 0x300
  101 +#define CTL_REG_MACON2 0x301
  102 +#define CTL_REG_MACON3 0x302
  103 +#define CTL_REG_MACON4 0x303
  104 +#define CTL_REG_MABBIPG 0x304
  105 +#define CTL_REG_MAIPGL 0x306
  106 +#define CTL_REG_MAIPGH 0x307
  107 +#define CTL_REG_MACLCON1 0x308
  108 +#define CTL_REG_MACLCON2 0x309
  109 +#define CTL_REG_MAMXFLL 0x30A
  110 +#define CTL_REG_MAMXFLH 0x30B
  111 +#define CTL_REG_MAPHSUP 0x30D
  112 +#define CTL_REG_MICON 0x311
  113 +#define CTL_REG_MICMD 0x312
  114 +#define CTL_REG_MIREGADR 0x314
  115 +#define CTL_REG_MIWRL 0x316
  116 +#define CTL_REG_MIWRH 0x317
  117 +#define CTL_REG_MIRDL 0x318
  118 +#define CTL_REG_MIRDH 0x319
  119 +
  120 +/* Control Registers accessible in Bank 3 */
  121 +#define CTL_REG_MAADR1 0x400
  122 +#define CTL_REG_MAADR0 0x401
  123 +#define CTL_REG_MAADR3 0x402
  124 +#define CTL_REG_MAADR2 0x403
  125 +#define CTL_REG_MAADR5 0x404
  126 +#define CTL_REG_MAADR4 0x405
  127 +#define CTL_REG_EBSTSD 0x406
  128 +#define CTL_REG_EBSTCON 0x407
  129 +#define CTL_REG_EBSTCSL 0x408
  130 +#define CTL_REG_EBSTCSH 0x409
  131 +#define CTL_REG_MISTAT 0x40A
  132 +#define CTL_REG_EREVID 0x412
  133 +#define CTL_REG_ECOCON 0x415
  134 +#define CTL_REG_EFLOCON 0x417
  135 +#define CTL_REG_EPAUSL 0x418
  136 +#define CTL_REG_EPAUSH 0x419
  137 +
  138 +/* PHY Register */
  139 +#define PHY_REG_PHCON1 0x00
  140 +#define PHY_REG_PHSTAT1 0x01
  141 +#define PHY_REG_PHID1 0x02
  142 +#define PHY_REG_PHID2 0x03
  143 +#define PHY_REG_PHCON2 0x10
  144 +#define PHY_REG_PHSTAT2 0x11
  145 +#define PHY_REG_PHLCON 0x14
  146 +
  147 +/* Receive Filter Register (ERXFCON) bits */
  148 +#define ENC_RFR_UCEN 0x80
  149 +#define ENC_RFR_ANDOR 0x40
  150 +#define ENC_RFR_CRCEN 0x20
  151 +#define ENC_RFR_PMEN 0x10
  152 +#define ENC_RFR_MPEN 0x08
  153 +#define ENC_RFR_HTEN 0x04
  154 +#define ENC_RFR_MCEN 0x02
  155 +#define ENC_RFR_BCEN 0x01
  156 +
  157 +/* ECON1 Register Bits */
  158 +#define ENC_ECON1_TXRST 0x80
  159 +#define ENC_ECON1_RXRST 0x40
  160 +#define ENC_ECON1_DMAST 0x20
  161 +#define ENC_ECON1_CSUMEN 0x10
  162 +#define ENC_ECON1_TXRTS 0x08
  163 +#define ENC_ECON1_RXEN 0x04
  164 +#define ENC_ECON1_BSEL1 0x02
  165 +#define ENC_ECON1_BSEL0 0x01
  166 +
  167 +/* ECON2 Register Bits */
  168 +#define ENC_ECON2_AUTOINC 0x80
  169 +#define ENC_ECON2_PKTDEC 0x40
  170 +#define ENC_ECON2_PWRSV 0x20
  171 +#define ENC_ECON2_VRPS 0x08
  172 +
  173 +/* EIR Register Bits */
  174 +#define ENC_EIR_PKTIF 0x40
  175 +#define ENC_EIR_DMAIF 0x20
  176 +#define ENC_EIR_LINKIF 0x10
  177 +#define ENC_EIR_TXIF 0x08
  178 +#define ENC_EIR_WOLIF 0x04
  179 +#define ENC_EIR_TXERIF 0x02
  180 +#define ENC_EIR_RXERIF 0x01
  181 +
  182 +/* ESTAT Register Bits */
  183 +#define ENC_ESTAT_INT 0x80
  184 +#define ENC_ESTAT_LATECOL 0x10
  185 +#define ENC_ESTAT_RXBUSY 0x04
  186 +#define ENC_ESTAT_TXABRT 0x02
  187 +#define ENC_ESTAT_CLKRDY 0x01
  188 +
  189 +/* EIE Register Bits */
  190 +#define ENC_EIE_INTIE 0x80
  191 +#define ENC_EIE_PKTIE 0x40
  192 +#define ENC_EIE_DMAIE 0x20
  193 +#define ENC_EIE_LINKIE 0x10
  194 +#define ENC_EIE_TXIE 0x08
  195 +#define ENC_EIE_WOLIE 0x04
  196 +#define ENC_EIE_TXERIE 0x02
  197 +#define ENC_EIE_RXERIE 0x01
  198 +
  199 +/* MACON1 Register Bits */
  200 +#define ENC_MACON1_LOOPBK 0x10
  201 +#define ENC_MACON1_TXPAUS 0x08
  202 +#define ENC_MACON1_RXPAUS 0x04
  203 +#define ENC_MACON1_PASSALL 0x02
  204 +#define ENC_MACON1_MARXEN 0x01
  205 +
  206 +/* MACON2 Register Bits */
  207 +#define ENC_MACON2_MARST 0x80
  208 +#define ENC_MACON2_RNDRST 0x40
  209 +#define ENC_MACON2_MARXRST 0x08
  210 +#define ENC_MACON2_RFUNRST 0x04
  211 +#define ENC_MACON2_MATXRST 0x02
  212 +#define ENC_MACON2_TFUNRST 0x01
  213 +
  214 +/* MACON3 Register Bits */
  215 +#define ENC_MACON3_PADCFG2 0x80
  216 +#define ENC_MACON3_PADCFG1 0x40
  217 +#define ENC_MACON3_PADCFG0 0x20
  218 +#define ENC_MACON3_TXCRCEN 0x10
  219 +#define ENC_MACON3_PHDRLEN 0x08
  220 +#define ENC_MACON3_HFRMEN 0x04
  221 +#define ENC_MACON3_FRMLNEN 0x02
  222 +#define ENC_MACON3_FULDPX 0x01
  223 +
  224 +/* MACON4 Register Bits */
  225 +#define ENC_MACON4_DEFER 0x40
  226 +
  227 +/* MICMD Register Bits */
  228 +#define ENC_MICMD_MIISCAN 0x02
  229 +#define ENC_MICMD_MIIRD 0x01
  230 +
  231 +/* MISTAT Register Bits */
  232 +#define ENC_MISTAT_NVALID 0x04
  233 +#define ENC_MISTAT_SCAN 0x02
  234 +#define ENC_MISTAT_BUSY 0x01
  235 +
  236 +/* PHID1 and PHID2 values */
  237 +#define ENC_PHID1_VALUE 0x0083
  238 +#define ENC_PHID2_VALUE 0x1400
  239 +#define ENC_PHID2_MASK 0xFC00
  240 +
  241 +/* PHCON1 values */
  242 +#define ENC_PHCON1_PDPXMD 0x0100
  243 +
  244 +/* PHSTAT1 values */
  245 +#define ENC_PHSTAT1_LLSTAT 0x0004
  246 +
  247 +/* PHSTAT2 values */
  248 +#define ENC_PHSTAT2_LSTAT 0x0400
  249 +#define ENC_PHSTAT2_DPXSTAT 0x0200
  250 +
  251 +#endif
... ... @@ -54,6 +54,8 @@
54 54 int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr);
55 55 int e1000_initialize(bd_t *bis);
56 56 int eepro100_initialize(bd_t *bis);
  57 +int enc28j60_initialize(unsigned int bus, unsigned int cs,
  58 + unsigned int max_hz, unsigned int mode);
57 59 int ep93xx_eth_initialize(u8 dev_num, int base_addr);
58 60 int ethoc_initialize(u8 dev_num, int base_addr);
59 61 int eth_3com_initialize (bd_t * bis);