lan8710a: use new libnetdriver
Change-Id: Iaee4d75a5dfafc72d94f0b02681f9aea1c9da535
This commit is contained in:
parent
96e62d65b6
commit
5af3c2565f
3 changed files with 197 additions and 528 deletions
|
@ -6,7 +6,7 @@ FILES=$(PROG).conf
|
||||||
FILESNAME=$(PROG)
|
FILESNAME=$(PROG)
|
||||||
FILESDIR= /etc/system.conf.d
|
FILESDIR= /etc/system.conf.d
|
||||||
|
|
||||||
DPADD+= ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
|
DPADD+= ${LIBNETDRIVER} ${LIBSYS}
|
||||||
LDADD+= -lnetdriver -lsys -ltimers
|
LDADD+= -lnetdriver -lsys
|
||||||
|
|
||||||
.include <minix.service.mk>
|
.include <minix.service.mk>
|
||||||
|
|
|
@ -1,31 +1,28 @@
|
||||||
#include <minix/drivers.h>
|
#include <minix/drivers.h>
|
||||||
#include <minix/netdriver.h>
|
#include <minix/netdriver.h>
|
||||||
#include <net/gen/ether.h>
|
|
||||||
#include <net/gen/eth_io.h>
|
|
||||||
#include <minix/sysutil.h>
|
|
||||||
#include <minix/board.h>
|
#include <minix/board.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "lan8710a.h"
|
#include "lan8710a.h"
|
||||||
#include "lan8710a_reg.h"
|
#include "lan8710a_reg.h"
|
||||||
|
|
||||||
/* Local functions */
|
/* Local functions */
|
||||||
static void lan8710a_readv_s(message *m, int from_int);
|
static int lan8710a_init(unsigned int instance, ether_addr_t *addr);
|
||||||
static void lan8710a_writev_s(message *m, int from_int);
|
|
||||||
static void lan8710a_conf(message *m);
|
|
||||||
static void lan8710a_getstat(message *m);
|
|
||||||
|
|
||||||
static void lan8710a_init(void);
|
|
||||||
static void lan8710a_enable_interrupt(int interrupt);
|
|
||||||
static void lan8710a_interrupt(message *m);
|
|
||||||
static void lan8710a_map_regs(void);
|
|
||||||
static void lan8710a_stop(void);
|
static void lan8710a_stop(void);
|
||||||
|
static ssize_t lan8710a_recv(struct netdriver_data *data, size_t max);
|
||||||
|
static int lan8710a_send(struct netdriver_data *data, size_t size);
|
||||||
|
static void lan8710a_stat(eth_stat_t *stat);
|
||||||
|
static void lan8710a_intr(unsigned int mask);
|
||||||
|
|
||||||
|
static void lan8710a_enable_interrupt(int interrupt);
|
||||||
|
static void lan8710a_map_regs(void);
|
||||||
static void lan8710a_dma_config_tx(u8_t desc_idx);
|
static void lan8710a_dma_config_tx(u8_t desc_idx);
|
||||||
static void lan8710a_dma_reset_init(void);
|
static void lan8710a_dma_reset_init(void);
|
||||||
static void lan8710a_init_addr(void);
|
static void lan8710a_init_addr(ether_addr_t *addr);
|
||||||
static void lan8710a_init_desc(void);
|
static void lan8710a_init_desc(void);
|
||||||
static void lan8710a_init_mdio(void);
|
static void lan8710a_init_mdio(void);
|
||||||
static int lan8710a_init_hw(void);
|
static int lan8710a_init_hw(ether_addr_t *addr);
|
||||||
static void lan8710a_reset_hw();
|
static void lan8710a_reset_hw(void);
|
||||||
|
|
||||||
static void lan8710a_phy_write(u32_t reg, u32_t value);
|
static void lan8710a_phy_write(u32_t reg, u32_t value);
|
||||||
static u32_t lan8710a_phy_read(u32_t reg);
|
static u32_t lan8710a_phy_read(u32_t reg);
|
||||||
|
@ -35,16 +32,17 @@ static void lan8710a_reg_write(volatile u32_t *reg, u32_t value);
|
||||||
static void lan8710a_reg_set(volatile u32_t *reg, u32_t value);
|
static void lan8710a_reg_set(volatile u32_t *reg, u32_t value);
|
||||||
static void lan8710a_reg_unset(volatile u32_t *reg, u32_t value);
|
static void lan8710a_reg_unset(volatile u32_t *reg, u32_t value);
|
||||||
|
|
||||||
static void mess_reply(message *req, message *reply);
|
|
||||||
static void reply(lan8710a_t *e);
|
|
||||||
|
|
||||||
/* Local variables */
|
/* Local variables */
|
||||||
static lan8710a_t lan8710a_state;
|
static lan8710a_t lan8710a_state;
|
||||||
|
|
||||||
/* SEF functions and variables. */
|
static const struct netdriver lan8710a_table = {
|
||||||
static void sef_local_startup(void);
|
.ndr_init = lan8710a_init,
|
||||||
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
|
.ndr_stop = lan8710a_stop,
|
||||||
static void sef_cb_signal_handler(int signal);
|
.ndr_recv = lan8710a_recv,
|
||||||
|
.ndr_send = lan8710a_send,
|
||||||
|
.ndr_stat = lan8710a_stat,
|
||||||
|
.ndr_intr = lan8710a_intr
|
||||||
|
};
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* main *
|
* main *
|
||||||
|
@ -52,122 +50,45 @@ static void sef_cb_signal_handler(int signal);
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
struct machine machine;
|
||||||
|
|
||||||
/* Local variables */
|
env_setargs(argc, argv);
|
||||||
message m;
|
|
||||||
int r;
|
|
||||||
int ipc_status;
|
|
||||||
struct machine machine ;
|
|
||||||
|
|
||||||
sys_getmachine(&machine);
|
sys_getmachine(&machine);
|
||||||
if ( BOARD_IS_BB(machine.board_id)) {
|
if (BOARD_IS_BB(machine.board_id))
|
||||||
|
netdriver_task(&lan8710a_table);
|
||||||
|
|
||||||
/* SEF local startup */
|
|
||||||
env_setargs(argc, argv);
|
|
||||||
sef_local_startup();
|
|
||||||
|
|
||||||
/* Main driver loop */
|
|
||||||
for (;;) {
|
|
||||||
r = netdriver_receive(ANY, &m, &ipc_status);
|
|
||||||
if (r != OK) {
|
|
||||||
panic("netdriver_receive failed: %d", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_ipc_notify(ipc_status)) {
|
|
||||||
switch (_ENDPOINT_P(m.m_source)) {
|
|
||||||
case HARDWARE:
|
|
||||||
lan8710a_interrupt(&m);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (m.m_type) {
|
|
||||||
case DL_WRITEV_S:
|
|
||||||
lan8710a_writev_s(&m, FALSE);
|
|
||||||
break;
|
|
||||||
case DL_READV_S:
|
|
||||||
lan8710a_readv_s(&m, FALSE);
|
|
||||||
break;
|
|
||||||
case DL_CONF:
|
|
||||||
lan8710a_conf(&m);
|
|
||||||
break;
|
|
||||||
case DL_GETSTAT_S:
|
|
||||||
lan8710a_getstat(&m);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
panic("Illegal message: %d", m.m_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* sef_local_startup *
|
* lan8710a_init *
|
||||||
*============================================================================*/
|
|
||||||
static void
|
|
||||||
sef_local_startup()
|
|
||||||
{
|
|
||||||
/* Register init callbacks. */
|
|
||||||
sef_setcb_init_fresh(sef_cb_init_fresh);
|
|
||||||
sef_setcb_init_lu(sef_cb_init_fresh);
|
|
||||||
sef_setcb_init_restart(sef_cb_init_fresh);
|
|
||||||
|
|
||||||
/* Register live update callbacks. */
|
|
||||||
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
|
|
||||||
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree);
|
|
||||||
|
|
||||||
/* Register signal callbacks. */
|
|
||||||
sef_setcb_signal_handler(sef_cb_signal_handler);
|
|
||||||
|
|
||||||
/* Let SEF perform startup. */
|
|
||||||
sef_startup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*============================================================================*
|
|
||||||
* sef_cb_init_fresh *
|
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static int
|
static int
|
||||||
sef_cb_init_fresh(int UNUSED( type), sef_init_info_t *UNUSED( info))
|
lan8710a_init(unsigned int instance, ether_addr_t * addr)
|
||||||
{
|
{
|
||||||
/* Initialize the ethernet driver. */
|
/* Initialize the ethernet driver. */
|
||||||
long v = 0;
|
|
||||||
|
|
||||||
/* Clear state. */
|
/* Clear state. */
|
||||||
memset(&lan8710a_state, 0, sizeof(lan8710a_state));
|
memset(&lan8710a_state, 0, sizeof(lan8710a_state));
|
||||||
|
|
||||||
|
strlcpy(lan8710a_state.name, "lan8710a#0", LAN8710A_NAME_LEN);
|
||||||
|
lan8710a_state.name[9] += instance;
|
||||||
|
lan8710a_state.instance = instance;
|
||||||
|
|
||||||
/* Initialize driver. */
|
/* Initialize driver. */
|
||||||
lan8710a_init();
|
lan8710a_map_regs();
|
||||||
|
|
||||||
/* Get instance of ethernet device */
|
lan8710a_init_hw(addr);
|
||||||
env_parse("instance", "d", 0, &v, 0, 255);
|
|
||||||
lan8710a_state.instance = (int) v;
|
|
||||||
|
|
||||||
/* Announce we are up! */
|
|
||||||
netdriver_announce();
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
|
||||||
* sef_cb_signal_handler *
|
|
||||||
*============================================================================*/
|
|
||||||
static void
|
|
||||||
sef_cb_signal_handler(int signal)
|
|
||||||
{
|
|
||||||
/* Only check for termination signal, ignore anything else. */
|
|
||||||
if (signal != SIGTERM)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lan8710a_stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_enable_interrupt *
|
* lan8710a_enable_interrupt *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_enable_interrupt(interrupt)
|
lan8710a_enable_interrupt(int interrupt)
|
||||||
u8_t interrupt;
|
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -182,14 +103,13 @@ u8_t interrupt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_interrupt *
|
* lan8710a_intr *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_interrupt(m)
|
lan8710a_intr(unsigned int mask)
|
||||||
message *m;
|
|
||||||
{
|
{
|
||||||
lan8710a_t *e = &lan8710a_state;
|
|
||||||
u32_t dma_status;
|
u32_t dma_status;
|
||||||
|
|
||||||
/* Check the card for interrupt reason(s). */
|
/* Check the card for interrupt reason(s). */
|
||||||
|
@ -201,7 +121,7 @@ message *m;
|
||||||
if (rx_stat) {
|
if (rx_stat) {
|
||||||
cp = lan8710a_reg_read(CPDMA_STRAM_RX_CP(0));
|
cp = lan8710a_reg_read(CPDMA_STRAM_RX_CP(0));
|
||||||
|
|
||||||
lan8710a_readv_s(&(e->rx_message), TRUE);
|
netdriver_recv();
|
||||||
|
|
||||||
lan8710a_reg_write(CPDMA_STRAM_RX_CP(0), cp);
|
lan8710a_reg_write(CPDMA_STRAM_RX_CP(0), cp);
|
||||||
lan8710a_reg_write(CPDMA_EOI_VECTOR, RX_INT);
|
lan8710a_reg_write(CPDMA_EOI_VECTOR, RX_INT);
|
||||||
|
@ -212,7 +132,7 @@ message *m;
|
||||||
/* Disabling channels, where Tx interrupt occurred */
|
/* Disabling channels, where Tx interrupt occurred */
|
||||||
lan8710a_reg_set(CPDMA_TX_INTMASK_CLEAR, tx_stat);
|
lan8710a_reg_set(CPDMA_TX_INTMASK_CLEAR, tx_stat);
|
||||||
|
|
||||||
lan8710a_writev_s(&(e->tx_message), TRUE);
|
netdriver_send();
|
||||||
|
|
||||||
lan8710a_reg_write(CPDMA_STRAM_TX_CP(0), cp);
|
lan8710a_reg_write(CPDMA_STRAM_TX_CP(0), cp);
|
||||||
lan8710a_reg_write(CPDMA_EOI_VECTOR, TX_INT);
|
lan8710a_reg_write(CPDMA_EOI_VECTOR, TX_INT);
|
||||||
|
@ -226,61 +146,19 @@ message *m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-enable Rx interrupt. */
|
/* Re-enable Rx interrupt. */
|
||||||
if(m->m_notify.interrupts & (1 << RX_INT))
|
if (mask & (1 << RX_INT))
|
||||||
lan8710a_enable_interrupt(RX_INT);
|
lan8710a_enable_interrupt(RX_INT);
|
||||||
|
|
||||||
/* Re-enable Tx interrupt. */
|
/* Re-enable Tx interrupt. */
|
||||||
if(m->m_notify.interrupts & (1 << TX_INT))
|
if (mask & (1 << TX_INT))
|
||||||
lan8710a_enable_interrupt(TX_INT);
|
lan8710a_enable_interrupt(TX_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
|
||||||
* lan8710a_conf *
|
|
||||||
*============================================================================*/
|
|
||||||
static void
|
|
||||||
lan8710a_conf(m)
|
|
||||||
message *m;
|
|
||||||
{
|
|
||||||
message reply;
|
|
||||||
|
|
||||||
if (!(lan8710a_state.status & LAN8710A_ENABLED) &&
|
|
||||||
!(lan8710a_init_hw())) {
|
|
||||||
reply.m_type = DL_CONF_REPLY;
|
|
||||||
reply.m_netdrv_net_dl_conf.stat = ENXIO;
|
|
||||||
mess_reply(m, &reply);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Reply back to INET. */
|
|
||||||
reply.m_type = DL_CONF_REPLY;
|
|
||||||
reply.m_netdrv_net_dl_conf.stat = OK;
|
|
||||||
memcpy(reply.m_netdrv_net_dl_conf.hw_addr,
|
|
||||||
lan8710a_state.address.ea_addr,
|
|
||||||
sizeof(reply.m_netdrv_net_dl_conf.hw_addr));
|
|
||||||
mess_reply(m, &reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*============================================================================*
|
|
||||||
* lan8710a_init *
|
|
||||||
*============================================================================*/
|
|
||||||
static void
|
|
||||||
lan8710a_init(void)
|
|
||||||
{
|
|
||||||
lan8710a_map_regs();
|
|
||||||
strlcpy(lan8710a_state.name, "lan8710a#0", LAN8710A_NAME_LEN);
|
|
||||||
lan8710a_state.name[9] += lan8710a_state.instance;
|
|
||||||
lan8710a_state.status |= LAN8710A_DETECTED;
|
|
||||||
|
|
||||||
if (!(lan8710a_state.status & LAN8710A_ENABLED) &&
|
|
||||||
!(lan8710a_init_hw())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_init_addr *
|
* lan8710a_init_addr *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_init_addr(void)
|
lan8710a_init_addr(ether_addr_t * addr)
|
||||||
{
|
{
|
||||||
static char eakey[]= LAN8710A_ENVVAR "#_EA";
|
static char eakey[]= LAN8710A_ENVVAR "#_EA";
|
||||||
static char eafmt[]= "x:x:x:x:x:x";
|
static char eafmt[]= "x:x:x:x:x:x";
|
||||||
|
@ -296,22 +174,20 @@ lan8710a_init_addr(void)
|
||||||
if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
|
if (env_parse(eakey, eafmt, i, &v, 0x00L, 0xFFL) != EP_SET)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
lan8710a_state.address.ea_addr[i] = v;
|
addr->ea_addr[i] = v;
|
||||||
}
|
|
||||||
if (i != 6) {
|
|
||||||
lan8710a_state.address.ea_addr[0] =
|
|
||||||
(lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF);
|
|
||||||
lan8710a_state.address.ea_addr[1] =
|
|
||||||
((lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF00) >> 8);
|
|
||||||
lan8710a_state.address.ea_addr[2] =
|
|
||||||
((lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF0000) >> 16);
|
|
||||||
lan8710a_state.address.ea_addr[3] =
|
|
||||||
((lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF000000) >> 24);
|
|
||||||
lan8710a_state.address.ea_addr[4] =
|
|
||||||
(lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF);
|
|
||||||
lan8710a_state.address.ea_addr[5] =
|
|
||||||
((lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF00) >> 8);
|
|
||||||
}
|
}
|
||||||
|
if (i == 6)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No; get the address from the chip itself.
|
||||||
|
*/
|
||||||
|
addr->ea_addr[0] = lan8710a_reg_read(CTRL_MAC_ID0_HI) & 0xFF;
|
||||||
|
addr->ea_addr[1] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 8) & 0xFF;
|
||||||
|
addr->ea_addr[2] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 16) & 0xFF;
|
||||||
|
addr->ea_addr[3] = (lan8710a_reg_read(CTRL_MAC_ID0_HI) >> 24) & 0xFF;
|
||||||
|
addr->ea_addr[4] = lan8710a_reg_read(CTRL_MAC_ID0_LO) & 0xFF;
|
||||||
|
addr->ea_addr[5] = (lan8710a_reg_read(CTRL_MAC_ID0_LO) >> 8) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
|
@ -411,40 +287,28 @@ lan8710a_map_regs(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_getstat *
|
* lan8710a_stat *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_getstat(mp)
|
lan8710a_stat(eth_stat_t * stat)
|
||||||
message *mp;
|
|
||||||
{
|
{
|
||||||
int r;
|
stat->ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR)
|
||||||
eth_stat_t stats;
|
|
||||||
|
|
||||||
stats.ets_recvErr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR)
|
|
||||||
+ lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR)
|
+ lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR)
|
||||||
+ lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE);
|
+ lan8710a_reg_read(CPSW_STAT_RX_OVERSIZE);
|
||||||
stats.ets_sendErr = 0;
|
stat->ets_sendErr = 0;
|
||||||
stats.ets_OVW = 0;
|
stat->ets_OVW = 0;
|
||||||
stats.ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR);
|
stat->ets_CRCerr = lan8710a_reg_read(CPSW_STAT_RX_CRC_ERR);
|
||||||
stats.ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR);
|
stat->ets_frameAll = lan8710a_reg_read(CPSW_STAT_RX_AGNCD_ERR);
|
||||||
stats.ets_missedP = 0;
|
stat->ets_missedP = 0;
|
||||||
stats.ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD);
|
stat->ets_packetR = lan8710a_reg_read(CPSW_STAT_RX_GOOD);
|
||||||
stats.ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD);
|
stat->ets_packetT = lan8710a_reg_read(CPSW_STAT_TX_GOOD);
|
||||||
stats.ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS);
|
stat->ets_collision = lan8710a_reg_read(CPSW_STAT_COLLISIONS);
|
||||||
stats.ets_transAb = 0;
|
stat->ets_transAb = 0;
|
||||||
stats.ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR);
|
stat->ets_carrSense = lan8710a_reg_read(CPSW_STAT_CARR_SENS_ERR);
|
||||||
stats.ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN);
|
stat->ets_fifoUnder = lan8710a_reg_read(CPSW_STAT_TX_UNDERRUN);
|
||||||
stats.ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN);
|
stat->ets_fifoOver = lan8710a_reg_read(CPSW_STAT_RX_OVERRUN);
|
||||||
stats.ets_CDheartbeat = 0;
|
stat->ets_CDheartbeat = 0;
|
||||||
stats.ets_OWC = 0;
|
stat->ets_OWC = 0;
|
||||||
|
|
||||||
sys_safecopyto(mp->m_source, mp->m_net_netdrv_dl_getstat_s.grant, 0,
|
|
||||||
(vir_bytes)&stats, sizeof(stats));
|
|
||||||
mp->m_type = DL_STAT_REPLY;
|
|
||||||
|
|
||||||
if ((r=ipc_send(mp->m_source, mp)) != OK) {
|
|
||||||
panic("lan8710a_getstat: ipc_send() failed: %d", r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
|
@ -455,9 +319,6 @@ lan8710a_stop(void)
|
||||||
{
|
{
|
||||||
/* Reset hardware. */
|
/* Reset hardware. */
|
||||||
lan8710a_reset_hw();
|
lan8710a_reset_hw();
|
||||||
|
|
||||||
/* Exit driver. */
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
|
@ -584,12 +445,10 @@ lan8710a_init_desc(void)
|
||||||
* lan8710a_init_hw *
|
* lan8710a_init_hw *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static int
|
static int
|
||||||
lan8710a_init_hw(void)
|
lan8710a_init_hw(ether_addr_t * addr)
|
||||||
{
|
{
|
||||||
int r, i;
|
int r, i;
|
||||||
|
|
||||||
lan8710a_state.status |= LAN8710A_ENABLED;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the interrupt handler and policy. Do not automatically
|
* Set the interrupt handler and policy. Do not automatically
|
||||||
* re-enable interrupts. Return the IRQ line number on interrupts.
|
* re-enable interrupts. Return the IRQ line number on interrupts.
|
||||||
|
@ -756,7 +615,7 @@ lan8710a_init_hw(void)
|
||||||
lan8710a_init_mdio();
|
lan8710a_init_mdio();
|
||||||
|
|
||||||
/* Getting MAC Address */
|
/* Getting MAC Address */
|
||||||
lan8710a_init_addr();
|
lan8710a_init_addr(addr);
|
||||||
|
|
||||||
/* Initialize descriptors */
|
/* Initialize descriptors */
|
||||||
lan8710a_init_desc();
|
lan8710a_init_desc();
|
||||||
|
@ -824,244 +683,145 @@ lan8710a_init_mdio(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_writev_s *
|
* lan8710a_send *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static int
|
||||||
lan8710a_writev_s(mp, from_int)
|
lan8710a_send(struct netdriver_data * data, size_t size)
|
||||||
message *mp;
|
|
||||||
int from_int;
|
|
||||||
{
|
{
|
||||||
iovec_s_t iovec[LAN8710A_IOVEC_NR];
|
|
||||||
lan8710a_t *e = &lan8710a_state;
|
lan8710a_t *e = &lan8710a_state;
|
||||||
lan8710a_desc_t *p_tx_desc;
|
lan8710a_desc_t *p_tx_desc;
|
||||||
u8_t *p_buf;
|
u8_t *buf;
|
||||||
int r, size, buf_data_len, i;
|
|
||||||
|
|
||||||
/* Are we called from the interrupt handler? */
|
/* setup descriptors */
|
||||||
if (!from_int) {
|
p_tx_desc = &(e->tx_desc[e->tx_desc_idx]);
|
||||||
/* We cannot write twice simultaneously. */
|
|
||||||
assert(!(e->status & LAN8710A_WRITING));
|
|
||||||
|
|
||||||
/* Copy write message. */
|
/*
|
||||||
e->tx_message = *mp;
|
* Check if descriptor is available for host and suspend if not.
|
||||||
e->client = mp->m_source;
|
*/
|
||||||
e->status |= LAN8710A_WRITING;
|
if (LAN8710A_DESC_FLAG_OWN & p_tx_desc->pkt_len_flags)
|
||||||
|
return SUSPEND;
|
||||||
|
|
||||||
/* verify vector count */
|
/* Drop packets that exceed the size of our transmission buffer. */
|
||||||
assert(mp->m_net_netdrv_dl_writev_s.count > 0);
|
if (size > LAN8710A_IOBUF_SIZE) {
|
||||||
assert(mp->m_net_netdrv_dl_writev_s.count < LAN8710A_IOVEC_NR);
|
printf("%s: dropping large packet (%zu)\n", e->name, size);
|
||||||
|
|
||||||
/*
|
return OK;
|
||||||
* Copy the I/O vector table.
|
|
||||||
*/
|
|
||||||
if ((r = sys_safecopyfrom(mp->m_source,
|
|
||||||
mp->m_net_netdrv_dl_writev_s.grant, 0,
|
|
||||||
(vir_bytes) iovec,
|
|
||||||
mp->m_net_netdrv_dl_writev_s.count *
|
|
||||||
sizeof(iovec_s_t))) != OK) {
|
|
||||||
panic("sys_safecopyfrom() failed: %d", r);
|
|
||||||
}
|
|
||||||
/* setup descriptors */
|
|
||||||
p_tx_desc = &(e->tx_desc[e->tx_desc_idx]);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if descriptor is available for host
|
|
||||||
* and drop the packet if not.
|
|
||||||
*/
|
|
||||||
if (LAN8710A_DESC_FLAG_OWN & p_tx_desc->pkt_len_flags) {
|
|
||||||
panic("No available transmit descriptor.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual address of buffer */
|
|
||||||
p_buf = e->p_tx_buf + e->tx_desc_idx * LAN8710A_IOBUF_SIZE;
|
|
||||||
buf_data_len = 0;
|
|
||||||
for (i = 0; i < mp->m_net_netdrv_dl_writev_s.count; i++) {
|
|
||||||
if ((buf_data_len + iovec[i].iov_size)
|
|
||||||
> LAN8710A_IOBUF_SIZE) {
|
|
||||||
panic("packet too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy data to buffer */
|
|
||||||
size = iovec[i].iov_size
|
|
||||||
< (LAN8710A_IOBUF_SIZE - buf_data_len) ?
|
|
||||||
iovec[i].iov_size
|
|
||||||
: (LAN8710A_IOBUF_SIZE - buf_data_len);
|
|
||||||
|
|
||||||
/* Copy bytes to TX queue buffers. */
|
|
||||||
if ((r = sys_safecopyfrom(mp->m_source,
|
|
||||||
iovec[i].iov_grant, 0,
|
|
||||||
(vir_bytes) p_buf, size)) != OK) {
|
|
||||||
panic("sys_safecopyfrom() failed: %d", r);
|
|
||||||
}
|
|
||||||
p_buf += size;
|
|
||||||
buf_data_len += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set descriptor length */
|
|
||||||
p_tx_desc->buffer_length_off = buf_data_len;
|
|
||||||
/* set flags */
|
|
||||||
p_tx_desc->pkt_len_flags = (LAN8710A_DESC_FLAG_OWN |
|
|
||||||
LAN8710A_DESC_FLAG_SOP |
|
|
||||||
LAN8710A_DESC_FLAG_EOP |
|
|
||||||
TX_DESC_TO_PORT1 |
|
|
||||||
TX_DESC_TO_PORT_EN);
|
|
||||||
p_tx_desc->pkt_len_flags |= buf_data_len;
|
|
||||||
|
|
||||||
/* setup DMA transfer */
|
|
||||||
lan8710a_dma_config_tx(e->tx_desc_idx);
|
|
||||||
|
|
||||||
e->tx_desc_idx++;
|
|
||||||
if (LAN8710A_NUM_TX_DESC == e->tx_desc_idx) {
|
|
||||||
e->tx_desc_idx = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e->status |= LAN8710A_TRANSMIT;
|
|
||||||
}
|
}
|
||||||
reply(e);
|
|
||||||
|
/* virtual address of buffer */
|
||||||
|
buf = e->p_tx_buf + e->tx_desc_idx * LAN8710A_IOBUF_SIZE;
|
||||||
|
|
||||||
|
netdriver_copyin(data, 0, buf, size);
|
||||||
|
|
||||||
|
/* set descriptor length */
|
||||||
|
p_tx_desc->buffer_length_off = size;
|
||||||
|
/* set flags */
|
||||||
|
p_tx_desc->pkt_len_flags = (LAN8710A_DESC_FLAG_OWN |
|
||||||
|
LAN8710A_DESC_FLAG_SOP |
|
||||||
|
LAN8710A_DESC_FLAG_EOP |
|
||||||
|
TX_DESC_TO_PORT1 |
|
||||||
|
TX_DESC_TO_PORT_EN);
|
||||||
|
p_tx_desc->pkt_len_flags |= size;
|
||||||
|
|
||||||
|
/* setup DMA transfer */
|
||||||
|
lan8710a_dma_config_tx(e->tx_desc_idx);
|
||||||
|
|
||||||
|
e->tx_desc_idx++;
|
||||||
|
if (LAN8710A_NUM_TX_DESC == e->tx_desc_idx)
|
||||||
|
e->tx_desc_idx = 0;
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_readv_s *
|
* lan8710a_recv *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static ssize_t
|
||||||
lan8710a_readv_s(mp, from_int)
|
lan8710a_recv(struct netdriver_data * data, size_t max)
|
||||||
message *mp;
|
|
||||||
int from_int;
|
|
||||||
{
|
{
|
||||||
iovec_s_t iovec[LAN8710A_IOVEC_NR];
|
|
||||||
lan8710a_t *e = &lan8710a_state;
|
lan8710a_t *e = &lan8710a_state;
|
||||||
lan8710a_desc_t *p_rx_desc;
|
lan8710a_desc_t *p_rx_desc;
|
||||||
u32_t flags;
|
u32_t flags;
|
||||||
u8_t *p_buf;
|
u8_t *buf;
|
||||||
u16_t pkt_data_len;
|
size_t off, size, chunk;
|
||||||
u16_t buf_bytes, buf_len;
|
|
||||||
int i, r, size;
|
|
||||||
|
|
||||||
/* Are we called from the interrupt handler? */
|
/*
|
||||||
if (!from_int) {
|
* Only handle one packet at a time.
|
||||||
e->rx_message = *mp;
|
*/
|
||||||
e->client = mp->m_source;
|
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
||||||
e->status |= LAN8710A_READING;
|
/* find next OWN descriptor with SOP flag */
|
||||||
e->rx_size = 0;
|
while ((0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) &&
|
||||||
|
(0 == (LAN8710A_DESC_FLAG_OWN & p_rx_desc->pkt_len_flags))) {
|
||||||
|
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
|
||||||
|
/* set ownership of current descriptor to EMAC */
|
||||||
|
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
|
||||||
|
|
||||||
assert(e->rx_message.m_net_netdrv_dl_readv_s.count > 0);
|
e->rx_desc_idx++;
|
||||||
assert(e->rx_message.m_net_netdrv_dl_readv_s.count < LAN8710A_IOVEC_NR);
|
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
|
||||||
}
|
e->rx_desc_idx = 0;
|
||||||
if (e->status & LAN8710A_READING) {
|
|
||||||
/*
|
|
||||||
* Copy the I/O vector table first.
|
|
||||||
*/
|
|
||||||
if ((r = sys_safecopyfrom(e->rx_message.m_source,
|
|
||||||
e->rx_message.m_net_netdrv_dl_readv_s.grant, 0,
|
|
||||||
(vir_bytes) iovec,
|
|
||||||
e->rx_message.m_net_netdrv_dl_readv_s.count *
|
|
||||||
sizeof(iovec_s_t))) != OK) {
|
|
||||||
panic("sys_safecopyfrom() failed: %d", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only handle one packet at a time.
|
|
||||||
*/
|
|
||||||
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
||||||
/* find next OWN descriptor with SOP flag */
|
|
||||||
while ((0 == (LAN8710A_DESC_FLAG_SOP &
|
|
||||||
p_rx_desc->pkt_len_flags)) &&
|
|
||||||
(0 == (LAN8710A_DESC_FLAG_OWN &
|
|
||||||
p_rx_desc->pkt_len_flags))) {
|
|
||||||
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
|
|
||||||
/* set ownership of current descriptor to EMAC */
|
|
||||||
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
|
|
||||||
|
|
||||||
e->rx_desc_idx++;
|
|
||||||
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
|
|
||||||
e->rx_desc_idx = 0;
|
|
||||||
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
|
||||||
}
|
|
||||||
if (0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) {
|
|
||||||
/* SOP was not found */
|
|
||||||
reply(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy to vector elements.
|
|
||||||
*/
|
|
||||||
pkt_data_len = 0;
|
|
||||||
buf_bytes = 0;
|
|
||||||
p_buf = e->p_rx_buf + e->rx_desc_idx * LAN8710A_IOBUF_SIZE;
|
|
||||||
for (i = 0; i < e->rx_message.m_net_netdrv_dl_readv_s.count; i++) {
|
|
||||||
buf_len = p_rx_desc->buffer_length_off & 0xFFFF;
|
|
||||||
if (buf_bytes == buf_len) {
|
|
||||||
/* Whole buffer move to the next descriptor */
|
|
||||||
p_rx_desc->buffer_length_off =
|
|
||||||
LAN8710A_IOBUF_SIZE;
|
|
||||||
/* set ownership of current desc to EMAC */
|
|
||||||
p_rx_desc->pkt_len_flags =
|
|
||||||
LAN8710A_DESC_FLAG_OWN;
|
|
||||||
buf_bytes = 0;
|
|
||||||
|
|
||||||
e->rx_desc_idx++;
|
|
||||||
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
|
|
||||||
e->rx_desc_idx = 0;
|
|
||||||
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
|
||||||
p_buf = e->p_rx_buf + (e->rx_desc_idx *
|
|
||||||
LAN8710A_IOBUF_SIZE) +
|
|
||||||
(p_rx_desc->buffer_length_off >> 16);
|
|
||||||
buf_len = p_rx_desc->buffer_length_off & 0xFFFF;
|
|
||||||
}
|
|
||||||
size = iovec[i].iov_size < (buf_len - buf_bytes) ?
|
|
||||||
iovec[i].iov_size :
|
|
||||||
(buf_len - buf_bytes);
|
|
||||||
|
|
||||||
if ((r = sys_safecopyto(e->rx_message.m_source,
|
|
||||||
iovec[i].iov_grant, 0,
|
|
||||||
(vir_bytes) p_buf,
|
|
||||||
size)) != OK) {
|
|
||||||
panic("sys_safecopyto() failed: %d", r);
|
|
||||||
}
|
|
||||||
p_buf += size;
|
|
||||||
buf_bytes += size;
|
|
||||||
pkt_data_len += size;
|
|
||||||
|
|
||||||
/* if EOP flag is set -> stop processing */
|
|
||||||
if ((LAN8710A_DESC_FLAG_EOP & p_rx_desc->pkt_len_flags) &&
|
|
||||||
(buf_bytes == buf_len)) {
|
|
||||||
/* end of packet */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
/* reset owned descriptors up to EOP flag */
|
|
||||||
flags = p_rx_desc->pkt_len_flags;
|
|
||||||
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
|
|
||||||
/* set ownership of current descriptor to EMAC */
|
|
||||||
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
|
|
||||||
|
|
||||||
e->rx_desc_idx++;
|
|
||||||
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
|
|
||||||
e->rx_desc_idx = 0;
|
|
||||||
|
|
||||||
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
|
||||||
}
|
|
||||||
while (0 == (flags & LAN8710A_DESC_FLAG_EOP));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update state.
|
|
||||||
*/
|
|
||||||
e->status |= LAN8710A_RECEIVED;
|
|
||||||
e->rx_size = pkt_data_len;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
reply(e);
|
|
||||||
|
if (0 == (LAN8710A_DESC_FLAG_SOP & p_rx_desc->pkt_len_flags)) {
|
||||||
|
/* SOP was not found */
|
||||||
|
return SUSPEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy data from descriptors, from SOP to EOP inclusive.
|
||||||
|
* TODO: make sure that the presence of a SOP slot implies the presence
|
||||||
|
* of an EOP slot, because we are not checking for ownership below..
|
||||||
|
*/
|
||||||
|
size = 0;
|
||||||
|
off = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
buf = e->p_rx_buf + e->rx_desc_idx * LAN8710A_IOBUF_SIZE + off;
|
||||||
|
chunk = p_rx_desc->buffer_length_off & 0xFFFF;
|
||||||
|
|
||||||
|
/* Truncate packets that are too large. */
|
||||||
|
if (chunk > max - size)
|
||||||
|
chunk = max - size;
|
||||||
|
|
||||||
|
if (chunk > 0) {
|
||||||
|
netdriver_copyout(data, size, buf, chunk);
|
||||||
|
|
||||||
|
size += chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = p_rx_desc->pkt_len_flags;
|
||||||
|
|
||||||
|
/* Whole buffer move to the next descriptor */
|
||||||
|
p_rx_desc->buffer_length_off = LAN8710A_IOBUF_SIZE;
|
||||||
|
/* set ownership of current desc to EMAC */
|
||||||
|
p_rx_desc->pkt_len_flags = LAN8710A_DESC_FLAG_OWN;
|
||||||
|
|
||||||
|
e->rx_desc_idx++;
|
||||||
|
if (LAN8710A_NUM_RX_DESC == e->rx_desc_idx)
|
||||||
|
e->rx_desc_idx = 0;
|
||||||
|
p_rx_desc = &(e->rx_desc[e->rx_desc_idx]);
|
||||||
|
|
||||||
|
/* if EOP flag is set -> stop processing */
|
||||||
|
if (flags & LAN8710A_DESC_FLAG_EOP)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: the upper 16 bits of buffer_length_off are used *only*
|
||||||
|
* for descriptors *after* the first one; I'm retaining this
|
||||||
|
* behavior because I don't have the chip's spec, but it may be
|
||||||
|
* better to simplify/correct this behavior. --David
|
||||||
|
*/
|
||||||
|
off = p_rx_desc->buffer_length_off >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* lan8710a_phy_write *
|
* lan8710a_phy_write *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_phy_write(reg, value)
|
lan8710a_phy_write(u32_t reg, u32_t value)
|
||||||
u32_t reg;
|
|
||||||
u32_t value;
|
|
||||||
{
|
{
|
||||||
if (!(lan8710a_reg_read(MDIOUSERACCESS0) & MDIO_GO)) {
|
if (!(lan8710a_reg_read(MDIOUSERACCESS0) & MDIO_GO)) {
|
||||||
/* Clearing MDIOUSERACCESS0 register */
|
/* Clearing MDIOUSERACCESS0 register */
|
||||||
|
@ -1072,7 +832,8 @@ u32_t value;
|
||||||
lan8710a_reg_set(MDIOUSERACCESS0,
|
lan8710a_reg_set(MDIOUSERACCESS0,
|
||||||
lan8710a_state.phy_address << MDIO_PHYADR);
|
lan8710a_state.phy_address << MDIO_PHYADR);
|
||||||
/* Data written only 16 bits. */
|
/* Data written only 16 bits. */
|
||||||
lan8710a_reg_set(MDIOUSERACCESS0, (value & 0xFFFF) << MDIO_DATA);
|
lan8710a_reg_set(MDIOUSERACCESS0,
|
||||||
|
(value & 0xFFFF) << MDIO_DATA);
|
||||||
lan8710a_reg_set(MDIOUSERACCESS0, MDIO_GO);
|
lan8710a_reg_set(MDIOUSERACCESS0, MDIO_GO);
|
||||||
|
|
||||||
/* Waiting for writing completion */
|
/* Waiting for writing completion */
|
||||||
|
@ -1084,8 +845,7 @@ u32_t value;
|
||||||
* lan8710a_phy_read *
|
* lan8710a_phy_read *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static u32_t
|
static u32_t
|
||||||
lan8710a_phy_read(reg)
|
lan8710a_phy_read(u32_t reg)
|
||||||
u32_t reg;
|
|
||||||
{
|
{
|
||||||
u32_t value = 0xFFFFFFFF;
|
u32_t value = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
@ -1115,7 +875,7 @@ u32_t reg;
|
||||||
* lan8710a_reset_hw *
|
* lan8710a_reset_hw *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_reset_hw()
|
lan8710a_reset_hw(void)
|
||||||
{
|
{
|
||||||
/* Assert a Device Reset signal. */
|
/* Assert a Device Reset signal. */
|
||||||
lan8710a_phy_write(LAN8710A_CTRL_REG, LAN8710A_SOFT_RESET);
|
lan8710a_phy_write(LAN8710A_CTRL_REG, LAN8710A_SOFT_RESET);
|
||||||
|
@ -1128,8 +888,7 @@ lan8710a_reset_hw()
|
||||||
* lan8710a_reg_read *
|
* lan8710a_reg_read *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static u32_t
|
static u32_t
|
||||||
lan8710a_reg_read(reg)
|
lan8710a_reg_read(volatile u32_t *reg)
|
||||||
volatile u32_t *reg;
|
|
||||||
{
|
{
|
||||||
u32_t value;
|
u32_t value;
|
||||||
|
|
||||||
|
@ -1144,9 +903,7 @@ volatile u32_t *reg;
|
||||||
* lan8710a_reg_write *
|
* lan8710a_reg_write *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_reg_write(reg, value)
|
lan8710a_reg_write(volatile u32_t *reg, u32_t value)
|
||||||
volatile u32_t *reg;
|
|
||||||
u32_t value;
|
|
||||||
{
|
{
|
||||||
/* Write to memory mapped register. */
|
/* Write to memory mapped register. */
|
||||||
*reg = value;
|
*reg = value;
|
||||||
|
@ -1156,9 +913,7 @@ u32_t value;
|
||||||
* lan8710a_reg_set *
|
* lan8710a_reg_set *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_reg_set(reg, value)
|
lan8710a_reg_set(volatile u32_t *reg, u32_t value)
|
||||||
volatile u32_t *reg;
|
|
||||||
u32_t value;
|
|
||||||
{
|
{
|
||||||
u32_t data;
|
u32_t data;
|
||||||
|
|
||||||
|
@ -1173,9 +928,7 @@ u32_t value;
|
||||||
* lan8710a_reg_unset *
|
* lan8710a_reg_unset *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
static void
|
static void
|
||||||
lan8710a_reg_unset(reg, value)
|
lan8710a_reg_unset(volatile u32_t *reg, u32_t value)
|
||||||
volatile u32_t *reg;
|
|
||||||
u32_t value;
|
|
||||||
{
|
{
|
||||||
u32_t data;
|
u32_t data;
|
||||||
|
|
||||||
|
@ -1185,61 +938,3 @@ u32_t value;
|
||||||
/* Unset value, and write back. */
|
/* Unset value, and write back. */
|
||||||
lan8710a_reg_write(reg, data & ~value);
|
lan8710a_reg_write(reg, data & ~value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================================*
|
|
||||||
* mess_reply *
|
|
||||||
*============================================================================*/
|
|
||||||
static void
|
|
||||||
mess_reply(req, reply)
|
|
||||||
message *req;message *reply;
|
|
||||||
{
|
|
||||||
if (ipc_send(req->m_source, reply) != OK) {
|
|
||||||
panic("unable to send reply message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*============================================================================*
|
|
||||||
* reply *
|
|
||||||
*============================================================================*/
|
|
||||||
static void
|
|
||||||
reply(e)
|
|
||||||
lan8710a_t *e;
|
|
||||||
{
|
|
||||||
message msg;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Only reply to client for read/write request. */
|
|
||||||
if (!(e->status & LAN8710A_READING ||
|
|
||||||
e->status & LAN8710A_WRITING)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Construct reply message. */
|
|
||||||
msg.m_type = DL_TASK_REPLY;
|
|
||||||
msg.m_netdrv_net_dl_task.flags = DL_NOFLAGS;
|
|
||||||
msg.m_netdrv_net_dl_task.count = 0;
|
|
||||||
|
|
||||||
/* Did we successfully receive packet(s)? */
|
|
||||||
if (e->status & LAN8710A_READING &&
|
|
||||||
e->status & LAN8710A_RECEIVED) {
|
|
||||||
msg.m_netdrv_net_dl_task.flags |= DL_PACK_RECV;
|
|
||||||
msg.m_netdrv_net_dl_task.count =
|
|
||||||
e->rx_size >= ETH_MIN_PACK_SIZE ?
|
|
||||||
e->rx_size : ETH_MIN_PACK_SIZE;
|
|
||||||
|
|
||||||
/* Clear flags. */
|
|
||||||
e->status &= ~(LAN8710A_READING | LAN8710A_RECEIVED);
|
|
||||||
}
|
|
||||||
/* Did we successfully transmit packet(s)? */
|
|
||||||
if (e->status & LAN8710A_TRANSMIT &&
|
|
||||||
e->status & LAN8710A_WRITING) {
|
|
||||||
msg.m_netdrv_net_dl_task.flags |= DL_PACK_SEND;
|
|
||||||
|
|
||||||
/* Clear flags. */
|
|
||||||
e->status &= ~(LAN8710A_WRITING | LAN8710A_TRANSMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Acknowledge to INET. */
|
|
||||||
if ((r = ipc_send(e->client, &msg) != OK)) {
|
|
||||||
panic("ipc_send() failed: %d", r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,26 +16,9 @@
|
||||||
#define LAN8710A_DEBUG_PRINT(args)
|
#define LAN8710A_DEBUG_PRINT(args)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR
|
|
||||||
#define ERR (-1) /* general error flag */
|
|
||||||
#endif
|
|
||||||
#ifndef OK
|
|
||||||
#define OK 0 /* general OK flag */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAP_FAILED ((void *) -1) /* mmap() failed */
|
|
||||||
|
|
||||||
/* Ethernet driver defines */
|
/* Ethernet driver defines */
|
||||||
#define LAN8710A_NAME_LEN (11)
|
#define LAN8710A_NAME_LEN (11)
|
||||||
|
|
||||||
/* Ethernet driver states */
|
|
||||||
#define LAN8710A_DETECTED (1 << 0)
|
|
||||||
#define LAN8710A_ENABLED (1 << 1)
|
|
||||||
#define LAN8710A_READING (1 << 2)
|
|
||||||
#define LAN8710A_WRITING (1 << 3)
|
|
||||||
#define LAN8710A_RECEIVED (1 << 4)
|
|
||||||
#define LAN8710A_TRANSMIT (1 << 5)
|
|
||||||
|
|
||||||
/* Descriptors flags */
|
/* Descriptors flags */
|
||||||
#define LAN8710A_DESC_FLAG_OWN (1 << 29) /* ownership flag */
|
#define LAN8710A_DESC_FLAG_OWN (1 << 29) /* ownership flag */
|
||||||
#define LAN8710A_DESC_FLAG_SOP (1 << 31) /* start of packet flag */
|
#define LAN8710A_DESC_FLAG_SOP (1 << 31) /* start of packet flag */
|
||||||
|
@ -58,9 +41,6 @@
|
||||||
/** Number of receive descriptors */
|
/** Number of receive descriptors */
|
||||||
#define LAN8710A_NUM_RX_DESC (255)
|
#define LAN8710A_NUM_RX_DESC (255)
|
||||||
|
|
||||||
/** Number of I/O vectors to use. */
|
|
||||||
#define LAN8710A_IOVEC_NR (16)
|
|
||||||
|
|
||||||
/** Size of each I/O buffer per descriptor. */
|
/** Size of each I/O buffer per descriptor. */
|
||||||
#define LAN8710A_IOBUF_SIZE (1520)
|
#define LAN8710A_IOBUF_SIZE (1520)
|
||||||
|
|
||||||
|
@ -89,11 +69,9 @@ typedef struct lan8710a_t
|
||||||
phys_bytes rx_desc_phy;
|
phys_bytes rx_desc_phy;
|
||||||
phys_bytes tx_desc_phy;
|
phys_bytes tx_desc_phy;
|
||||||
char name[LAN8710A_NAME_LEN];
|
char name[LAN8710A_NAME_LEN];
|
||||||
int status;
|
|
||||||
int irq_rx_hook; /* Rx interrupt Request Vector Hook. */
|
int irq_rx_hook; /* Rx interrupt Request Vector Hook. */
|
||||||
int irq_tx_hook; /* Tx interrupt Request Vector Hook. */
|
int irq_tx_hook; /* Tx interrupt Request Vector Hook. */
|
||||||
int instance;
|
int instance;
|
||||||
ether_addr_t address; /* Ethernet MAC address. */
|
|
||||||
u8_t *regs;
|
u8_t *regs;
|
||||||
u32_t phy_address;
|
u32_t phy_address;
|
||||||
u8_t *p_rx_buf; /* pointer to the buffer with receive frames */
|
u8_t *p_rx_buf; /* pointer to the buffer with receive frames */
|
||||||
|
@ -101,10 +79,6 @@ typedef struct lan8710a_t
|
||||||
|
|
||||||
u16_t tx_desc_idx; /* index of the next transmit desciptor */
|
u16_t tx_desc_idx; /* index of the next transmit desciptor */
|
||||||
u16_t rx_desc_idx; /* index of the next receive desciptor */
|
u16_t rx_desc_idx; /* index of the next receive desciptor */
|
||||||
int client;
|
|
||||||
message tx_message;
|
|
||||||
message rx_message;
|
|
||||||
unsigned int rx_size;
|
|
||||||
|
|
||||||
/* register mapping */
|
/* register mapping */
|
||||||
vir_bytes regs_cp_per;
|
vir_bytes regs_cp_per;
|
||||||
|
|
Loading…
Reference in a new issue