/* * init_emac: Initializes the Ethernet control registers */ static int init_emac(bcmenet_softc *softc) { ETHERNET_MAC_INFO EnetInfos[BP_MAX_ENET_MACS]; #if defined(_BCM96348_) uint32 gpiomode; #endif /* disable ethernet MAC while updating its registers */ EMAC->config = EMAC_DISABLE ; while(EMAC->config & EMAC_DISABLE); /* issue soft reset, wait for it to complete */ EMAC->config = EMAC_SOFT_RESET; while (EMAC->config & EMAC_SOFT_RESET); BpGetEthernetMacInfo( EnetInfos, BP_MAX_ENET_MACS ); memcpy(&softc->EnetInfo,&EnetInfos[EMAC_INFO_INDEX],sizeof(softc->EnetInfo)); softc->emac = EMAC; #if defined(_BCM96348_) if (softc->emac == EMAC2) { if (softc->EnetInfo.ucPhyType != BP_ENET_INTERNAL_PHY) { gpiomode = GPIO->GPIOMode; gpiomode |= (GROUP3_EXT_MII|GROUP0_EXT_MII); /* External MII */ if ((softc->EnetInfo.usConfigType == BP_ENET_CONFIG_SPI_SSB_1) || (softc->EnetInfo.usConfigType == BP_ENET_CONFIG_SPI_SSB_2) || (softc->EnetInfo.usConfigType == BP_ENET_CONFIG_SPI_SSB_3)) { gpiomode &= ~GROUP1_SPI_MASTER; gpiomode |= GROUP1_SPI_MASTER; } GPIO->GPIOMode = gpiomode; } } #endif if (mii_init(softc)) return -1; /* Initialize emac registers */ EMAC->rxControl = EMAC_FC_EN; // //EMAC_PROM; NO Promiscuous > 5.0 #ifdef MAC_LOOPBACK EMAC->rxControl |= EMAC_LOOPBACK; #endif EMAC->rxMaxLength = ENET_MAX_MTU_SIZE; EMAC->txMaxLength = ENET_MAX_MTU_SIZE; /* tx threshold = abs(63-(0.63*DMA_MAX_BURST_LENGTH)) */ EMAC->txThreshold = EMAC_TX_WATERMARK; EMAC->mibControl = EMAC_NO_CLEAR; /* clear MIBs on read */ EMAC->intMask = 0; /* mask all EMAC interrupts*/ EMAC->config |= EMAC_ENABLE; softc->dmaCtrl->controller_cfg |= DMA_MASTER_EN; return 0; }
/** * Probe PCI device * * @v pci PCI device * @ret rc Return status code */ static int skeleton_probe ( struct pci_device *pci ) { struct net_device *netdev; struct skeleton_nic *skel; int rc; /* Allocate and initialise net device */ netdev = alloc_etherdev ( sizeof ( *skel ) ); if ( ! netdev ) { rc = -ENOMEM; goto err_alloc; } netdev_init ( netdev, &skeleton_operations ); skel = netdev->priv; pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( skel, 0, sizeof ( *skel ) ); /* Fix up PCI device */ adjust_pci_device ( pci ); /* Map registers */ skel->regs = ioremap ( pci->membase, SKELETON_BAR_SIZE ); /* Reset the NIC */ if ( ( rc = skeleton_reset ( skel ) ) != 0 ) goto err_reset; /* Initialise and reset MII interface */ mii_init ( &skel->mii, &skeleton_mii_operations ); if ( ( rc = mii_reset ( &skel->mii ) ) != 0 ) { DBGC ( skel, "SKELETON %p could not reset MII: %s\n", skel, strerror ( rc ) ); goto err_mii_reset; } /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register_netdev; /* Set initial link state */ skeleton_check_link ( netdev ); return 0; unregister_netdev ( netdev ); err_register_netdev: err_mii_reset: skeleton_reset ( skel ); err_reset: iounmap ( skel->regs ); netdev_nullify ( netdev ); netdev_put ( netdev ); err_alloc: return rc; }
void reset_phys(void) { int phyno; unsigned short v; /* reset the damn phys */ mii_init(); for (phyno = 0; phyno < 32; ++phyno) { fec8xx_miiphy_read(NULL, phyno, PHY_PHYIDR1, &v); if (v == 0xFFFF) continue; fec8xx_miiphy_write(NULL, phyno, PHY_BMCR, PHY_BMCR_POWD); udelay(10000); fec8xx_miiphy_write(NULL, phyno, PHY_BMCR, PHY_BMCR_RESET | PHY_BMCR_AUTON); udelay(10000); } }
/* * Miscellaneous intialization */ int misc_init_r (void) { volatile immap_t *immr = (immap_t *) CFG_IMMR; volatile memctl8xx_t *memctl = &immr->im_memctl; /* * Set up UPMB to handle the Virtex FPGA SelectMap interface */ upmconfig (UPMB, (uint *) selectmap_upm_table, sizeof (selectmap_upm_table) / sizeof (uint)); memctl->memc_mbmr = 0x0; config_mpc8xx_ioports (immr); #if (CONFIG_COMMANDS & CFG_CMD_MII) mii_init (); #endif #if (CONFIG_FPGA) gen860t_init_fpga (); #endif return 0; }
int misc_init_r (void) { uchar val; /* * Make sure that RTC has clock output enabled (triggers watchdog!) */ val = i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, 0x0D); val |= 0x80; i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, 0x0D, val); /* * Configure PHY to setup LED's correctly and use 100MBit, FD */ mii_init(); /* disable auto-negotiation, 100mbit, full-duplex */ fec8xx_miiphy_write(NULL, 0, MII_BMCR, 0x2100); /* set LED's to Link, Transmit, Receive */ fec8xx_miiphy_write(NULL, 0, MII_NWAYTEST, 0x4122); return 0; }
/* * MII device/info/read/write * * Syntax: * mii device {devname} * mii info {addr} * mii read {addr} {reg} * mii write {addr} {reg} {data} */ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { char op; unsigned char addr, reg; unsigned short data; int rcode = 0; char *devname; if (argc < 2) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } #if defined(CONFIG_8xx) || defined(CONFIG_MCF52x2) mii_init (); #endif /* * We use the last specified parameters, unless new ones are * entered. */ op = last_op; addr = last_addr; data = last_data; reg = last_reg; if ((flag & CMD_FLAG_REPEAT) == 0) { op = argv[1][0]; if (argc >= 3) addr = simple_strtoul (argv[2], NULL, 16); if (argc >= 4) reg = simple_strtoul (argv[3], NULL, 16); if (argc >= 5) data = simple_strtoul (argv[4], NULL, 16); } /* use current device */ devname = miiphy_get_current_dev(); /* * check device/read/write/list. */ if (op == 'i') { unsigned char j, start, end; unsigned int oui; unsigned char model; unsigned char rev; /* * Look for any and all PHYs. Valid addresses are 0..31. */ if (argc >= 3) { start = addr; end = addr + 1; } else { start = 0; end = 31; } for (j = start; j < end; j++) { if (miiphy_info (devname, j, &oui, &model, &rev) == 0) { printf ("PHY 0x%02X: " "OUI = 0x%04X, " "Model = 0x%02X, " "Rev = 0x%02X, " "%3dbase%s, %s\n", j, oui, model, rev, miiphy_speed (devname, j), miiphy_is_1000base_x (devname, j) ? "X" : "T", (miiphy_duplex (devname, j) == FULL) ? "FDX" : "HDX"); } } } else if (op == 'r') { if (miiphy_read (devname, addr, reg, &data) != 0) { puts ("Error reading from the PHY\n"); rcode = 1; } else { printf ("%04X\n", data & 0x0000FFFF); } } else if (op == 'w') { if (miiphy_write (devname, addr, reg, data) != 0) { puts ("Error writing to the PHY\n"); rcode = 1; } } else if (op == 'd') { if (argc == 2) miiphy_listdev (); else miiphy_set_current_dev (argv[2]); } else { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } /* * Save the parameters for repeats. */ last_op = op; last_addr = addr; last_data = data; last_reg = reg; return rcode; }
void vEMACInit( void ) { int iData; extern int periph_clk_khz; const unsigned portCHAR ucMACAddress[] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 }; /* Enable the ENET clock. */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; /* Allow concurrent access to MPU controller to avoid bus errors. */ MPU_CESR = 0; prvInitialiseDescriptors(); /* Reset and enable. */ ENET_ECR = ENET_ECR_RESET_MASK; /* Wait at least 8 clock cycles */ vTaskDelay( 2 ); /* Start the MII interface*/ mii_init( 0, periph_clk_khz / 1000L ); /* Configure the transmit interrupt. */ set_irq_priority( emacTX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); enable_irq( emacTX_INTERRUPT_NO ); /* Configure the receive interrupt. */ set_irq_priority( emacRX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); enable_irq( emacRX_INTERRUPT_NO ); /* Configure the error interrupt. */ set_irq_priority( emacERROR_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); enable_irq( emacERROR_INTERRUPT_NO ); /* Configure the pins to the PHY - RMII mode used. */ PORTB_PCR0 = PORT_PCR_MUX( 4 ); /* RMII0_MDIO / MII0_MDIO. */ PORTB_PCR1 = PORT_PCR_MUX( 4 ); /* RMII0_MDC / MII0_MDC */ PORTA_PCR14 = PORT_PCR_MUX( 4 ); /* RMII0_CRS_DV / MII0_RXDV */ PORTA_PCR12 = PORT_PCR_MUX( 4 ); /* RMII0_RXD1 / MII0_RXD1 */ PORTA_PCR13 = PORT_PCR_MUX( 4 ); /* RMII0_RXD0/MII0_RXD0 */ PORTA_PCR15 = PORT_PCR_MUX( 4 ); /* RMII0_TXEN/MII0_TXEN */ PORTA_PCR16 = PORT_PCR_MUX( 4 ); /* RMII0_TXD0/MII0_TXD0 */ PORTA_PCR17 = PORT_PCR_MUX( 4 ); /* RMII0_TXD1/MII0_TXD1 */ /* Is there communication with the PHY? */ do { vTaskDelay( emacLINK_DELAY ); iData = 0xFFFF; mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &iData ); } while( iData == 0xFFFF ); /* Start to auto negotiate. */ mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) ); /* Wait for auto negotiate to complete. */ do { vTaskDelay( emacLINK_DELAY ); mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &iData ); } while( !( iData & PHY_BMSR_AN_COMPLETE ) ); /* A link has been established. What was negotiated? */ iData = 0; mii_read( 0, configPHY_ADDRESS, emacPHY_STATUS, &iData ); /* Clear the Individual and Group Address Hash registers */ ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0; ENET_GAUR = 0; /* Set the Physical Address for the selected ENET */ enet_set_address( 0, ucMACAddress ); ENET_RCR = ENET_RCR_MAX_FL( UIP_BUFSIZE ) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK; /* Clear the control registers. */ ENET_TCR = 0; if( iData & emacPHY_DUPLEX_STATUS ) { /* Full duplex */ ENET_RCR &= ( unsigned long )~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { /* Half duplex */ ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK; } if( iData & emacPHY_SPEED_STATUS ) { /* 10Mbps */ ENET_RCR |= ENET_RCR_RMII_10T_MASK; } ENET_ECR = ENET_ECR_EN1588_MASK; /* Store and forward checksum. */ ENET_TFWR = ENET_TFWR_STRFWD_MASK; /* Set Rx Buffer Size */ ENET_MRBR = ( unsigned short ) UIP_BUFSIZE; /* Point to the start of the circular Rx buffer descriptor queue */ ENET_RDSR = ( unsigned long ) &( xRxDescriptors[ 0 ] ); /* Point to the start of the circular Tx buffer descriptor queue */ ENET_TDSR = ( unsigned long ) &( xTxDescriptors[ 0 ] ); /* Clear all ENET interrupt events */ ENET_EIR = ( unsigned long ) -1; /* Enable interrupts. */ ENET_EIMR = 0 /*rx irqs*/ | ENET_EIMR_RXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_RXB_MASK*/ /*xmit irqs*/ | ENET_EIMR_TXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_TXB_MASK*/ /*enet irqs*/ | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK ; /* Enable the MAC itself. */ ENET_ECR |= ENET_ECR_ETHEREN_MASK; /* Indicate that there have been empty receive buffers produced */ ENET_RDAR = ENET_RDAR_RDAR_MASK; }
/** * Probe device * * @v func USB function * @v config Configuration descriptor * @ret rc Return status code */ static int smsc95xx_probe ( struct usb_function *func, struct usb_configuration_descriptor *config ) { struct usb_device *usb = func->usb; struct net_device *netdev; struct smsc95xx_device *smsc95xx; int rc; /* Allocate and initialise structure */ netdev = alloc_etherdev ( sizeof ( *smsc95xx ) ); if ( ! netdev ) { rc = -ENOMEM; goto err_alloc; } netdev_init ( netdev, &smsc95xx_operations ); netdev->dev = &func->dev; smsc95xx = netdev->priv; memset ( smsc95xx, 0, sizeof ( *smsc95xx ) ); smsc95xx->usb = usb; smsc95xx->bus = usb->port->hub->bus; smsc95xx->netdev = netdev; usbnet_init ( &smsc95xx->usbnet, func, &smsc95xx_intr_operations, &smsc95xx_in_operations, &smsc95xx_out_operations ); usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0, SMSC95XX_INTR_MAX_FILL ); usb_refill_init ( &smsc95xx->usbnet.in, ( sizeof ( struct smsc95xx_tx_header ) - sizeof ( struct smsc95xx_rx_header ) ), SMSC95XX_IN_MTU, SMSC95XX_IN_MAX_FILL ); mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations ); DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name ); /* Describe USB network device */ if ( ( rc = usbnet_describe ( &smsc95xx->usbnet, config ) ) != 0 ) { DBGC ( smsc95xx, "SMSC95XX %p could not describe: %s\n", smsc95xx, strerror ( rc ) ); goto err_describe; } /* Reset device */ if ( ( rc = smsc95xx_reset ( smsc95xx ) ) != 0 ) goto err_reset; /* Read MAC address */ if ( ( rc = smsc95xx_fetch_mac ( smsc95xx, netdev->hw_addr ) ) != 0 ) goto err_fetch_mac; /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register; usb_func_set_drvdata ( func, netdev ); return 0; unregister_netdev ( netdev ); err_register: err_fetch_mac: err_reset: err_describe: netdev_nullify ( netdev ); netdev_put ( netdev ); err_alloc: return rc; }
/** * Probe PCI device * * @v pci PCI device * @ret rc Return status code */ static int rhine_probe ( struct pci_device *pci ) { struct net_device *netdev; struct rhine_nic *rhn; uint8_t revision; unsigned int i; int rc; /* Allocate and initialise net device */ netdev = alloc_etherdev ( sizeof ( *rhn ) ); if ( ! netdev ) { rc = -ENOMEM; goto err_alloc; } netdev_init ( netdev, &rhine_operations ); rhn = netdev->priv; pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( rhn, 0, sizeof ( *rhn ) ); rhine_init_ring ( &rhn->tx, RHINE_TXDESC_NUM, RHINE_TXQUEUE_BASE ); rhine_init_ring ( &rhn->rx, RHINE_RXDESC_NUM, RHINE_RXQUEUE_BASE ); /* Fix up PCI device */ adjust_pci_device ( pci ); /* Map registers */ rhn->regs = ioremap ( pci->membase, RHINE_BAR_SIZE ); rhn->ioaddr = pci->ioaddr; DBGC ( rhn, "RHINE %p regs at %08lx, I/O at %04lx\n", rhn, pci->membase, pci->ioaddr ); /* Reset the NIC */ if ( ( rc = rhine_reset ( rhn ) ) != 0 ) goto err_reset; /* Reload EEPROM */ if ( ( rc = rhine_reload_eeprom ( rhn ) ) != 0 ) goto err_reload_eeprom; /* Read card revision and enable MMIO */ pci_read_config_byte ( pci, PCI_REVISION, &revision ); DBGC ( rhn, "RHINE %p revision %#02x detected\n", rhn, revision ); rhine_enable_mmio ( rhn, revision ); /* Read MAC address */ for ( i = 0 ; i < ETH_ALEN ; i++ ) netdev->hw_addr[i] = readb ( rhn->regs + RHINE_MAC + i ); /* Initialise and reset MII interface */ mii_init ( &rhn->mii, &rhine_mii_operations ); if ( ( rc = mii_reset ( &rhn->mii ) ) != 0 ) { DBGC ( rhn, "RHINE %p could not reset MII: %s\n", rhn, strerror ( rc ) ); goto err_mii_reset; } DBGC ( rhn, "RHINE PHY vendor %04x device %04x\n", rhine_mii_read ( &rhn->mii, 0x02 ), rhine_mii_read ( &rhn->mii, 0x03 ) ); /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register_netdev; /* Set initial link state */ rhine_check_link ( netdev ); return 0; err_register_netdev: err_mii_reset: err_reload_eeprom: rhine_reset ( rhn ); err_reset: netdev_nullify ( netdev ); netdev_put ( netdev ); err_alloc: return rc; }
/** * In this function, the hardware should be initialized. * Called from ethernetif_init(). * * @param netif the already initialized lwip network interface structure * for this ethernetif */ static void low_level_init(struct netif *netif) { StatusType result; int data; /* set MAC hardware address length */ netif->hwaddr_len = ETHARP_HWADDR_LEN; /* set MAC hardware address */ netif->hwaddr[0] = MAC_ADDR0; netif->hwaddr[1] = MAC_ADDR1; netif->hwaddr[2] = MAC_ADDR2; netif->hwaddr[3] = MAC_ADDR3; netif->hwaddr[4] = MAC_ADDR4; netif->hwaddr[5] = MAC_ADDR5; /* maximum transfer unit */ netif->mtu = ENET_MAX_PKT_SIZE - 20; /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; /* enable the ENET clock */ SIM_SCGC2 |= SIM_SCGC2_ENET_MASK; /* allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, otherwise bus error */ MPU_CESR = 0; init_enet_bufs(); /* create semaphores */ sem_rx = CoCreateSem(NUM_ENET_TX_BUFS, NUM_ENET_TX_BUFS, 1); sem_tx = CoCreateSem(0, NUM_ENET_RX_BUFS, 1); /* Set the Reset bit and clear the Enable bit */ ENET_ECR = ENET_ECR_RESET_MASK; /* Wait at least 8 clock cycles */ for (data = 0; data < 10; data++) { asm("NOP"); } /* start MII interface */ mii_init(50/*BUS_CLOCK*/); // enet tx interrupt NVIC_SetPriority(ENET_Transmit_IRQn, 6); NVIC_EnableIRQ(ENET_Transmit_IRQn); // enet rx interrupt NVIC_SetPriority(ENET_Receive_IRQn, 6); NVIC_EnableIRQ(ENET_Receive_IRQn); //enet error interrupt NVIC_SetPriority(ENET_Error_IRQn, 6); NVIC_EnableIRQ(ENET_Error_IRQn); /* Make sure the external interface signals are enabled */ PORTB_PCR0 = PORT_PCR_MUX(4); //RMII0_MDIO/MII0_MDIO PORTB_PCR1 = PORT_PCR_MUX(4); //RMII0_MDC/MII0_MDC #if USE_MII_MODE PORTA_PCR14 = PORT_PCR_MUX(4); //RMII0_CRS_DV/MII0_RXDV //PORTA_PCR5 = PORT_PCR_MUX(4); //RMII0_RXER/MII0_RXER PORTA_PCR12 = PORT_PCR_MUX(4); //RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4); //RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4); //RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4); //RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4); //RMII0_TXD1/MII0_TXD1 PORTA_PCR11 = PORT_PCR_MUX(4); //MII0_RXCLK PORTA_PCR25 = PORT_PCR_MUX(4); //MII0_TXCLK PORTA_PCR9 = PORT_PCR_MUX(4); //MII0_RXD3 PORTA_PCR10 = PORT_PCR_MUX(4); //MII0_RXD2 PORTA_PCR28 = PORT_PCR_MUX(4); //MII0_TXER PORTA_PCR24 = PORT_PCR_MUX(4); //MII0_TXD2 PORTA_PCR26 = PORT_PCR_MUX(4); //MII0_TXD3 PORTA_PCR27 = PORT_PCR_MUX(4); //MII0_CRS PORTA_PCR29 = PORT_PCR_MUX(4); //MII0_COL #else PORTA_PCR14 = PORT_PCR_MUX(4); //RMII0_CRS_DV/MII0_RXDV // PORTA_PCR5 = PORT_PCR_MUX(4); //RMII0_RXER/MII0_RXER PORTA_PCR12 = PORT_PCR_MUX(4); //RMII0_RXD1/MII0_RXD1 PORTA_PCR13 = PORT_PCR_MUX(4); //RMII0_RXD0/MII0_RXD0 PORTA_PCR15 = PORT_PCR_MUX(4); //RMII0_TXEN/MII0_TXEN PORTA_PCR16 = PORT_PCR_MUX(4); //RMII0_TXD0/MII0_TXD0 PORTA_PCR17 = PORT_PCR_MUX(4); //RMII0_TXD1/MII0_TXD1 #endif /* USE_MII_MODE */ /* Can we talk to the PHY? */ do { CoTickDelay(PHY_LINK_DELAY); data = 0xffff; mii_read(PHY_ADDR, MII_PHYID1, (uint16_t*)&data); } while (data == 0xffff); /* Start auto negotiate. */ mii_write(PHY_ADDR, MII_BMCR, (MII_BMCR_ANRESTART | MII_BMCR_ANENABLE)); /* Wait for auto negotiate to complete. */ do { CoTickDelay(PHY_LINK_DELAY); mii_read(PHY_ADDR, MII_BMSR, (uint16_t*)&data); } while (!(data & MII_BMSR_ANEGCOMPLETE)); /* When we get here we have a link - find out what has been negotiated. */ data = 0; mii_read(PHY_ADDR, PHY_STATUS, (uint16_t*)&data); /* Set the Physical Address for the selected ENET */ ENET_PALR = (uint32_t)((netif->hwaddr[0] << 24) | (netif->hwaddr[1] << 16) | (netif->hwaddr[2] << 8) | netif->hwaddr[3]); ENET_PAUR = (uint32_t)((netif->hwaddr[4] << 24) | (netif->hwaddr[5] << 16)); /* Clear the Individual and Group Address Hash registers */ ENET_IALR = 0; ENET_IAUR = 0; ENET_GALR = 0; ENET_GAUR = 0; #if USE_MII_MODE /* various mode/status setup */ ENET_RCR = ENET_RCR_MAX_FL(ENET_MAX_PKT_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK; #else ENET_RCR = ENET_RCR_MAX_FL(ENET_MAX_PKT_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK; #endif /* clear rx/tx control registers */ ENET_TCR = 0; /* setup half or full duplex */ if (data & PHY_DUPLEX_STATUS) { /* full duplex */ ENET_RCR &= ~ENET_RCR_DRT_MASK; ENET_TCR |= ENET_TCR_FDEN_MASK; } else { /* half duplex */ ENET_RCR |= ENET_RCR_DRT_MASK; ENET_TCR &= ~ENET_TCR_FDEN_MASK; } /* Setup speed */ if (data & PHY_SPEED_STATUS) { /* 10Mbps */ ENET_RCR |= ENET_RCR_RMII_10T_MASK; } #if USE_PROMISCUOUS_MODE ENET_RCR |= ENET_RCR_PROM_MASK; #endif #ifdef ENHANCED_BD ENET_ECR = ENET_ECR_EN1588_MASK; #else ENET_ECR = 0; #endif #if ENET_HARDWARE_CHECKSUM /* enable discard on wrong protocol checksum and other nice features */ ENET_RACC = ENET_RACC_IPDIS_MASK | ENET_RACC_PRODIS_MASK | ENET_RACC_LINEDIS_MASK | ENET_RACC_IPDIS_MASK | ENET_RACC_PADREM_MASK; /* enable protocol checksum insertion */ ENET_TACC = ENET_TACC_IPCHK_MASK | ENET_TACC_PROCHK_MASK; #endif ENET_TFWR = ENET_TFWR_STRFWD_MASK; #if ENET_HARDWARE_SHIFT /* enable ethernet header alignment for rx */ ENET_RACC |= ENET_RACC_SHIFT16_MASK; /* enable ethernet header alignment for tx */ ENET_TACC |= ENET_TACC_SHIFT16_MASK; #endif /* set rx buffer size */ ENET_MRBR = ENET_RX_BUF_SIZE; /* point to the start of the circular rx buffer descriptor queue */ ENET_RDSR = (uint32_t)rx_bd; /* point to the start of the circular tx buffer descriptor queue */ ENET_TDSR = (uint32_t)tx_bd; /* clear all ENET interrupt events */ ENET_EIR = -1u; /* enable interrupts */ ENET_EIMR = 0 /* rx irqs */ | ENET_EIMR_RXF_MASK /* only for complete frame, not partial buffer descriptor */ /* tx irqs */ | ENET_EIMR_TXF_MASK /* only for complete frame, not partial buffer descriptor */ /* others enet irqs */ | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK; /* create the task that handles the MAC ENET */ result = CoCreateTask((FUNCPtr)ethernetif_input, (void *)netif, TASK_ETHIF_PRIO, &stack[TASK_ETHIF_STACK_SIZE - 1], TASK_ETHIF_STACK_SIZE); if (result == E_CREATE_FAIL) { LWIP_DEBUGF(NETIF_DEBUG,("Task for ETH recive created failed !\n\r ")); }; /* Enable the MAC itself */ ENET_ECR |= ENET_ECR_ETHEREN_MASK; /* Indicate that there have been empty receive buffers produced */ ENET_RDAR = ENET_RDAR_RDAR_MASK; }
static BT_ERROR mac_init(BT_HANDLE hMAC) { volatile LM3Sxx_MAC_REGS *pRegs = hMAC->pRegs; BT_u32 ulTemp; BT_ERROR Error = BT_ERR_NONE; struct _MII_HANDLE *pMII = mii_init(hMAC, &Error); if(!pMII) { return Error; } Error = BT_RegisterMiiBus((BT_HANDLE) pMII, &pMII->mii); if(Error) { return Error; } /* Do whatever else is needed to initialize interface. */ /* Disable all mac Interrupts. */ pRegs->MACIM &= ~(LM3Sxx_MAC_MACIM_PHYINT | LM3Sxx_MAC_MACIM_MDINT | LM3Sxx_MAC_MACIM_RXER | LM3Sxx_MAC_MACIM_FOV | LM3Sxx_MAC_MACIM_RXINT | LM3Sxx_MAC_MACIM_TXEMP | LM3Sxx_MAC_MACIM_TXER); ulTemp = pRegs->MACRIS; pRegs->MACIACK = ulTemp; BT_u8 ucMAC[6] = {0x00, 0x50, 0x45, 0x67, 0x89, 0xEF}; mac_setaddr(hMAC, ucMAC, 6); /* Initialize the mac Controller. */ BT_u32 ulInputClk = BT_LM3Sxx_GetMainFrequency(); BT_u32 ulDiv = (ulInputClk / 2) / 2500000; pRegs->MACMDV = (ulDiv & 0xFF); /* * Configure the mac Controller for normal operation. * - Enable TX Duplex Mode * - Enable TX Padding * - Enable TX CRC Generation * - Enable RX Multicast Reception */ // Setup the Transmit Control Register. ulTemp = pRegs->MACTCTL; ulTemp &= ~(LM3Sxx_MAC_MACTCTL_DUPLEX | LM3Sxx_MAC_MACTCTL_CRC | LM3Sxx_MAC_MACTCTL_PADEN); ulTemp |= (LM3Sxx_MAC_MACTCTL_DUPLEX | LM3Sxx_MAC_MACTCTL_CRC | LM3Sxx_MAC_MACTCTL_PADEN); pRegs->MACTCTL = ulTemp; // Setup the Receive Control Register. ulTemp = pRegs->MACRCTL; ulTemp &= ~(LM3Sxx_MAC_MACRCTL_BADCRC | LM3Sxx_MAC_MACRCTL_PRMS | LM3Sxx_MAC_MACRCTL_AMUL); ulTemp |= LM3Sxx_MAC_MACRCTL_AMUL; pRegs->MACRCTL = ulTemp; // Setup the Time Stamp Configuration register. ulTemp = pRegs->MACTS; ulTemp &= ~(LM3Sxx_MAC_MACTS_TSEN); pRegs->MACTS = ulTemp; /* Enable the mac Controller transmitter and receiver. */ // Reset the receive FIFO. pRegs->MACRCTL |= LM3Sxx_MAC_MACRCTL_RSTFIFO; // Enable the Ethernet receiver. pRegs->MACRCTL |= LM3Sxx_MAC_MACRCTL_RXEN; // Enable Ethernet transmitter. pRegs->MACTCTL |= LM3Sxx_MAC_MACTCTL_TXEN; // Reset the receive FIFO again, after the receiver has been enabled. pRegs->MACRCTL |= LM3Sxx_MAC_MACRCTL_RSTFIFO; /* Enable mac TX and RX Packet Interrupts. */ pRegs->MACIM |= (LM3Sxx_MAC_MACIM_TXEMP | LM3Sxx_MAC_MACIM_RXINT); return BT_ERR_NONE; }