38 #define MII_PHYIDR1 0x02 39 #define MII_PHYIDR2 0x03 43 #define MII_BMCR_RST BIT (15) 44 #define MII_BMCR_ANEG_EN BIT (12) 45 #define MII_BMCR_ANEG_RST BIT (9) 48 #define MII_BMSR_ANEGACK BIT (5) 49 #define MII_BMSR_LINK BIT (2) 52 #define MII_ANAR_100_FD BIT (8) 53 #define MII_ANAR_10_FD BIT (6) 59 #define PHY_MDC_Hz 2500000 60 #define PHY_RETRIES 3000 64 #define ETH_RX_BUF_SIZE 2 65 #define ETH_TX_BUF_SIZE 1 66 #define ETH_FRAME_SIZE 0x614 177 pEth->
staadd = SET_PHYAD(phy_addr) | SET_REGAD(reg_addr) | STAOP | STABUSY;
178 while (pEth->
staadd & STABUSY) ;
183 pEth->
staadd = SET_PHYAD(phy_addr) | SET_REGAD(reg_addr) | STABUSY;
184 while (pEth->
staadd & STABUSY) ;
203 uint32_t clock_divisor, sysctl_mdcdiv, phy_stadat, counter;
208 *(
volatile uint16_t *) VR_CTL |= PHYCLKOE;
227 sysctl_mdcdiv = clock_divisor / 2 - 1;
228 ASSERT (sysctl_mdcdiv <= 0x3f);
230 rprintp (
"PHY ID: %04x %04x\n",
241 pEth->
sysctl = SET_MDCDIV(sysctl_mdcdiv) | RXDWA ;
258 rprintp(
"Ethernet link is down\n");
262 task_delay (tick_from_ms (10));
282 bfin_dma_channel_init(DMA_CHANNEL_EMAC_RX, 0, 4);
283 bfin_dma_channel_init(DMA_CHANNEL_EMAC_TX, 0, 4);
297 memset ((
uint8_t *)rxStatusWord, 0,
sizeof(rxStatusWord));
298 memset ((
uint8_t *)txStatusWord, 0,
sizeof(txStatusWord));
300 txDMADesc[0].next = &txDMADesc[1];
301 txDMADesc[0].start_addr = &txBuffer[0];
302 txDMADesc[0].config = DMA_CONFIG_DMA_EN |
303 DMA_CONFIG_WDSIZE(DMA_WDSIZE_32BIT) |
304 DMA_CONFIG_NDSIZE(5) |
305 DMA_CONFIG_FLOW(DMA_FLOW_DESCRIPTOR_LIST_LARGE);
307 txDMADesc[1].next = &txDMADesc[0];
308 txDMADesc[1].start_addr = &txStatusWord[0];
309 txDMADesc[1].config = DMA_CONFIG_DMA_EN |
311 DMA_CONFIG_WDSIZE(DMA_WDSIZE_32BIT) |
312 DMA_CONFIG_NDSIZE(0) |
313 DMA_CONFIG_FLOW(DMA_FLOW_STOP);
315 rxDMADesc[0].next = &rxDMADesc[1];
316 rxDMADesc[0].start_addr = &rxBuffer[0];
317 rxDMADesc[0].config = DMA_CONFIG_DMA_EN |
319 DMA_CONFIG_WDSIZE(DMA_WDSIZE_32BIT) |
320 DMA_CONFIG_NDSIZE(5) |
321 DMA_CONFIG_FLOW(DMA_FLOW_DESCRIPTOR_LIST_LARGE);
323 rxDMADesc[1].next = &rxDMADesc[2];
324 rxDMADesc[1].start_addr = &rxStatusWord[0];
325 rxDMADesc[1].config = DMA_CONFIG_DMA_EN |
327 DMA_CONFIG_WDSIZE(DMA_WDSIZE_32BIT) |
328 DMA_CONFIG_NDSIZE(5) |
329 DMA_CONFIG_FLOW(DMA_FLOW_DESCRIPTOR_LIST_LARGE);
331 rxDMADesc[2].next = &rxDMADesc[3];
332 rxDMADesc[2].start_addr = &rxBuffer[1];
333 rxDMADesc[2].config = DMA_CONFIG_DMA_EN |
335 DMA_CONFIG_WDSIZE(DMA_WDSIZE_32BIT) |
336 DMA_CONFIG_NDSIZE(5) |
337 DMA_CONFIG_FLOW(DMA_FLOW_DESCRIPTOR_LIST_LARGE);
339 rxDMADesc[3].next = &rxDMADesc[0];
340 rxDMADesc[3].start_addr = &rxStatusWord[1];
341 rxDMADesc[3].config = DMA_CONFIG_DMA_EN |
343 DMA_CONFIG_WDSIZE(DMA_WDSIZE_32BIT) |
344 DMA_CONFIG_NDSIZE(5) |
345 DMA_CONFIG_FLOW(DMA_FLOW_DESCRIPTOR_LIST_LARGE);
347 bfin_dma_channel_enable(DMA_CHANNEL_EMAC_RX, &rxDMADesc[0]);
350 pEth->
opmode |= ASTP | PSF | RE;
356 UASSERT(length > 0, EARG);
361 while (bfin_dma_channel_interrupt_is_active (DMA_CHANNEL_EMAC_TX));
363 txBuffer[
txIdx].length = length;
364 memcpy(txBuffer[txIdx].
data, packet, length);
366 bfin_dma_channel_enable(DMA_CHANNEL_EMAC_TX, txDMADesc);
369 while ((txStatusWord[txIdx] & TX_COMP) == 0);
371 ASSERT(txStatusWord[txIdx] & TX_OK);
373 txStatusWord[
txIdx] = 0;
390 if ((status & RX_COMP) == 0) {
393 else if ((status & RX_OK) == 0) {
398 else if (status & RX_DMAO) {
404 length = status & RX_FRLEN;
410 memcpy(packet, rxBuffer[rxIdx].
data, length);
412 bfin_dma_channel_interrupt_clear (DMA_CHANNEL_EMAC_RX);
413 rxStatusWord[
rxIdx] = 0;
static ethernet_data_t rxBuffer [ETH_RX_BUF_SIZE] __attribute__((section(".dma")))
static uint8_t lw_emac_init_registers(uint8_t *ethAddr)
static uint32_t lw_emac_read_phy_reg(uint8_t phy_addr, uint8_t reg_addr)
static void lw_emac_set_mac_addr(uint8_t *ethAddr)
int bfin_EMAC_send(void *packet, int length)
static void lw_emac_write_phy_reg(uint8_t phy_addr, uint8_t reg_addr, uint32_t data)
struct bfin_emac_regs bfin_emac_regs_t
int bfin_EMAC_recv(uint8_t *packet, size_t size)
int bfin_EMAC_init(uint8_t *ethAddr)
#define MII_BMCR_ANEG_RST
static volatile bfin_emac_regs_t * pEth
struct ethernet_data ethernet_data_t
COMPILETIME_ASSERT(offsetof(bfin_emac_regs_t, opmode)==0x0)