
Hi Nobuhiro,
Nobuhiro Iwamatsu wrote:
Renesas SH7763 has 2 channel Ethernet device. This is 10/100/1000 Base support. But this patch check 10/100 Base only.
Signed-off-by: Nobuhiro Iwamatsu iwamatsu.nobuhiro@renesas.com
drivers/net/Makefile | 1 + drivers/net/sh_eth.c | 599 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/sh_eth.h | 195 ++++++++++++++++
Where's the code that has this driver being initialized by net/eth.c? Is it in another patch or should I just go to bed?
3 files changed, 795 insertions(+), 0 deletions(-) create mode 100644 drivers/net/sh_eth.c create mode 100644 drivers/net/sh_eth.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 5b031c9..e2a6b35 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -66,6 +66,7 @@ COBJS-y += uli526x.o COBJS-y += vsc7385.o COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o +COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c new file mode 100644 index 0000000..869a8f0 --- /dev/null +++ b/drivers/net/sh_eth.c @@ -0,0 +1,599 @@ +/*
- sh_eth.c - Driver for Renesas SH7763's ethernet controler.
- Copyright (C) 2008 Renesas Solutions Corp.
- Copyright (c) 2008 Nobuhiro Iwamatsu
- Copyright (c) 2007 Carlos Munoz carlos@kenati.com
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+#include <config.h> +#include <common.h> +#include <malloc.h> +#include <net.h> +#include <asm/errno.h>
+#include "sh_eth.h"
+#ifndef CONFIG_SH_ETHER_USE_PORT +# error "Please define CONFIG_SH_ETHER_USE_PORT" +#endif +#ifndef CONFIG_SH_ETHER_PHY_ADDR +# error "Please define CONFIG_SH_ETHER_PHY_ADDR" +#endif
+extern int eth_init(bd_t *bd); +extern void eth_halt(void); +extern int eth_rx(void); +extern int eth_send(volatile void *packet, int length);
+static struct dev_info_s *dev;
+/*
- Bits are written to the PHY serially using the
- PIR register, just like a bit banger.
- */
+static void sh_eth_mii_write_phy_bits(int port, u32 val, int len) +{
- int i;
- u32 pir;
- /* Bit positions is 1 less than the number of bits */
- for (i = len - 1; i >= 0; i--) {
/* Write direction, bit to write, clock is low */
pir = 2 | ((val & 1 << i) ? 1 << 2 : 0);
OUT32(PIR(port), pir);
PHY_DELAY;
/* Write direction, bit to write, clock is high */
pir = 3 | ((val & 1 << i) ? 1 << 2 : 0);
OUT32(PIR(port), pir);
PHY_DELAY;
/* Write direction, bit to write, clock is low */
pir = 2 | ((val & 1 << i) ? 1 << 2 : 0);
OUT32(PIR(port), pir);
PHY_DELAY;
- }
+}
+static void sh_eth_mii_bus_release(int port) +{
- /* Read direction, clock is low */
- OUT32(PIR(port), 0);
- PHY_DELAY;
- /* Read direction, clock is high */
- OUT32(PIR(port), 1);
- PHY_DELAY;
- /* Read direction, clock is low */
- OUT32(PIR(port), 0);
- PHY_DELAY;
+}
+static void sh_eth_mii_ind_bus_release(int port) +{
- /* Read direction, clock is low */
- OUT32(PIR(port), 0);
- PHY_DELAY;
+}
+static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len) +{
- int i;
- u32 pir;
- *val = 0;
- for (i = len - 1; i >= 0; i--) {
/* Read direction, clock is high */
OUT32(PIR(port), 1);
PHY_DELAY;
/* Read bit */
pir = IN32(PIR(port));
*val |= (pir & 8) ? 1 << i : 0;
/* Read direction, clock is low */
OUT32(PIR(port), 0);
PHY_DELAY;
- }
- return 0;
+}
+/* To read a phy register, mii managements frames are sent to the phy.
- The frames look like this:
- pre (32 bits): 0xffff ffff
- st (2 bits): 01
- op (2bits): 10: read 01: write
- phyad (5 bits): xxxxx
- regad (5 bits): xxxxx
- ta (Bus release):
- data (16 bits): read data */
+static u32 sh_eth_mii_read_phy_reg(int port, u8 phy_addr, int reg) +{
- u32 val;
- /* Sent mii management frame */
- /* pre */
- sh_eth_mii_write_phy_bits(port, 0xffffffff, 32);
- /* st (start of frame) */
- sh_eth_mii_write_phy_bits(port, 0x1, 2);
- /* op (code) */
- sh_eth_mii_write_phy_bits(port, 0x2, 2);
- /* phy address */
- sh_eth_mii_write_phy_bits(port, phy_addr, 5);
- /* Register to read */
- sh_eth_mii_write_phy_bits(port, reg, 5);
- /* Bus release */
- sh_eth_mii_bus_release(port);
- /* Read register */
- sh_eth_mii_read_phy_bits(port, &val, 16);
- return val;
+}
+/* To write a phy register, mii managements frames are sent to the phy.
- The frames look like this:
- pre (32 bits): 0xffff ffff
- st (2 bits): 01
- op (2bits): 10: read 01: write
- phyad (5 bits): xxxxx
- regad (5 bits): xxxxx
- ta (2 bits): 10
- data (16 bits): write data
- idle (Independent bus release) */
+static void sh_eth_mii_write_phy_reg(int port, u8 phy_addr, int reg, u16 val) +{
- /* Sent mii management frame */
- /* pre */
- sh_eth_mii_write_phy_bits(port, 0xffffffff, 32);
- /* st (start of frame) */
- sh_eth_mii_write_phy_bits(port, 0x1, 2);
- /* op (code) */
- sh_eth_mii_write_phy_bits(port, 0x1, 2);
- /* phy address */
- sh_eth_mii_write_phy_bits(port, phy_addr, 5);
- /* Register to read */
- sh_eth_mii_write_phy_bits(port, reg, 5);
- /* ta */
- sh_eth_mii_write_phy_bits(port, 0x2, 2);
- /* Write register data */
- sh_eth_mii_write_phy_bits(port, val, 16);
- /* Independent bus release */
- sh_eth_mii_ind_bus_release(port);
+}
+void eth_halt(void) +{ +}
+int eth_send(volatile void *packet, int len) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- int timeout;
- int rc = 0;
- if (!packet || len > 0xffff) {
printf("eth_send: Invalid argument\n");
return -EINVAL;
- }
- /* packet must be a 4 byte boundary */
- if ((int)packet & (4 - 1)) {
printf("eth_send: packet not 4 byte alligned\n");
return -EFAULT;
- }
- /* Update tx descriptor */
- port_info->tx_desc_cur->td2 = ADDR_TO_PHY(packet);
- port_info->tx_desc_cur->td1 = len << 16;
- /* Must preserve the end of descriptor list indication */
- if (port_info->tx_desc_cur->td0 & TDLE)
port_info->tx_desc_cur->td0 = TACT | TFP | TDLE;
- else
port_info->tx_desc_cur->td0 = TACT | TFP;
- /* Restart the transmitter if disabled */
- if (!(IN32(EDTRR(port)) & 0x3))
OUT32(EDTRR(port), 0x3);
- /* Wait until packet is transmitted */
- timeout = 1000;
- while (port_info->tx_desc_cur->td0 & TACT && timeout--)
udelay(100);
- if (timeout < 0) {
printf("eth_send: transmit timeout\n");
rc = -1;
goto err;
- }
err:
- port_info->tx_desc_cur++;
- if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC)
port_info->tx_desc_cur = port_info->tx_desc_base;
- return rc;
+}
+int eth_rx(void) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- int len = 0;
- volatile u8 *packet;
- /* Check if the rx descriptor is ready */
- if (!(port_info->rx_desc_cur->rd0 & RACT)) {
/* Check for errors */
if (!(port_info->rx_desc_cur->rd0 & RFE)) {
len = port_info->rx_desc_cur->rd1 & 0xffff;
packet = (volatile u8 *)
ADDR_TO_P2(port_info->rx_desc_cur->rd2);
NetReceive(packet, len);
}
/* Make current descriptor available again */
if (port_info->rx_desc_cur->rd0 & RDLE)
port_info->rx_desc_cur->rd0 = RACT | RDLE;
else
port_info->rx_desc_cur->rd0 = RACT;
/* Point to the next descriptor */
port_info->rx_desc_cur++;
if (port_info->rx_desc_cur >=
port_info->rx_desc_base + NUM_RX_DESC)
port_info->rx_desc_cur = port_info->rx_desc_base;
- }
- /* Restart the receiver if disabled */
- if (!(IN32(EDRRR(port)) & 0x1))
OUT32(EDRRR(port), 0x1);
- return len;
+}
+static int sh_eth_reset(struct dev_info_s *dev) +{
- int port = dev->port;
- int i;
- /* Start e-dmac transmitter and receiver */
- OUT32(EDSR(port), 0x3);
- /* Perform a software reset and wait for it to complete */
- OUT32(EDMR(port), 0x3);
- for (i = 0; i < 1000; i++) {
if (!(IN32(EDMR(port)) & 0x3))
break;
udelay(1000);
- }
- if (i == 100) {
printf("Error: Software reset timeout\n");
return -1;
- }
- return 0;
+}
+static int sh_eth_tx_desc_init(struct dev_info_s *dev) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- u32 tmp_addr;
- struct tx_desc_s *cur_tx_desc;
- int i;
- /* Allocate tx descriptors. They must be TX_DESC_SIZE bytes
aligned */
- if (!(port_info->tx_desc_malloc = malloc(NUM_TX_DESC *
sizeof(struct tx_desc_s) +
TX_DESC_SIZE - 1))) {
printf("Error: malloc failed\n");
return -ENOMEM;
- }
- tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) &
~(TX_DESC_SIZE - 1));
- /* Make sure we use a P2 address (non-cacheable) */
- port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr);
- port_info->tx_desc_cur = port_info->tx_desc_base;
- /* Initialize all descriptors */
- for (cur_tx_desc = port_info->tx_desc_base, i = 0; i < NUM_TX_DESC;
cur_tx_desc++, i++) {
cur_tx_desc->td0 = 0;
cur_tx_desc->td1 = 0;
cur_tx_desc->td2 = 0;
- }
- /* Mark the end of the descriptors */
- cur_tx_desc--;
- cur_tx_desc->td0 |= TDLE;
- /* Point the controller to the tx descriptor list. Must use physical
addresses */
- OUT32(TDLAR(port), ADDR_TO_PHY(port_info->tx_desc_base));
- OUT32(TDFAR(port), ADDR_TO_PHY(port_info->tx_desc_base));
- OUT32(TDFXR(port), ADDR_TO_PHY(cur_tx_desc));
- OUT32(TDFFR(port), 0x0000001);
- return 0;
+}
+static int sh_eth_rx_desc_init(struct dev_info_s *dev) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- u32 tmp_addr;
- struct rx_desc_s *cur_rx_desc;
- u8 *rx_buf;
- int i;
- /* Allocate rx descriptors. They must be RX_DESC_SIZE bytes
aligned */
- if (!(port_info->rx_desc_malloc = malloc(NUM_RX_DESC *
sizeof(struct rx_desc_s) +
RX_DESC_SIZE - 1))) {
printf("Error: malloc failed\n");
return -ENOMEM;
- }
- tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) &
~(RX_DESC_SIZE - 1));
- /* Make sure we use a P2 address (non-cacheable) */
- port_info->rx_desc_base = (struct rx_desc_s *)ADDR_TO_P2(tmp_addr);
- port_info->rx_desc_cur = port_info->rx_desc_base;
- /* Allocate rx data buffers. They must be 32 bytes aligned and in
P2 area */
- if (!(port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE +
31))) {
printf("Error: malloc failed\n");
free(port_info->rx_desc_malloc);
port_info->rx_desc_malloc = NULL;
return -ENOMEM;
- }
- tmp_addr = (u32) (((int)port_info->rx_buf_malloc + (32 - 1)) &
~(32 - 1));
- port_info->rx_buf_base = (u8 *) ADDR_TO_P2(tmp_addr);
- /* Initialize all descriptors */
- for (cur_rx_desc = port_info->rx_desc_base,
rx_buf = port_info->rx_buf_base, i = 0;
i < NUM_RX_DESC; cur_rx_desc++, rx_buf += MAX_BUF_SIZE, i++) {
cur_rx_desc->rd0 = RACT;
cur_rx_desc->rd1 = MAX_BUF_SIZE << 16;
cur_rx_desc->rd2 = (u32) ADDR_TO_PHY(rx_buf);
- }
- /* Mark the end of the descriptors */
- cur_rx_desc--;
- cur_rx_desc->rd0 |= RDLE;
- /* Point the controller to the rx descriptor list */
- OUT32(RDLAR(port), ADDR_TO_PHY(port_info->rx_desc_base));
- OUT32(RDFAR(port), ADDR_TO_PHY(port_info->rx_desc_base));
- OUT32(RDFXR(port), ADDR_TO_PHY(cur_rx_desc));
- OUT32(RDFFR(port), 0x00000001);
- return 0;
+}
+static void sh_eth_desc_free(struct dev_info_s *dev) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- if (port_info->tx_desc_malloc) {
free(port_info->tx_desc_malloc);
port_info->tx_desc_malloc = NULL;
- }
- if (port_info->rx_desc_malloc) {
free(port_info->rx_desc_malloc);
port_info->rx_desc_malloc = NULL;
- }
- if (port_info->rx_buf_malloc) {
free(port_info->rx_buf_malloc);
port_info->rx_buf_malloc = NULL;
- }
+}
+static int sh_eth_desc_init(struct dev_info_s *dev) +{
- int rc;
- if ((rc = sh_eth_tx_desc_init(dev)) || (rc = sh_eth_rx_desc_init(dev))) {
sh_eth_desc_free(dev);
return rc;
- }
- return 0;
+}
+static int sh_eth_phy_config(struct dev_info_s *dev) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- int timeout;
- u32 val;
- /* Reset phy */
- sh_eth_mii_write_phy_reg(port, port_info->phy_addr, 0, 0x8000);
This code has quite a few magic numbers. Considering that you're submitting a header file too, it's hard to justify not adding mnemonics.
- timeout = 10;
- while (timeout--) {
val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 0);
if (!(val & 0x8000))
break;
udelay(50000);
- }
- if (timeout < 0) {
printf("sh_eth_phy_config() phy reset timeout\n");
return -1;
- }
- /* Advertise 100/10 baseT full/half duplex */
- sh_eth_mii_write_phy_reg(port, port_info->phy_addr, 4, 0x01e1);
- /* Autonegotiation, normal operation, full duplex, enable tx */
- sh_eth_mii_write_phy_reg(port, port_info->phy_addr, 0, 0x1200);
- /* Wait for autonegotiation to complete */
- timeout = 100;
- while (timeout--) {
val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1);
if (val & 0x0020)
Another magic number that should be a #defined bit mask
break;
udelay(50000);
- }
- if (timeout < 0) {
printf("sh_eth_phy_config() phy auto-negotiation failed\n");
return -1;
- }
- return 0;
+}
+static int sh_eth_config(struct dev_info_s *dev, bd_t * bd) +{
- int port = dev->port;
- struct port_info_s *port_info = &dev->port_info[port];
- u32 val;
- u32 phy_status;
- int rc;
- /* Configure e-dmac registers */
- OUT32(EDMR(port), (IN32(EDMR(port)) & ~0x00000030) | 0x00000040);
- OUT32(EESIPR(port), 0);
- OUT32(TRSCER(port), 0);
- OUT32(TFTR(port), 0);
- OUT32(FDR(port), 0x0000071f);
- OUT32(RMCR(port), 1);
- OUT32(RPADIR(port), 0);
- OUT32(FCFTR(port), 0x00170007);
- /* Configure e-mac registers */
- OUT32(ECSIPR(port), 0);
- val = bd->bi_enetaddr[0] << 24 | bd->bi_enetaddr[1] << 16 |
bd->bi_enetaddr[2] << 8 | bd->bi_enetaddr[3];
- OUT32(MAHR(port), val);
- val = bd->bi_enetaddr[4] << 8 | bd->bi_enetaddr[5];
- OUT32(MALR(port), val);
- OUT32(RFLR(port), 0x000005ee);
- OUT32(PIPR(port), 0);
- OUT32(APR(port), 4);
- OUT32(MPR(port), 6);
- OUT32(TPAUSER(port), 6);
- /* Configure phy */
- if ((rc = sh_eth_phy_config(dev)))
return rc;
- /* Read phy status to finish configuring the e-mac */
- phy_status = sh_eth_mii_read_phy_reg(dev->port,
dev->port_info[dev->port].phy_addr,
1);
- /* Set the transfer speed */
- if (phy_status & 0x6000) {
printf("100Base/");
OUT32(GECMR(port), 0x4);
- } else {
printf("10Base/");
OUT32(GECMR(port), 0x0);
- }
- /* Check if full duplex mode is supported by the phy */
- if (phy_status & 0x5000) {
printf("Full\n");
OUT32(ECMR(port), 0x041f2062);
- } else {
printf("Half\n");
OUT32(ECMR(port), 0x041f2060);
- }
- return 0;
+}
+static int sh_eth_start(struct dev_info_s *dev) +{
- int port = dev->port;
- /*
* Enable the e-dmac receiver only. The transmitter will be enabled when
* we have something to transmit
*/
- OUT32(EDRRR(port), 0x1);
- return 0;
+}
+static int sh_eth_get_mac(bd_t *bd) +{
- char *s, *e;
- int i;
- s = getenv("ethaddr");
- if (s != NULL) {
for (i = 0; i < 6; ++i) {
bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
- } else {
puts("Please set MAC address\n");
- }
- return 0;
+}
+int eth_init(bd_t * bd) +{
- int rc;
- /* Allocate main device information structure */
- if (!(dev = malloc(sizeof(*dev)))) {
printf("eth_init: malloc failed\n");
return -ENOMEM;
- }
- memset(dev, 0, sizeof(*dev));
- dev->port = CONFIG_SH_ETHER_USE_PORT;
- dev->port_info[dev->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
- sh_eth_get_mac(bd);
- if ((rc = sh_eth_reset(dev)) || (rc = sh_eth_desc_init(dev)))
goto err;
- if ((rc = sh_eth_config(dev, bd)) || (rc = sh_eth_start(dev)))
goto err_desc;
- return 0;
+err_desc:
- sh_eth_desc_free(dev);
+err:
- free(dev);
- printf("eth_init: Failed\n");
- return rc;
+} diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h new file mode 100644 index 0000000..12a4528 --- /dev/null +++ b/drivers/net/sh_eth.h @@ -0,0 +1,195 @@ +/*
- gether.h - Driver for Renesas SH7763's gigabit ethernet controler.
- Copyright (c) 2007 Carlos Munoz carlos@kenati.com
- Copyright (c) 2008 Nobuhiro Iwamatsu
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+#include <asm/types.h>
+#define SHETHER_NAME "sh_eth"
+/* Malloc returns addresses in the P1 area (cacheable). However we need to
- use area P2 (non-cacheable) */
+#define ADDR_TO_P2(addr) ((((int)(addr) & ~0xe0000000) | 0xa0000000))
+/* The ethernet controller needs to use physical addresses */ +#define ADDR_TO_PHY(addr) ((int)(addr) & ~0xe0000000)
+/* Number of supported ports */ +#define MAX_PORT_NUM 2
+/* Buffers must be big enough to hold the largest ethernet frame. Also, rx
- buffers must be a multiple of 32 bytes */
+#define MAX_BUF_SIZE (48 * 32)
+/* The number of tx descriptors must be large enough to point to 5 or more
- frames. If each frame uses 2 descriptors, at least 10 descriptors are needed.
- We use one descriptor per frame */
+#define NUM_TX_DESC 8
+/* The size of the tx descriptor is determined by how much padding is used.
- 4, 20, or 52 bytes of padding can be used */
+#define TX_DESC_PADDING 4 +#define TX_DESC_SIZE (12 + TX_DESC_PADDING)
+/* Tx descriptor. We always use 4 bytes of padding */ +struct tx_desc_s {
- volatile u32 td0;
- u32 td1;
- u32 td2; /* Buffer start */
- u32 padding;
+};
+/* TD0 */ +#define TACT (0x1 << 31) /* Valid/invalid */ +#define TDLE (0x1 << 30) /* List end */ +#define TFP (0x3 << 28) /* Frame position */ +#define TFP_END (0x1 << 28) /* End of frame */ +#define TFP_START (0x2 << 28) /* Start of frame */ +#define TFE (0x1 << 27) /* Error occurrence */ +#define TWBI (0x1 << 26) /* Write-back completion int */ +#define TFS (0xfff << 0) /* Frame status */ +#define TFS_UNFLW (0x1 << 9) /* Underflow */ +#define TFS_ABORT (0x1 << 8) /* Abort */
+/* TD1 */ +#define TDL (0xffff << 16) /* Buffer data length */
+/* There is no limitation in the number of rx descriptors */ +#define NUM_RX_DESC 8
+/* The size of the rx descriptor is determined by how much padding is used.
- 4, 20, or 52 bytes of padding can be used */
+#define RX_DESC_PADDING 4 +#define RX_DESC_SIZE (12 + RX_DESC_PADDING)
+/* Rx descriptor. We always use 4 bytes of padding */ +struct rx_desc_s {
- volatile u32 rd0;
- volatile u32 rd1;
- u32 rd2; /* Buffer start */
- u32 padding;
+};
+/* RD0 */ +#define RACT (0x1 << 31) /* Valid/invalid */ +#define RDLE (0x1 << 30) /* List end */ +#define RFP (0x3 << 28) /* Frame position */ +#define RFP_END (0x1 << 28) /* End of frame */ +#define RFP_START (0x2 << 28) /* Start of frame */ +#define RFE (0x1 << 27) /* Error occurrence */ +#define PV (0x1 << 26) /* Padding Insertion */ +#define RFS (0xfff << 0) /* Frame status */ +#define RFS_OVFLW (0x1 << 9) /* Overflow */ +#define RFS_ABORT (0x1 << 8) /* Abort */ +#define RFS_MCAST (0x1 << 7) /* Multicast Address */ +#define RFS_CEXT (0x1 << 6) /* Carrier ext error */ +#define RFS_CELOSS (0x1 << 5) /* Carrier ext loss */ +#define RFS_RBF (0x1 << 4) /* Residual-bit frame error */ +#define RFS_LONG (0x1 << 3) /* Long frame */ +#define RFS_SHORT (0x1 << 2) /* Short frame */ +#define RFS_PHY (0x1 << 1) /* PHY rx error */ +#define RFS_CRC (0x1 << 0) /* CRC error */
+/* RD1 */ +#define RBL (0xffff << 16) /* Buffer length */ +#define RDL (0xffff << 0) /* Buffer data length */
+struct port_info_s {
- struct tx_desc_s *tx_desc_malloc;
- struct tx_desc_s *tx_desc_base;
- struct tx_desc_s *tx_desc_cur;
- struct rx_desc_s *rx_desc_malloc;
- struct rx_desc_s *rx_desc_base;
- struct rx_desc_s *rx_desc_cur;
- u8 *rx_buf_malloc;
- u8 *rx_buf_base;
- u8 mac_addr[6];
- u8 phy_addr;
+};
+struct dev_info_s {
- int port;
- struct port_info_s port_info[MAX_PORT_NUM];
+};
+#define IN16(reg) (*(u16 *)(reg)) +#define IN32(reg) (*(u32 *)(reg)) +#define OUT16(reg, val) (*(u16 *)(reg) = (val)) +#define OUT32(reg, val) (*(u32 *)(reg) = (val))
Please use the accessors in include/asm-sh/io.h instead of defining your own.
+#define PDCR 0xffef0006 +#define PECR 0xffef0008 +#define PFCR 0xffef000a +#define PGCR 0xffef000c +#define PHCR 0xffef000e +#define PJCR 0xffef0012 +#define PKCR 0xffef0014 +#define PLCR 0xffef0016 +#define PMCR 0xffef0018 +#define PSEL1 0xffef0072 +#define PSEL2 0xffef0074 +#define PSEL3 0xffef0076
+#define BASE_IO_ADDR 0xfee00000
+#define EDSR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0000)
+#define TDLAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0010) +#define TDFAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0014) +#define TDFXR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0018) +#define TDFFR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x001c)
+#define RDLAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0030) +#define RDFAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0034) +#define RDFXR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0038) +#define RDFFR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x003c)
+#define EDMR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0400) +#define EDTRR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0408) +#define EDRRR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0410) +#define EESR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0428) +#define EESIPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0430) +#define TRSCER(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0438) +#define TFTR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0448) +#define FDR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0450) +#define RMCR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0458) +#define RPADIR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0460) +#define FCFTR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0468) +#define ECMR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0500) +#define RFLR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0508) +#define ECSIPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0518) +#define PIR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0520) +#define PIPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x052c) +#define APR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0554) +#define MPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0558) +#define TPAUSER(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0564) +#define GECMR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x05b0) +#define MALR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x05c8) +#define MAHR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x05c0)
+/* Bit values for EESR */ +#define EESR_CERF (0x1 << 0) +#define EESR_PRE (0x1 << 1) +#define EESR_RTSF (0x1 << 2) +#define EESR_RTLF (0x1 << 3) +#define EESR_RFOF (0x1 << 16) +#define EESR_FR (1 << 18)
+/* PHY values */ +#define PHY_DELAY udelay(1)
As I already mentioned, please put more bit definitions here.
regards, Ben