mv_eth.c
来自「适合KS8695X」· C语言 代码 · 共 1,878 行 · 第 1/5 页
C
1,878 行
win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
/* Set the access control for address window (EPAPR) READ & WRITE */
eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
/* Set access parameters for Internal SRAM */
win_param.win = ETH_WIN4; /* Use Ethernet window 0 */
win_param.target = EBAR_TARGET_CBS; /* Target - Internal SRAM */
win_param.attributes = EBAR_ATTR_CBS_SRAM | EBAR_ATTR_CBS_SRAM_BLOCK0;
win_param.high_addr = 0;
win_param.base_addr = mv_get_internal_sram_base (); /* Get base addr */
win_param.size = MV64360_INTERNAL_SRAM_SIZE; /* Get bank size */
win_param.enable = 1; /* Enable the access */
win_param.access_ctrl = EWIN_ACCESS_FULL; /* Enable full access */
/* Set the access control for address window (EPAPR) READ & WRITE */
eth_set_access_control (p_eth_port_ctrl->port_num, &win_param);
eth_port_init_mac_tables (p_eth_port_ctrl->port_num);
ethernet_phy_set (p_eth_port_ctrl->port_num,
p_eth_port_ctrl->port_phy_addr);
return;
}
/*******************************************************************************
* eth_port_start - Start the Ethernet port activity.
*
* DESCRIPTION:
* This routine prepares the Ethernet port for Rx and Tx activity:
* 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
* has been initialized a descriptor's ring (using ether_init_tx_desc_ring
* for Tx and ether_init_rx_desc_ring for Rx)
* 2. Initialize and enable the Ethernet configuration port by writing to
* the port's configuration and command registers.
* 3. Initialize and enable the SDMA by writing to the SDMA's
* configuration and command registers.
* After completing these steps, the ethernet port SDMA can starts to
* perform Rx and Tx activities.
*
* Note: Each Rx and Tx queue descriptor's list must be initialized prior
* to calling this function (use ether_init_tx_desc_ring for Tx queues and
* ether_init_rx_desc_ring for Rx queues).
*
* INPUT:
* ETH_PORT_INFO *p_eth_port_ctrl Ethernet port control struct
*
* OUTPUT:
* Ethernet port is ready to receive and transmit.
*
* RETURN:
* false if the port PHY is not up.
* true otherwise.
*
*******************************************************************************/
static bool eth_port_start (ETH_PORT_INFO * p_eth_port_ctrl)
{
int queue;
volatile ETH_TX_DESC *p_tx_curr_desc;
volatile ETH_RX_DESC *p_rx_curr_desc;
unsigned int phy_reg_data;
ETH_PORT eth_port_num = p_eth_port_ctrl->port_num;
/* Assignment of Tx CTRP of given queue */
for (queue = 0; queue < MAX_TX_QUEUE_NUM; queue++) {
CURR_TFD_GET (p_tx_curr_desc, queue);
MV_REG_WRITE ((MV64360_ETH_TX_CURRENT_QUEUE_DESC_PTR_0
(eth_port_num)
+ (4 * queue)),
((unsigned int) p_tx_curr_desc));
}
/* Assignment of Rx CRDP of given queue */
for (queue = 0; queue < MAX_RX_QUEUE_NUM; queue++) {
CURR_RFD_GET (p_rx_curr_desc, queue);
MV_REG_WRITE ((MV64360_ETH_RX_CURRENT_QUEUE_DESC_PTR_0
(eth_port_num)
+ (4 * queue)),
((unsigned int) p_rx_curr_desc));
if (p_rx_curr_desc != NULL)
/* Add the assigned Ethernet address to the port's address table */
eth_port_uc_addr_set (p_eth_port_ctrl->port_num,
p_eth_port_ctrl->port_mac_addr,
queue);
}
/* Assign port configuration and command. */
MV_REG_WRITE (MV64360_ETH_PORT_CONFIG_REG (eth_port_num),
p_eth_port_ctrl->port_config);
MV_REG_WRITE (MV64360_ETH_PORT_CONFIG_EXTEND_REG (eth_port_num),
p_eth_port_ctrl->port_config_extend);
MV_REG_WRITE (MV64360_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
p_eth_port_ctrl->port_serial_control);
MV_SET_REG_BITS (MV64360_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num),
ETH_SERIAL_PORT_ENABLE);
/* Assign port SDMA configuration */
MV_REG_WRITE (MV64360_ETH_SDMA_CONFIG_REG (eth_port_num),
p_eth_port_ctrl->port_sdma_config);
MV_REG_WRITE (MV64360_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT
(eth_port_num), 0x3fffffff);
MV_REG_WRITE (MV64360_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG
(eth_port_num), 0x03fffcff);
/* Turn off the port/queue bandwidth limitation */
MV_REG_WRITE (MV64360_ETH_MAXIMUM_TRANSMIT_UNIT (eth_port_num), 0x0);
/* Enable port Rx. */
MV_REG_WRITE (MV64360_ETH_RECEIVE_QUEUE_COMMAND_REG (eth_port_num),
p_eth_port_ctrl->port_rx_queue_command);
/* Check if link is up */
eth_port_read_smi_reg (eth_port_num, 1, &phy_reg_data);
if (!(phy_reg_data & 0x20))
return false;
return true;
}
/*******************************************************************************
* eth_port_uc_addr_set - This function Set the port Unicast address.
*
* DESCRIPTION:
* This function Set the port Ethernet MAC address.
*
* INPUT:
* ETH_PORT eth_port_num Port number.
* char * p_addr Address to be set
* ETH_QUEUE queue Rx queue number for this MAC address.
*
* OUTPUT:
* Set MAC address low and high registers. also calls eth_port_uc_addr()
* To set the unicast table with the proper information.
*
* RETURN:
* N/A.
*
*******************************************************************************/
static void eth_port_uc_addr_set (ETH_PORT eth_port_num,
unsigned char *p_addr, ETH_QUEUE queue)
{
unsigned int mac_h;
unsigned int mac_l;
mac_l = (p_addr[4] << 8) | (p_addr[5]);
mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
(p_addr[2] << 8) | (p_addr[3] << 0);
MV_REG_WRITE (MV64360_ETH_MAC_ADDR_LOW (eth_port_num), mac_l);
MV_REG_WRITE (MV64360_ETH_MAC_ADDR_HIGH (eth_port_num), mac_h);
/* Accept frames of this address */
eth_port_uc_addr (eth_port_num, p_addr[5], queue, ACCEPT_MAC_ADDR);
return;
}
/*******************************************************************************
* eth_port_uc_addr - This function Set the port unicast address table
*
* DESCRIPTION:
* This function locates the proper entry in the Unicast table for the
* specified MAC nibble and sets its properties according to function
* parameters.
*
* INPUT:
* ETH_PORT eth_port_num Port number.
* unsigned char uc_nibble Unicast MAC Address last nibble.
* ETH_QUEUE queue Rx queue number for this MAC address.
* int option 0 = Add, 1 = remove address.
*
* OUTPUT:
* This function add/removes MAC addresses from the port unicast address
* table.
*
* RETURN:
* true is output succeeded.
* false if option parameter is invalid.
*
*******************************************************************************/
static bool eth_port_uc_addr (ETH_PORT eth_port_num,
unsigned char uc_nibble,
ETH_QUEUE queue, int option)
{
unsigned int unicast_reg;
unsigned int tbl_offset;
unsigned int reg_offset;
/* Locate the Unicast table entry */
uc_nibble = (0xf & uc_nibble);
tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */
reg_offset = uc_nibble % 4; /* Entry offset within the above register */
switch (option) {
case REJECT_MAC_ADDR:
/* Clear accepts frame bit at specified unicast DA table entry */
unicast_reg =
MV_REG_READ ((MV64360_ETH_DA_FILTER_UNICAST_TABLE_BASE
(eth_port_num)
+ tbl_offset));
unicast_reg &= (0x0E << (8 * reg_offset));
MV_REG_WRITE ((MV64360_ETH_DA_FILTER_UNICAST_TABLE_BASE
(eth_port_num)
+ tbl_offset), unicast_reg);
break;
case ACCEPT_MAC_ADDR:
/* Set accepts frame bit at unicast DA filter table entry */
unicast_reg =
MV_REG_READ ((MV64360_ETH_DA_FILTER_UNICAST_TABLE_BASE
(eth_port_num)
+ tbl_offset));
unicast_reg |= ((0x01 | queue) << (8 * reg_offset));
MV_REG_WRITE ((MV64360_ETH_DA_FILTER_UNICAST_TABLE_BASE
(eth_port_num)
+ tbl_offset), unicast_reg);
break;
default:
return false;
}
return true;
}
#if 0 /* FIXME */
/*******************************************************************************
* eth_port_mc_addr - Multicast address settings.
*
* DESCRIPTION:
* This API controls the MV device MAC multicast support.
* The MV device supports multicast using two tables:
* 1) Special Multicast Table for MAC addresses of the form
* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_fF).
* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
* Table entries in the DA-Filter table.
* In this case, the function calls eth_port_smc_addr() routine to set the
* Special Multicast Table.
* 2) Other Multicast Table for multicast of another type. A CRC-8bit
* is used as an index to the Other Multicast Table entries in the
* DA-Filter table.
* In this case, the function calculates the CRC-8bit value and calls
* eth_port_omc_addr() routine to set the Other Multicast Table.
* INPUT:
* ETH_PORT eth_port_num Port number.
* unsigned char *p_addr Unicast MAC Address.
* ETH_QUEUE queue Rx queue number for this MAC address.
* int option 0 = Add, 1 = remove address.
*
* OUTPUT:
* See description.
*
* RETURN:
* true is output succeeded.
* false if add_address_table_entry( ) failed.
*
*******************************************************************************/
static void eth_port_mc_addr (ETH_PORT eth_port_num,
unsigned char *p_addr,
ETH_QUEUE queue, int option)
{
unsigned int mac_h;
unsigned int mac_l;
unsigned char crc_result = 0;
int mac_array[48];
int crc[8];
int i;
if ((p_addr[0] == 0x01) &&
(p_addr[1] == 0x00) &&
(p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00))
eth_port_smc_addr (eth_port_num, p_addr[5], queue, option);
else {
/* Calculate CRC-8 out of the given address */
mac_h = (p_addr[0] << 8) | (p_addr[1]);
mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) |
(p_addr[4] << 8) | (p_addr[5] << 0);
for (i = 0; i < 32; i++)
mac_array[i] = (mac_l >> i) & 0x1;
for (i = 32; i < 48; i++)
mac_array[i] = (mac_h >> (i - 32)) & 0x1;
crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^
mac_array[39] ^ mac_array[35] ^ mac_array[34] ^
mac_array[31] ^ mac_array[30] ^ mac_array[28] ^
mac_array[23] ^ mac_array[21] ^ mac_array[19] ^
mac_array[18] ^ mac_array[16] ^ mac_array[14] ^
mac_array[12] ^ mac_array[8] ^ mac_array[7] ^
mac_array[6] ^ mac_array[0];
crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
mac_array[43] ^ mac_array[41] ^ mac_array[39] ^
mac_array[36] ^ mac_array[34] ^ mac_array[32] ^
mac_array[30] ^ mac_array[29] ^ mac_array[28] ^
mac_array[24] ^ mac_array[23] ^ mac_array[22] ^
mac_array[21] ^ mac_array[20] ^ mac_array[18] ^
mac_array[17] ^ mac_array[16] ^ mac_array[15] ^
mac_array[14] ^ mac_array[13] ^ mac_array[12] ^
mac_array[9] ^ mac_array[6] ^ mac_array[1] ^
mac_array[0];
crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^
mac_array[43] ^ mac_array[42] ^ mac_array[39] ^
mac_array[37] ^ mac_array[34] ^ mac_array[33] ^
mac_array[29] ^ mac_array[28] ^ mac_array[25] ^
mac_array[24] ^ mac_array[22] ^ mac_array[17] ^
mac_array[15] ^ mac_array[13] ^ mac_array[12] ^
mac_array[10] ^ mac_array[8] ^ mac_array[6] ^
mac_array[2] ^ mac_array[1] ^ mac_array[0];
crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^
mac_array[43] ^ mac_array[40] ^ mac_array[38] ^
mac_array[35] ^ mac_array[34] ^ mac_array[30] ^
mac_array[29] ^ mac_array[26] ^ mac_array[25] ^
mac_array[23] ^ mac_array[18] ^ mac_array[16] ^
mac_array[14] ^ mac_array[13] ^ mac_array[11] ^
mac_array[9] ^ mac_array[7] ^ mac_array[3] ^
mac_array[2] ^ mac_array[1];
crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^
mac_array[41] ^ mac_array[39] ^ mac_array[36] ^
mac_array[35] ^ mac_array[31] ^ mac_array[30] ^
mac_array[27] ^ mac_array[26] ^ mac_array[24] ^
mac_array[19] ^ mac_array[17] ^ mac_array[15] ^
mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
mac_array[8] ^ mac_array[4] ^ mac_array[3] ^
mac_array[2];
crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^
mac_array[42] ^ mac_array[40] ^ mac_array[37] ^
mac_array[36] ^ mac_array[32] ^ mac_array[31] ^
mac_array[28] ^ mac_array[27] ^ mac_array[25] ^
mac_array[20] ^ mac_array[18] ^ mac_array[16] ^
mac_array[15] ^ mac_array[13] ^ mac_array[11] ^
mac_array[9] ^ mac_array[5] ^ mac_array[4] ^
mac_array[3];
crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^
mac_array[41] ^ mac_array[38] ^ mac_array[37] ^
mac_array[33] ^ mac_array[32] ^ mac_array[29] ^
mac_array[28] ^ mac_array[26] ^ mac_array[21] ^
mac_array[19] ^ mac_array[17] ^ mac_array[16] ^
mac_array[14] ^ mac_array[12] ^ mac_array[10] ^
mac_array[6] ^ mac_array[5] ^ mac_array[4];
crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^
mac_array[39] ^ mac_array[38] ^ mac_array[34] ^
mac_array[33] ^ mac_array[30] ^ mac_array[29] ^
mac_array[27] ^ mac_array[22] ^ mac_array[20] ^
mac_array[18] ^ mac_array[17] ^ mac_array[15] ^
mac_array[13] ^ mac_array[11] ^ mac_array[7] ^
mac_array[6] ^ mac_array[5];
for (i = 0; i < 8; i++)
crc_result = crc_result | (crc[i] << i);
et
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?