[bsp/cvitek] eth driver support phy link detect
Signed-off-by: flyingcys <flyingcys@163.com>
This commit is contained in:
parent
cf56227000
commit
2e224b30ad
@ -27,6 +27,8 @@
|
|||||||
// #define ETH_RX_DUMP
|
// #define ETH_RX_DUMP
|
||||||
|
|
||||||
#define MAX_ADDR_LEN 6
|
#define MAX_ADDR_LEN 6
|
||||||
|
#define DETECT_THREAD_PRIORITY RT_THREAD_PRIORITY_MAX - 2
|
||||||
|
#define DETECT_THREAD_STACK_SIZE 4096
|
||||||
|
|
||||||
struct _dw_eth
|
struct _dw_eth
|
||||||
{
|
{
|
||||||
@ -109,7 +111,7 @@ static int cvi_eth_mac_phy_enable(uint32_t enable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set mac address */
|
/* set mac address */
|
||||||
memcpy(addr.b, g_mac_addr, sizeof(g_mac_addr));
|
rt_memcpy(addr.b, g_mac_addr, sizeof(g_mac_addr));
|
||||||
ret = cvi_eth_mac_set_macaddr(g_mac_handle, &addr);
|
ret = cvi_eth_mac_set_macaddr(g_mac_handle, &addr);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
@ -174,6 +176,36 @@ static void dw_gmac_handler_irq(int vector, void *param)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void phy_link_detect(void *param)
|
||||||
|
{
|
||||||
|
int link_status = -1;
|
||||||
|
int link_status_old = -1;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
link_status = eth_phy_update_link(g_phy_handle);
|
||||||
|
LOG_D("eth link status: %d", link_status);
|
||||||
|
|
||||||
|
if (link_status_old != link_status)
|
||||||
|
{
|
||||||
|
if (link_status == 0)
|
||||||
|
{
|
||||||
|
LOG_I("eth link up");
|
||||||
|
eth_device_linkchange(&(dw_eth_device.parent), RT_TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_I("eth link down");
|
||||||
|
eth_device_linkchange(&(dw_eth_device.parent), RT_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
link_status_old = link_status;
|
||||||
|
}
|
||||||
|
rt_thread_delay(RT_TICK_PER_SECOND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static rt_err_t rt_dw_eth_init(rt_device_t dev)
|
static rt_err_t rt_dw_eth_init(rt_device_t dev)
|
||||||
{
|
{
|
||||||
struct _dw_eth *dw_eth;
|
struct _dw_eth *dw_eth;
|
||||||
@ -209,8 +241,23 @@ static rt_err_t rt_dw_eth_init(rt_device_t dev)
|
|||||||
rt_hw_interrupt_install(dw_eth->irq, dw_gmac_handler_irq, g_mac_handle, "e0");
|
rt_hw_interrupt_install(dw_eth->irq, dw_gmac_handler_irq, g_mac_handle, "e0");
|
||||||
rt_hw_interrupt_umask(dw_eth->irq);
|
rt_hw_interrupt_umask(dw_eth->irq);
|
||||||
|
|
||||||
/* change device link status */
|
LOG_D("PHY MAC init success");
|
||||||
eth_device_linkchange(&(dw_eth_device.parent), RT_TRUE);
|
|
||||||
|
rt_thread_t link_detect;
|
||||||
|
link_detect = rt_thread_create("link_detect",
|
||||||
|
phy_link_detect,
|
||||||
|
(void *)&dw_eth_device,
|
||||||
|
DETECT_THREAD_STACK_SIZE,
|
||||||
|
DETECT_THREAD_PRIORITY,
|
||||||
|
2);
|
||||||
|
if (link_detect != RT_NULL)
|
||||||
|
{
|
||||||
|
rt_thread_startup(link_detect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = -RT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
@ -275,7 +322,7 @@ struct pbuf* rt_dw_eth_rx(rt_device_t dev)
|
|||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
int32_t len = cvi_eth_mac_read_frame(g_mac_handle, RecvDataBuf, GMAC_BUF_LEN);
|
int32_t len = cvi_eth_mac_read_frame(g_mac_handle, RecvDataBuf, GMAC_BUF_LEN);
|
||||||
if((len <= 0) || (len > GMAC_BUF_LEN))
|
if ((len <= 0) || (len > GMAC_BUF_LEN))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -308,11 +355,11 @@ struct pbuf* rt_dw_eth_rx(rt_device_t dev)
|
|||||||
* actually received size. In this case, ensure the tot_len member of the
|
* actually received size. In this case, ensure the tot_len member of the
|
||||||
* pbuf is the sum of the chained pbuf len members.
|
* pbuf is the sum of the chained pbuf len members.
|
||||||
*/
|
*/
|
||||||
memcpy((u8_t*)q->payload, (u8_t*)&RecvDataBuf[i], q->len);
|
rt_memcpy((u8_t*)q->payload, (u8_t*)&RecvDataBuf[i], q->len);
|
||||||
i = i + q->len;
|
i = i + q->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((i != p->tot_len) || (i > len))
|
if ((i != p->tot_len) || (i > len))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -348,14 +395,14 @@ rt_err_t rt_dw_eth_tx(rt_device_t dev, struct pbuf* p)
|
|||||||
variable. */
|
variable. */
|
||||||
MEMCPY((uint8_t *)&SendDataBuf[len], (uint8_t *)q->payload, q->len);
|
MEMCPY((uint8_t *)&SendDataBuf[len], (uint8_t *)q->payload, q->len);
|
||||||
len = len + q->len;
|
len = len + q->len;
|
||||||
if((len > GMAC_BUF_LEN) || (len > p->tot_len))
|
if ((len > GMAC_BUF_LEN) || (len > p->tot_len))
|
||||||
{
|
{
|
||||||
LOG_E("rt_dw_eth_tx: error, len=%d, tot_len=%d", len, p->tot_len);
|
LOG_E("rt_dw_eth_tx: error, len=%d, tot_len=%d", len, p->tot_len);
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len == p->tot_len)
|
if (len == p->tot_len)
|
||||||
{
|
{
|
||||||
if (cvi_eth_mac_send_frame(g_mac_handle, SendDataBuf, len) < 0)
|
if (cvi_eth_mac_send_frame(g_mac_handle, SendDataBuf, len) < 0)
|
||||||
ret = -RT_ERROR;
|
ret = -RT_ERROR;
|
||||||
@ -405,7 +452,6 @@ static int rthw_eth_init(void)
|
|||||||
LOG_E("eth_device_init failed: %d", ret);
|
LOG_E("eth_device_init failed: %d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
INIT_DEVICE_EXPORT(rthw_eth_init);
|
INIT_DEVICE_EXPORT(rthw_eth_init);
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
||||||
*/
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
#include "cvi_eth_phy.h"
|
#include "cvi_eth_phy.h"
|
||||||
@ -88,6 +100,51 @@ static int32_t eth_read_phy_id(eth_phy_priv_t *priv, uint8_t phy_addr, uint32_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ffs: find first bit set. This is defined the same way as
|
||||||
|
* the libc and compiler builtin ffs routines, therefore
|
||||||
|
* differs in spirit from the above ffz (man ffs).
|
||||||
|
*/
|
||||||
|
static inline int32_t ffs(int32_t x)
|
||||||
|
{
|
||||||
|
int32_t r = 1;
|
||||||
|
|
||||||
|
if (!x)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(x & 0xffff))
|
||||||
|
{
|
||||||
|
x >>= 16;
|
||||||
|
r += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(x & 0xff))
|
||||||
|
{
|
||||||
|
x >>= 8;
|
||||||
|
r += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(x & 0xf))
|
||||||
|
{
|
||||||
|
x >>= 4;
|
||||||
|
r += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(x & 3))
|
||||||
|
{
|
||||||
|
x >>= 2;
|
||||||
|
r += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(x & 1))
|
||||||
|
{
|
||||||
|
x >>= 1;
|
||||||
|
r += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static eth_phy_dev_t * eth_get_phy_by_mask(eth_phy_priv_t *priv, uint32_t phy_mask, phy_if_mode_t interface)
|
static eth_phy_dev_t * eth_get_phy_by_mask(eth_phy_priv_t *priv, uint32_t phy_mask, phy_if_mode_t interface)
|
||||||
{
|
{
|
||||||
uint32_t phy_id = 0xffffffff;
|
uint32_t phy_id = 0xffffffff;
|
||||||
@ -283,33 +340,9 @@ int32_t genphy_update_link(eth_phy_dev_t *phy_dev)
|
|||||||
|
|
||||||
if ((phy_dev->priv->link_info.autoneg == CSI_ETH_AUTONEG_ENABLE) &&
|
if ((phy_dev->priv->link_info.autoneg == CSI_ETH_AUTONEG_ENABLE) &&
|
||||||
!(mii_reg & CVI_BMSR_ANEGCOMPLETE)) {
|
!(mii_reg & CVI_BMSR_ANEGCOMPLETE)) {
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
rt_kprintf("%s waiting for PHY auto negotiation to complete...\n",
|
|
||||||
phy_dev->name);
|
|
||||||
while (!(mii_reg & CVI_BMSR_ANEGCOMPLETE)) {
|
|
||||||
/*
|
|
||||||
* Timeout reached ?
|
|
||||||
*/
|
|
||||||
if (i > CVI_PHY_ANEG_TIMEOUT) {
|
|
||||||
rt_kprintf("TIMEOUT!\n");
|
|
||||||
phy_dev->link_state = ETH_LINK_DOWN;
|
phy_dev->link_state = ETH_LINK_DOWN;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
// if ((i++ % 1000) == 0)
|
|
||||||
// rt_kprintf(".");
|
|
||||||
i ++;
|
|
||||||
|
|
||||||
rt_hw_us_delay(1000); /* 1 ms */
|
|
||||||
|
|
||||||
ret = eth_phy_read(phy_dev->priv, phy_addr, CVI_MII_BMSR, &mii_reg);
|
|
||||||
if (ret != 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rt_kprintf("auto negotiation Done!\n");
|
|
||||||
phy_dev->link_state = ETH_LINK_UP;
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Read the link a second time to clear the latched state */
|
/* Read the link a second time to clear the latched state */
|
||||||
@ -590,7 +623,7 @@ eth_phy_handle_t cvi_eth_phy_init(csi_eth_phy_read_t fn_read, csi_eth_phy_write
|
|||||||
phy_dev = eth_connect_phy(priv, phy_mask, interface);
|
phy_dev = eth_connect_phy(priv, phy_mask, interface);
|
||||||
if (phy_dev == NULL) {
|
if (phy_dev == NULL) {
|
||||||
rt_kprintf("No phy device found!\n");
|
rt_kprintf("No phy device found!\n");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
rt_kprintf("connect phy id: 0x%X\n", phy_dev->phy_id);
|
rt_kprintf("connect phy id: 0x%X\n", phy_dev->phy_id);
|
||||||
|
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2020 AlibabaGroup Holding Limited
|
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* @file phy.h
|
* @file phy.h
|
||||||
@ -359,40 +371,10 @@ int32_t eth_phy_update_link(eth_phy_handle_t handle);
|
|||||||
int32_t genphy_config(eth_phy_dev_t *phy_dev);
|
int32_t genphy_config(eth_phy_dev_t *phy_dev);
|
||||||
int32_t genphy_update_link(eth_phy_dev_t *phy_dev);
|
int32_t genphy_update_link(eth_phy_dev_t *phy_dev);
|
||||||
|
|
||||||
/*
|
int32_t cvi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state);
|
||||||
* ffs: find first bit set. This is defined the same way as
|
|
||||||
* the libc and compiler builtin ffs routines, therefore
|
|
||||||
* differs in spirit from the above ffz (man ffs).
|
|
||||||
*/
|
|
||||||
|
|
||||||
// static inline int32_t ffs(int32_t x)
|
eth_phy_handle_t cvi_eth_phy_init(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write);
|
||||||
// {
|
|
||||||
// int32_t r = 1;
|
|
||||||
|
|
||||||
// if (!x)
|
|
||||||
// return 0;
|
|
||||||
// if (!(x & 0xffff)) {
|
|
||||||
// x >>= 16;
|
|
||||||
// r += 16;
|
|
||||||
// }
|
|
||||||
// if (!(x & 0xff)) {
|
|
||||||
// x >>= 8;
|
|
||||||
// r += 8;
|
|
||||||
// }
|
|
||||||
// if (!(x & 0xf)) {
|
|
||||||
// x >>= 4;
|
|
||||||
// r += 4;
|
|
||||||
// }
|
|
||||||
// if (!(x & 3)) {
|
|
||||||
// x >>= 2;
|
|
||||||
// r += 2;
|
|
||||||
// }
|
|
||||||
// if (!(x & 1)) {
|
|
||||||
// x >>= 1;
|
|
||||||
// r += 1;
|
|
||||||
// }
|
|
||||||
// return r;
|
|
||||||
// }
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
||||||
*/
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
#include "dw_eth_mac.h"
|
#include "dw_eth_mac.h"
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
#define roundup(x, y) ( \
|
#define roundup(x, y) ( \
|
||||||
{ \
|
{ \
|
||||||
@ -91,7 +104,7 @@ static void tx_descs_init(eth_mac_handle_t handle)
|
|||||||
desc_p->dmamac_next = (unsigned long)&desc_table_p[0];
|
desc_p->dmamac_next = (unsigned long)&desc_table_p[0];
|
||||||
|
|
||||||
/* Flush all Tx buffer descriptors at once */
|
/* Flush all Tx buffer descriptors at once */
|
||||||
rt_hw_cpu_dcache_clean((unsigned long)priv->tx_mac_descrtable, sizeof(priv->tx_mac_descrtable));
|
rt_hw_cpu_dcache_clean((void *)priv->tx_mac_descrtable, sizeof(priv->tx_mac_descrtable));
|
||||||
|
|
||||||
dma_reg->txdesclistaddr = (unsigned long)&desc_table_p[0];
|
dma_reg->txdesclistaddr = (unsigned long)&desc_table_p[0];
|
||||||
|
|
||||||
@ -114,7 +127,7 @@ static void rx_descs_init(eth_mac_handle_t handle)
|
|||||||
* Otherwise there's a chance to get some of them flushed in RAM when
|
* Otherwise there's a chance to get some of them flushed in RAM when
|
||||||
* GMAC is already pushing data to RAM via DMA. This way incoming from
|
* GMAC is already pushing data to RAM via DMA. This way incoming from
|
||||||
* GMAC data will be corrupted. */
|
* GMAC data will be corrupted. */
|
||||||
rt_hw_cpu_dcache_clean((unsigned long)rxbuffs, CVI_RX_TOTAL_BUFSIZE);
|
rt_hw_cpu_dcache_clean((void *)rxbuffs, CVI_RX_TOTAL_BUFSIZE);
|
||||||
|
|
||||||
for (idx = 0; idx < CVI_CONFIG_RX_DESCR_NUM; idx++) {
|
for (idx = 0; idx < CVI_CONFIG_RX_DESCR_NUM; idx++) {
|
||||||
desc_p = &desc_table_p[idx];
|
desc_p = &desc_table_p[idx];
|
||||||
@ -132,7 +145,7 @@ static void rx_descs_init(eth_mac_handle_t handle)
|
|||||||
desc_p->dmamac_next = (unsigned long)&desc_table_p[0];
|
desc_p->dmamac_next = (unsigned long)&desc_table_p[0];
|
||||||
|
|
||||||
/* Flush all Rx buffer descriptors at once */
|
/* Flush all Rx buffer descriptors at once */
|
||||||
rt_hw_cpu_dcache_clean((unsigned long)priv->rx_mac_descrtable, sizeof(priv->rx_mac_descrtable));
|
rt_hw_cpu_dcache_clean((void *)priv->rx_mac_descrtable, sizeof(priv->rx_mac_descrtable));
|
||||||
|
|
||||||
dma_reg->rxdesclistaddr = (unsigned long)&desc_table_p[0];
|
dma_reg->rxdesclistaddr = (unsigned long)&desc_table_p[0];
|
||||||
|
|
||||||
@ -238,8 +251,8 @@ static int32_t designware_eth_enable(eth_mac_handle_t handle, int32_t control)
|
|||||||
struct dw_gmac_mac_regs *mac_reg = mac_dev->priv->mac_regs_p;
|
struct dw_gmac_mac_regs *mac_reg = mac_dev->priv->mac_regs_p;
|
||||||
eth_link_state_t link_state = mac_dev->phy_dev->link_state;
|
eth_link_state_t link_state = mac_dev->phy_dev->link_state;
|
||||||
|
|
||||||
if (link_state == ETH_LINK_DOWN)
|
// if (link_state == ETH_LINK_DOWN)
|
||||||
return -1;
|
// return -1;
|
||||||
|
|
||||||
switch (control) {
|
switch (control) {
|
||||||
case CSI_ETH_MAC_CONTROL_TX:
|
case CSI_ETH_MAC_CONTROL_TX:
|
||||||
@ -320,7 +333,7 @@ static int32_t designware_eth_send(eth_mac_handle_t handle, const uint8_t *frame
|
|||||||
|
|
||||||
/* Check if the descriptor is owned by CPU */
|
/* Check if the descriptor is owned by CPU */
|
||||||
while (1) {
|
while (1) {
|
||||||
rt_hw_cpu_dcache_invalidate(desc_start, desc_end - desc_start);
|
rt_hw_cpu_dcache_invalidate((void *)desc_start, desc_end - desc_start);
|
||||||
if (!(desc_p->txrx_status & CVI_DESC_TXSTS_OWNBYDMA)) {
|
if (!(desc_p->txrx_status & CVI_DESC_TXSTS_OWNBYDMA)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -335,7 +348,7 @@ static int32_t designware_eth_send(eth_mac_handle_t handle, const uint8_t *frame
|
|||||||
memcpy((void *)data_start, frame, length);
|
memcpy((void *)data_start, frame, length);
|
||||||
|
|
||||||
/* Flush data to be sent */
|
/* Flush data to be sent */
|
||||||
rt_hw_cpu_dcache_clean(data_start, data_end - data_start);
|
rt_hw_cpu_dcache_clean((void *)data_start, data_end - data_start);
|
||||||
|
|
||||||
#if defined(CONFIG_DW_ALTDESCRIPTOR)
|
#if defined(CONFIG_DW_ALTDESCRIPTOR)
|
||||||
desc_p->txrx_status |= CVI_DESC_TXSTS_TXFIRST | CVI_DESC_TXSTS_TXLAST;
|
desc_p->txrx_status |= CVI_DESC_TXSTS_TXFIRST | CVI_DESC_TXSTS_TXLAST;
|
||||||
@ -355,7 +368,7 @@ static int32_t designware_eth_send(eth_mac_handle_t handle, const uint8_t *frame
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Flush modified buffer descriptor */
|
/* Flush modified buffer descriptor */
|
||||||
rt_hw_cpu_dcache_clean(desc_start, desc_end - desc_start);
|
rt_hw_cpu_dcache_clean((void *)desc_start, desc_end - desc_start);
|
||||||
|
|
||||||
/* Test the wrap-around condition. */
|
/* Test the wrap-around condition. */
|
||||||
if (++desc_num >= CVI_CONFIG_TX_DESCR_NUM)
|
if (++desc_num >= CVI_CONFIG_TX_DESCR_NUM)
|
||||||
@ -383,7 +396,7 @@ static int32_t designware_eth_recv(eth_mac_handle_t handle, uint8_t **packetp)
|
|||||||
uint64_t data_end;
|
uint64_t data_end;
|
||||||
|
|
||||||
/* Invalidate entire buffer descriptor */
|
/* Invalidate entire buffer descriptor */
|
||||||
rt_hw_cpu_dcache_invalidate(desc_start, desc_end - desc_start);
|
rt_hw_cpu_dcache_invalidate((void *)desc_start, desc_end - desc_start);
|
||||||
status = desc_p->txrx_status;
|
status = desc_p->txrx_status;
|
||||||
/* Check if the owner is the CPU */
|
/* Check if the owner is the CPU */
|
||||||
if (!(status & CVI_DESC_RXSTS_OWNBYDMA)) {
|
if (!(status & CVI_DESC_RXSTS_OWNBYDMA)) {
|
||||||
@ -391,7 +404,7 @@ static int32_t designware_eth_recv(eth_mac_handle_t handle, uint8_t **packetp)
|
|||||||
CVI_DESC_RXSTS_FRMLENSHFT;
|
CVI_DESC_RXSTS_FRMLENSHFT;
|
||||||
/* Invalidate received data */
|
/* Invalidate received data */
|
||||||
data_end = data_start + roundup(length, DW_GMAC_DMA_ALIGN);
|
data_end = data_start + roundup(length, DW_GMAC_DMA_ALIGN);
|
||||||
rt_hw_cpu_dcache_invalidate(data_start, data_end - data_start);
|
rt_hw_cpu_dcache_invalidate((void *)data_start, data_end - data_start);
|
||||||
*packetp = (uint8_t *)((uint64_t)desc_p->dmamac_addr);
|
*packetp = (uint8_t *)((uint64_t)desc_p->dmamac_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +428,7 @@ static int32_t designware_free_pkt(eth_mac_handle_t handle)
|
|||||||
desc_p->txrx_status |= CVI_DESC_RXSTS_OWNBYDMA;
|
desc_p->txrx_status |= CVI_DESC_RXSTS_OWNBYDMA;
|
||||||
|
|
||||||
/* Flush only status field - others weren't changed */
|
/* Flush only status field - others weren't changed */
|
||||||
rt_hw_cpu_dcache_clean(desc_start, desc_end - desc_start);
|
rt_hw_cpu_dcache_clean((void *)desc_start, desc_end - desc_start);
|
||||||
|
|
||||||
/* Test the wrap-around condition. */
|
/* Test the wrap-around condition. */
|
||||||
if (++desc_num >= CVI_CONFIG_RX_DESCR_NUM)
|
if (++desc_num >= CVI_CONFIG_RX_DESCR_NUM)
|
||||||
@ -619,10 +632,9 @@ int32_t cvi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *m
|
|||||||
\param[in] handle ethernet handle
|
\param[in] handle ethernet handle
|
||||||
\param[in] frame Pointer to frame buffer with data to send
|
\param[in] frame Pointer to frame buffer with data to send
|
||||||
\param[in] len Frame buffer length in bytes
|
\param[in] len Frame buffer length in bytes
|
||||||
\param[in] flags Frame transmit flags (see CSI_ETH_MAC_TX_FRAME_...)
|
|
||||||
\return error code
|
\return error code
|
||||||
*/
|
*/
|
||||||
int32_t cvi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags)
|
int32_t cvi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len)
|
||||||
{
|
{
|
||||||
RT_ASSERT(handle);
|
RT_ASSERT(handle);
|
||||||
RT_ASSERT(frame);
|
RT_ASSERT(frame);
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) Cvitek Co., Ltd. 2019-2022. All rights reserved.
|
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
||||||
*/
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#ifndef _DW_GMAC_182x_H_
|
#ifndef _DW_GMAC_182x_H_
|
||||||
#define _DW_GMAC_182x_H_
|
#define _DW_GMAC_182x_H_
|
||||||
|
|
||||||
@ -327,6 +338,84 @@ static inline void *memalign(uint32_t align, uint32_t size, void **mem_unalign)
|
|||||||
}
|
}
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
\brief Write Ethernet PHY Register through Management Interface.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] phy_addr 5-bit device address
|
||||||
|
\param[in] reg_addr 5-bit register address
|
||||||
|
\param[in] data 16-bit data to write
|
||||||
|
\return error code
|
||||||
|
*/
|
||||||
|
int32_t dw_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Control Ethernet Interface.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] control Operation
|
||||||
|
\param[in] arg Argument of operation (optional)
|
||||||
|
\return error code
|
||||||
|
*/
|
||||||
|
int32_t cvi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg);
|
||||||
|
/**
|
||||||
|
\brief Get Ethernet MAC Address.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] mac Pointer to address
|
||||||
|
\return error code
|
||||||
|
*/
|
||||||
|
int32_t cvi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Set Ethernet MAC Address.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] mac Pointer to address
|
||||||
|
\return error code
|
||||||
|
*/
|
||||||
|
int32_t cvi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Connect phy device to mac device.
|
||||||
|
\param[in] handle_mac mac handle
|
||||||
|
\param[in] handle_phy phy handle
|
||||||
|
*/
|
||||||
|
void dw_eth_mac_connect_phy(eth_mac_handle_t handle_mac, eth_phy_handle_t handle_phy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Read Ethernet PHY Register through Management Interface.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] phy_addr 5-bit device address
|
||||||
|
\param[in] reg_addr 5-bit register address
|
||||||
|
\param[out] data Pointer where the result is written to
|
||||||
|
\return error code
|
||||||
|
*/
|
||||||
|
int32_t dw_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Send Ethernet frame.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] frame Pointer to frame buffer with data to send
|
||||||
|
\param[in] len Frame buffer length in bytes
|
||||||
|
\return error code
|
||||||
|
*/
|
||||||
|
int32_t cvi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Read data of received Ethernet frame.
|
||||||
|
\param[in] handle ethernet handle
|
||||||
|
\param[in] frame Pointer to frame buffer for data to read into
|
||||||
|
\param[in] len Frame buffer length in bytes
|
||||||
|
\return number of data bytes read or execution status
|
||||||
|
- value >= 0: number of data bytes read
|
||||||
|
- value < 0: error occurred, value is execution status as defined with execution_status
|
||||||
|
*/
|
||||||
|
int32_t cvi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief This function is used to initialize Ethernet device and register an event callback.
|
||||||
|
\param[in] idx device id
|
||||||
|
\param[in] cb callback to handle ethernet event
|
||||||
|
\return return ethernet handle if success
|
||||||
|
*/
|
||||||
|
eth_mac_handle_t cvi_eth_mac_init(unsigned int *base);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
|
||||||
*/
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
// #include <mmio.h>
|
|
||||||
|
|
||||||
#include "cvi_eth_phy.h"
|
#include "cvi_eth_phy.h"
|
||||||
#include "mii.h"
|
#include "mii.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #define CVI_ETH_PHY_LOOPBACK
|
// #define CVI_ETH_PHY_LOOPBACK
|
||||||
#define LOOPBACK_XMII2MAC 0x8000
|
#define LOOPBACK_XMII2MAC 0x8000
|
||||||
#define LOOPBACK_PCS2MAC 0x2000
|
#define LOOPBACK_PCS2MAC 0x2000
|
||||||
@ -334,14 +342,9 @@ int32_t cv181x_start(eth_phy_handle_t handle)
|
|||||||
assert(handle);
|
assert(handle);
|
||||||
|
|
||||||
eth_phy_dev_t *dev = (eth_phy_dev_t *)handle;
|
eth_phy_dev_t *dev = (eth_phy_dev_t *)handle;
|
||||||
int32_t ret;
|
|
||||||
|
|
||||||
/* Read the Status (2x to make sure link is right) */
|
/* Read the Status (2x to make sure link is right) */
|
||||||
ret = genphy_update_link(dev);
|
genphy_update_link(dev);
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cv181x_parse_status(dev);
|
return cv181x_parse_status(dev);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user