Пример #1
0
static void k64f_phy_task(void *data) {
  struct netif *netif = (struct netif*)data;
  bool connection_status;
  enet_dev_if_t * enetIfPtr = (enet_dev_if_t*)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
  PHY_STATE crt_state = {STATE_UNKNOWN, (enet_phy_speed_t)STATE_UNKNOWN, (enet_phy_duplex_t)STATE_UNKNOWN};
  PHY_STATE prev_state;

  prev_state = crt_state;
  while (true) {
    // Get current status
    phy_get_link_status(enetIfPtr, &connection_status);
    crt_state.connected = connection_status ? 1 : 0;
    phy_get_link_speed(enetIfPtr, &crt_state.speed);
    phy_get_link_duplex(enetIfPtr, &crt_state.duplex);

    // Compare with previous state
    if (crt_state.connected != prev_state.connected) {
      if (crt_state.connected)
        tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1);
      else
        tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
    }

    if (crt_state.speed != prev_state.speed)
      BW_ENET_RCR_RMII_10T(enetIfPtr->deviceNumber, crt_state.speed == kEnetSpeed10M ? kEnetCfgSpeed10M : kEnetCfgSpeed100M);

    // TODO: duplex change requires disable/enable of Ethernet interface, to be implemented

    prev_state = crt_state;
    osDelay(PHY_TASK_PERIOD_MS);
  }
}
Пример #2
0
/******************************************************************************
Functions (for system that has no ET_LINKSTA pin using)
******************************************************************************/
static void polling_link_status_(void)
{
	static uint16_t timer_1s = 0;
	static int16_t pre_link_stat = R_PHY_ERROR;
	int16_t link_stat;

	if((timer_1s % 100) == 0) {
		link_stat = phy_get_link_status();
		if(pre_link_stat != link_stat) {
			if(link_stat == R_PHY_OK) {
				g_ether_LchngFlag = ETHER_FLAG_ON_LINK_ON;
			} else {
				g_ether_LchngFlag = ETHER_FLAG_ON_LINK_OFF;
			}
		}
		pre_link_stat = link_stat;
	}
	timer_1s++;
}
Пример #3
0
static void k64f_phy_task(void *data) {
  struct netif *netif = (struct netif*)data;
  bool connection_status;
  enet_dev_if_t * enetIfPtr = (enet_dev_if_t*)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
  PHY_STATE crt_state = {STATE_UNKNOWN, (enet_phy_speed_t)STATE_UNKNOWN, (enet_phy_duplex_t)STATE_UNKNOWN};
  PHY_STATE prev_state;

  prev_state = crt_state;

  // TODO: this can't be an infinite loop anymore. Events, people. Give me events. WHERE ARE MY EVENTS ?!
  // TODO: maybe this should also be called from the Ethernet interrupt handler ? (probably not thouogh, since the interrupt
  //       handler doesn't seem to have a PHY-related source (but check this!))
  // TODO: +--> what actually happens is that the requests to read/write PHY registers via the MII interface should be
  //       asynchronous (and their completion can generate an interrupt), so completely ignore this for now and assume
  //       that the Ethernet cable is always connected and the link speed never changes. Yuck.

  while (true) {
    // Get current status
    phy_get_link_status(enetIfPtr, &connection_status);
    crt_state.connected = connection_status ? 1 : 0;
    phy_get_link_speed(enetIfPtr, &crt_state.speed);
    phy_get_link_duplex(enetIfPtr, &crt_state.duplex);

    // Compare with previous state
    if (crt_state.connected != prev_state.connected) {
      if (crt_state.connected)
        tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1);
      else
        tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
    }

    if (crt_state.speed != prev_state.speed)
      BW_ENET_RCR_RMII_10T(enetIfPtr->deviceNumber, crt_state.speed == kEnetSpeed10M ? kEnetCfgSpeed10M : kEnetCfgSpeed100M);

    // TODO: duplex change requires disable/enable of Ethernet interface, to be implemented

    prev_state = crt_state;
    osDelay(PHY_TASK_PERIOD_MS);
  }
}
Пример #4
0
int phy_link_status() {
    bool connection_status;
    enet_dev_if_t * enetIfPtr = (enet_dev_if_t*)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
    phy_get_link_status(enetIfPtr, &connection_status);
    return (int)connection_status;
}
Пример #5
0
//------------------------------------------------------------------------------
int HWInit(bd_t * bd)
{
	int btemp;
	unsigned int duplex, speed;
	unsigned long tmp1, mst = 250;

	// Enable MAC interface
	CLKPWR->clkpwr_macclk_ctrl = (CLKPWR_MACCTRL_HRCCLK_EN |
		CLKPWR_MACCTRL_MMIOCLK_EN | CLKPWR_MACCTRL_DMACLK_EN |
#ifdef USE_PHY_RMII
		CLKPWR_MACCTRL_USE_RMII_PINS);
#else
		CLKPWR_MACCTRL_USE_MII_PINS);
