summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorJiaojinxing <jiaojinxing1987@gmail.com>2015-04-29 06:35:06 (GMT)
committer Jiaojinxing <jiaojinxing1987@gmail.com>2015-04-29 06:35:06 (GMT)
commit57e8c5611542afdd35864c131f983890b9255fbc (patch)
treeb582efa726b430656388c79b24cce56410be3a32
parenta0200eddd20b23bb7aefc07dbdfd1dea9c5d991b (diff)
downloadbspam335x-57e8c5611542afdd35864c131f983890b9255fbc.zip
bspam335x-57e8c5611542afdd35864c131f983890b9255fbc.tar.gz
bspam335x-57e8c5611542afdd35864c131f983890b9255fbc.tar.bz2
Optimized the CPSW driver.
-rw-r--r--SylixOS/bsp/config.h4
-rw-r--r--SylixOS/driver/netif/am335x_cpsw.c137
-rw-r--r--SylixOS/driver/netif/cpswif.c85
-rw-r--r--SylixOS/driver/netif/cpswif.h1
4 files changed, 219 insertions, 8 deletions
diff --git a/SylixOS/bsp/config.h b/SylixOS/bsp/config.h
index d7b0aab..f96d19f 100644
--- a/SylixOS/bsp/config.h
+++ b/SylixOS/bsp/config.h
@@ -81,6 +81,10 @@
#define BSP_CFG_EN2_NETMASK "255.255.255.0"
#define BSP_CFG_EN2_GATEWAY "192.168.2.1"
/*********************************************************************************************************
+ CPSW 驱动配置
+*********************************************************************************************************/
+#define BSP_CFG_CPSW_TX_DMA_PBUF 1
+/*********************************************************************************************************
开发板相关配置
*********************************************************************************************************/
#if defined(evmAM335x)
diff --git a/SylixOS/driver/netif/am335x_cpsw.c b/SylixOS/driver/netif/am335x_cpsw.c
index 518e1ce..62a5c67 100644
--- a/SylixOS/driver/netif/am335x_cpsw.c
+++ b/SylixOS/driver/netif/am335x_cpsw.c
@@ -54,11 +54,11 @@ __AM335X_CPSW_CONTROLER _G_am335xCpswControlers[MAX_CPSW_INST] = {
The lwIP network interface structure for CPSW ports.
*********************************************************************************************************/
#ifdef CPSW_DUAL_MAC_MODE
-static struct netif _G_am335xCpswNetIfs[MAX_CPSW_INST * MAX_SLAVEPORT_PER_INST];
-static atomic_t _G_atomicAm335xCpswNetIfLinks[MAX_CPSW_INST * MAX_SLAVEPORT_PER_INST];
+static struct netif _G_am335xCpswNetIfs[MAX_CPSW_INST * MAX_SLAVEPORT_PER_INST];
+static atomic_t _G_atomicAm335xCpswNetIfLinks[MAX_CPSW_INST * MAX_SLAVEPORT_PER_INST];
#else
-static struct netif _G_am335xCpswNetIfs[MAX_CPSW_INST];
-static atomic_t _G_atomicAm335xCpswNetIfLinks[MAX_CPSW_INST];
+static struct netif _G_am335xCpswNetIfs[MAX_CPSW_INST];
+static atomic_t _G_atomicAm335xCpswNetIfLinks[MAX_CPSW_INST];
#endif
/*********************************************************************************************************
Helper to identify ports
@@ -70,6 +70,98 @@ static __AM335X_CPSW_PORTIF _G_am335xCpswPortIfs[MAX_CPSW_INST * MAX_SLAVEPO
*********************************************************************************************************/
extern err_t cpswif_autoneg_config(u32_t inst_num, u32_t port_num);
/*********************************************************************************************************
+ 网络工作队列
+*********************************************************************************************************/
+static LW_JOB_QUEUE _G_am335xTxNetJobQ;
+static LW_JOB_MSG _G_am335xTxNetJobMsgs[LW_CFG_LWIP_JOBQUEUE_SIZE];
+/*********************************************************************************************************
+ INTERNAL FUNC
+*********************************************************************************************************/
+static VOID __am335xTxNetJobThread(VOID); /* 作业处理程序 */
+/*********************************************************************************************************
+** 函数名称: __am335xTxNetJobqueueInit
+** 功能描述: 初始化 Net jobqueue 处理 机制
+** 输 入 : NONE
+** 输 出 : 是否初始化成功
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xTxNetJobqueueInit (VOID)
+{
+ LW_OBJECT_HANDLE hNetJobThread;
+ LW_CLASS_THREADATTR threadattr;
+
+ if (_jobQueueInit(&_G_am335xTxNetJobQ,
+ &_G_am335xTxNetJobMsgs[0], LW_CFG_LWIP_JOBQUEUE_SIZE, LW_FALSE)) {
+ return (PX_ERROR);
+ }
+
+ API_ThreadAttrBuild(&threadattr, LW_CFG_LWIP_STK_SIZE,
+ LW_PRIO_T_NETJOB,
+ (LW_OPTION_THREAD_STK_CHK | LW_OPTION_THREAD_SAFE | LW_OPTION_OBJECT_GLOBAL),
+ LW_NULL);
+
+ hNetJobThread = API_ThreadCreate("t_txnetjob",
+ (PTHREAD_START_ROUTINE)__am335xTxNetJobThread,
+ (PLW_CLASS_THREADATTR)&threadattr,
+ LW_NULL); /* 建立 job 处理线程 */
+ if (!hNetJobThread) {
+ _jobQueueFinit(&_G_am335xTxNetJobQ);
+ return (PX_ERROR);
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xTxNetJobAdd
+** 功能描述: 加入网络异步处理作业队列
+** 输 入 : pfunc 函数指针
+** pvArg0 函数参数
+** pvArg1 函数参数
+** pvArg2 函数参数
+** pvArg3 函数参数
+** pvArg4 函数参数
+** pvArg5 函数参数
+** 输 出 : 操作是否成功
+** 全局变量:
+** 调用模块:
+ API 函数
+*********************************************************************************************************/
+static INT __am335xTxNetJobAdd (VOIDFUNCPTR pfunc,
+ PVOID pvArg0,
+ PVOID pvArg1,
+ PVOID pvArg2,
+ PVOID pvArg3,
+ PVOID pvArg4,
+ PVOID pvArg5)
+{
+ if (!pfunc) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+
+ if (_jobQueueAdd(&_G_am335xTxNetJobQ, pfunc, pvArg0, pvArg1, pvArg2, pvArg3, pvArg4, pvArg5)) {
+ _ErrorHandle(ERROR_EXCE_LOST);
+ return (PX_ERROR);
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: _NetJobThread
+** 功能描述: 网络工作队列处理线程
+** 输 入 : NONE
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xTxNetJobThread (VOID)
+{
+ for (;;) {
+ _jobQueueExec(&_G_am335xTxNetJobQ, LW_OPTION_WAIT_INFINITE);
+ }
+}
+/*********************************************************************************************************
** 函数名称: __am335xCpswRxJob
** 功能描述: CPSW 接收工作
** 输 入 : ulVector 中断向量
@@ -110,7 +202,7 @@ static irqreturn_t __am335xCpswRxIsr (PVOID pvArg, ULONG ulVector)
{
API_InterVectorDisable(ulVector);
- netJobAdd((VOIDFUNCPTR)__am335xCpswRxJob, (PVOID)ulVector, 0, 0, 0, 0, 0);
+ API_NetJobAdd((VOIDFUNCPTR)__am335xCpswRxJob, (PVOID)ulVector, 0, 0, 0, 0, 0);
return (LW_IRQ_HANDLED_DISV);
}
@@ -127,7 +219,7 @@ static irqreturn_t __am335xCpswTxIsr (PVOID pvArg, ULONG ulVector)
{
API_InterVectorDisable(ulVector);
- netJobAdd((VOIDFUNCPTR)__am335xCpswTxJob, (PVOID)ulVector, 0, 0, 0, 0, 0);
+ __am335xTxNetJobAdd((VOIDFUNCPTR)__am335xCpswTxJob, (PVOID)ulVector, 0, 0, 0, 0, 0);
return (LW_IRQ_HANDLED_DISV);
}
@@ -172,6 +264,12 @@ static VOID __am335xCpswLinkStatusCheck (UINT uiInstNum, UINT uiSlavePortNum)
if (cpswif_link_status(uiInstNum, uiSlavePortNum)) {
+ API_TimeMSleep(100);
+
+ if (!cpswif_link_status(uiInstNum, uiSlavePortNum)) {
+ return;
+ }
+
if (!(pCpswPortIf->flags & NETIF_FLAG_LINK_UP)) {
if (ERR_OK == cpswif_autoneg_config(uiInstNum, uiSlavePortNum)) {
@@ -193,6 +291,12 @@ static VOID __am335xCpswLinkStatusCheck (UINT uiInstNum, UINT uiSlavePortNum)
}
}
} else {
+ API_TimeMSleep(100);
+
+ if (cpswif_link_status(uiInstNum, uiSlavePortNum)) {
+ return;
+ }
+
if (pCpswPortIf->flags & NETIF_FLAG_LINK_UP) {
pCpswPortIf->flags &= ~NETIF_FLAG_LINK_UP;
@@ -227,7 +331,7 @@ static PVOID __am335xCpswLinkStatusCheckThread (PVOID pvArg)
while (1) {
__am335xCpswLinkStatusCheck(0, uiSlavePortNum);
- API_TimeSleep(LW_OPTION_WAIT_A_SECOND / 4);
+ API_TimeMSleep(250);
}
return (LW_NULL);
@@ -443,6 +547,8 @@ INT arm335xCpswInit (VOID)
if (!pCpswControler->CPSWC_bIsInit) {
+ __am335xTxNetJobqueueInit();
+
am335xEnableModule(am335xModuleIdGet("CPGMAC0"));
@@ -462,6 +568,7 @@ INT arm335xCpswInit (VOID)
goto __error_handle;
}
+#if BSP_CFG_CPSW_TX_DMA_PBUF == 0
pCpswControler->CPSWC_ulCpswCppiRamVirtAddrBase =
pCpswControler->CPSWC_ulCpswCppiRamPhyAddrBase;
if (API_VmmMap((PVOID)pCpswControler->CPSWC_ulCpswCppiRamVirtAddrBase,
@@ -471,6 +578,17 @@ INT arm335xCpswInit (VOID)
printk(KERN_ERR "arm335xCpswInit(): failed to remap!\n");
goto __error_handle;
}
+#else
+ pCpswControler->CPSWC_stCpswCppiRamPhyAddrSize = 20 * 1024;
+ pCpswControler->CPSWC_ulCpswCppiRamPhyAddrBase = (addr_t)
+ API_VmmDmaAllocAlign(pCpswControler->CPSWC_stCpswCppiRamPhyAddrSize, 8);
+ if (!pCpswControler->CPSWC_ulCpswCppiRamPhyAddrBase) {
+ printk(KERN_ERR "arm335xCpswInit(): failed to alloc cppi ram!\n");
+ goto __error_handle;
+ }
+ pCpswControler->CPSWC_ulCpswCppiRamVirtAddrBase =
+ pCpswControler->CPSWC_ulCpswCppiRamPhyAddrBase;
+#endif
pCpswControler->CPSWC_ulCpswWrVirtAddrBase =
pCpswControler->CPSWC_ulCpswMidoVirtAddrBase +
@@ -564,7 +682,12 @@ INT arm335xCpswInit (VOID)
__error_handle:
if (pCpswControler->CPSWC_ulCpswCppiRamVirtAddrBase) {
+#if BSP_CFG_CPSW_TX_DMA_PBUF == 0
API_VmmIoUnmap((PVOID)pCpswControler->CPSWC_ulCpswCppiRamVirtAddrBase);
+#else
+ API_VmmDmaFree((PVOID)pCpswControler->CPSWC_ulCpswCppiRamPhyAddrBase);
+ pCpswControler->CPSWC_ulCpswCppiRamPhyAddrBase = 0;
+#endif
pCpswControler->CPSWC_ulCpswCppiRamVirtAddrBase = 0;
}
diff --git a/SylixOS/driver/netif/cpswif.c b/SylixOS/driver/netif/cpswif.c
index 13ee7cb..b8aaeb5 100644
--- a/SylixOS/driver/netif/cpswif.c
+++ b/SylixOS/driver/netif/cpswif.c
@@ -93,6 +93,11 @@
#ifndef SIZE_CPPI_RAM
#define SIZE_CPPI_RAM 0x2000
#endif
+
+#ifdef SYLIXOS
+#undef SIZE_CPPI_RAM
+#define SIZE_CPPI_RAM (cpswinst->cppi_ram_size)
+#endif
#define PORT_1 0x0
#define PORT_2 0x1
@@ -287,12 +292,66 @@ struct cpswinst{
struct txch txch;
struct rxch rxch;
- LW_HANDLE txlock;
+#ifdef SYLIXOS
+ LW_HANDLE txlock;
+ u32_t cppi_ram_size;
+#if BSP_CFG_CPSW_TX_DMA_PBUF > 0
+ LW_OBJECT_HANDLE tx_pbuf_partition;
+ PVOID tx_pbuf_pool;
+#endif
+#endif
}cpswinst;
/* Defining set of CPSW base addresses for all the instances */
static struct cpswinst cpsw_inst_data[MAX_CPSW_INST];
+#ifdef SYLIXOS
+#if BSP_CFG_CPSW_TX_DMA_PBUF > 0
+
+#define __CPSW_TX_PBUF_SIZE (PBUF_LEN_MAX + SIZEOF_STRUCT_PBUF)
+#define __CPSW_TX_PBUF_COUNT ((SIZE_CPPI_RAM >> 1) / sizeof(cpdma_tx_bd))
+
+static void dma_pbuf_init(struct cpswinst *cpswinst)
+{
+ cpswinst->tx_pbuf_pool = API_VmmDmaAllocAlign(__CPSW_TX_PBUF_COUNT * __CPSW_TX_PBUF_SIZE, 8);
+
+ cpswinst->tx_pbuf_partition = API_PartitionCreate("cpsw_tx_part",
+ cpswinst->tx_pbuf_pool,
+ __CPSW_TX_PBUF_COUNT,
+ __CPSW_TX_PBUF_SIZE,
+ LW_OPTION_OBJECT_GLOBAL,
+ LW_NULL);
+}
+
+static struct pbuf *dma_pbuf_alloc(struct cpswinst *cpswinst, pbuf_layer l, u16_t length, pbuf_type type)
+{
+ struct pbuf *p;
+
+ p = API_PartitionGet(cpswinst->tx_pbuf_partition);
+ if (p) {
+ bzero(p, sizeof(*p));
+
+ p->len = length;
+ p->tot_len = length;
+ p->type = type;
+ p->ref = 1;
+ p->payload = ((UCHAR *)p) + SIZEOF_STRUCT_PBUF;
+ }
+ return (p);
+}
+
+static u8_t dma_pbuf_free(struct cpswinst *cpswinst, struct pbuf *p)
+{
+ if (p && p->ref) {
+ if (--p->ref == 0) {
+ API_PartitionPut(cpswinst->tx_pbuf_partition, p);
+ }
+ }
+ return (0);
+}
+#endif
+#endif
+
/**
* Function to setup the instance parameters inside the interface
* @param cpswif The interface structure pointer
@@ -329,8 +388,14 @@ cpswif_inst_config(struct cpswportif *cpswif) {
#endif
#ifdef SYLIXOS
+ cpswinst->cppi_ram_size = CPSW0_CPPI_RAM_SIZE;
+
cpswinst->txlock = API_SemaphoreBCreate("cpsw_txlock", 1,
LW_OPTION_OBJECT_GLOBAL, LW_NULL);
+
+#if BSP_CFG_CPSW_TX_DMA_PBUF > 0
+ dma_pbuf_init(cpswinst);
+#endif
#endif
}
}
@@ -1697,8 +1762,10 @@ cpswif_transmit(struct netif *netif, struct pbuf *pbuf) {
* Make sure that the payload is written to memory. Clean
* the portion of cache to make it coherent with the memory.
*/
+#if defined(SYLIXOS) && (BSP_CFG_CPSW_TX_DMA_PBUF == 0)
CacheDataCleanBuff((u32_t)(q->payload), (u32_t)(q->len));
#endif
+#endif
/* Intialize the buffer pointer and length */
curr_bd->bufptr = (u32_t)(q->payload);
curr_bd->bufoff_len = (q->len) & CPDMA_BD_LEN_MASK;
@@ -1780,7 +1847,15 @@ cpswif_output(struct netif *netif, struct pbuf *p) {
#endif
len = (p->tot_len < MIN_PKT_LEN) ? MIN_PKT_LEN : p->tot_len;
+#if defined(SYLIXOS) && (BSP_CFG_CPSW_TX_DMA_PBUF > 0)
+ struct cpswportif *cpswif = netif->state;
+ u32_t inst_num = cpswif->inst_num;
+ struct cpswinst *cpswinst = &cpsw_inst_data[inst_num];
+
+ q = dma_pbuf_alloc(cpswinst, PBUF_RAW, len, PBUF_POOL);
+#else
q = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+#endif
if (!q) {
return ERR_MEM;
}
@@ -1814,7 +1889,11 @@ cpswif_output(struct netif *netif, struct pbuf *p) {
#ifdef SYLIXOS
if (stat != ERR_OK) {
+#if BSP_CFG_CPSW_TX_DMA_PBUF > 0
+ dma_pbuf_free(cpswinst, p);
+#else
pbuf_free(p);
+#endif
}
#endif
@@ -2438,7 +2517,11 @@ cpswif_tx_inthandler(u32_t inst_num, struct netif * netif_arr) {
snmp_inc_ifoutucastpkts(netif_arr + if_num);
#endif
+#if defined(SYLIXOS) && (BSP_CFG_CPSW_TX_DMA_PBUF > 0)
+ dma_pbuf_free(cpswinst, (struct pbuf *)curr_bd->pbuf);
+#else
pbuf_free((struct pbuf *)curr_bd->pbuf);
+#endif
LINK_STATS_INC(link.xmit);
send_head = txch->send_head;
diff --git a/SylixOS/driver/netif/cpswif.h b/SylixOS/driver/netif/cpswif.h
index ec0cb4a..0a272dc 100644
--- a/SylixOS/driver/netif/cpswif.h
+++ b/SylixOS/driver/netif/cpswif.h
@@ -120,6 +120,7 @@ extern __AM335X_CPSW_CONTROLER _G_am335xCpswControlers[MAX_CPSW_INST];
#define CPSW0_SLIVER_1_REGS _G_am335xCpswControlers[0].CPSWC_ulCpswSliver1VirtAddrBase
#define CPSW0_PORT_2_REGS _G_am335xCpswControlers[0].CPSWC_ulCpswPort2VirtAddrBase
#define CPSW0_SLIVER_2_REGS _G_am335xCpswControlers[0].CPSWC_ulCpswSliver2VirtAddrBase
+#define CPSW0_CPPI_RAM_SIZE _G_am335xCpswControlers[0].CPSWC_stCpswCppiRamPhyAddrSize
#endif
#ifdef evmAM335x