#endif

	// Set RMII management clock rate. This clock should be slower
	// than 12.5MHz (for NXP PHYs only). For a divider of 28, the
	// clock rate when HCLK is 150MHz will be 5.4MHz
	ENETMAC->mcfg = MCFG_CLOCK_SELECT(MCFG_CLOCK_HOST_DIV_28);

	// Reset all MAC logic
	ENETMAC->mac1 = (MAC1_SOFT_RESET | MAC1_SIMULATION_RESET |
		MAC1_RESET_MCS_TX | MAC1_RESET_TX | MAC1_RESET_MCS_RX |
		MAC1_RESET_RX);
	ENETMAC->command = (COMMAND_REG_RESET | COMMAND_TXRESET |
		COMMAND_RXRESET);
	msDelay(10);

	// Initial MAC initialization
	ENETMAC->mac1 = MAC1_PASS_ALL_RX_FRAMES;
	ENETMAC->mac2 = (MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE);
	ENETMAC->maxf = ENET_MAXF_SIZE;

	// Maximum number of retries, 0x37 collision window, gap */
	ENETMAC->clrt = (CLRT_LOAD_RETRY_MAX(0xF) |
		CLRT_LOAD_COLLISION_WINDOW(0x37));
	ENETMAC->ipgr = IPGR_LOAD_PART2(0x12);

#ifdef USE_PHY_RMII
	// RMII setup
	ENETMAC->command = (COMMAND_RMII | COMMAND_PASSRUNTFRAME);
	ENETMAC->supp = SUPP_RESET_RMII;
	msDelay(10);
#else
	// MII setup
	ENETMAC->command = COMMAND_PASSRUNTFRAME;
#endif
	// Enable rate auto-negotiation for the link
	if (RMII_Write(PHY_BMCR,
		(PHY_BMCR_100MB | PHY_BMCR_AUTON)) == 0)
	{
		return 0;
	}
        
	mst = 1000;
        btemp = 1;
        while(mst > 0)
        {
                /* Wait for Link status to set UP or Timeout */
                if(phy_get_link_status() == 0) {
                        mst = 0;
                        btemp = 0;
                        printf("ENET:auto-negotiation complete#$\n");
                }
                else {
                        mst--;
                        msDelay(1);
                }
        }
        if(btemp) {
                printf("ENET:auto-negotiation failed#$\n");
                return 0;
        }

        /* Read PHY Status Register to determine Ethernet Configuration */
        tmp1 = 0;
        RMII_Read (DP83848_PHY_STATUS,&tmp1);
        duplex = (tmp1 & 0x0004) >> 2;
        speed = (tmp1 & 0x0002) >> 1;

	// Configure Full/Half Duplex mode
	if (duplex == 1)
	{
		// 10MBase full duplex is supported
		ENETMAC->mac2 |= MAC2_FULL_DUPLEX;
		ENETMAC->command |= COMMAND_FULLDUPLEX;
		ENETMAC->ipgt = IPGT_LOAD(0x15);
		printf("ENET:FULL DUPLEX\n");
	}
	else
	{
		ENETMAC->ipgt = IPGT_LOAD(0x12);
		printf("ENET:HALF DUPLEX\n");
	}

	// Configure 100MBit/10MBit mode
	if (speed == 0)
	{
		// 100MBase mode
		ENETMAC->supp = SUPP_SPEED;
		printf("ENET:100MBase\n");
	}
	else
	{
		// 10MBase mode
		ENETMAC->supp = 0;
		printf("ENET:10Base\n");
	}

	// Save station address
	ENETMAC->sa [2] = (unsigned long) (bd->bi_enetaddr[0] | (bd->bi_enetaddr[1] << 8));
	ENETMAC->sa [1] = (unsigned long) (bd->bi_enetaddr[2] | (bd->bi_enetaddr[3] << 8));
	ENETMAC->sa [0] = (unsigned long) (bd->bi_enetaddr[4] | (bd->bi_enetaddr[5] << 8));

	// Setup TX and RX descriptors
	txrx_setup();

	// Enable broadcast and matching address packets
	ENETMAC->rxfliterctrl = (RXFLTRW_ACCEPTUBROADCAST |
		RXFLTRW_ACCEPTPERFECT);

	// Clear and enable interrupts
	ENETMAC->intclear = 0xFFFF;
	ENETMAC->intenable = 0;

	// Enable receive and transmit mode of MAC ethernet core
	ENETMAC->command |= (COMMAND_RXENABLE | COMMAND_TXENABLE);
	ENETMAC->mac1 |= MAC1_RECV_ENABLE;

	// Perform a 'dummy' send of the first ethernet frame with a size of 0
	// to 'prime' the MAC. The first packet after a reset seems to wait
	// until at least 2 packets are ready to go.
	tmp1 = 0;
	eth_send(&tmp1, 4);

	return 1;
}