Update to SDK_2.6.25-RC70
cp -prf * ../prism/
cd ../prism
git add -Af .
git commit
Change-Id: I5b34d94e309432c90ab4a7d6c63def4683ac6737
diff --git a/arch/arm/plat-feroceon/Kconfig b/arch/arm/plat-feroceon/Kconfig
index 27399df..a99448e 100755
--- a/arch/arm/plat-feroceon/Kconfig
+++ b/arch/arm/plat-feroceon/Kconfig
@@ -449,10 +449,28 @@
---help---
Select printk buffer chunk granularity.
+choice
+ prompt "DRAM Access Configuration for 88F6601 SoC"
+ default MV_DRAM_DEFAULT_ACCESS_CFG
+
+config MV_DRAM_DEFAULT_ACCESS_CFG
+ bool "Default DRAM access configuration(by bootloader)"
+ ---help---
+ Choosing this option keeps bootloader DRAM access configuration.
+
+config MV_DRAM_FASTPATH_ACCESS_CFG
+ bool "DRAM fast-path access configuration"
+ ---help---
+ Choosing this option will enable DRAM fast-path access configuration.
+
+config MV_DRAM_XBAR_ACCESS_CFG
+ bool "DRAM XBAR access configuration"
+ ---help---
+ Choosing this option will enable DRAM XBAR access configuration.
+
+endchoice
endmenu
endif
-
-
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/Kconfig b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/Kconfig
index 401c3b7..12c6a42 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/Kconfig
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/Kconfig
@@ -2,15 +2,25 @@
depends on MV_INCLUDE_CUST
config MV_CUST
- bool "Support for Marvell Customer Driver"
- default y
- ---help---
+ bool "Support for Marvell Customer Driver"
+ default y
+ ---help---
config MV_CUST_IGMP_HANDLE
bool "Enable MV_CUST IGMP handling"
default y
---help---
+config MV_CUST_MLD_HANDLE
+ bool "Enable MV_CUST MLD handling"
+ default y
+ ---help---
+
+config MV_CUST_LPBK_DETECT_HANDLE
+ bool "Enable MV_CUST UNI loopback detect handling"
+ default y
+ ---help---
+
config MV_CUST_UDP_SAMPLE_HANDLE
bool "Enable MV_CUST sample UDP handling"
default n
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.c
index 2f78724..39f93ac 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.c
@@ -133,7 +133,8 @@
mv_cust_ioctl_omci_set_t cust_omci_set;
mv_cust_ioctl_llid_set_t cust_llid_set;
mv_cust_ioctl_flow_map_t cust_flow_map;
- mv_cust_ioctl_dscp_map_t cust_dscp_map;
+ mv_cust_ioctl_dscp_map_t cust_dscp_map;
+ mv_cust_ioctl_app_etype_t cust_app_etype;
int enable;
int rc;
@@ -165,7 +166,7 @@
MVCUST_ERR_PRINT("copy_from_user failed\n");
goto ioctlErr;
}
- mv_cust_omci_enable(enable);
+ mv_cust_app_flag_set(MV_CUST_APP_TYPE_OMCI, enable);
ret = 0;
break;
@@ -176,7 +177,7 @@
MVCUST_ERR_PRINT("copy_from_user failed\n");
goto ioctlErr;
}
- mv_cust_eoam_enable(enable);
+ mv_cust_app_flag_set(MV_CUST_APP_TYPE_OAM, enable);
ret = 0;
break;
@@ -269,6 +270,17 @@
}
break;
+ case MV_CUST_IOCTL_APP_ETH_TYPE_SET:
+ if(copy_from_user(&cust_app_etype, (mv_cust_ioctl_app_etype_t *)arg, sizeof(mv_cust_ioctl_app_etype_t)))
+ {
+ MVCUST_ERR_PRINT("copy_from_user failed\n");
+ goto ioctlErr;
+ }
+
+ mv_cust_app_etype_set(cust_app_etype.app_type, cust_app_etype.eth_type);\
+ ret = 0;
+ break;
+
default:
ret = -EINVAL;
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.h
index ee49477..e42503c 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_dev.h
@@ -63,13 +63,6 @@
int mvcust_sysfs_init (void);
void mvcust_sysfs_delete (void);
-void mv_cust_omci_print (void);
-void mv_cust_eoam_print (void);
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-void mv_cust_igmp_print (void);
-#endif
-void mv_cust_loopdet_print (void);
-
#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
void mv_cust_udp_spec_print_all (void);
#endif
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.c
index a50854c..97733e9 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.c
@@ -57,6 +57,9 @@
static uint32_t gs_mv_cust_trace_flag = 0;
+/* Defined to support T-CONT state */
+static bool gs_tcont_state[CPH_MAX_TCONT_NUM];
+
/******************************************************************************
* External Declarations
@@ -197,7 +200,7 @@
dir = cust_flow->dir;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==%s: vid[%d], pbits[%d], mod_vid[%d], mod_pbits[%d], T-CONT[%d], SWF queue[%d], HWF queue[%d], GEM port[%d], dir[%d]\n\r",
__FUNCTION__, vid, pbits, mod_vid, mod_pbits,
((pkt_fwd!= NULL)? pkt_fwd->trg_port:0),
@@ -308,7 +311,7 @@
}
/* In case to disable packet forwarding */
else {
- /* CLear forwarding information */
+ /* Clear forwarding information */
pPbitsMap->pkt_fwd[pbits].trg_port = 0;
pPbitsMap->pkt_fwd[pbits].trg_queue = 0;
pPbitsMap->pkt_fwd[pbits].trg_hwf_queue = 0;
@@ -381,7 +384,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT== %s:\n\r",__FUNCTION__);
}
@@ -409,7 +412,7 @@
int mv_cust_dscp_map_set(mv_cust_dscp_pbits_t *dscp_map)
{
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==%s: in_use[%d]\n\r", __FUNCTION__,
((dscp_map!= NULL)? dscp_map->in_use:0));
}
@@ -432,7 +435,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT== %s:\n\r",__FUNCTION__);
}
@@ -464,7 +467,7 @@
mv_cust_pbits_map_t *pPbitsMap = NULL;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==: vid[%d],pbits[%d]\n\r", vid, pbits);
}
@@ -490,7 +493,7 @@
pVidEntry = &gs_vid_index_table[dir].pbits_map_index[vid];
if (*pVidEntry >= MV_CUST_MAX_PBITS_MAP_TABLE_SIZE) {
- MVCUST_TRACE_PRINT(KERN_INFO "%s, pVidEntry[%d], does not need to delete \n\r",__FUNCTION__, *pVidEntry);
+ MVCUST_TRACE_PRINT(KERN_INFO,"%s, pVidEntry[%d], does not need to delete \n\r",__FUNCTION__, *pVidEntry);
return MV_CUST_OK;
}
@@ -512,7 +515,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==:\n\r");
}
@@ -540,7 +543,7 @@
int mv_cust_dscp_map_del(void)
{
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==\n\r");
}
@@ -551,7 +554,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==\n\r");
}
@@ -581,7 +584,7 @@
uint32_t pbits_index = 0;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==\n\r");
}
@@ -597,7 +600,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==\n\r");
}
@@ -641,7 +644,7 @@
pkt_fwd = &cust_flow->pkt_frwd;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==: vid[%d], pbits[%d], dir[%d]\n\r", vid, pbits, dir);
}
@@ -675,7 +678,7 @@
pkt_fwd->in_use = 0;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==\n\r");
}
@@ -691,17 +694,20 @@
pPktFrwd = &pPbitsMap->pkt_fwd[index];
/* If specific flow mapping rule exists */
- if (pPktFrwd->in_use != 0) {
+ if (pPktFrwd->in_use != 0) {
pkt_fwd->trg_port = pPktFrwd->trg_port;
- pkt_fwd->trg_queue = pPktFrwd->trg_queue;
+ if (false == mv_cust_get_tcont_state(pPktFrwd->trg_port))
+ pkt_fwd->trg_queue = CPH_INVALID_TRGT_QUEUE;
+ else
+ pkt_fwd->trg_queue = pPktFrwd->trg_queue;
pkt_fwd->trg_hwf_queue = pPktFrwd->trg_hwf_queue;
pkt_fwd->gem_port = pPktFrwd->gem_port;
cust_flow->mod_vid = pPbitsMap->mod_vid[index];
- cust_flow->mod_pbits = pPbitsMap->mod_pbits[index];
+ cust_flow->mod_pbits = pPbitsMap->mod_pbits[index];
pkt_fwd->in_use = 1;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"trg_port(%d), trg_queue(%d) trg_hwf_queue(%d) gem_port(%d), mod_vid(%d), mod_pbits(%d)\n\r",
cust_flow->pkt_frwd.trg_port, cust_flow->pkt_frwd.trg_queue, cust_flow->pkt_frwd.trg_hwf_queue,
cust_flow->pkt_frwd.gem_port, cust_flow->mod_vid, cust_flow->mod_pbits);
@@ -714,17 +720,20 @@
pPktFrwd = &pPbitsMap->pkt_fwd[index];
/* If default flow mapping rule exists */
- if (pPktFrwd->in_use != 0) {
+ if (pPktFrwd->in_use != 0) {
pkt_fwd->trg_port = pPktFrwd->trg_port;
- pkt_fwd->trg_queue = pPktFrwd->trg_queue;
+ if (false == mv_cust_get_tcont_state(pPktFrwd->trg_port))
+ pkt_fwd->trg_queue = CPH_INVALID_TRGT_QUEUE;
+ else
+ pkt_fwd->trg_queue = pPktFrwd->trg_queue;
pkt_fwd->trg_hwf_queue = pPktFrwd->trg_hwf_queue;
pkt_fwd->gem_port = pPktFrwd->gem_port;
cust_flow->mod_vid = pPbitsMap->mod_vid[index];
- cust_flow->mod_pbits = pPbitsMap->mod_pbits[index];
+ cust_flow->mod_pbits = pPbitsMap->mod_pbits[index];
pkt_fwd->in_use = 1;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"trg_port(%d), trg_queue(%d) trg_hwf_queue(%d) gem_port(%d), mod_vid(%d), mod_pbits(%d)\n\r",
cust_flow->pkt_frwd.trg_port, cust_flow->pkt_frwd.trg_queue, cust_flow->pkt_frwd.trg_hwf_queue,
cust_flow->pkt_frwd.gem_port, cust_flow->mod_vid, cust_flow->mod_pbits);
@@ -735,7 +744,7 @@
pkt_fwd->in_use = 0;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==\n\r");
}
return MV_CUST_FAIL;
@@ -743,7 +752,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==\n\r");
}
@@ -778,7 +787,7 @@
uint32_t dscp = 0;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==ENTER==: dscp[%d] \n\r", dscp);
}
@@ -812,7 +821,7 @@
pVidEntry = &gs_vid_index_table[dir].pbits_map_index[MV_CUST_DEFAULT_UNTAG_RULE];
if (*pVidEntry >= MV_CUST_MAX_PBITS_MAP_TABLE_SIZE) {
- //MVCUST_TRACE_PRINT(KERN_INFO "%s, pVidEntry[%d], does not exist \n\r",__FUNCTION__, *pVidEntry);
+ //MVCUST_TRACE_PRINT(KERN_INFO,"%s, pVidEntry[%d], does not exist \n\r",__FUNCTION__, *pVidEntry);
}
else {
@@ -822,8 +831,11 @@
pPktFrwd = &pPbitsMap->pkt_fwd[pbitsIndex];
if (pPktFrwd->in_use != 0) {
- cust_flow->pkt_frwd.trg_port = pPktFrwd->trg_port;
- cust_flow->pkt_frwd.trg_queue = pPktFrwd->trg_queue;
+ cust_flow->pkt_frwd.trg_port = pPktFrwd->trg_port;
+ if (false == mv_cust_get_tcont_state(pPktFrwd->trg_port))
+ cust_flow->pkt_frwd.trg_queue = CPH_INVALID_TRGT_QUEUE;
+ else
+ cust_flow->pkt_frwd.trg_queue = pPktFrwd->trg_queue;
cust_flow->pkt_frwd.trg_hwf_queue = pPktFrwd->trg_hwf_queue;
cust_flow->pkt_frwd.gem_port = pPktFrwd->gem_port;
cust_flow->mod_vid = pPbitsMap->mod_vid[pbitsIndex];
@@ -831,11 +843,11 @@
cust_flow->pkt_frwd.in_use = 1;
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"trg_port(%d), trg_queue(%d), trg_hwf_queue(%d), gem_port(%d), mod_vid(%d), mod_pbits(%d)\n\r",
cust_flow->pkt_frwd.trg_port, cust_flow->pkt_frwd.trg_queue, cust_flow->pkt_frwd.trg_hwf_queue,
cust_flow->pkt_frwd.gem_port, cust_flow->mod_vid, cust_flow->mod_pbits);
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==:\n\r");
}
@@ -845,7 +857,7 @@
}
if (gs_mv_cust_trace_flag) {
- MVCUST_TRACE_PRINT(KERN_INFO
+ MVCUST_TRACE_PRINT(KERN_INFO,
"==EXIT==:\n\r");
}
@@ -876,7 +888,7 @@
uint32_t index = 0;
uint32_t table_index = 0;
- //MVCUST_TRACE_PRINT(KERN_INFO "==ENTER==\n\r");
+ //MVCUST_TRACE_PRINT(KERN_INFO,"==ENTER==\n\r");
/* Print Valid VID index entries */
printk(KERN_INFO "In Upstream Direction \n----------------------------------\n");
@@ -923,17 +935,15 @@
for (table_index=0; table_index<MV_CUST_MAX_PBITS_MAP_TABLE_SIZE; table_index++) {
if(gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].in_use != 0) {
printk(KERN_INFO "P-bits Flow Mapping Table %d\n----------------------------\n", table_index);
- printk(KERN_INFO "P-bits in_use mod_vid mod_pbits trg_port trg_queue trg_hwf_queue gem_port\n");
+ printk(KERN_INFO "P-bits in_use mod_vid mod_pbits trg_queue trg_hwf_queue \n");
for (index=0; index<MV_CUST_PBITS_MAP_MAX_ENTRY_NUM; index++)
- printk(KERN_INFO "%1.1d %3.3s %4.4d %1.1d %2.2d %2.2d %2.2d %4.4d\n",
+ printk(KERN_INFO "%1.1d %3.3s %4.4d %1.1d %2.2d %2.2d \n",
index,
(gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].pkt_fwd[index].in_use!=0)? "YES":"",
gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].mod_vid[index],
gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].mod_pbits[index],
- gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].pkt_fwd[index].trg_port,
gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].pkt_fwd[index].trg_queue,
- gs_pbits_map_table[MV_CUST_FLOW_DIR_US][table_index].pkt_fwd[index].trg_hwf_queue,
- gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].pkt_fwd[index].gem_port);
+ gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][table_index].pkt_fwd[index].trg_hwf_queue);
}
}
@@ -953,7 +963,7 @@
}
printk(KERN_INFO "\n\n");
- //MVCUST_TRACE_PRINT(KERN_INFO "==EXIT==\n\r");
+ //MVCUST_TRACE_PRINT(KERN_INFO,"==EXIT==\n\r");
return MV_CUST_OK;
}
@@ -977,22 +987,90 @@
*******************************************************************************/
int mv_cust_flow_map_init(void)
{
- uint32_t pbits_index = 0;
+ uint32_t index = 0;
/* Initializes VID index table */
memset((uint8_t *)&gs_vid_index_table, MV_CUST_INVALID_PBITS_TABLE_INDEX, sizeof(gs_vid_index_table));
/* Initializes P-bits mapping tables */
- for (pbits_index=0; pbits_index<MV_CUST_MAX_PBITS_MAP_TABLE_SIZE; pbits_index++) {
- memset((uint8_t *)&gs_pbits_map_table[MV_CUST_FLOW_DIR_US][pbits_index], 0, sizeof(mv_cust_pbits_map_t));
- gs_pbits_map_table[MV_CUST_FLOW_DIR_US][pbits_index].in_use = 0;
- memset((uint8_t *)&gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][pbits_index], 0, sizeof(mv_cust_pbits_map_t));
- gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][pbits_index].in_use = 0;
+ for (index = 0; index < MV_CUST_MAX_PBITS_MAP_TABLE_SIZE; index++) {
+ memset((uint8_t *)&gs_pbits_map_table[MV_CUST_FLOW_DIR_US][index], 0, sizeof(mv_cust_pbits_map_t));
+ gs_pbits_map_table[MV_CUST_FLOW_DIR_US][index].in_use = 0;
+ memset((uint8_t *)&gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][index], 0, sizeof(mv_cust_pbits_map_t));
+ gs_pbits_map_table[MV_CUST_FLOW_DIR_DS][index].in_use = 0;
}
/* Initializes DSCP to P-bits mapping table */
memset((uint8_t *)&gs_dscp_map_table, 0, sizeof(mv_cust_dscp_pbits_t));
gs_dscp_map_table.in_use = 0;
-
+
+ /* Initializes T-CONT state, default value is false */
+ for (index = 0; index < CPH_MAX_TCONT_NUM; index++)
+ gs_tcont_state[index] = false;
+
return MV_CUST_OK;
}
+
+/*******************************************************************************
+**
+** mv_cust_get_tcont_state
+** ___________________________________________________________________________
+**
+** DESCRIPTION: The function get T-CONT state
+**
+** INPUTS:
+** tcont - T-CONT
+**
+** OUTPUTS:
+** None.
+**
+** RETURNS:
+** state - State of T-CONT, enabled or disabled.
+**
+*******************************************************************************/
+bool mv_cust_get_tcont_state(uint32_t tcont)
+{
+ /* Check tcont */
+ if (tcont >= CPH_MAX_TCONT_NUM)
+ {
+ MVCUST_TRACE_PRINT(KERN_ERR,"tcont[%d] is illegal, should be less than [%d]\n", tcont, CPH_MAX_TCONT_NUM);
+ return false;
+ }
+
+ return gs_tcont_state[tcont];
+}
+
+/*******************************************************************************
+**
+** mv_cust_set_tcont_state
+** ___________________________________________________________________________
+**
+** DESCRIPTION: The function sets T-CONT state in mv_cust
+**
+** INPUTS:
+** tcont - T-CONT
+** state - State of T-CONT, enabled or disabled.
+**
+** OUTPUTS:
+** None.
+**
+** RETURNS:
+** On success, the function returns (MV_OK). On error different types are
+** returned according to the case.
+**
+*******************************************************************************/
+MV_STATUS mv_cust_set_tcont_state(uint32_t tcont, bool state)
+{
+ /* Check tcont */
+ if (tcont >= CPH_MAX_TCONT_NUM)
+ {
+ MVCUST_TRACE_PRINT(KERN_ERR,"tcont[%d] is illegal, should be less than [%d]\n", tcont, CPH_MAX_TCONT_NUM);
+ return MV_FAIL;
+ }
+
+ /* Apply t-cont state to mv_cust */
+ gs_tcont_state[tcont] = state;
+
+ return MV_OK;
+}
+EXPORT_SYMBOL(mv_cust_set_tcont_state);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.h
index 5880b9a..787542a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_flow_map.h
@@ -36,17 +36,19 @@
/******************************************************************************
* Data Enum and Structure
******************************************************************************/
-#define MVCUST_TRACE_PRINT(format, ...) printk("%s(%d): "format,__FUNCTION__,__LINE__, ##__VA_ARGS__)
+#define MVCUST_TRACE_PRINT(level, format, ...) printk(level "%s(%d):"format, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define MV_CUST_OK (0)
#define MV_CUST_FAIL (1)
+#define CPH_MAX_TCONT_NUM (8) /* Maximum T-CONT number */
+#define CPH_INVALID_TRGT_QUEUE (0xFF) /* Invalid target queue number */
#define MV_CUST_VID_NOT_CARE_VALUE (4096) /* Does not care for VID */
-#define MV_CUST_PBITS_NOT_CARE_VALUE (8) /* Does not care for P-bits */
-#define MV_CUST_DSCP_NOT_CARE_VALUE (64) /* Does not care for DSCP */
+#define MV_CUST_PBITS_NOT_CARE_VALUE (8) /* Does not care for P-bits */
+#define MV_CUST_DSCP_NOT_CARE_VALUE (64) /* Does not care for DSCP */
-#define MV_CUST_MAX_TRG_PORT_VALUE (2+8-1)/* Maximum target port value, T-CONT7 */
+#define MV_CUST_MAX_TRG_PORT_VALUE (8-1) /* Maximum target port value, T-CONT7 */
#define MV_CUST_MAX_TRG_QUEUE_VALUE (7) /* Maximum target queue value */
#define MV_CUST_MAX_GEM_PORT_VALUE (4095) /* Maximum GEM port value */
@@ -314,5 +316,44 @@
*******************************************************************************/
int mv_cust_flow_map_init(void);
+/*******************************************************************************
+**
+** mv_cust_get_tcont_state
+** ___________________________________________________________________________
+**
+** DESCRIPTION: The function get T-CONT state
+**
+** INPUTS:
+** tcont - T-CONT
+**
+** OUTPUTS:
+** None.
+**
+** RETURNS:
+** state - State of T-CONT, enabled or disabled.
+**
+*******************************************************************************/
+bool mv_cust_get_tcont_state(uint32_t tcont);
+
+/*******************************************************************************
+**
+** mv_cust_set_tcont_state
+** ___________________________________________________________________________
+**
+** DESCRIPTION: The function sets T-CONT state in mv_cust
+**
+** INPUTS:
+** tcont - T-CONT
+** state - State of T-CONT, enabled or disabled.
+**
+** OUTPUTS:
+** None.
+**
+** RETURNS:
+** On success, the function returns (MV_OK). On error different types are
+** returned according to the case.
+**
+*******************************************************************************/
+MV_STATUS mv_cust_set_tcont_state(uint32_t tcont, bool state);
#endif /* __mv_cust_flow_map_h__ */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_mng_if.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_mng_if.h
index 9556bfe..470a81c 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_mng_if.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_mng_if.h
@@ -47,10 +47,7 @@
#define MV_CUST_IOCTL_MAP_RULE_CLEAR _IOW(MV_CUST_IOCTL_MAGIC, 9, unsigned int)
#define MV_CUST_IOCTL_TAG_MAP_RULE_GET _IOR(MV_CUST_IOCTL_MAGIC, 10, unsigned int)
#define MV_CUST_IOCTL_UNTAG_MAP_RULE_GET _IOR(MV_CUST_IOCTL_MAGIC, 11, unsigned int)
-
-
-
-
+#define MV_CUST_IOCTL_APP_ETH_TYPE_SET _IOW(MV_CUST_IOCTL_MAGIC, 12, unsigned int)
/* Enums
------------------------------------------------------------------------------*/
@@ -77,6 +74,12 @@
mv_cust_dscp_pbits_t dscp_map;
} mv_cust_ioctl_dscp_map_t;
+typedef struct
+{
+ mv_cust_app_type_e app_type;
+ uint16_t eth_type;
+} mv_cust_ioctl_app_etype_t;
+
/* MV_CUST Char Device Structure */
/* ========================= */
typedef struct
@@ -85,6 +88,7 @@
mv_cust_ioctl_llid_set_t mv_cust_ioctl_llid_set;
mv_cust_ioctl_flow_map_t mv_cust_ioctl_flow_map;
mv_cust_ioctl_dscp_map_t mv_cust_ioctl_dscp_map;
+ mv_cust_ioctl_app_etype_t mv_cust_ioctl_app_etype;
struct cdev cdev;
} mv_cust_cdev_t;
@@ -105,23 +109,3 @@
------------------------------------------------------------------------------*/
#endif /* _MV_CUST_MNG_IF_H_ */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.c
index 7c9055b..c57b076 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.c
@@ -39,6 +39,9 @@
#include <linux/if_vlan.h>
#include <net/ip.h>
#include <net/ipv6.h>
+#ifdef CONFIG_MV_CUST_MLD_HANDLE
+#include <linux/icmpv6.h>
+#endif
#include <mvOs.h>
#include <ctrlEnv/mvCtrlEnvLib.h>
@@ -48,167 +51,179 @@
#include "mv_cust_flow_map.h"
#include "mv_cust_mng_if.h"
+/*----------------------------------------------------------------------------*/
+/* External declaration */
+/*----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------*/
+/* Global static definition */
+/*----------------------------------------------------------------------------*/
/* YUVAL - update to pnc define */
#define MH_GEM_PORT_MASK (0x0FFF)
#define MH_EPON_OAM_TYPE (0x8809)
#define ETY_IPV4 (0x0800)
#define IPV4_PROTO_OFFSET (9)
+#define MV_CUST_SWF_TX_QUEUE (6)
#define CUST_TBL_NUM_ENTRIES(a) (sizeof(a)/sizeof(a[0]))
/*Static Declarations */
-static int mv_eth_ports_num = 0;
+static int mv_eth_ports_num = 0;
+static int mv_cust_debug_code = 0;
+
static int mv_cust_omci_gemport = 0;
-
-static int mv_cust_omci_valid = 0;
-static int mv_cust_eoam_valid = 0;
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-static int mv_cust_igmp_detect = 1;
-static uint16_t mv_cust_igmp_type;
-static struct mv_eth_tx_spec igmp_tx_spec = {0, MV_ETH_F_MH, 0, 0};
-#endif
-static int mv_cust_port_loopback_detect = 1;
-static int mv_cust_debug_code = 0;
-static int mv_cust_xpon_oam_rx_gh = 0;
-
-static uint16_t mv_cust_xpon_oam_type;
-static uint16_t mv_cust_loopdet_type;
+static int mv_cust_omci_rx_gh = 0;
+static int mv_cust_oam_rx_gh = 0;
/* Protocol definitions */
-static struct mv_eth_tx_spec omci_mgmt_tx_spec = {0};
+static struct mv_eth_tx_spec omci_mgmt_tx_spec = {0, 0, 0, MV_CUST_SWF_TX_QUEUE};
static struct mv_eoam_llid_spec epon_mgmt_tx_spec[MV_CUST_NUM_LLID];
+#define EPON_MGMT_ENTRIES CUST_TBL_NUM_ENTRIES(epon_mgmt_tx_spec)
#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
-static struct mv_port_tx_spec port_spec_cfg[CONFIG_MV_ETH_PORTS_NUM];
+static struct mv_port_tx_spec udp_port_spec_cfg[CONFIG_MV_ETH_PORTS_NUM];
+#define PORT_ENTRIES CUST_TBL_NUM_ENTRIES(udp_port_spec_cfg)
#endif
#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
static int mv_cust_flow_map = 0;
-static int mv_cust_flow_map_parse(uint8_t *data, uint16_t *vlan, uint8_t *pbits, uint8_t dir);
-static int mv_cust_flow_map_mod(uint8_t *data, uint16_t vid, uint8_t pbits, uint8_t dir);
#endif
+/* Default Application Ethernet type used for socket and skb */
+#define MV_CUST_ETH_TYPE_IGMP (0xA000)
+#define MV_CUST_ETH_TYPE_MLD (0xAB00)
+#define MV_CUST_ETH_TYPE_LPBK (0xFFFA)
+#define MV_CUST_ETH_TYPE_OAM (0xBABA)
+/* The Ethernet tpye of OAM/OMCI could be same since they will not use at the same time*/
+#define MV_CUST_ETH_TYPE_OMCI (0xBABA)
-#define PORT_ENTRIES CUST_TBL_NUM_ENTRIES(port_spec_cfg)
-#define EPON_MGMT_ENTRIES CUST_TBL_NUM_ENTRIES(epon_mgmt_tx_spec)
-
-
-void mv_cust_omci_print(void)
+/* Global cust configuration*/
+/* Pay attention that the order could be be changed and the entry could not be removed */
+static mv_cust_app_config_t gCustConfig[] =
{
- printk("************* OMCI Configuration *****************\n\n");
- printk("OMCI: valid = %d, gemport = %d, ethtype = 0x%04x, gh_keep = %d\n",
- mv_cust_omci_valid, mv_cust_omci_gemport, ntohs(mv_cust_xpon_oam_type), mv_cust_xpon_oam_rx_gh);
- printk("OMCI: txp = %d, txq = %d, hw_cmd = 0x%08x, flags = 0x%04x on TX \n",
- omci_mgmt_tx_spec.txp, omci_mgmt_tx_spec.txq, omci_mgmt_tx_spec.hw_cmd, omci_mgmt_tx_spec.flags);
- printk("\n");
+ /* Application Type */ /* Enable Flag */ /*Application Eth type*/ /* Application Description*/
+ {MV_CUST_APP_TYPE_IGMP, MV_CUST_APP_DISABLE, MV_CUST_ETH_TYPE_IGMP, "IGMP application"},
+ {MV_CUST_APP_TYPE_MLD, MV_CUST_APP_DISABLE, MV_CUST_ETH_TYPE_MLD, "MLD application"},
+ {MV_CUST_APP_TYPE_LPBK, MV_CUST_APP_DISABLE, MV_CUST_ETH_TYPE_LPBK, "Loopback detection application"},
+ {MV_CUST_APP_TYPE_OAM, MV_CUST_APP_DISABLE, MV_CUST_ETH_TYPE_OAM, "eOAM application"},
+ {MV_CUST_APP_TYPE_OMCI, MV_CUST_APP_DISABLE, MV_CUST_ETH_TYPE_OMCI, "OMCI application"},
+};
+
+/*----------------------------------------------------------------------------*/
+/* Function implementation */
+/*----------------------------------------------------------------------------*/
+
+void mv_cust_debug_info_set(int val)
+{
+ mv_cust_debug_code = val;
+ return;
}
-void mv_cust_eoam_print(void)
+void mv_cust_app_flag_set(mv_cust_app_type_e app_type, uint16_t enable)
{
- int i;
- printk("************* eOAM Configuration *****************\n\n");
- printk("EOAM: valid = %d, ethtype = 0x%04x, gh_keep = %d\n",
- mv_cust_eoam_valid, ntohs(mv_cust_xpon_oam_type), mv_cust_xpon_oam_rx_gh);
- for (i=0;i <(EPON_MGMT_ENTRIES);i++) {
- printk("llid%d: mac=%02x:%02x:%02x:%02x:%02x:%02x, txp=%d, txq=%d, hw_cmd=0x%08x, flags = 0x%04x\n",
- i,
- epon_mgmt_tx_spec[i].llid_mac_address[0],epon_mgmt_tx_spec[i].llid_mac_address[1],
- epon_mgmt_tx_spec[i].llid_mac_address[2],epon_mgmt_tx_spec[i].llid_mac_address[3],
- epon_mgmt_tx_spec[i].llid_mac_address[4],epon_mgmt_tx_spec[i].llid_mac_address[5],
- epon_mgmt_tx_spec[i].tx_spec.txp, epon_mgmt_tx_spec[i].tx_spec.txq,
- epon_mgmt_tx_spec[i].tx_spec.hw_cmd, epon_mgmt_tx_spec[i].tx_spec.flags);
- printk("\n");
+ if (mv_cust_debug_code)
+ printk("%s() In, app_type[%d], enable[%d] \n", __func__, app_type, enable);
+
+ if (app_type > (MV_CUST_APP_TYPE_MAX-1))
+ {
+ printk("%s: illegal application type[%d], allowed max type[%d] \n",
+ __func__, app_type, MV_CUST_APP_TYPE_MAX-1);
+ return;
}
-}
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-void mv_cust_igmp_print(void)
-{
- printk("************* IGMP Configuration *****************\n\n");
- printk("IGMP valid = %d, ethtype = 0x%04x, on RX\n",
- mv_cust_igmp_detect, ntohs(mv_cust_igmp_type));
- printk("IGMP txp = %d, txq = %d, , hw_cmd = 0x%08x on TX\n",
- igmp_tx_spec.txp, igmp_tx_spec.txq, igmp_tx_spec.hw_cmd);
- printk("\n");
-}
-#endif
-
-void mv_cust_loopdet_print(void)
-{
- printk("************* Port Loopback Configuration *****************\n\n");
- printk("Port Loopback valid = %d, ethtype = 0x%04x, on RX\n",
- mv_cust_port_loopback_detect, ntohs(mv_cust_loopdet_type));
-}
-
-
-#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
-int mv_cust_udp_spec_print(int port)
-{
- int i;
- struct eth_port *pp = mv_eth_port_by_id(port);
- struct mv_udp_port_tx_spec *udp_spec;
-
- if (!pp)
- return -ENODEV;
-
- udp_spec = &(port_spec_cfg[port].udp_dst[0]);
-
- printk("\n**** port #%d - TX UDP Dest Port configuration *****\n", port);
- printk("----------------------------------------------------\n");
- printk("ID udp_dst txp txq flags hw_cmd func_add\n");
- for (i = 0; i < sizeof(port_spec_cfg[port].udp_dst)/sizeof(port_spec_cfg[port].udp_dst[0]); i++) {
- if (udp_spec[i].tx_spec.txq != MV_ETH_TXQ_INVALID)
- printk("%2d %04d %d %d 0x%04x 0x%08x 0x%p\n",
- i, ntohs(udp_spec[i].udp_port),
- udp_spec[i].tx_spec.txp, udp_spec[i].tx_spec.txq,
- udp_spec[i].tx_spec.flags, udp_spec[i].tx_spec.hw_cmd,
- udp_spec[i].tx_spec.tx_func);
- }
- printk("-----------------------------------------------------\n");
-
- udp_spec = &(port_spec_cfg[port].udp_src[0]);
-
- printk("**** port #%d - TX UDP Source Port configuration *****\n", port);
- printk("-----------------------------------------------------\n");
- printk("ID udp_src txp txq flags hw_cmd func_add\n");
- for (i = 0; i < sizeof(port_spec_cfg[port].udp_src)/sizeof(port_spec_cfg[port].udp_src[0]); i++) {
- if (udp_spec[i].tx_spec.txq != MV_ETH_TXQ_INVALID)
- printk("%2d %04d %d %d 0x%04x 0x%08x 0x%p\n",
- i, ntohs(udp_spec[i].udp_port),
- udp_spec[i].tx_spec.txp, udp_spec[i].tx_spec.txq,
- udp_spec[i].tx_spec.flags, udp_spec[i].tx_spec.hw_cmd,
- udp_spec[i].tx_spec.tx_func);
- }
- printk("**************************************************************\n");
-
-
- return 0;
-}
-
-void mv_cust_udp_spec_print_all(void)
-{
- int port;
-
- for (port=0;port < CONFIG_MV_ETH_PORTS_NUM ;port++) {
- mv_cust_udp_spec_print(port);
- }
-}
-#endif
-
+ if (app_type == MV_CUST_APP_TYPE_OMCI)
+ {
+ if (enable)
+ {
+ if (gCustConfig[MV_CUST_APP_TYPE_OAM].enable)
+ {
+ MVCUST_ERR_PRINT("EPON is already valid\n");
+ return;
+ }
+ gCustConfig[MV_CUST_APP_TYPE_OMCI].enable = MV_CUST_APP_ENABLE;
#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
-void mv_cust_flow_map_print(void)
-{
- printk("************* Flow Mapping Configuration *****************\n\n");
- printk("FLow mapping valid = %d\n", mv_cust_flow_map);
-}
+ mv_cust_flow_map = 1;
#endif
+ }
+ else
+ {
+ gCustConfig[MV_CUST_APP_TYPE_OMCI].enable = MV_CUST_APP_DISABLE;
+#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
+ mv_cust_flow_map = 0;
+#endif
+ }
+ }
+ else if(app_type == MV_CUST_APP_TYPE_OAM)
+ {
+ if (enable)
+ {
+ if (gCustConfig[MV_CUST_APP_TYPE_OMCI].enable)
+ {
+ MVCUST_ERR_PRINT("GPON is already valid\n");
+ return;
+ }
+ gCustConfig[MV_CUST_APP_TYPE_OAM].enable = MV_CUST_APP_ENABLE;
+#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
+ mv_cust_flow_map = 0;
+#endif
+ }
+ else
+ {
+ gCustConfig[MV_CUST_APP_TYPE_OAM].enable = MV_CUST_APP_DISABLE;
+#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
+ mv_cust_flow_map = 0;
+#endif
+ }
-void mv_cust_omci_hw_cmd_set(uint32_t hw_cmd)
-{
- omci_mgmt_tx_spec.hw_cmd = hw_cmd;
+ }
+ else
+ {
+ if (enable == MV_CUST_APP_ENABLE)
+ gCustConfig[app_type].enable = MV_CUST_APP_ENABLE;
+ else
+ gCustConfig[app_type].enable = MV_CUST_APP_DISABLE;
+ }
+
+ return;
}
-EXPORT_SYMBOL(mv_cust_omci_hw_cmd_set);
+EXPORT_SYMBOL(mv_cust_app_flag_set);
+
+
+void mv_cust_app_etype_set(mv_cust_app_type_e app_type, uint16_t eth_type)
+{
+ if (mv_cust_debug_code)
+ printk("%s() In, app_type[%d], eth_type[%d] \n", __func__, app_type, eth_type);
+
+ if (app_type > (MV_CUST_APP_TYPE_MAX-1))
+ {
+ printk("%s: illegal application type[%d], allowed max type[%d] \n",
+ __func__, app_type, MV_CUST_APP_TYPE_MAX-1);
+ return;
+ }
+
+ gCustConfig[app_type].eth_type = eth_type;
+
+ return;
+}
+EXPORT_SYMBOL(mv_cust_app_etype_set);
+
+
+void mv_cust_rec_skb(int port, struct sk_buff *skb)
+{
+ uint32_t rx_status;
+ struct eth_port *pp;
+
+ rx_status = netif_receive_skb(skb);
+ pp = mv_eth_port_by_id(port);
+ STAT_DBG(if (rx_status) (pp->stats.rx_drop_sw++));
+}
+
+void mv_cust_omci_rx_gh_set(int val)
+{
+ mv_cust_omci_rx_gh = val;
+ return;
+}
int mv_cust_omci_tx_set(int tcont, int txq)
{
@@ -226,6 +241,16 @@
return 0;
}
+void mv_cust_omci_gemport_set(int gemport)
+{
+ mv_cust_omci_gemport = gemport;
+ return;
+}
+
+void mv_cust_omci_hw_cmd_set(uint32_t hw_cmd)
+{
+ omci_mgmt_tx_spec.hw_cmd = hw_cmd;
+}
int mv_cust_omci_set(int tcont, int txq, int gem_port, int keep_rx_mh)
{
@@ -243,14 +268,91 @@
mv_cust_omci_gemport_set(gem_port);
hw_cmd = ((gem_port << 8) | 0x0010);
mv_cust_omci_hw_cmd_set(hw_cmd);
- mv_cust_xpon_oam_rx_gh_set(keep_rx_mh);
+ mv_cust_omci_rx_gh_set(keep_rx_mh);
- mv_cust_omci_enable(1);
+ mv_cust_app_flag_set(MV_CUST_APP_TYPE_OMCI, MV_CUST_APP_ENABLE);
return 0;
}
EXPORT_SYMBOL(mv_cust_omci_set);
+void mv_cust_omci_print(void)
+{
+ printk("************* OMCI Configuration *****************\n\n");
+ printk("OMCI: valid = %d, gemport = %d, ethtype = 0x%04x, gh_keep = %d\n",
+ gCustConfig[MV_CUST_APP_TYPE_OMCI].enable,
+ mv_cust_omci_gemport,
+ ntohs(gCustConfig[MV_CUST_APP_TYPE_OMCI].eth_type),
+ mv_cust_omci_rx_gh);
+ printk("OMCI: txp = %d, txq = %d, hw_cmd = 0x%08x, flags = 0x%04x on TX \n",
+ omci_mgmt_tx_spec.txp, omci_mgmt_tx_spec.txq, omci_mgmt_tx_spec.hw_cmd, omci_mgmt_tx_spec.flags);
+ printk("\n");
+}
+
+static int mv_cust_omci_gem_parse(uint8_t *data)
+{
+ uint16_t gh;
+
+ gh = ntohs(*(uint16_t *)data);
+
+ if(mv_cust_debug_code)
+ printk("%s:gh= 0x(%04x) - mv_cust_omci_gemport= 0x(%04x) \n", __func__, gh, mv_cust_omci_gemport);
+
+ /* Compare GH for omci_gemport */
+ if ( (gh & MH_GEM_PORT_MASK) != mv_cust_omci_gemport ) {
+ if(mv_cust_debug_code)
+ printk("%s: compare GH for OMCI_gemport failed: gh= 0x(%04x) - mv_cust_omci_gemport= 0x(%04x) \n", __func__, gh, mv_cust_omci_gemport);
+ return(0);
+ }
+
+ return(1);
+}
+
+static int mv_cust_omci_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
+{
+ uint32_t rx_bytes;
+
+ if (!mv_cust_omci_gem_parse(skb->data))
+ return 0;
+ if (mv_cust_omci_rx_gh) {
+ rx_bytes = rx_desc->dataSize;
+ }
+ else {
+ skb->data += MV_ETH_MH_SIZE;
+ rx_bytes = rx_desc->dataSize - MV_ETH_MH_SIZE;
+ }
+ skb->tail += rx_bytes;
+ skb->len = rx_bytes;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->protocol = htons(gCustConfig[MV_CUST_APP_TYPE_OMCI].eth_type);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ skb->dev = dev;
+#endif
+ mv_cust_rec_skb(port, skb);
+
+ return 1;
+}
+
+int mv_cust_omci_tx(int port, struct net_device *dev, struct sk_buff *skb,
+ struct mv_eth_tx_spec *tx_spec_out)
+{
+ if ((skb->protocol == htons(gCustConfig[MV_CUST_APP_TYPE_OMCI].eth_type))
+ && (MV_CUST_APP_ENABLE == gCustConfig[MV_CUST_APP_TYPE_OMCI].enable)
+ && (port == MV_PON_PORT_ID)) {
+ memcpy (tx_spec_out, &omci_mgmt_tx_spec, sizeof(struct mv_eth_tx_spec));
+ if(mv_cust_debug_code)
+ printk("%s", __func__);
+ return 1;
+ }
+ return 0;
+}
+
+
+void mv_cust_oam_rx_gh_set(int val)
+{
+ mv_cust_oam_rx_gh = val;
+ return;
+}
int mv_cust_eoam_llid_set(int llid, uint8_t *llid_mac, int txq)
{
@@ -272,31 +374,6 @@
}
EXPORT_SYMBOL(mv_cust_eoam_llid_set);
-
-MV_STATUS mv_cust_omci_enable(int enable)
-{
- if (enable) {
-
- if (mv_cust_eoam_valid) {
- MVCUST_ERR_PRINT("EPON is already valid\n");
- return MV_ERROR;
- }
- mv_cust_omci_valid = 1;
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
- mv_cust_flow_map = 1;
-#endif
- }
- else {
- mv_cust_omci_valid = 0;
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
- mv_cust_flow_map = 0;
-#endif
- }
-
- return MV_OK;
-}
-
-
void mv_cust_eoam_init(void)
{
int i;
@@ -312,63 +389,407 @@
}
/* In Rx, keep the MH for EOAM */
- mv_cust_xpon_oam_rx_gh_set(1);
+ mv_cust_oam_rx_gh_set(1);
return ;
}
-EXPORT_SYMBOL(mv_cust_eoam_init);
-
-MV_STATUS mv_cust_eoam_enable(int enable)
+void mv_cust_eoam_print(void)
{
+ int i;
+ printk("************* eOAM Configuration *****************\n\n");
+ printk("EOAM: valid = %d, ethtype = 0x%04x, gh_keep = %d\n",
+ gCustConfig[MV_CUST_APP_TYPE_OAM].enable,
+ ntohs(gCustConfig[MV_CUST_APP_TYPE_OAM].eth_type),
+ mv_cust_oam_rx_gh);
+ for (i=0;i <(EPON_MGMT_ENTRIES);i++) {
+ printk("llid%d: mac=%02x:%02x:%02x:%02x:%02x:%02x, txp=%d, txq=%d, hw_cmd=0x%08x, flags = 0x%04x\n",
+ i,
+ epon_mgmt_tx_spec[i].llid_mac_address[0],epon_mgmt_tx_spec[i].llid_mac_address[1],
+ epon_mgmt_tx_spec[i].llid_mac_address[2],epon_mgmt_tx_spec[i].llid_mac_address[3],
+ epon_mgmt_tx_spec[i].llid_mac_address[4],epon_mgmt_tx_spec[i].llid_mac_address[5],
+ epon_mgmt_tx_spec[i].tx_spec.txp, epon_mgmt_tx_spec[i].tx_spec.txq,
+ epon_mgmt_tx_spec[i].tx_spec.hw_cmd, epon_mgmt_tx_spec[i].tx_spec.flags);
+ printk("\n");
+ }
+}
+
+static int mv_cust_eoam_type_parse(uint8_t *data)
+{
+ uint16_t ety;
+
+ ety = ntohs(*(uint16_t *)(data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN));
if(mv_cust_debug_code)
- printk("%s: enable = %d\n", __func__, enable);
+ printk("%s: ety 0x(%04x)\n", __func__, ety);
- if (enable) {
- if (mv_cust_omci_valid) {
- MVCUST_ERR_PRINT("OMCI is already valid\n");
- return MV_ERROR;
- }
- mv_cust_eoam_valid = 1;
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
- mv_cust_flow_map = 0;
-#endif
+ /* Compare EPON OAM ether_type */
+ if (ety == MH_EPON_OAM_TYPE)
+ return(1);
+
+ return(0);
+}
+
+static int mv_cust_epon_oam_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
+{
+ uint32_t rx_bytes;
+
+ if (!mv_cust_eoam_type_parse(skb->data))
+ return 0;
+
+ if (mv_cust_oam_rx_gh) {
+ rx_bytes = rx_desc->dataSize;
}
else {
- mv_cust_eoam_valid = 0;
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
- mv_cust_flow_map = 0;
-#endif
+ skb->data += MV_ETH_MH_SIZE;
+ rx_bytes = rx_desc->dataSize - MV_ETH_MH_SIZE;
}
- return MV_OK;
-}
-EXPORT_SYMBOL(mv_cust_eoam_enable);
+ skb->tail += rx_bytes;
+ skb->len = rx_bytes;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->protocol = htons(gCustConfig[MV_CUST_APP_TYPE_OAM].eth_type);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ skb->dev = dev;
+#endif
+ mv_cust_rec_skb(port, skb);
-#if 0
-MV_STATUS mv_cust_eoam_tx_func_set(void (*tx_func) (uint8_t *data, int size, struct mv_eth_tx_spec *tx_spec))
+ return 1;
+}
+
+int mv_cust_eoam_tx(int port, struct net_device *dev, struct sk_buff *skb,
+ struct mv_eth_tx_spec *tx_spec_out)
{
+ int mac_match, i;
- if (mv_cust_debug_code)
- printk("%s: \n", __func__);
-
- /* System cannot be OMCI_valid */
- if (mv_cust_omci_valid) {
- MVCUST_ERR_PRINT("EPON is valid\n");
- return MV_ERROR;
+ if ((skb->protocol == htons(gCustConfig[MV_CUST_APP_TYPE_OAM].eth_type))
+ && (MV_CUST_APP_ENABLE == gCustConfig[MV_CUST_APP_TYPE_OAM].enable)
+ && port == MV_PON_PORT_ID) {
+ /* Lookup MAC Address */
+ for (i=0; i<(EPON_MGMT_ENTRIES);i++) {
+ mac_match = memcmp((void *) &(epon_mgmt_tx_spec[i].llid_mac_address[0]),
+ (void *)(skb->data + /*MV_ETH_MH_SIZE +*/ ETH_ALEN),
+ ETH_ALEN);
+ if (!mac_match) {
+ memcpy (tx_spec_out, &epon_mgmt_tx_spec[i].tx_spec, sizeof(struct mv_eth_tx_spec));
+ if(mv_cust_debug_code)
+ printk("%s, llid = %d", __func__, i);
+ return 1;
+ }
+ }
+ /* Source MAC Address not found */
+ if(mv_cust_debug_code) {
+ printk("(%s)Input Packet first bytes:\n", __func__);
+ for (i=0;i<24;i++) {
+ if (i%8== 0)
+ printk("\n");
+ printk ("%02x ", *(skb->data + i));
+ }
+ }
}
- /*Pointer cannot be null */
- if (!tx_func) {
- MVCUST_ERR_PRINT("NULL pointer\n");
- }
-
- xpon_mgmt_tx_spec.tx_func = tx_func;
-
- return MV_OK;
+ return 0;
}
-EXPORT_SYMBOL(mv_cust_eoam_tx_func_set);
+
+
+#ifdef CONFIG_MV_CUST_IGMP_HANDLE
+void mv_cust_igmp_print(void)
+{
+ printk("************* IGMP Configuration *****************\n\n");
+ printk("IGMP valid = %d, ethtype = 0x%04x \n",
+ gCustConfig[MV_CUST_APP_TYPE_IGMP].enable,
+ gCustConfig[MV_CUST_APP_TYPE_IGMP].eth_type);
+ printk("IGMP default txq = %d\n",MV_CUST_SWF_TX_QUEUE);
+ printk("\n");
+}
+
+static int mv_cust_igmp_parse(uint8_t *data)
+{
+ uint16_t ety;
+ uint8_t proto;
+ uint8_t *fieldp = data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN;
+
+ /* Loop through VLAN tags */
+ ety = ntohs(*(uint16_t *)fieldp);
+ while (ety == 0x8100 || ety == 0x9100 || ety == 0x88A8) {
+ fieldp+= VLAN_HLEN;
+ ety = ntohs(*(uint16_t *)fieldp);
+ }
+
+ if(mv_cust_debug_code)
+ printk("%s:ety 0x(%04x)\n", __func__, ety);
+
+ if (ety == ETY_IPV4) {
+ fieldp+= 2;
+ fieldp+= IPV4_PROTO_OFFSET;
+ proto = *fieldp;
+ if (mv_cust_debug_code)
+ printk("%s:proto 0x(%02x)\n", __func__, proto);
+
+ if (proto == IPPROTO_IGMP)
+ return(1);
+ }
+
+ return(0);
+}
+
+static int mv_cust_igmp_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
+{
+ uint32_t rx_bytes;
+
+ if (!mv_cust_igmp_parse(skb->data))
+ return 0;
+
+ /* To Indicate the source GMAC */
+ skb->data[0] = port;
+
+ rx_bytes = rx_desc->dataSize;
+
+ skb->tail += rx_bytes;
+ skb->len = rx_bytes;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->protocol = htons(gCustConfig[MV_CUST_APP_TYPE_IGMP].eth_type);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ skb->dev = dev;
+#endif
+ mv_cust_rec_skb(port, skb);
+
+ return 1;
+}
+
+int mv_cust_igmp_tx(int port, struct net_device *dev, struct sk_buff *skb,
+ struct mv_eth_tx_spec *tx_spec_out)
+{
+ if (gCustConfig[MV_CUST_APP_TYPE_IGMP].enable == MV_CUST_APP_ENABLE) {
+ /* Check application Ethernet type */
+ if (skb->protocol == htons(gCustConfig[MV_CUST_APP_TYPE_IGMP].eth_type)) {
+
+ /* The Mapping and VLAN mod should be support in next phase */
+ if (MV_PON_PORT_ID == port)
+ {
+ tx_spec_out->flags = MV_ETH_F_MH;
+ }
+ else
+ {
+ tx_spec_out->flags = 0;
+ }
+
+ tx_spec_out->txp = 0;
+ tx_spec_out->txq = MV_CUST_SWF_TX_QUEUE;
+ tx_spec_out->hw_cmd = 0;
+#ifdef CONFIG_MV_ETH_TX_SPECIAL
+ tx_spec_out->tx_func = NULL;
+#endif
+ return 1;
+ }
+ }
+ return 0;
+}
+
#endif
+
+#ifdef CONFIG_MV_CUST_MLD_HANDLE
+void mv_cust_mld_print(void)
+{
+ printk("************* MLD Configuration *****************\n\n");
+ printk("MLD valid = %d, ethtype = 0x%04x \n",
+ gCustConfig[MV_CUST_APP_TYPE_MLD].enable,
+ gCustConfig[MV_CUST_APP_TYPE_MLD].eth_type);
+ printk("MLD default txq = %d\n",MV_CUST_SWF_TX_QUEUE);
+ printk("\n");
+}
+
+static int mv_cust_mld_parse(uint8_t *data)
+{
+ uint16_t ety;
+ uint8_t *fieldp = data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN;
+
+
+ /* Loop through VLAN tags */
+ ety = ntohs(*(uint16_t *)fieldp);
+ while (ety == 0x8100 || ety == 0x9100 ||ety == 0x88A8) {
+ fieldp+= VLAN_HLEN;
+ ety = ntohs(*(uint16_t *)fieldp);
+ }
+
+ if(mv_cust_debug_code)
+ printk("%s:ety 0x(%04x)\n", __func__, ety);
+
+ if (ety == ETH_P_IPV6)
+ {
+ struct ipv6hdr *hdr = (struct ipv6hdr *)(fieldp+2);
+ struct ipv6_hopopt_hdr *hopopthdr ;
+ struct icmp6hdr *pic;
+
+ if (hdr->nexthdr != NEXTHDR_HOP )
+ return 0;
+
+ hopopthdr = (struct ipv6_hopopt_hdr *)((uint8_t *)hdr+ sizeof(struct ipv6hdr));
+
+ if ( hopopthdr->nexthdr != IPPROTO_ICMPV6)
+ return 0;
+
+ pic = (struct icmp6hdr *)((uint8_t *)hopopthdr+ipv6_optlen(hopopthdr));
+
+ switch (pic->icmp6_type) {
+ case ICMPV6_MGM_QUERY:
+ case ICMPV6_MGM_REPORT:
+ case ICMPV6_MGM_REDUCTION:
+ case ICMPV6_MLD2_REPORT:
+ return 1;
+ default:
+ break;
+ }
+
+ }
+
+ return(0);
+}
+
+static int mv_cust_mld_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
+{
+ uint32_t rx_bytes;
+
+ if (!mv_cust_mld_parse(skb->data))
+ return 0;
+
+ /* To Indicate the source GMAC */
+ skb->data[0] = port;
+
+ rx_bytes = rx_desc->dataSize;
+
+ skb->tail += rx_bytes;
+ skb->len = rx_bytes;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->protocol = htons(gCustConfig[MV_CUST_APP_TYPE_MLD].eth_type);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ skb->dev = dev;
+#endif
+
+ mv_cust_rec_skb(port, skb);
+
+ return 1;
+}
+
+int mv_cust_mld_tx(int port, struct net_device *dev, struct sk_buff *skb,
+ struct mv_eth_tx_spec *tx_spec_out)
+{
+ if (gCustConfig[MV_CUST_APP_TYPE_MLD].enable == MV_CUST_APP_ENABLE) {
+ /* Check application Ethernet type */
+ if (skb->protocol == htons(gCustConfig[MV_CUST_APP_TYPE_MLD].eth_type)) {
+
+ /* The Mapping and VLAN mod should be support in next phase */
+ if (MV_PON_PORT_ID == port)
+ {
+ tx_spec_out->flags = MV_ETH_F_MH;
+ }
+ else
+ {
+ tx_spec_out->flags = 0;
+ }
+
+ tx_spec_out->txp = 0;
+ tx_spec_out->txq = MV_CUST_SWF_TX_QUEUE;
+ tx_spec_out->hw_cmd = 0;
+#ifdef CONFIG_MV_ETH_TX_SPECIAL
+ tx_spec_out->tx_func = NULL;
+#endif
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#endif
+
+
+#ifdef CONFIG_MV_CUST_LPBK_DETECT_HANDLE
+void mv_cust_loopdet_print(void)
+{
+ printk("************* UNI loopback detection Configuration *****************\n\n");
+ printk("Lpbk detect valid = %d, ethtype = 0x%04x \n",
+ gCustConfig[MV_CUST_APP_TYPE_LPBK].enable,
+ gCustConfig[MV_CUST_APP_TYPE_LPBK].eth_type);
+ printk("Lpbk detect default txq = %d\n",MV_CUST_SWF_TX_QUEUE);
+ printk("\n");
+}
+
+static int mv_cust_loopdet_parse(uint8_t *data)
+{
+ uint16_t ety;
+ uint8_t *fieldp = data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN;
+
+ /* Loop through VLAN tags */
+ ety = ntohs(*(uint16_t *)fieldp);
+ while (ety == 0x8100 || ety == 0x9100 ||ety == 0x88A8) {
+ fieldp+= VLAN_HLEN;
+ ety = ntohs(*(uint16_t *)fieldp);
+ }
+ if(mv_cust_debug_code)
+ printk("%s: ety 0x(%04x)\n", __func__, ety);
+
+ /* Compare EPON OAM ether_type */
+ if (ety == gCustConfig[MV_CUST_APP_TYPE_LPBK].eth_type)
+ return(1);
+
+ return(0);
+}
+
+static int mv_cust_loopdet_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
+{
+ uint32_t rx_bytes;
+
+ if (!mv_cust_loopdet_parse(skb->data))
+ return 0;
+
+ /* To Indicate the source GMAC */
+ skb->data[0] = port;
+
+ rx_bytes = rx_desc->dataSize;
+
+ skb->tail += rx_bytes;
+ skb->len = rx_bytes;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->protocol = htons(gCustConfig[MV_CUST_APP_TYPE_LPBK].eth_type);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ skb->dev = dev;
+#endif
+ mv_cust_rec_skb(port, skb);
+
+ return 1;
+}
+
+int mv_cust_loopdet_tx(int port, struct net_device *dev, struct sk_buff *skb,
+ struct mv_eth_tx_spec *tx_spec_out)
+{
+ if (MV_CUST_APP_ENABLE == gCustConfig[MV_CUST_APP_TYPE_LPBK].enable) {
+ /* Check application Ethernet type */
+ if (skb->protocol == htons(gCustConfig[MV_CUST_APP_TYPE_LPBK].eth_type)) {
+
+ if (MV_PON_PORT_ID == port)
+ {
+ tx_spec_out->flags = MV_ETH_F_MH;
+ }
+ else
+ {
+ tx_spec_out->flags = 0;
+ }
+
+ tx_spec_out->txp = 0;
+ tx_spec_out->txq = MV_CUST_SWF_TX_QUEUE;
+ tx_spec_out->hw_cmd = 0;
+#ifdef CONFIG_MV_ETH_TX_SPECIAL
+ tx_spec_out->tx_func = NULL;
+#endif
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#endif
+
+
+#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
static inline void mv_cust_copy_tx_spec(struct mv_eth_tx_spec * tx_spec,
uint8_t txp, uint8_t txq,
uint16_t flags, uint32_t hw_cmd)
@@ -379,9 +800,58 @@
tx_spec->flags = flags;
}
+int mv_cust_udp_spec_print(int port)
+{
+ int i;
+ struct eth_port *pp = mv_eth_port_by_id(port);
+ struct mv_udp_port_tx_spec *udp_spec;
+
+ if (!pp)
+ return -ENODEV;
+
+ udp_spec = &(udp_port_spec_cfg[port].udp_dst[0]);
+
+ printk("\n**** port #%d - TX UDP Dest Port configuration *****\n", port);
+ printk("----------------------------------------------------\n");
+ printk("ID udp_dst txp txq flags hw_cmd func_add\n");
+ for (i = 0; i < sizeof(udp_port_spec_cfg[port].udp_dst)/sizeof(udp_port_spec_cfg[port].udp_dst[0]); i++) {
+ if (udp_spec[i].tx_spec.txq != MV_ETH_TXQ_INVALID)
+ printk("%2d %04d %d %d 0x%04x 0x%08x 0x%p\n",
+ i, ntohs(udp_spec[i].udp_port),
+ udp_spec[i].tx_spec.txp, udp_spec[i].tx_spec.txq,
+ udp_spec[i].tx_spec.flags, udp_spec[i].tx_spec.hw_cmd,
+ udp_spec[i].tx_spec.tx_func);
+ }
+ printk("-----------------------------------------------------\n");
+
+ udp_spec = &(udp_port_spec_cfg[port].udp_src[0]);
+
+ printk("**** port #%d - TX UDP Source Port configuration *****\n", port);
+ printk("-----------------------------------------------------\n");
+ printk("ID udp_src txp txq flags hw_cmd func_add\n");
+ for (i = 0; i < sizeof(udp_port_spec_cfg[port].udp_src)/sizeof(udp_port_spec_cfg[port].udp_src[0]); i++) {
+ if (udp_spec[i].tx_spec.txq != MV_ETH_TXQ_INVALID)
+ printk("%2d %04d %d %d 0x%04x 0x%08x 0x%p\n",
+ i, ntohs(udp_spec[i].udp_port),
+ udp_spec[i].tx_spec.txp, udp_spec[i].tx_spec.txq,
+ udp_spec[i].tx_spec.flags, udp_spec[i].tx_spec.hw_cmd,
+ udp_spec[i].tx_spec.tx_func);
+ }
+ printk("**************************************************************\n");
+
+ return 0;
+}
-#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
+void mv_cust_udp_spec_print_all(void)
+{
+ int port;
+
+ for (port=0;port < CONFIG_MV_ETH_PORTS_NUM ;port++) {
+ mv_cust_udp_spec_print(port);
+ }
+}
+
MV_STATUS mv_cust_udp_int_spec_set(struct mv_udp_port_tx_spec *udp_spec, uint16_t udp_port, int table_size,
uint8_t txp, uint8_t txq, uint16_t flags, uint32_t hw_cmd)
{
@@ -411,14 +881,14 @@
MV_STATUS mv_cust_udp_src_spec_set(int tx_port, uint16_t udp_src_port, uint8_t txp, uint8_t txq, uint16_t flags, uint32_t hw_cmd)
{
struct eth_port *pp = mv_eth_port_by_id(tx_port);
- struct mv_udp_port_tx_spec *udp_src_spec = port_spec_cfg[tx_port].udp_src;
+ struct mv_udp_port_tx_spec *udp_src_spec = udp_port_spec_cfg[tx_port].udp_src;
MV_STATUS mv_status;
if (!pp)
return -ENODEV;
mv_status = mv_cust_udp_int_spec_set(udp_src_spec, udp_src_port,
- sizeof(port_spec_cfg[tx_port].udp_src)/sizeof(port_spec_cfg[tx_port].udp_src[0]),
+ sizeof(udp_port_spec_cfg[tx_port].udp_src)/sizeof(udp_port_spec_cfg[tx_port].udp_src[0]),
txp, txq, flags, hw_cmd);
if (mv_status != MV_OK)
@@ -432,14 +902,14 @@
MV_STATUS mv_cust_udp_dest_spec_set(int tx_port, uint16_t udp_dest_port, uint8_t txp, uint8_t txq, uint16_t flags, uint32_t hw_cmd)
{
struct eth_port *pp = mv_eth_port_by_id(tx_port);
- struct mv_udp_port_tx_spec *udp_dst_spec = port_spec_cfg[tx_port].udp_dst;
+ struct mv_udp_port_tx_spec *udp_dst_spec = udp_port_spec_cfg[tx_port].udp_dst;
MV_STATUS mv_status;
if (!pp)
return -ENODEV;
mv_status = mv_cust_udp_int_spec_set(udp_dst_spec, udp_dest_port,
- sizeof(port_spec_cfg[tx_port].udp_dst)/sizeof(port_spec_cfg[tx_port].udp_dst[0]),
+ sizeof(udp_port_spec_cfg[tx_port].udp_dst)/sizeof(udp_port_spec_cfg[tx_port].udp_dst[0]),
txp, txq, flags, hw_cmd);
if (mv_status != MV_OK)
@@ -462,101 +932,21 @@
for (tx_port=0; tx_port<num_ports;tx_port++) {
/* Invalidate UDP Dest ports, set txq=invalid */
- for (i=0;i<(sizeof(port_spec_cfg[tx_port].udp_dst)/sizeof(port_spec_cfg[tx_port].udp_dst[0]));i++) {
- memset(&(port_spec_cfg[tx_port].udp_dst[i]), 0, sizeof(struct mv_udp_port_tx_spec));
- port_spec_cfg[tx_port].udp_dst[i].tx_spec.txq = MV_ETH_TXQ_INVALID;
+ for (i=0;i<(sizeof(udp_port_spec_cfg[tx_port].udp_dst)/sizeof(udp_port_spec_cfg[tx_port].udp_dst[0]));i++) {
+ memset(&(udp_port_spec_cfg[tx_port].udp_dst[i]), 0, sizeof(struct mv_udp_port_tx_spec));
+ udp_port_spec_cfg[tx_port].udp_dst[i].tx_spec.txq = MV_ETH_TXQ_INVALID;
}
/* Invalidate UDP Source ports, , set txq=invalid */
- for (i=0;i<(sizeof(port_spec_cfg[tx_port].udp_src)/sizeof(port_spec_cfg[tx_port].udp_src[0]));i++) {
- memset(&(port_spec_cfg[tx_port].udp_src[i]), 0, sizeof(struct mv_udp_port_tx_spec));
- port_spec_cfg[tx_port].udp_src[i].tx_spec.txq = MV_ETH_TXQ_INVALID;
+ for (i=0;i<(sizeof(udp_port_spec_cfg[tx_port].udp_src)/sizeof(udp_port_spec_cfg[tx_port].udp_src[0]));i++) {
+ memset(&(udp_port_spec_cfg[tx_port].udp_src[i]), 0, sizeof(struct mv_udp_port_tx_spec));
+ udp_port_spec_cfg[tx_port].udp_src[i].tx_spec.txq = MV_ETH_TXQ_INVALID;
}
}
return;
}
-#endif
-int mv_cust_omci_tx(int port, struct net_device *dev, struct sk_buff *skb,
- struct mv_eth_tx_spec *tx_spec_out)
-{
- if ( (skb->protocol == mv_cust_xpon_oam_type)
- && mv_cust_omci_valid
- && port == MV_PON_PORT_ID) {
- memcpy (tx_spec_out, &omci_mgmt_tx_spec, sizeof(struct mv_eth_tx_spec));
- if(mv_cust_debug_code)
- printk("%s", __func__);
- return 1;
- }
- return 0;
-}
-
-
-int mv_cust_eoam_tx(int port, struct net_device *dev, struct sk_buff *skb,
- struct mv_eth_tx_spec *tx_spec_out)
-{
- int mac_match, i;
-
- if (skb->protocol == mv_cust_xpon_oam_type
- && mv_cust_eoam_valid
- && port == MV_PON_PORT_ID) {
- /* Lookup MAC Address */
- for (i=0; i<(EPON_MGMT_ENTRIES);i++) {
- mac_match = memcmp((void *) &(epon_mgmt_tx_spec[i].llid_mac_address[0]),
- (void *)(skb->data + /*MV_ETH_MH_SIZE +*/ ETH_ALEN),
- ETH_ALEN);
- if (!mac_match) {
- memcpy (tx_spec_out, &epon_mgmt_tx_spec[i].tx_spec, sizeof(struct mv_eth_tx_spec));
- if(mv_cust_debug_code)
- printk("%s, llid = %d", __func__, i);
- return 1;
- }
- }
- /* Source MAC Address not found */
- if(mv_cust_debug_code) {
- printk("(%s)Input Packet first bytes:\n", __func__);
- for (i=0;i<24;i++) {
- if (i%8== 0)
- printk("\n");
- printk ("%02x ", *(skb->data + i));
- }
- }
- }
- return 0;
-}
-
-
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-int mv_cust_igmp_tx(int port, struct net_device *dev, struct sk_buff *skb,
- struct mv_eth_tx_spec *tx_spec_out)
-{
- if (mv_cust_igmp_detect) {
- /* Check Tx XPON Type */
- if (skb->protocol == mv_cust_igmp_type) {
- memcpy (tx_spec_out, &igmp_tx_spec, sizeof(struct mv_eth_tx_spec));
-
- /* MH should not be set */
- tx_spec_out->flags = 0;
- if (2 == port)
- {
- tx_spec_out->txp = skb->data[0];
- tx_spec_out->hw_cmd = ((skb->data[2] << 8) | skb->data[3]) << 8;
- skb->data[2] |= 0x80;
- }
- tx_spec_out->txq = skb->data[1];
-
- skb_pull(skb, 2);
-
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-
-#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
int mv_cust_udp_port_tx(int port, struct net_device *dev, struct sk_buff *skb,
struct mv_eth_tx_spec *tx_spec_out)
{
@@ -572,14 +962,14 @@
if (skb->protocol == ETY_IPV4) {
/* Get UDP Port */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- iphdrp = skb->nh.iph;
+ iphdrp = skb->nh.iph;
#else
- iphdrp = ip_hdr(skb);
+ iphdrp = ip_hdr(skb);
#endif
if ((iphdrp) && (iphdrp->protocol == IPPROTO_UDP)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
- udphdrp = skb->h.uh;
+ udphdrp = skb->h.uh;
#else
udphdrp = udp_hdr(skb);
#endif
@@ -588,20 +978,20 @@
udphdrp = (struct udphdr *)((char *)udphdrp + (4*(iphdrp->ihl)));
}
/* Find configured UDP Source Port*/
- for (i=0; i < sizeof(port_spec_cfg[port].udp_src)/sizeof(port_spec_cfg[port].udp_src[0]);i++) {
- if ((udphdrp->source == port_spec_cfg[port].udp_src[i].udp_port) &&
- (port_spec_cfg[port].udp_src[i].tx_spec.txq != MV_ETH_TXQ_INVALID)) {
- memcpy (tx_spec_out, &(port_spec_cfg[port].udp_src[i].tx_spec), sizeof(struct mv_eth_tx_spec));
+ for (i=0; i < sizeof(udp_port_spec_cfg[port].udp_src)/sizeof(udp_port_spec_cfg[port].udp_src[0]);i++) {
+ if ((udphdrp->source == udp_port_spec_cfg[port].udp_src[i].udp_port) &&
+ (udp_port_spec_cfg[port].udp_src[i].tx_spec.txq != MV_ETH_TXQ_INVALID)) {
+ memcpy (tx_spec_out, &(udp_port_spec_cfg[port].udp_src[i].tx_spec), sizeof(struct mv_eth_tx_spec));
if (mv_cust_debug_code)
printk("%s: found udp_src 0x(%04x)\n", __func__, ntohs(udphdrp->source));
return 1;
}
}
/* Find configured UDP Dest. Port*/
- for (i=0; i < sizeof(port_spec_cfg[port].udp_dst)/sizeof(port_spec_cfg[port].udp_dst[0]);i++) {
- if ((udphdrp->dest == port_spec_cfg[port].udp_dst[i].udp_port) &&
- (port_spec_cfg[port].udp_src[i].tx_spec.txq != MV_ETH_TXQ_INVALID)) {
- memcpy (tx_spec_out, &(port_spec_cfg[port].udp_dst[i].tx_spec), sizeof(struct mv_eth_tx_spec));
+ for (i=0; i < sizeof(udp_port_spec_cfg[port].udp_dst)/sizeof(udp_port_spec_cfg[port].udp_dst[0]);i++) {
+ if ((udphdrp->dest == udp_port_spec_cfg[port].udp_dst[i].udp_port) &&
+ (udp_port_spec_cfg[port].udp_src[i].tx_spec.txq != MV_ETH_TXQ_INVALID)) {
+ memcpy (tx_spec_out, &(udp_port_spec_cfg[port].udp_dst[i].tx_spec), sizeof(struct mv_eth_tx_spec));
if (mv_cust_debug_code)
printk("%s: found udp_dst 0x(%04x)\n", __func__, ntohs(udphdrp->dest));
return 1;
@@ -626,7 +1016,116 @@
}
#endif
+
#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
+void mv_cust_flow_map_print(void)
+{
+ printk("************* Flow Mapping Configuration *****************\n\n");
+ printk("Flow mapping valid = %d\n", mv_cust_flow_map);
+}
+
+static int mv_cust_flow_map_parse(uint8_t *data, uint16_t *vlan, uint8_t *pbits, uint8_t dir)
+{
+ uint16_t ety;
+ uint8_t *fieldp ;
+
+ if (MV_CUST_FLOW_DIR_US == dir)
+ fieldp = data + ETH_ALEN + ETH_ALEN;
+ else
+ fieldp = data + ETH_ALEN + ETH_ALEN + MV_ETH_MH_SIZE;
+
+ /* Loop through VLAN tags */
+ ety = ntohs(*(uint16_t *)fieldp);
+ if (ety == 0x8100 || ety == 0x88A8 || ety == 0x9100) {
+ fieldp += 2;
+ *vlan = ntohs(*(uint16_t *)fieldp);
+ *pbits = (*vlan >> 13 ) & 0x7;
+ *vlan = (*vlan) & 0xfff;
+ return(1);
+ }
+ else {
+ return(0);
+ }
+
+ return(0);
+}
+
+static int mv_cust_flow_map_mod(uint8_t *data, uint16_t vid, uint8_t pbits, uint8_t dir)
+{
+ uint16_t ety = 0;
+ uint16_t vlan = 0;
+ uint8_t *fieldp;
+
+ if (MV_CUST_FLOW_DIR_US == dir)
+ fieldp = data + ETH_ALEN + ETH_ALEN;
+ else
+ fieldp = data + ETH_ALEN + ETH_ALEN + MV_ETH_MH_SIZE;
+
+ /* If not need to modify VID or P-bits */
+ if((vid == MV_CUST_VID_NOT_CARE_VALUE) &&
+ (pbits == MV_CUST_PBITS_NOT_CARE_VALUE))
+ return (1);
+
+ /* Loop through VLAN tags */
+ ety = ntohs(*(uint16_t *)fieldp);
+ if (ety == 0x8100 || ety == 0x88A8 || ety == 0x9100) {
+ fieldp += 2;
+
+ vlan = ntohs(*(uint16_t *)fieldp);
+
+ if (vid < MV_CUST_VID_NOT_CARE_VALUE)
+ vlan = (vlan & 0xf000) | (vid & 0xfff);
+ if (pbits < MV_CUST_PBITS_NOT_CARE_VALUE)
+ vlan = (vlan & 0x0fff) | ((pbits & 0x7) << 13);
+
+ *(uint16_t *)fieldp = htons(vlan);
+ return(1);
+ }
+ else {
+ return(0);
+ }
+
+ return(0);
+}
+
+static int mv_cust_flow_map_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
+{
+ uint16_t vlan = 0;
+ uint8_t pbits = 0;
+ int btag = 0;
+ int ret = 0;
+ mv_cust_ioctl_flow_map_t cust_flow;
+
+ if (MV_PON_PORT_ID != port)
+ return 0;
+
+ if (mv_cust_flow_map) {
+
+ /* Parse packets to check whether it is tagged or untagged, and get vlan and pbits in tagged mode */
+ btag = mv_cust_flow_map_parse(skb->data, &vlan, &pbits, MV_CUST_FLOW_DIR_DS);
+ //printk(KERN_ERR " %s TX packet 1 btag[%d] vlan[%d] pbits[%d]\n", __func__, btag, vlan, pbits);
+
+ /* The frame is tagged */
+ if (btag == 1) {
+ cust_flow.vid = vlan;
+ cust_flow.pbits = pbits;
+ cust_flow.dir = MV_CUST_FLOW_DIR_DS;
+
+ ret = mv_cust_tag_map_rule_get(&cust_flow);
+ //printk(KERN_ERR " %s TX packet 2 trg_port[%d] trg_queue[%d] gem_port[%d]\n", __func__, pkt_fwd.trg_port, pkt_fwd.trg_queue, pkt_fwd.gem_port);
+
+ /* Modify VID and P-bits if needed */
+ if (ret == MV_CUST_OK) {
+
+ /* modify VID and P-bits if needed */
+ ret = mv_cust_flow_map_mod(skb->data, cust_flow.mod_vid, cust_flow.mod_pbits, MV_CUST_FLOW_DIR_DS);
+ }
+ }
+ }
+
+ return 1;
+}
+
int mv_cust_flow_map_tx(int port, struct net_device *dev, struct sk_buff *skb,
struct mv_eth_tx_spec *tx_spec_out)
{
@@ -647,8 +1146,6 @@
/* Parse packets to check whether it is tagged or untagged, and get vlan and pbits in tagged mode */
btag = mv_cust_flow_map_parse(skb->data, &vlan, &pbits, MV_CUST_FLOW_DIR_US);
- //printk(KERN_ERR " %s TX packet 1 btag[%d] vlan[%d] pbits[%d]\n", __func__, btag, vlan, pbits);
-
/* The frame is tagged */
if (btag == 1) {
cust_flow.vid = vlan;
@@ -733,368 +1230,44 @@
}
return 0;
}
+
#endif
-void mv_cust_debug_info_set(int val)
+
+
+void mv_cust_print(int type)
{
- mv_cust_debug_code = val;
- return;
-}
-
-void mv_cust_omci_type_set(uint16_t type)
-{
- mv_cust_xpon_oam_type = htons(type);
- return;
-}
-EXPORT_SYMBOL(mv_cust_omci_type_set);
-
-void mv_cust_epon_oam_type_set(uint16_t type)
-{
- mv_cust_xpon_oam_type = htons(type);
- return;
-}
-EXPORT_SYMBOL(mv_cust_epon_oam_type_set);
-
-
-void mv_cust_xpon_oam_rx_gh_set(int val)
-{
- mv_cust_xpon_oam_rx_gh = val;
- return;
-}
-EXPORT_SYMBOL(mv_cust_xpon_oam_rx_gh_set);
-
-
+ switch (type)
+ {
#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-void mv_cust_igmp_type_set(uint16_t type)
-{
- mv_cust_igmp_type = htons(type);
+ case MV_CUST_APP_TYPE_IGMP:
+ mv_cust_igmp_print();
+ break;
+#endif
+#ifdef CONFIG_MV_CUST_MLD_HANDLE
+ case MV_CUST_APP_TYPE_MLD:
+ mv_cust_mld_print();
+ break;
+#endif
+#ifdef CONFIG_MV_CUST_LPBK_DETECT_HANDLE
+ case MV_CUST_APP_TYPE_LPBK:
+ mv_cust_loopdet_print();
+ break;
+#endif
+ case MV_CUST_APP_TYPE_OAM:
+ mv_cust_eoam_print();
+ break;
+ case MV_CUST_APP_TYPE_OMCI:
+ mv_cust_omci_print();
+ break;
+ default:
+ break;
+ }
+
return;
}
-EXPORT_SYMBOL(mv_cust_igmp_type_set);
-#endif
-
-void mv_cust_loopdet_type_set(uint16_t type)
-{
- mv_cust_loopdet_type = htons(type);
- return;
-}
-EXPORT_SYMBOL(mv_cust_loopdet_type_set);
-
-
-void mv_cust_omci_gemport_set(int gemport)
-{
- mv_cust_omci_gemport = gemport;
- return;
-}
-EXPORT_SYMBOL(mv_cust_omci_gemport_set);
-
-
-static int mv_cust_omci_gem_parse(uint8_t *data)
-{
- uint16_t gh;
-
- gh = ntohs(*(uint16_t *)data);
-
- if(mv_cust_debug_code)
- printk("%s:gh= 0x(%04x) - mv_cust_omci_gemport= 0x(%04x) \n", __func__, gh, mv_cust_omci_gemport);
-
- /* Compare GH for omci_gemport */
- if ( (gh & MH_GEM_PORT_MASK) != mv_cust_omci_gemport ) {
- if(mv_cust_debug_code)
- printk("%s: compare GH for OMCI_gemport failed: gh= 0x(%04x) - mv_cust_omci_gemport= 0x(%04x) \n", __func__, gh, mv_cust_omci_gemport);
- return(0);
- }
-
- return(1);
-}
-
-static int mv_cust_eoam_type_parse(uint8_t *data)
-{
- uint16_t ety;
-
- ety = ntohs(*(uint16_t *)(data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN));
-
- if(mv_cust_debug_code)
- printk("%s: ety 0x(%04x)\n", __func__, ety);
-
- /* Compare EPON OAM ether_type */
- if (ety == MH_EPON_OAM_TYPE)
- return(1);
-
- return(0);
-}
-
-
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-static int mv_cust_igmp_parse(uint8_t *data)
-{
- uint16_t ety;
- uint8_t proto;
- uint8_t *fieldp = data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN;
-
- /* Loop through VLAN tags */
- ety = ntohs(*(uint16_t *)fieldp);
- while (ety == 0x8100 || ety == 0x88A8) {
- fieldp+= VLAN_HLEN;
- ety = ntohs(*(uint16_t *)fieldp);
- }
-
- if(mv_cust_debug_code)
- printk("%s:ety 0x(%04x)\n", __func__, ety);
-
- if (ety == ETY_IPV4) {
- fieldp+= 2;
- fieldp+= IPV4_PROTO_OFFSET;
- proto = *fieldp;
- if (mv_cust_debug_code)
- printk("%s:proto 0x(%02x)\n", __func__, proto);
-
- if (proto == IPPROTO_IGMP)
- return(1);
- }
-
- return(0);
-}
-#endif
-
-static int mv_cust_loopdet_parse(uint8_t *data)
-{
- uint16_t ety;
- uint8_t *fieldp = data + MV_ETH_MH_SIZE + ETH_ALEN + ETH_ALEN;
-
- /* Loop through VLAN tags */
- ety = ntohs(*(uint16_t *)fieldp);
- while (ety == 0x8100 || ety == 0x88A8) {
- fieldp+= VLAN_HLEN;
- ety = ntohs(*(uint16_t *)fieldp);
- }
- if(mv_cust_debug_code)
- printk("%s: ety 0x(%04x)\n", __func__, ety);
-
- /* Compare EPON OAM ether_type */
- if (ety == mv_cust_loopdet_type)
- return(1);
-
- return(0);
-}
-
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
-static int mv_cust_flow_map_parse(uint8_t *data, uint16_t *vlan, uint8_t *pbits, uint8_t dir)
-{
- uint16_t ety;
- uint8_t *fieldp;
-
- if (MV_CUST_FLOW_DIR_US == dir)
- fieldp = data + ETH_ALEN + ETH_ALEN;
- else if (MV_CUST_FLOW_DIR_DS == dir)
- fieldp = data + ETH_ALEN + ETH_ALEN + MV_ETH_MH_SIZE;
-
- /* Loop through VLAN tags */
- ety = ntohs(*(uint16_t *)fieldp);
- if (ety == 0x8100 || ety == 0x88A8 || ety == 0x9100) {
- fieldp += 2;
- *vlan = ntohs(*(uint16_t *)fieldp);
- *pbits = (*vlan >> 13 ) & 0x7;
- *vlan = (*vlan) & 0xfff;
- return(1);
- }
- else {
- return(0);
- }
-
- return(0);
-}
-
-static int mv_cust_flow_map_mod(uint8_t *data, uint16_t vid, uint8_t pbits, uint8_t dir)
-{
- uint16_t ety = 0;
- uint16_t vlan = 0;
- uint8_t *fieldp;
-
- if (MV_CUST_FLOW_DIR_US == dir)
- fieldp = data + ETH_ALEN + ETH_ALEN;
- else if (MV_CUST_FLOW_DIR_DS == dir)
- fieldp = data + ETH_ALEN + ETH_ALEN + MV_ETH_MH_SIZE;
-
- /* If not need to modify VID or P-bits */
- if((vid == MV_CUST_VID_NOT_CARE_VALUE) &&
- (pbits == MV_CUST_PBITS_NOT_CARE_VALUE))
- return (1);
-
- /* Loop through VLAN tags */
- ety = ntohs(*(uint16_t *)fieldp);
- if (ety == 0x8100 || ety == 0x88A8 || ety == 0x9100) {
- fieldp += 2;
-
- vlan = ntohs(*(uint16_t *)fieldp);
-
- if (vid < MV_CUST_VID_NOT_CARE_VALUE)
- vlan = (vlan & 0xf000) | (vid & 0xfff);
- if (pbits < MV_CUST_PBITS_NOT_CARE_VALUE)
- vlan = (vlan & 0x0fff) | ((pbits & 0x7) << 13);
-
- *(uint16_t *)fieldp = htons(vlan);
- return(1);
- }
- else {
- return(0);
- }
-
- return(0);
-}
-
-#endif
-
-void mv_cust_rec_skb(int port, struct sk_buff *skb)
-{
- uint32_t rx_status;
- struct eth_port *pp;
-
- rx_status = netif_receive_skb(skb);
- pp = mv_eth_port_by_id(port);
- STAT_DBG(if (rx_status) (pp->stats.rx_drop_sw++));
-}
-
-
-static int mv_cust_omci_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
-{
- uint32_t rx_bytes;
-
- if (!mv_cust_omci_gem_parse(skb->data))
- return 0;
- if (mv_cust_xpon_oam_rx_gh) {
- rx_bytes = rx_desc->dataSize;
- }
- else {
- skb->data += MV_ETH_MH_SIZE;
- rx_bytes = rx_desc->dataSize - MV_ETH_MH_SIZE;
- }
- skb->tail += rx_bytes;
- skb->len = rx_bytes;
- skb->protocol = eth_type_trans(skb, dev);
- skb->protocol = mv_cust_xpon_oam_type;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- skb->dev = dev;
-#endif
- mv_cust_rec_skb(port, skb);
-
- return 1;
-}
-
-static int mv_cust_epon_oam_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
-{
- uint32_t rx_bytes;
-
- if (!mv_cust_eoam_type_parse(skb->data))
- return 0;
-
- if (mv_cust_xpon_oam_rx_gh) {
- rx_bytes = rx_desc->dataSize;
- }
- else {
- skb->data += MV_ETH_MH_SIZE;
- rx_bytes = rx_desc->dataSize - MV_ETH_MH_SIZE;
- }
-
- skb->tail += rx_bytes;
- skb->len = rx_bytes;
- skb->protocol = eth_type_trans(skb, dev);
- skb->protocol = mv_cust_xpon_oam_type;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- skb->dev = dev;
-#endif
- mv_cust_rec_skb(port, skb);
-
- return 1;
-}
-
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-static int mv_cust_igmp_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
-{
- uint32_t rx_bytes;
-
- if (!mv_cust_igmp_parse(skb->data))
- return 0;
-
- /* To Indicate the source GMAC */
- skb->data[0] = port;
-
- rx_bytes = rx_desc->dataSize;
-
- skb->tail += rx_bytes;
- skb->len = rx_bytes;
- skb->protocol = eth_type_trans(skb, dev);
- skb->protocol = mv_cust_igmp_type;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- skb->dev = dev;
-#endif
- mv_cust_rec_skb(port, skb);
-
- return 1;
-}
-#endif
-
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
-static int mv_cust_flow_map_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
-{
- uint32_t rx_bytes;
- uint16_t vlan = 0;
- uint8_t pbits = 0;
- int btag = 0;
- int ret = 0;
- mv_cust_ioctl_flow_map_t cust_flow;
-
- if (MV_PON_PORT_ID != port)
- return 0;
-
- if (mv_cust_flow_map) {
-
- /* Parse packets to check whether it is tagged or untagged, and get vlan and pbits in tagged mode */
- btag = mv_cust_flow_map_parse(skb->data, &vlan, &pbits, MV_CUST_FLOW_DIR_DS);
- //printk(KERN_ERR " %s TX packet 1 btag[%d] vlan[%d] pbits[%d]\n", __func__, btag, vlan, pbits);
-
- /* The frame is tagged */
- if (btag == 1) {
- cust_flow.vid = vlan;
- cust_flow.pbits = pbits;
- cust_flow.dir = MV_CUST_FLOW_DIR_DS;
-
- ret = mv_cust_tag_map_rule_get(&cust_flow);
- //printk(KERN_ERR " %s TX packet 2 trg_port[%d] trg_queue[%d] gem_port[%d]\n", __func__, pkt_fwd.trg_port, pkt_fwd.trg_queue, pkt_fwd.gem_port);
-
- /* Modify VID and P-bits if needed */
- if (ret == MV_CUST_OK) {
-
- /* modify VID and P-bits if needed */
- ret = mv_cust_flow_map_mod(skb->data, cust_flow.mod_vid, cust_flow.mod_pbits, MV_CUST_FLOW_DIR_DS);
- }
- }
- }
-
- return 1;
-}
-#endif
-
-static int mv_cust_loopdet_rx(int port, struct net_device *dev, struct sk_buff *skb, struct neta_rx_desc *rx_desc)
-{
- uint32_t rx_bytes;
-
- if (!mv_cust_loopdet_parse(skb->data))
- return 0;
-
- rx_bytes = rx_desc->dataSize;
-
- skb->tail += rx_bytes;
- skb->len = rx_bytes;
- skb->protocol = eth_type_trans(skb, dev);
- skb->protocol = mv_cust_loopdet_type;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- skb->dev = dev;
-#endif
- mv_cust_rec_skb(port, skb);
+EXPORT_SYMBOL(mv_cust_print);
- return 1;
-}
void mv_cust_rx_func(int port, int rxq, struct net_device *dev,
struct sk_buff *skb, struct neta_rx_desc *rx_desc)
@@ -1112,7 +1285,7 @@
if (rx_desc->pncInfo & NETA_PNC_RX_SPECIAL)
{
- if (mv_cust_omci_valid) {
+ if (gCustConfig[MV_CUST_APP_TYPE_OMCI].enable == MV_CUST_APP_ENABLE) {
if (mv_cust_omci_rx(port, dev, skb, rx_desc)) {
if(mv_cust_debug_code)
printk("%s omci_packet\n", __func__);
@@ -1120,7 +1293,7 @@
}
}
else{
- if (mv_cust_eoam_valid) {
+ if (gCustConfig[MV_CUST_APP_TYPE_OAM].enable == MV_CUST_APP_ENABLE) {
if (mv_cust_epon_oam_rx(port, dev, skb, rx_desc)) {
if (mv_cust_debug_code)
printk("%s eoam_packet\n", __func__);
@@ -1130,7 +1303,7 @@
}
#ifdef CONFIG_MV_CUST_IGMP_HANDLE
- if (mv_cust_igmp_detect) {
+ if (gCustConfig[MV_CUST_APP_TYPE_IGMP].enable == MV_CUST_APP_ENABLE) {
if (mv_cust_igmp_rx(port, dev, skb, rx_desc)) {
if(mv_cust_debug_code)
printk("%s igmp_packet\n", __func__);
@@ -1139,15 +1312,27 @@
}
#endif
- if (mv_cust_port_loopback_detect) {
+#ifdef CONFIG_MV_CUST_MLD_HANDLE
+ if (gCustConfig[MV_CUST_APP_TYPE_MLD].enable == MV_CUST_APP_ENABLE) {
+ if (mv_cust_mld_rx(port, dev, skb, rx_desc)) {
+ if(mv_cust_debug_code)
+ printk("%s mld_packet\n", __func__);
+ return;
+ }
+ }
+#endif
+
+#ifdef CONFIG_MV_CUST_LPBK_DETECT_HANDLE
+ if (gCustConfig[MV_CUST_APP_TYPE_LPBK].enable == MV_CUST_APP_ENABLE) {
if (mv_cust_loopdet_rx(port, dev, skb, rx_desc)) {
if(mv_cust_debug_code)
printk("%s loop_det_packet\n", __func__);
return;
}
}
+#endif
- MVCUST_ERR_PRINT("Special pkt arrived from port(%d), was not handled. \n", port);
+ //MVCUST_ERR_PRINT("Special pkt arrived from port(%d), was not handled. \n", port);
dev_kfree_skb_any(skb);
if(mv_cust_debug_code) {
printk("Input Packet first bytes:\n");
@@ -1175,6 +1360,7 @@
return;
}
+
int mv_cust_tx_func(int port, struct net_device *dev, struct sk_buff *skb,
struct mv_eth_tx_spec *tx_spec_out)
{
@@ -1183,14 +1369,24 @@
if (mv_cust_eoam_tx(port, dev, skb, tx_spec_out))
return 1;
-
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
- if (mv_cust_flow_map_tx(port, dev, skb, tx_spec_out))
+
+#ifdef CONFIG_MV_CUST_IGMP_HANDLE
+ if (mv_cust_igmp_tx(port, dev, skb, tx_spec_out))
return 1;
#endif
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
- if (mv_cust_igmp_tx(port, dev, skb, tx_spec_out))
+#ifdef CONFIG_MV_CUST_MLD_HANDLE
+ if (mv_cust_mld_tx(port, dev, skb, tx_spec_out))
+ return 1;
+#endif
+
+#ifdef CONFIG_MV_CUST_LPBK_DETECT_HANDLE
+ if (mv_cust_loopdet_tx(port, dev, skb, tx_spec_out))
+ return 1;
+#endif
+
+#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
+ if (mv_cust_flow_map_tx(port, dev, skb, tx_spec_out))
return 1;
#endif
@@ -1204,6 +1400,7 @@
return 0;
}
+
int mvcust_netdev_init(void)
{
uint32_t port_i;
@@ -1215,16 +1412,16 @@
mv_eth_ports_num = CONFIG_MV_ETH_PORTS_NUM;
mv_cust_eoam_init();
+
+#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
+ mv_cust_udp_table_del();
+#endif
/* Initialize flow mapping data structure */
#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
mv_cust_flow_map_init();
#endif
-#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
- mv_cust_udp_table_del();
-#endif
-
/* Register special receive check function */
#ifdef CONFIG_MV_ETH_RX_SPECIAL
for (port_i=0;port_i< mv_eth_ports_num;port_i++) {
@@ -1240,13 +1437,5 @@
}
#endif /* CONFIG_MV_ETH_TX_SPECIAL */
- /* Set global constants */
- mv_cust_xpon_oam_type = htons(0xBABA);
-
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
- mv_cust_igmp_type = htons(0xA000);
-#endif
- mv_cust_loopdet_type = htons(0xA0A0);
-
return 0;
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.h
index ac34927..4079631 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_netdev.h
@@ -48,21 +48,45 @@
struct mv_udp_port_tx_spec {
- __be16 udp_port;
- struct mv_eth_tx_spec tx_spec;
+ __be16 udp_port;
+ struct mv_eth_tx_spec tx_spec;
};
struct mv_port_tx_spec {
- struct mv_udp_port_tx_spec udp_src[MV_CUST_MAS_UDP_SRC_PORT];
- struct mv_udp_port_tx_spec udp_dst[MV_CUST_MAS_UDP_DST_PORT];
+ struct mv_udp_port_tx_spec udp_src[MV_CUST_MAS_UDP_SRC_PORT];
+ struct mv_udp_port_tx_spec udp_dst[MV_CUST_MAS_UDP_DST_PORT];
};
struct mv_eoam_llid_spec {
- uint8_t llid_mac_address[6];
- struct mv_eth_tx_spec tx_spec;
+ uint8_t llid_mac_address[6];
+ struct mv_eth_tx_spec tx_spec;
};
+typedef enum
+{
+ MV_CUST_APP_TYPE_IGMP = 0, /* For IGMP application */
+ MV_CUST_APP_TYPE_MLD, /* For MLD application */
+ MV_CUST_APP_TYPE_LPBK, /* For loopback detection application */
+ MV_CUST_APP_TYPE_OAM, /* For eOAM application */
+ MV_CUST_APP_TYPE_OMCI, /* For OMCI application */
+ MV_CUST_APP_TYPE_MAX /* Max number of application */
+} mv_cust_app_type_e;
+
+/* Enum: enable or disable application*/
+typedef enum
+{
+ MV_CUST_APP_DISABLE = 0,
+ MV_CUST_APP_ENABLE = 1,
+} mv_cust_app_flag_e;
+
+typedef struct
+{
+ mv_cust_app_type_e app_type; /* Application type, such as IGMP, MLD */
+ uint16_t enable; /* Flag indicates whether to enable application Rx/Tx */
+ uint16_t eth_type; /* Application Ethernet type used for socket/skb */
+ char *name; /* The readable name of the application */
+} mv_cust_app_config_t;
/******************************************************
@@ -70,27 +94,19 @@
*******************************************************/
void mv_cust_omci_hw_cmd_set(unsigned int hw_cmd);
int mv_cust_omci_tx_set(int tcont, int txq);
-//int mv_cust_eoam_tx_set(int txp, int txq);
-MV_STATUS mv_cust_omci_enable(int enable);
-MV_STATUS mv_cust_eoam_enable(int enable);
-//MV_STATUS mv_cust_eoam_tx_func_set(void (*tx_func) (uint8_t *data, int size, struct mv_eth_tx_spec *tx_spec));
+
#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
MV_STATUS mv_cust_udp_src_spec_set(int tx_port, uint16_t udp_src_port, uint8_t txp, uint8_t txq, uint16_t flags, uint32_t hw_cmd);
MV_STATUS mv_cust_udp_dest_spec_set(int tx_port, uint16_t udp_dest_port, uint8_t txp, uint8_t txq, uint16_t flags, uint32_t hw_cmd);
#endif
-void mv_cust_omci_type_set(unsigned short int type);
-void mv_cust_xpon_oam_rx_gh_set(int val);
-void mv_cust_epon_oam_type_set(unsigned short int type);
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
-void mv_cust_igmp_type_set(unsigned short int type);
-#endif
-void mv_cust_omci_gemport_set(int gemport);
-void mv_cust_loopdet_type_set(unsigned short int type);
+
+void mv_cust_oam_rx_gh_set(int val);
int mv_cust_omci_set(int tcont, int txq, int gemport, int keep_rx_mh);
int mv_cust_eoam_llid_set(int llid, uint8_t *llid_mac, int txq);
-
-
+void mv_cust_app_flag_set(mv_cust_app_type_e app_type, uint16_t enable);
+void mv_cust_app_etype_set(mv_cust_app_type_e app_type, uint16_t eth_type);
+void mv_cust_print(int type);
#endif /* __mv_cust_netdev_h__ */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_sysfs.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_sysfs.c
index 395c59c..3c50c88 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_sysfs.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_cust/mv_cust_sysfs.c
@@ -52,34 +52,31 @@
static ssize_t mv_cust_spec_proc_help(char *buf)
{
int off = 0;
- off += sprintf(buf+off, "cat help - show this help\n");
- off += sprintf(buf+off, "cat omci - show OMCI configuration\n");
- off += sprintf(buf+off, "cat eoam - show eoam configuration\n");
- off += sprintf(buf+off, "cat loopdet - show loop detect configuration\n");
- off += sprintf(buf+off, "cat udp_ports - show special udp source and dest. port configuration\n");
-#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
- off += sprintf(buf+off, "cat flow_map - show flow mapping configuration\n");
- off += sprintf(buf+off, "cat flow_map_show - show flow mapping rules \n");
- off += sprintf(buf+off, "cat flow_map_clear - clear all flow mapping rules\n");
- off += sprintf(buf+off, "cat dscp_map_del - delete DSCP to P-bits mapping rules\n");
+ off += sprintf(buf+off, "cat help - show this help\n");
+#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
+ off += sprintf(buf+off, "cat udp_ports - show special udp source and dest. port configuration\n");
#endif
- off += sprintf(buf+off, "cat igmp - show igmp configuration\n");
+#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
+ off += sprintf(buf+off, "cat flow_map - show flow mapping configuration\n");
+ off += sprintf(buf+off, "cat flow_map_show - show flow mapping rules \n");
+ off += sprintf(buf+off, "cat flow_map_clear - clear all flow mapping rules\n");
+ off += sprintf(buf+off, "cat dscp_map_del - delete DSCP to P-bits mapping rules\n");
+#endif
+ off += sprintf(buf+off, "cat tcont_show - Show all T-CONT state\n");
+ off += sprintf(buf+off, "echo tcont state > tcont_set - Set T-CONT tatus, tcont(0~7), state(1:enable, 0:disable) \n");
off += sprintf(buf+off, "echo hex > debug - Set Customized module debug information \n");
- off += sprintf(buf+off, "echo hex > omci_type - Set OMCI ethertype\n");
+ off += sprintf(buf+off, "echo app_type > app_show - Show application configuration. 0:igmp, 1:mld, 2:lpbk, 3:eoam, 4:omci\n");
+ off += sprintf(buf+off, "echo app_type enable > app_flag_set - Enable/disable application. 0:igmp, 1:mld, 2:lpbk, 3:eoam, 4:omci, 1:enable, 0:disable\n");
+ off += sprintf(buf+off, "echo app_type hex > app_etype_set- Set application Eth type. 0:igmp, 1:mld, 2:lpbk, 3:eoam, 4:omci\n");
off += sprintf(buf+off, "echo tc txq gem keep_mh > omci_set - set udp source port special Tx behavior\n");
- off += sprintf(buf+off, "echo hex > omci_ena - Disable/Enable OMCI packet detection\n");
- //off += sprintf(buf+off, "echo txp txq > omci_txq - set T-CONT and TX queue for outgoing OMCI packet\n");
- //off += sprintf(buf+off, "echo hex > omci_cmd - 4B of tx desc offset 0xc\n");
- //off += sprintf(buf+off, "echo hex > omci_gemp - gemportid to detect OMCI packets\n");
- off += sprintf(buf+off, "echo hex > eoam_type - Set EPON EOAM ethertype\n");
+ off += sprintf(buf+off, "echo keep_mh > eoam_gh_keep - Keep or not keep GH for eOAM packets, 1:keep, 0:do not keep\n");
off += sprintf(buf+off, "echo txq > eoam_txq - set TX queue into sw_buffer for EOAM llid command\n");
off += sprintf(buf+off, "echo mac[0]-mac[5] > eoam_mac - set LLID mac into sw_buffer for EOAM llid command\n");
off += sprintf(buf+off, "echo llid > eoam_write - Write EOAM txq and mac address from sw_buffer into LLID\n");
- off += sprintf(buf+off, "echo hex > eoam_enable - Disable/Enable eOAM packet detection\n");
- //off += sprintf(buf+off, "echo hex > igmp_type - Set IGMP ethertype\n");
- off += sprintf(buf+off, "echo hex > loopdet_type - Set Port Loopback Detect ethertype\n");
+#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
off += sprintf(buf+off, "echo p udp_src(dec) txp txq flags hw_cmd > udp_src - set udp source port special Tx behavior\n");
off += sprintf(buf+off, "echo p udp_dst(dec) txp txq flags hw_cmd > udp_dst - set udp dest. port special Tx behavior\n");
+#endif
#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
off += sprintf(buf+off, "echo hex > flow_map_debug - Set flow mapping debug flag, 1:enable, 0:disable \n");
off += sprintf(buf+off, "echo vid pbits mod_vid mod_pbits trg_port trg_queue trg_hwf_queue gem_port > flow_map_us_set - set U/S flow mapping rule\n");
@@ -97,8 +94,10 @@
static ssize_t mv_cust_spec_proc_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- int off = 0;
- const char* name = attr->attr.name;
+ int off = 0;
+ int index = 0;
+ bool state;
+ const char* name = attr->attr.name;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -106,30 +105,11 @@
if (!strcmp(name, "help") ) {
off = mv_cust_spec_proc_help(buf);
}
- else if (!strcmp(name, "omci")) {
- mv_cust_omci_print();
- }
- else if (!strcmp(name, "eoam")) {
- mv_cust_eoam_print();
- }
- else if (!strcmp(name, "igmp")) {
-#ifdef CONFIG_MV_CUST_IGMP_HANDLE
- mv_cust_igmp_print();
-#else
- printk("mv_cust module was not compiled with IGMP Support\n");
-#endif
-
- }
- else if (!strcmp(name, "loopdet")) {
- mv_cust_loopdet_print();
- }
+#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
else if (!strcmp(name, "udp_ports")) {
-#ifdef CONFIG_MV_CUST_UDP_SAMPLE_HANDLE
mv_cust_udp_spec_print_all();
-#else
- printk("mv_cust module was not compiled with UDP SAMPLE Config Support\n");
-#endif
}
+#endif
#ifdef CONFIG_MV_CUST_FLOW_MAP_HANDLE
else if (!strcmp(name, "flow_map")) {
mv_cust_flow_map_print();
@@ -143,7 +123,17 @@
else if (!strcmp(name, "dscp_map_del")) {
mv_cust_dscp_map_del();
}
-#endif
+#endif
+ else if (!strcmp(name, "tcont_show")) {
+ printk(KERN_INFO "MV_CUST T-CONT state table\n");
+ printk(KERN_INFO "Default invalid Txq:%d \n", CPH_INVALID_TRGT_QUEUE);
+ printk(KERN_INFO "--------------------------\n");
+ for (index = 0; index < CPH_MAX_TCONT_NUM; index++)
+ {
+ state = mv_cust_get_tcont_state(index);
+ printk(KERN_INFO "T-CONT%1.1d: %s\n", index, (state==true)?"enabled":"disabled");
+ }
+ }
else
off = mv_cust_spec_proc_help(buf);
@@ -151,7 +141,6 @@
}
-
static ssize_t mv_cust_spec_proc_1_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
@@ -167,51 +156,24 @@
v = 0;
sscanf(buf, "%x", &v);
-
+
raw_local_irq_save(flags);
if (!strcmp(name, "debug")) {
mv_cust_debug_info_set(v);
}
- else if (!strcmp(name, "omci_type")) {
- mv_cust_omci_type_set(v);
+ else if (!strcmp(name, "app_show")) {
+ mv_cust_print(v);
}
- else if (!strcmp(name, "eoam_type")) {
- mv_cust_epon_oam_type_set(v);
- }
+ else if (!strcmp(name, "eoam_gh_keep")) {
+ mv_cust_oam_rx_gh_set(v);
+ }
else if (!strcmp(name, "eoam_txq")) {
eoam_txq = v;
}
else if (!strcmp(name, "eoam_write")) {
mv_cust_eoam_llid_set((int)v, &eoam_mac[0], eoam_txq);
}
- /*
- else if (!strcmp(name, "omci_cmd")) {
- mv_cust_omci_hw_cmd_set(v);
- }
- */
- /*
- else if (!strcmp(name, "omci_gemp")) {
- mv_cust_omci_gemport_set(v);
- }
- */
- /*
- else if (!strcmp(name, "omci_gh_keep")) {
- mv_cust_xpon_oam_rx_gh_set(v);
- }
- */
- else if (!strcmp(name, "eoam_gh_keep")) {
- mv_cust_xpon_oam_rx_gh_set(v);
- }
- else if (!strcmp(name, "loopdet_type")) {
- mv_cust_loopdet_type_set(v);
- }
- else if (!strcmp(name, "omci_enable")) {
- mv_cust_omci_enable(v);
- }
- else if (!strcmp(name, "eoam_enable")) {
- mv_cust_eoam_enable(v);
- }
else
printk("%s: illegal operation <%s>\n", __FUNCTION__, attr->attr.name);
@@ -220,7 +182,7 @@
return len;
}
-#if 0
+
static ssize_t mv_cust_spec_proc_2_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
@@ -233,20 +195,24 @@
return -EPERM;
/* Read input */
+ p = 0;
v = 0;
sscanf(buf, "%d %x", &p, &v);
raw_local_irq_save(flags);
- /*
- if (!strcmp(name, "omci_txq")) {
- mv_cust_omci_tx_set(p, v);
+
+ if (!strcmp(name, "app_flag_set")) {
+ mv_cust_app_flag_set(p, v);
}
- */
- /*
- else if (!strcmp(name, "eoam_txq")) {
- mv_cust_eoam_tx_set(p, v);
+ else if (!strcmp(name, "app_etype_set")) {
+ mv_cust_app_etype_set(p, v);
}
- */
+ else if (!strcmp(name, "tcont_set")) {
+ if (v)
+ mv_cust_set_tcont_state(p, true);
+ else
+ mv_cust_set_tcont_state(p, false);
+ }
else
printk("%s: illegal operation <%s>\n", __FUNCTION__, attr->attr.name);
@@ -254,7 +220,6 @@
return len;
}
-#endif
static ssize_t mv_cust_spec_proc_6_store(struct device *dev,
@@ -447,61 +412,53 @@
return len;
}
+static DEVICE_ATTR(help, S_IRUSR, mv_cust_spec_proc_show, NULL);
static DEVICE_ATTR(debug, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-//static DEVICE_ATTR(omci_cmd, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-//static DEVICE_ATTR(omci_gemp, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-static DEVICE_ATTR(omci_type, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-//static DEVICE_ATTR(omci_gh_keep, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-static DEVICE_ATTR(loopdet_type, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-static DEVICE_ATTR(omci_ena, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
+
static DEVICE_ATTR(omci_set, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_6_store);
-static DEVICE_ATTR(eoam_enable, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-static DEVICE_ATTR(eoam_type, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
static DEVICE_ATTR(eoam_gh_keep, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-//static DEVICE_ATTR(omci_txq, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_2_store);
static DEVICE_ATTR(eoam_txq, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
-static DEVICE_ATTR(eoam_write, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
static DEVICE_ATTR(eoam_mac, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_6h_store);
+static DEVICE_ATTR(eoam_write, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
+
+static DEVICE_ATTR(tcont_show, S_IRUSR, mv_cust_spec_proc_show, NULL);
+static DEVICE_ATTR(tcont_set, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_2_store);
+
+static DEVICE_ATTR(app_show, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_1_store);
+static DEVICE_ATTR(app_flag_set, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_2_store);
+static DEVICE_ATTR(app_etype_set, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_2_store);
+
+static DEVICE_ATTR(udp_ports, S_IRUSR, mv_cust_spec_proc_show, NULL);
static DEVICE_ATTR(udp_src, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_6_store);
static DEVICE_ATTR(udp_dst, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_6_store);
-static DEVICE_ATTR(flow_map_debug, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
-static DEVICE_ATTR(flow_map_us_set,S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
-static DEVICE_ATTR(flow_map_ds_set,S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
-static DEVICE_ATTR(dscp_map_set, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_64_store);
-static DEVICE_ATTR(flow_map_del, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
-static DEVICE_ATTR(tag_flow_get, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
-static DEVICE_ATTR(untag_flow_get, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
-static DEVICE_ATTR(omci, S_IRUSR, mv_cust_spec_proc_show, NULL);
-static DEVICE_ATTR(eoam, S_IRUSR, mv_cust_spec_proc_show, NULL);
-static DEVICE_ATTR(igmp, S_IRUSR, mv_cust_spec_proc_show, NULL);
-static DEVICE_ATTR(loopdet, S_IRUSR, mv_cust_spec_proc_show, NULL);
-static DEVICE_ATTR(udp_ports, S_IRUSR, mv_cust_spec_proc_show, NULL);
static DEVICE_ATTR(flow_map, S_IRUSR, mv_cust_spec_proc_show, NULL);
static DEVICE_ATTR(flow_map_show, S_IRUSR, mv_cust_spec_proc_show, NULL);
static DEVICE_ATTR(flow_map_clear, S_IRUSR, mv_cust_spec_proc_show, NULL);
static DEVICE_ATTR(dscp_map_del, S_IRUSR, mv_cust_spec_proc_show, NULL);
+static DEVICE_ATTR(flow_map_debug, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
+static DEVICE_ATTR(flow_map_us_set,S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
+static DEVICE_ATTR(flow_map_ds_set,S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
+static DEVICE_ATTR(flow_map_del, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
+static DEVICE_ATTR(tag_flow_get, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
+static DEVICE_ATTR(untag_flow_get, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_flow_store);
+static DEVICE_ATTR(dscp_map_set, S_IWUSR, mv_cust_spec_proc_show, mv_cust_spec_proc_64_store);
-
-static DEVICE_ATTR(help, S_IRUSR, mv_cust_spec_proc_show, NULL);
-
static struct attribute *mv_cust_spec_proc_attrs[] = {
+ &dev_attr_help.attr,
&dev_attr_debug.attr,
- //&dev_attr_omci_cmd.attr,
- //&dev_attr_omci_gemp.attr,
- &dev_attr_omci_type.attr,
- //&dev_attr_omci_gh_keep.attr,
- //&dev_attr_omci_txq.attr,
- &dev_attr_omci_ena.attr,
&dev_attr_omci_set.attr,
- &dev_attr_eoam_type.attr,
&dev_attr_eoam_gh_keep.attr,
- &dev_attr_eoam_enable.attr,
&dev_attr_eoam_txq.attr,
- &dev_attr_eoam_write.attr,
&dev_attr_eoam_mac.attr,
- &dev_attr_loopdet_type.attr,
+ &dev_attr_eoam_write.attr,
+ &dev_attr_tcont_show.attr,
+ &dev_attr_tcont_set.attr,
+ &dev_attr_app_show.attr,
+ &dev_attr_app_flag_set.attr,
+ &dev_attr_app_etype_set.attr,
+ &dev_attr_udp_ports.attr,
&dev_attr_udp_src.attr,
&dev_attr_udp_dst.attr,
&dev_attr_flow_map_debug.attr,
@@ -510,17 +467,12 @@
&dev_attr_dscp_map_set.attr,
&dev_attr_flow_map_del.attr,
&dev_attr_tag_flow_get.attr,
- &dev_attr_untag_flow_get.attr,
- &dev_attr_omci.attr,
- &dev_attr_eoam.attr,
- &dev_attr_igmp.attr,
- &dev_attr_loopdet.attr,
- &dev_attr_udp_ports.attr,
+ &dev_attr_untag_flow_get.attr,
&dev_attr_flow_map.attr,
&dev_attr_flow_map_show.attr,
&dev_attr_flow_map_clear.attr,
&dev_attr_dscp_map_del.attr,
- &dev_attr_help.attr,
+
NULL
};
@@ -571,4 +523,3 @@
printk(KERN_INFO "= CUST Module SYS FS Remove ended successfully =\n");
}
-
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_api.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_api.h
index 9f1d9ac..11ccdc9 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_api.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_api.h
@@ -37,6 +37,10 @@
#define MAC_LEARN_OK 0
#define MAC_LEARN_FAIL 1
+/* CPU rate limit related*/
+#define MAC_LEARN_RATE_LIMIT 128
+#define MAC_LEARN_BUCKET_SIZE 2000
+
/* Function protype
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.c
index b911039..0d1e236 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.c
@@ -121,10 +121,11 @@
uint32_t i;
for (i = 0; i < MAC_LEARN_FDB_MAX_COUNT; i++) {
- /*Get spin lock*/
- spin_lock(&mac_learn_fdb.mac_learn_db_entry_lock[i]);
if (MAC_LEARN_FDB_VALID == mac_learn_fdb.mac_learn_db_entry[i].valid &&
MAC_LEARN_FDB_NON_STATIC == mac_learn_fdb.mac_learn_db_entry[i].state) {
+ /*Get spin lock*/
+ spin_lock(&mac_learn_fdb.mac_learn_db_entry_lock[i]);
+
memset(&del_mac_key, 0, sizeof(tpm_l2_acl_key_t));
memset(del_mac_key.mac.mac_sa_mask, 0xff, sizeof(u8)*MV_MAC_ADDR_SIZE);
memcpy(del_mac_key.mac.mac_sa, mac_learn_fdb.mac_learn_db_entry[i].src_mac_addr, sizeof(char) * MV_MAC_ADDR_SIZE);
@@ -142,12 +143,15 @@
return MAC_LEARN_FDB_FAIL;
}
- }
- /* Release spin lock */
- spin_unlock(&mac_learn_fdb.mac_learn_db_entry_lock[i]);
- if (mac_learn_db_pncidx_update(0, pnc_idx)) {
- MVMACLEARN_ERR_PRINT("TPM PNC index update failed(%d)\n", i);
- return MAC_LEARN_FDB_FAIL;
+
+ /* Release spin lock */
+ spin_unlock(&mac_learn_fdb.mac_learn_db_entry_lock[i]);
+
+ /* Update PnC index */
+ if (mac_learn_db_pncidx_update(0, pnc_idx)) {
+ MVMACLEARN_ERR_PRINT("TPM PNC index update failed(%d)\n", i);
+ return MAC_LEARN_FDB_FAIL;
+ }
}
}
@@ -285,8 +289,10 @@
if (!memcmp(src_mac_key->mac.mac_sa, mac_learn_fdb.mac_learn_db_entry[i].src_mac_addr, sizeof(char) * MV_MAC_ADDR_SIZE)) {
if (addr_exist)
*addr_exist = 1;
- if (mac_learn_db_entry)
+ if (mac_learn_db_entry) {
memcpy(mac_learn_db_entry, &mac_learn_fdb.mac_learn_db_entry[i], sizeof(mac_learn_db_entry_t));
+ mac_learn_db_entry->fdb_idx = i;
+ }
/* Release spin lock */
spin_unlock(&mac_learn_fdb.mac_learn_db_entry_lock[i]);
break;
@@ -545,6 +551,39 @@
printk("+--------------+---------------------+--------------+\n");
}
+/************************************************************************************
+* mac_learn_db_entry_state_update
+* Update entry state of an existing entry
+* input:
+* fdb_idx: FDB entry index
+* entry_state: FDB entry state
+*return:
+* success--MAC_LEARN_FDB_OK
+* failed --MAC_LEARN_FDB_FAIL
+************************************************************************************/
+int32_t mac_learn_db_entry_state_update(uint32_t fdb_idx, uint8_t entry_state)
+{
+ /* Para check */
+ if (fdb_idx >= MAC_LEARN_FDB_MAX_COUNT) {
+ MVMACLEARN_ERR_PRINT("MAC learn FDB entry index(%d) invalid\n", fdb_idx);
+ return MAC_LEARN_FDB_FAIL;
+ }
+
+ if ((MAC_LEARN_FDB_STATIC != entry_state) && (MAC_LEARN_FDB_NON_STATIC != entry_state)) {
+ MVMACLEARN_ERR_PRINT("MAC learn FDB entry state(%d) invalid\n", entry_state);
+ return MAC_LEARN_FDB_FAIL;
+ }
+
+ /* Get spin lock */
+ spin_lock(&mac_learn_fdb.mac_learn_db_entry_lock[fdb_idx]);
+ /* Update to expected state */
+ mac_learn_fdb.mac_learn_db_entry[fdb_idx].state = entry_state;
+ /* Release spin lock */
+ spin_unlock(&mac_learn_fdb.mac_learn_db_entry_lock[fdb_idx]);
+
+ return MAC_LEARN_FDB_OK;
+}
+
/***************************************************************************************************************
* mac_learn_fdb_init()
*
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.h
index 6f31b92..a650602 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_db.h
@@ -51,6 +51,7 @@
/* Typedefs
------------------------------------------------------------------------------*/
typedef struct {
+ uint32_t fdb_idx;
uint8_t valid;
uint8_t state;
uint8_t port;
@@ -88,6 +89,7 @@
void mac_learn_db_nonstatic_count_dec(void);
int32_t mac_learn_db_nonstatic_count_get(uint32_t *nonstatic_ount);
void mac_learn_db_valid_print(void);
+int32_t mac_learn_db_entry_state_update(uint32_t fdb_idx, uint8_t entry_state);
int32_t mac_learn_fdb_init(void);
#endif
\ No newline at end of file
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_logic.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_logic.c
index 0685b5a..e86f910 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_logic.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_logic.c
@@ -153,7 +153,7 @@
uint32_t i;
const uint32_t tpm_owner_id = TPM_MOD_OWNER_TPM;
uint32_t pnc_idx, read_count,hit_count = 0;
- uint32_t fdb_valid_count;
+ uint32_t fdb_nonstatic_valid_count;
tpm_l2_acl_key_t del_mac_key;
mac_learn_db_entry_t mac_learn_db_entry;
tpm_db_pnc_range_conf_t range_conf;
@@ -197,9 +197,9 @@
} else {
/* dec non static entry count */
mac_learn_db_nonstatic_count_dec();
- mac_learn_db_valid_count_get(&fdb_valid_count);
+ mac_learn_db_nonstatic_count_get(&fdb_nonstatic_valid_count);
/* start MAC learn again */
- if ((mac_learn_age->mac_learn_max_count - fdb_valid_count == 1) &&
+ if ((mac_learn_age->mac_learn_max_count - fdb_nonstatic_valid_count == 1) &&
(false == mac_learn_age->mac_learn_overwrite_enable)) {
/* Trap packet with new address to CPU again */
if (tpm_mac_learn_default_rule_act_set(tpm_owner_id, TPM_UNK_MAC_TRAP)) {
@@ -257,7 +257,16 @@
return;
}
+ /* Check non-static max count, if 0 just return */
+ if (src_mac->mac_learn_max_count == 0) {
+ /* Read buffer, in order to clear it to avoid bad effection for following MAC learn */
+ mv_mac_learn_queue_read(src_mac_key.mac.mac_sa);
+ return;
+ }
+
if (tpm_db_pnc_rng_conf_get(TPM_PNC_MAC_LEARN, &range_conf)){
+ /* Read buffer, in order to clear it to avoid bad effection for following MAC learn */
+ mv_mac_learn_queue_read(src_mac_key.mac.mac_sa);
MVMACLEARN_ERR_PRINT("TPM PnC range info get failed\n");
return;
}
@@ -285,11 +294,6 @@
/* Check non-static Full or not */
if (src_mac->mac_learn_max_count == nonstatic_count) {
if (true == src_mac->mac_learn_overwrite_enable) {
- /* Interval less than 0.2s, overwrite is forbidden*/
- if (time_after(jiffies, (unsigned long)src_mac->mac_learn_overwrite_time))
- src_mac->mac_learn_overwrite_time = jiffies + HZ / 5;/*update overwrite time*/
- else
- return;/*return from here, no any operation*/
/* Overwrite LU entry */
if (!mv_mac_learn_get_lu(&pnc_idx)) {
MVMACLEARN_DEBUG_PRINT("PnC index need to be overwritten: %d\n", pnc_idx);
@@ -409,27 +413,43 @@
memset(src_mac_key.mac.mac_sa_mask, 0xff, sizeof(u8)*MV_MAC_ADDR_SIZE);
memcpy(src_mac_key.mac.mac_sa, static_mac_addr, sizeof(char) * MV_MAC_ADDR_SIZE);
- /* Check the src mac exist in FDB or not*/
- if (mac_learn_db_find_mac_addr(&src_mac_key, &fdb_addr_exist, NULL)) {
- MVMACLEARN_ERR_PRINT("mac_learn_db_find_mac_addr failed\n");
- return MAC_LEARN_FAIL;
- }
- /* If Addr exist in FDB, return OK*/
- if (fdb_addr_exist == 1) {
- MVMACLEARN_WARN_PRINT("Entry already exist\n");
- return MAC_LEARN_OK;
- }
/*Get MAC learn range info*/
if (tpm_db_pnc_rng_conf_get(TPM_PNC_MAC_LEARN, &range_conf)){
MVMACLEARN_ERR_PRINT("TPM PnC range info get failed\n");
return MAC_LEARN_FAIL;
}
- /*check whether static free entry enough or not*/
+ /* get entry count info */
pnc_max_count = range_conf.api_end - range_conf.api_start + 1;
if (mac_learn_db_valid_count_get(&valid_count) ||
mac_learn_db_nonstatic_count_get(&non_static_count) ||
mv_mac_learn_op_max_count_get(&non_static_max))
return MAC_LEARN_FAIL;
+
+ /* Check the src mac exist in FDB or not*/
+ if (mac_learn_db_find_mac_addr(&src_mac_key, &fdb_addr_exist, &mac_learn_db_entry)) {
+ MVMACLEARN_ERR_PRINT("mac_learn_db_find_mac_addr failed\n");
+ return MAC_LEARN_FAIL;
+ }
+ /* If Addr exist in FDB, return OK*/
+ if (fdb_addr_exist == 1) {
+ if (MAC_LEARN_FDB_STATIC == mac_learn_db_entry.state) {
+ MVMACLEARN_WARN_PRINT("Entry already exist\n");
+ } else {
+ /*check whether static free entry enough or not*/
+ if ((valid_count - non_static_count) >= (pnc_max_count - non_static_max)) {
+ MVMACLEARN_ERR_PRINT("No free entry for static entry\n");
+ return MAC_LEARN_FAIL;
+ }
+ /* Update original entry state */
+ if (mac_learn_db_entry_state_update(mac_learn_db_entry.fdb_idx, MAC_LEARN_FDB_STATIC)) {
+ MVMACLEARN_ERR_PRINT("MAC learn FDB entry state update failed\n");
+ return MAC_LEARN_FAIL;
+ }
+ mac_learn_db_nonstatic_count_dec();
+ }
+ return MAC_LEARN_OK;
+ }
+ /*check whether static free entry enough or not*/
if ((valid_count - non_static_count) >= (pnc_max_count - non_static_max)) {
MVMACLEARN_ERR_PRINT("No free entry for static entry\n");
return MAC_LEARN_FAIL;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_mod.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_mod.c
index cd20927..26d4dd7 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_mod.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_mod.c
@@ -237,6 +237,9 @@
const uint32_t tpm_owner_id = TPM_MOD_OWNER_TPM;
tpm_db_pnc_range_conf_t range_conf;
tpm_init_pnc_mac_learn_enable_t pnc_mac_learn_enable;
+ tpm_gmacs_enum_t lpk_gmac;
+ uint32_t data_queue, mac_larn_queue;
+ uint32_t lpk_gmac_mh_en;
/*check original value and new value, if equal, return OK*/
if (mac_learn_enable == mc_mac_learn.mac_learn_enable)
@@ -264,6 +267,45 @@
else
mc_mac_learn.mac_learn_max_count = (range_conf.api_end - range_conf.api_start + 1) / 2;
MVMACLEARN_DEBUG_PRINT("non-static entry max count: %d\n",mc_mac_learn.mac_learn_max_count);
+
+ /* set PMT entry for MH modification on GMAC1 */
+ /*check data queue and mac learn queue, if equal, return error*/
+ if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac,
+ &data_queue,
+ TPM_GMAC1_QUEUE_DATA_TRAFFIC)) {
+ MVMACLEARN_ERR_PRINT("loopback gmac data queue get failed \n");
+ return MAC_LEARN_FAIL;
+ }
+ if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac,
+ &mac_larn_queue,
+ TPM_GMAC1_QUEUE_MAC_LEARN_TRAFFIC)) {
+ MVMACLEARN_ERR_PRINT("loopback gmac mac learn queue get failed \n");
+ return MAC_LEARN_FAIL;
+ }
+ if (data_queue == mac_larn_queue) {
+ MVMACLEARN_ERR_PRINT("loopback gmac Tx queue %d for data traffix and MAC learn equal\n",
+ data_queue);
+ return MAC_LEARN_FAIL;
+ }
+ MVMACLEARN_DEBUG_PRINT("lpk gmac %d Tx queue for mac learn: %d\n", lpk_gmac, mac_larn_queue);
+
+ /* limit band width on Tx mac learn queue of lpk gmac */
+ if (mvNetaTxqBurstSet((int)lpk_gmac, 0, mac_larn_queue, MAC_LEARN_BUCKET_SIZE) ||
+ mvNetaTxqRateSet((int)lpk_gmac, 0, mac_larn_queue, MAC_LEARN_RATE_LIMIT)) {
+ MVMACLEARN_ERR_PRINT("MAC learning CPU rate limit on queue %d failed\n", mac_larn_queue);
+ return MAC_LEARN_FAIL;
+ }
+
+ /* Check MH on lpk gmac */
+ if (tpm_db_gmac_mh_en_conf_get(lpk_gmac, &lpk_gmac_mh_en)) {
+ MVMACLEARN_ERR_PRINT("Marvell Header enable info get failed on GMAC%d\n", lpk_gmac);
+ return MAC_LEARN_FAIL;
+ }
+ if (!lpk_gmac_mh_en) {
+ MVMACLEARN_ERR_PRINT("Marvell Header is not enabled on GMAC%d\n", lpk_gmac);
+ return MAC_LEARN_FAIL;
+ }
+
/* Trap packet to CPU */
if (tpm_mac_learn_default_rule_act_set(tpm_owner_id, TPM_UNK_MAC_TRAP)) {
MVMACLEARN_ERR_PRINT("TPM default rule action set failed\n");
@@ -392,7 +434,7 @@
tpm_db_pnc_range_conf_t range_conf;
if (true == mc_mac_learn.mac_learn_enable) {
- MVMACLEARN_DEBUG_PRINT("Old max count: %d, New max count: %d\n", mc_mac_learn.mac_learn_enable, mac_learn_max_count);
+ MVMACLEARN_DEBUG_PRINT("Old max count: %d, New max count: %d\n", mc_mac_learn.mac_learn_max_count, mac_learn_max_count);
if (mac_learn_max_count < mc_mac_learn.mac_learn_max_count) {
if (!mac_learn_db_nonstatic_count_get(&non_static_count)) {
MVMACLEARN_DEBUG_PRINT("Current non-static num: %d\n", non_static_count);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_netdev.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_netdev.c
index ad69a42..5fb0b31 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_netdev.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_netdev.c
@@ -97,7 +97,7 @@
/* Register mac learn parse function */
for (port_i=0;port_i< mv_eth_ports_num;port_i++) {
- if (port_i == 0)
+ if (port_i == 0 || port_i == 1)
mv_eth_rx_mac_learn_func(port_i, mv_mac_learn_eth_rx_func);
else
mv_eth_rx_mac_learn_func(port_i, NULL);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_sysfs.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_sysfs.c
index 1e2e584..5831e77 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_sysfs.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_mac_learn/mv_mac_learn_sysfs.c
@@ -325,13 +325,20 @@
uint32_t max_count;
int parsedargs;
int numparms;
+ int temp;
numparms = sys_mac_learn_count_para(buf);
if (numparms != mac_learn_max_count_max) {
MVMACLEARN_ERR_PRINT("Parameter number not right");
} else {
/* Get parameters */
- parsedargs = sscanf(buf, "%d", &max_count);
+ parsedargs = sscanf(buf, "%d", &temp);
+ if (temp < 0) {
+ printk(KERN_INFO "ERROR: Negative Input(%d) can not be accepted\n", temp);
+ return;
+ }
+
+ max_count = temp;
if (parsedargs != numparms) {
printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
@@ -362,13 +369,20 @@
uint32_t expire_time;
int parsedargs;
int numparms;
+ int temp;
numparms = sys_mac_learn_count_para(buf);
if (numparms != mac_learn_expire_time_max) {
MVMACLEARN_ERR_PRINT("Parameter number not right");
} else {
/* Get parameters */
- parsedargs = sscanf(buf, "%d", &expire_time);
+ parsedargs = sscanf(buf, "%d", &temp);
+ if (temp < 0) {
+ printk(KERN_INFO "ERROR: Negative Input(%d) can not be accepted\n", temp);
+ return;
+ }
+
+ expire_time = temp;
if (parsedargs != numparms) {
printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/Kconfig b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/Kconfig
index 6046c62..dfc9301 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/Kconfig
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/Kconfig
@@ -1024,4 +1024,10 @@
---help---
If set swap of RX and TX descriptors in BE mode will be done by driver
+config MV_ETH_6601_LB_WA
+ bool "WA for 6601 (KW MC) w/ loopback traffic to CPU"
+ default n
+ ---help---
+ If set, RX traffic to CPU from GMAC1 is switched to GMAC0 netdev (eth1)
+
endmenu
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_eth_sysfs.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_eth_sysfs.c
index d6edeb5..24c3868 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_eth_sysfs.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_eth_sysfs.c
@@ -80,6 +80,7 @@
off += sprintf(buf+off, "echo p rxq t > rxq_type - set RXQ for different packet types. t=0-bpdu, 1-arp, 2-tcp, 3-udp\n");
off += sprintf(buf+off, "echo p > rx_reset - reset RX part of the port <p>\n");
off += sprintf(buf+off, "echo p txp > txp_reset - reset TX part of the port <p/txp>\n");
+ off += sprintf(buf+off, "echo p txp txq > txq_clean - clean TXQ <p/txp/txq> - invalidate descripotrs and free buffers\n");
off += sprintf(buf+off, "echo p txq tos > txq_tos - set <txq> for outgoing IP packets with <tos>\n");
off += sprintf(buf+off, "echo p txp txq cpu > txq_def - set default <txp/txq> for packets sent to port <p> by <cpu>\n");
off += sprintf(buf+off, "echo p txp {0|1} > ejp - enable/disable EJP mode for <port/txp>\n");
@@ -392,6 +393,8 @@
mvNetaTxqShow(p, txp, txq, v);
} else if (!strcmp(name, "txq_regs")) {
mvNetaTxqRegs(p, txp, txq);
+ } else if (!strcmp(name, "txq_clean")) {
+ err = mv_eth_txq_clean(p, txp, txq);
} else {
err = 1;
printk(KERN_ERR "%s: illegal operation <%s>\n", __func__, attr->attr.name);
@@ -416,6 +419,7 @@
static DEVICE_ATTR(txq_wrr, S_IWUSR, mv_eth_show, mv_eth_4_store);
static DEVICE_ATTR(txq_rate, S_IWUSR, mv_eth_show, mv_eth_4_store);
static DEVICE_ATTR(txq_burst, S_IWUSR, mv_eth_show, mv_eth_4_store);
+static DEVICE_ATTR(txq_clean, S_IWUSR, mv_eth_show, mv_eth_4_store);
static DEVICE_ATTR(txp_rate, S_IWUSR, mv_eth_show, mv_eth_3_store);
static DEVICE_ATTR(txp_burst, S_IWUSR, mv_eth_show, mv_eth_3_store);
static DEVICE_ATTR(txp_reset, S_IWUSR, mv_eth_show, mv_eth_3_store);
@@ -470,6 +474,7 @@
&dev_attr_txq_wrr.attr,
&dev_attr_txq_rate.attr,
&dev_attr_txq_burst.attr,
+ &dev_attr_txq_clean.attr,
&dev_attr_txp_rate.attr,
&dev_attr_txp_burst.attr,
&dev_attr_txp_reset.attr,
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.c
index 6d68843..86d8494 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.c
@@ -638,9 +638,15 @@
}
txq_ctrl = &pp->txq_ctrl[txp * CONFIG_MV_ETH_TXQ + txq];
if ((txq_ctrl->q) && (txq_ctrl->txq_size != value)) {
+ /* Reset of port/txp is required to change TXQ ring size */
+ if ((mvNetaTxqNextIndexGet(pp->port, txq_ctrl->txp, txq_ctrl->txq) != 0) ||
+ (mvNetaTxqPendDescNumGet(pp->port, txq_ctrl->txp, txq_ctrl->txq) != 0) ||
+ (mvNetaTxqSentDescNumGet(pp->port, txq_ctrl->txp, txq_ctrl->txq) != 0)) {
+ printk(KERN_ERR "%s: port=%d, txp=%d, txq=%d must be in its initial state\n",
+ __func__, port, txq_ctrl->txp, txq_ctrl->txq);
+ return -EINVAL;
+ }
mv_eth_txq_delete(pp, txq_ctrl);
- /* Reset of port/txp is required when TXQ ring size is changed */
- /* Reset done before as part of stop_internals function */
}
txq_ctrl->txq_size = value;
@@ -654,6 +660,12 @@
struct tx_queue *txq_ctrl;
struct eth_port *pp = mv_eth_port_by_id(port);
+ if (pp == NULL)
+ return -ENODEV;
+
+ if (pp == NULL)
+ return -ENODEV;
+
txq_ctrl = &pp->txq_ctrl[txp * CONFIG_MV_ETH_TXQ + txq];
if (txq_ctrl->cpu_owner) {
mode = MV_ETH_TXQ_CPU;
@@ -817,11 +829,12 @@
struct sk_buff *skb, struct neta_rx_desc *rx_desc))
{
struct eth_port *pp = mv_eth_port_by_id(port);
-
+
if (pp)
pp->rx_special_proc = func;
}
#endif /* CONFIG_MV_ETH_RX_SPECIAL */
+
#ifdef CONFIG_MV_MAC_LEARN
/* Register mac learn parse function */
void mv_eth_rx_mac_learn_func(int port, void (*func)(int port, int rxq, struct net_device *dev,
@@ -834,8 +847,7 @@
}
#endif /* CONFIG_MV_MAC_LEARN */
-static inline u16 mv_eth_select_txq(struct net_device *dev,
- struct sk_buff *skb)
+static inline u16 mv_eth_select_txq(struct net_device *dev, struct sk_buff *skb)
{
struct eth_port *pp = MV_ETH_PRIV(dev);
return mv_eth_tx_policy(pp, skb);
@@ -1232,6 +1244,121 @@
return skb;
}
+static inline void mv_eth_txq_buf_free(struct eth_port *pp, u32 shadow)
+{
+ if (!shadow)
+ return;
+
+ if (shadow & MV_ETH_SHADOW_SKB) {
+ shadow &= ~MV_ETH_SHADOW_SKB;
+ dev_kfree_skb_any((struct sk_buff *)shadow);
+ STAT_DBG(pp->stats.tx_skb_free++);
+ } else {
+ if (shadow & MV_ETH_SHADOW_EXT) {
+ shadow &= ~MV_ETH_SHADOW_EXT;
+ mv_eth_extra_pool_put(pp, (void *)shadow);
+ } else {
+ /* packet from NFP without BM */
+ struct eth_pbuf *pkt = (struct eth_pbuf *)shadow;
+ struct bm_pool *pool = &mv_eth_pool[pkt->pool];
+
+ if (mv_eth_pool_bm(pool)) {
+ /* Refill BM pool */
+ STAT_DBG(pool->stats.bm_put++);
+ mvBmPoolPut(pkt->pool, (MV_ULONG) pkt->physAddr);
+ } else {
+ mv_eth_pool_put(pool, pkt);
+ }
+ }
+ }
+}
+
+static inline void mv_eth_txq_cpu_clean(struct eth_port *pp, struct tx_queue *txq_ctrl)
+{
+ int hw_txq_i, last_txq_i, i, count;
+ u32 shadow;
+
+ hw_txq_i = mvNetaTxqNextIndexGet(pp->port, txq_ctrl->txp, txq_ctrl->txq);
+ last_txq_i = txq_ctrl->shadow_txq_put_i;
+
+ i = hw_txq_i;
+ count = 0;
+ while (i != last_txq_i) {
+ shadow = txq_ctrl->shadow_txq[i];
+ mv_eth_txq_buf_free(pp, shadow);
+ txq_ctrl->shadow_txq[i] = (u32)NULL;
+
+ i = MV_NETA_QUEUE_NEXT_DESC(&txq_ctrl->q->queueCtrl, i);
+ count++;
+ }
+ printk(KERN_INFO "\n%s: port=%d, txp=%d, txq=%d, mode=CPU\n",
+ __func__, pp->port, txq_ctrl->txp, txq_ctrl->txq);
+ printk(KERN_INFO "Free %d buffers: from desc=%d to desc=%d, tx_count=%d\n",
+ count, hw_txq_i, last_txq_i, txq_ctrl->txq_count);
+}
+
+static inline void mv_eth_txq_hwf_clean(struct eth_port *pp, struct tx_queue *txq_ctrl, int rx_port)
+{
+ int pool, hw_txq_i, last_txq_i, i, count;
+ struct neta_tx_desc *tx_desc;
+
+ hw_txq_i = mvNetaTxqNextIndexGet(pp->port, txq_ctrl->txp, txq_ctrl->txq);
+
+ if (mvNetaHwfTxqNextIndexGet(rx_port, pp->port, txq_ctrl->txp, txq_ctrl->txq, &last_txq_i) != MV_OK) {
+ printk(KERN_ERR "%s: mvNetaHwfTxqNextIndexGet failed\n", __func__);
+ return;
+ }
+
+ i = hw_txq_i;
+ count = 0;
+ while (i != last_txq_i) {
+ tx_desc = (struct neta_tx_desc *)MV_NETA_QUEUE_DESC_PTR(&txq_ctrl->q->queueCtrl, i);
+ if (mvNetaTxqDescIsValid(tx_desc)) {
+ mvNetaTxqDescInv(tx_desc);
+ mv_eth_tx_desc_flush(tx_desc);
+
+ pool = (tx_desc->command & NETA_TX_BM_POOL_ID_ALL_MASK) >> NETA_TX_BM_POOL_ID_OFFS;
+ mvBmPoolPut(pool, (MV_ULONG)tx_desc->bufPhysAddr);
+ count++;
+ }
+ i = MV_NETA_QUEUE_NEXT_DESC(&txq_ctrl->q->queueCtrl, i);
+ }
+ printk(KERN_DEBUG "\n%s: port=%d, txp=%d, txq=%d, mode=HWF-%d\n",
+ __func__, pp->port, txq_ctrl->txp, txq_ctrl->txq, rx_port);
+ printk(KERN_DEBUG "Free %d buffers to BM pool %d: from desc=%d to desc=%d\n",
+ count, pool, hw_txq_i, last_txq_i);
+}
+
+int mv_eth_txq_clean(int port, int txp, int txq)
+{
+ int mode, rx_port;
+ struct eth_port *pp;
+ struct tx_queue *txq_ctrl;
+
+ if (mvNetaTxpCheck(port, txp))
+ return -EINVAL;
+
+ if (mvNetaMaxCheck(txq, CONFIG_MV_ETH_TXQ))
+ return -EINVAL;
+
+ pp = mv_eth_port_by_id(port);
+ if ((pp == NULL) || (pp->txq_ctrl == NULL))
+ return -ENODEV;
+
+ txq_ctrl = &pp->txq_ctrl[txp * CONFIG_MV_ETH_TXQ + txq];
+
+ mode = mv_eth_ctrl_txq_mode_get(pp->port, txq_ctrl->txp, txq_ctrl->txq, &rx_port);
+ if (mode == MV_ETH_TXQ_CPU)
+ mv_eth_txq_cpu_clean(pp, txq_ctrl);
+ else if (mode == MV_ETH_TXQ_HWF)
+ mv_eth_txq_hwf_clean(pp, txq_ctrl, rx_port);
+// else
+// printk(KERN_ERR "%s: port=%d, txp=%d, txq=%d is not in use\n",
+// __func__, pp->port, txp, txq);
+
+ return 0;
+}
+
static inline void mv_eth_txq_bufs_free(struct eth_port *pp, struct tx_queue *txq_ctrl, int num)
{
u32 shadow;
@@ -1241,32 +1368,7 @@
for (i = 0; i < num; i++) {
shadow = txq_ctrl->shadow_txq[txq_ctrl->shadow_txq_get_i];
mv_eth_shadow_inc_get(txq_ctrl);
-
- if (!shadow)
- continue;
-
- if (shadow & MV_ETH_SHADOW_SKB) {
- shadow &= ~MV_ETH_SHADOW_SKB;
- dev_kfree_skb_any((struct sk_buff *)shadow);
- STAT_DBG(pp->stats.tx_skb_free++);
- } else {
- if (shadow & MV_ETH_SHADOW_EXT) {
- shadow &= ~MV_ETH_SHADOW_EXT;
- mv_eth_extra_pool_put(pp, (void *)shadow);
- } else {
- /* packet from NFP without BM */
- struct eth_pbuf *pkt = (struct eth_pbuf *)shadow;
- struct bm_pool *pool = &mv_eth_pool[pkt->pool];
-
- if (mv_eth_pool_bm(pool)) {
- /* Refill BM pool */
- STAT_DBG(pool->stats.bm_put++);
- mvBmPoolPut(pkt->pool, (MV_ULONG) pkt->physAddr);
- } else {
- mv_eth_pool_put(pool, pkt);
- }
- }
- }
+ mv_eth_txq_buf_free(pp, shadow);
}
}
@@ -1481,6 +1583,15 @@
dev = pp->dev;
#endif /* CONFIG_MV_ETH_SWITCH */
+#ifdef CONFIG_MV_ETH_6601_LB_WA
+ /* This workaround is for the 6601 w/ loopback.
+ All RX traffic originating from GMAC1 is treated as if comming from GMAC0 netdev */
+ if (pp->port == 1) {
+ struct eth_port *new_pp = mv_eth_port_by_id(0);
+ dev = new_pp->dev;
+ }
+#endif
+
STAT_DBG(pp->stats.rxq[rxq]++);
dev->stats.rx_packets++;
@@ -1659,6 +1770,9 @@
tx_spec.flags = pp->flags;
}
+ if (tx_spec.txq == MV_ETH_TXQ_INVALID)
+ goto out;
+
txq_ctrl = &pp->txq_ctrl[tx_spec.txp * CONFIG_MV_ETH_TXQ + tx_spec.txq];
if (txq_ctrl == NULL) {
printk(KERN_ERR "%s: invalidate txp/txq (%d/%d)\n", __func__, tx_spec.txp, tx_spec.txq);
@@ -1777,7 +1891,7 @@
#ifndef CONFIG_MV_ETH_TXDONE_ISR
if (txq_ctrl) {
if (txq_ctrl->txq_count >= mv_ctrl_txdone) {
- STAT_DIST(u32 tx_done = )mv_eth_txq_done(pp, txq_ctrl);
+ u32 tx_done = mv_eth_txq_done(pp, txq_ctrl);
STAT_DIST((tx_done < pp->dist_stats.tx_done_dist_size) ? pp->dist_stats.tx_done_dist[tx_done]++ : 0);
@@ -2111,12 +2225,8 @@
mv_eth_txq_bufs_free(pp, txq_ctrl, tx_done);
+ txq_ctrl->txq_count -= tx_done;
STAT_DBG(txq_ctrl->stats.txq_txdone += tx_done);
-
- /* reset txq */
- txq_ctrl->txq_count = 0;
- txq_ctrl->shadow_txq_put_i = 0;
- txq_ctrl->shadow_txq_get_i = 0;
}
inline u32 mv_eth_tx_done_pon(struct eth_port *pp, int *tx_todo)
@@ -2586,6 +2696,10 @@
causeRxTx = MV_REG_READ(NETA_INTR_NEW_CAUSE_REG(pp->port)) &
(MV_ETH_MISC_SUM_INTR_MASK | MV_ETH_TXDONE_INTR_MASK | MV_ETH_RX_INTR_MASK);
+ if ((pp->flags & MV_ETH_F_STARTED) == 0) {
+ printk(KERN_ERR "%s: port #%d is not started", __func__, pp->port);
+ }
+
if (causeRxTx & MV_ETH_MISC_SUM_INTR_MASK) {
MV_U32 causeMisc;
@@ -2804,7 +2918,7 @@
printk(KERN_ERR "\n o Warning: GbE port %d is powered off\n\n", port);
continue;
}
- if (!MV_PON_PORT(port) && !mvBoardIsGbEPortConnected(port)) {
+ if (!MV_PON_PORT(port) && !mvBoardIsGbEPortConnected(port) && (mvCtrlModelGet()!= MV_6601_DEV_ID)) {
printk(KERN_ERR "\n o Warning: GbE port %d is not connected to PHY/RGMII/Switch, skip initialization\n\n",
port);
continue;
@@ -2842,8 +2956,8 @@
} else if (status == 1) {
/* User selected to work without Gateway driver */
clear_bit(MV_ETH_F_SWITCH_BIT, &(pp->flags));
- printk(KERN_ERR " o Working in External Switch mode\n");
ext_switch_port_mask = mv_switch_link_detection_init();
+ printk(KERN_ERR " o Working in External Switch mode - switch_port_mask = 0x%x\n", ext_switch_port_mask);
}
}
@@ -3760,8 +3874,22 @@
for (queue = 0; queue < CONFIG_MV_ETH_TXQ; queue++) {
struct tx_queue *txq_ctrl = &pp->txq_ctrl[txp * CONFIG_MV_ETH_TXQ + queue];
- if (txq_ctrl->q)
- mv_eth_txq_done_force(pp, txq_ctrl);
+ if (txq_ctrl->q) {
+ int mode, rx_port;
+
+ mode = mv_eth_ctrl_txq_mode_get(pp->port, txp, queue, &rx_port);
+ if (mode == MV_ETH_TXQ_CPU) {
+ /* Free all buffers in TXQ */
+ mv_eth_txq_done_force(pp, txq_ctrl);
+ /* reset txq */
+ txq_ctrl->shadow_txq_put_i = 0;
+ txq_ctrl->shadow_txq_get_i = 0;
+ } else if (mode == MV_ETH_TXQ_HWF)
+ mv_eth_txq_hwf_clean(pp, txq_ctrl, rx_port);
+ else
+ printk(KERN_ERR "%s: port=%d, txp=%d, txq=%d is not in use\n",
+ __func__, pp->port, txp, queue);
+ }
}
mvNetaTxpReset(port, txp);
return 0;
@@ -4057,7 +4185,7 @@
int mv_eth_stop_internals(struct eth_port *pp)
{
unsigned long rwflags;
- int queue;
+ int txp, queue;
write_lock_irqsave(&pp->rwlock, rwflags);
@@ -4080,14 +4208,11 @@
#ifdef CONFIG_MV_ETH_HWF
mvNetaHwfEnable(pp->port, 0);
-#else
- {
- int txp;
- /* Reset TX port here. If HWF is supported reset must be called externally */
- for (txp = 0; txp < pp->txp_num; txp++)
- mv_eth_txp_reset(pp->port, txp);
- }
-#endif /* !CONFIG_MV_ETH_HWF */
+#endif /* CONFIG_MV_ETH_HWF */
+
+ for (txp = 0; txp < pp->txp_num; txp++)
+ for (queue = 0; queue < CONFIG_MV_ETH_TXQ; queue++)
+ mv_eth_txq_clean(pp->port, txp, queue);
if (mv_eth_ctrl_is_tx_enabled(pp)) {
int cpu;
@@ -5357,7 +5482,7 @@
return mv_eth_switch_change_mtu(mv_net_devs[portNo], mtu);
}
else
-#endif
+#endif
{
return mv_eth_change_mtu(mv_net_devs[portNo], mtu);
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.h
index 57c0b00..607a4bc 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_neta/net_dev/mv_netdev.h
@@ -653,6 +653,7 @@
int mv_eth_rx_reset(int port);
int mv_eth_txp_reset(int port, int txp);
+int mv_eth_txq_clean(int port, int txp, int txq);
MV_STATUS mv_eth_rx_ptks_coal_set(int port, int rxq, MV_U32 value);
MV_STATUS mv_eth_rx_time_coal_set(int port, int rxq, MV_U32 value);
@@ -677,6 +678,7 @@
void mv_eth_status_print(void);
void mv_eth_port_status_print(unsigned int port);
void mv_eth_port_stats_print(unsigned int port);
+void mv_eth_pool_status_print(int pool);
void mv_eth_set_noqueue(struct net_device *dev, int enable);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/Kconfig b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/Kconfig
index ff696e2..db660ea 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/Kconfig
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/Kconfig
@@ -124,4 +124,12 @@
Unselect this option only if you have source code of SLIC drivers.
If unsure, say "y"
+config MV_TDM_EXT_STATS
+ bool "Enable legacy TDM extended statistics"
+ depends on MV_TDM_SUPPORT
+ default n
+ ---help---
+ Choosing this option will export extended statistics to procfs.
+ This is relevant only for the legacy TDM unit.
+
endmenu
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tal.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tal.h
index d005b4f..f97431e 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tal.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tal.h
@@ -56,6 +56,9 @@
unsigned int tx_miss;
unsigned int rx_over;
unsigned int tx_under;
+#ifdef MV_TDM_EXT_STATS
+ MV_TDM_EXTENDED_STATS tdm_ext_stats;
+#endif
} tal_stats_t;
typedef struct {
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.c
index 4ae4bbc..1707719 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.c
@@ -98,7 +98,15 @@
int buffer_length, int *zero, void *ptr);
static int proc_tx_under_read(char *buffer, char **buffer_location, off_t offset,
int buffer_length, int *zero, void *ptr);
+#ifdef CONFIG_MV_TDM_EXT_STATS
+static int proc_dump_ext_stats(char *buffer, char **buffer_location, off_t offset,
+ int buffer_length, int *zero, void *ptr);
+#endif
+#ifdef CONFIG_MV_TDM_SUPPORT
+/* TDM SW Reset */
+static void tdm_if_stop_channels(unsigned long args);
+#endif
/* Module */
static int __init tdm_if_module_init(void);
@@ -110,6 +118,9 @@
static DECLARE_TASKLET(tdm_if_rx_tasklet, tdm_if_pcm_rx_process, 0);
static DECLARE_TASKLET(tdm_if_tx_tasklet, tdm_if_pcm_tx_process, 0);
#endif
+#ifdef CONFIG_MV_TDM_SUPPORT
+static DECLARE_TASKLET(tdm_if_stop_tasklet, tdm_if_stop_channels, 0);
+#endif
static DEFINE_SPINLOCK(tdm_if_lock);
static unsigned char *rxBuff = NULL, *txBuff = NULL;
static char irqnr;
@@ -121,6 +132,8 @@
static int tdm_init = 0;
static int buff_size = 0;
static unsigned short test_enable = 0;
+static int pcm_stop_flag;
+static int pcm_stop_status;
#ifdef CONFIG_MV_PHONE_USE_FIQ_PROCESSING
extern int __must_check
@@ -159,14 +172,49 @@
return sprintf(buffer, "%u\n", tx_under);
}
+#ifdef CONFIG_MV_TDM_EXT_STATS
+static int proc_dump_ext_stats(char *buffer, char **buffer_location, off_t offset,
+ int buffer_length, int *zero, void *ptr)
+{
+ char *str;
+ MV_TDM_EXTENDED_STATS tdm_ext_stats;
+
+ if (offset > 0)
+ return 0;
+
+ mvTdmExtStatsGet(&tdm_ext_stats);
+
+ str = buffer;
+ str += sprintf(str, "\nTDM Extended Statistics:\n");
+ str += sprintf(str, "intRxCount = %u\n", tdm_ext_stats.intRxCount);
+ str += sprintf(str, "intTxCount = %u\n", tdm_ext_stats.intTxCount);
+ str += sprintf(str, "intRx0Count = %u\n", tdm_ext_stats.intRx0Count);
+ str += sprintf(str, "intTx0Count = %u\n", tdm_ext_stats.intTx0Count);
+ str += sprintf(str, "intRx1Count = %u\n", tdm_ext_stats.intRx1Count);
+ str += sprintf(str, "intTx1Count = %u\n", tdm_ext_stats.intTx1Count);
+ str += sprintf(str, "intRx0Miss = %u\n", tdm_ext_stats.intRx0Miss);
+ str += sprintf(str, "intTx0Miss = %u\n", tdm_ext_stats.intTx0Miss);
+ str += sprintf(str, "intRx1Miss = %u\n", tdm_ext_stats.intRx1Miss);
+ str += sprintf(str, "intTx1Miss = %u\n", tdm_ext_stats.intTx1Miss);
+ str += sprintf(str, "pcmRestartCount = %u\n", tdm_ext_stats.pcmRestartCount);
+
+ return (int)(str - buffer);
+}
+#endif
+
MV_STATUS tdm_if_init(tdm_if_register_ops_t* register_ops, tdm_if_params_t* tdm_if_params)
{
MV_TDM_PARAMS tdm_params;
-
+
+ if (tdm_init) {
+ printk("Marvell Telephony Driver already started...\n");
+ return MV_OK;
+ }
+
printk("Loading Marvell Telephony Driver\n");
/* Check if any SLIC module exists */
- if(mvBoardTdmDevicesCountGet() == 0) {
+ if (mvBoardTdmDevicesCountGet() == 0) {
mvCtrlPwrClckSet(TDM_32CH_UNIT_ID, 0, MV_FALSE);
mvCtrlPwrClckSet(TDM_2CH_UNIT_ID, 0, MV_FALSE);
printk("%s: Warning, no SLIC module is connected\n",__FUNCTION__);
@@ -180,22 +228,22 @@
}
/* Shut down unused unit */
- if(mvCtrlTdmUnitTypeGet() == TDM_2CH_UNIT_ID) {
+ if (mvCtrlTdmUnitTypeGet() == TDM_2CH_UNIT_ID) {
mvCtrlPwrClckSet(TDM_32CH_UNIT_ID, 0, MV_FALSE);
}
else { /* TDM_32CH_UNIT_ID */
mvCtrlPwrClckSet(TDM_2CH_UNIT_ID, 0, MV_FALSE);
}
- if((register_ops == NULL) || (tdm_if_params == NULL)) {
+ if ((register_ops == NULL) || (tdm_if_params == NULL)) {
printk("%s: bad parameters\n",__FUNCTION__);
return MV_ERROR;
}
/* Check callbacks */
- if(register_ops->tdm_if_pcm_ops.pcm_tx_callback == NULL ||
- register_ops->tdm_if_pcm_ops.pcm_rx_callback == NULL ) {
+ if (register_ops->tdm_if_pcm_ops.pcm_tx_callback == NULL ||
+ register_ops->tdm_if_pcm_ops.pcm_rx_callback == NULL ) {
printk("%s: missing parameters\n",__FUNCTION__);
return MV_ERROR;
}
@@ -209,6 +257,8 @@
#endif
irq_init = 0;
tdm_init = 0;
+ pcm_stop_flag = 0;
+ pcm_stop_status = 0;
/* Extract test enable */
test_enable = tdm_if_params->test_enable;
@@ -233,8 +283,13 @@
tdm_if_register_ops->tdm_if_ctl_ops.ctl_pcm_start = tdm_if_pcm_start;
tdm_if_register_ops->tdm_if_ctl_ops.ctl_pcm_stop = tdm_if_pcm_stop;
+ /* Soft reset to PCM I/F */
+#ifdef CONFIG_MV_TDM_SUPPORT
+ mvTdmPcmIfReset();
+#endif
+
/* TDM init */
- if(mvSysTdmInit(&tdm_params) != MV_OK) {
+ if (mvSysTdmInit(&tdm_params) != MV_OK) {
printk("%s: Error, TDM initialization failed !!!\n",__FUNCTION__);
return MV_ERROR;
}
@@ -257,11 +312,16 @@
/* Create TDM procFS statistics */
tdm_stats = proc_mkdir("tdm", NULL);
- create_proc_read_entry("tdm_init", 0, tdm_stats, proc_tdm_init_read, NULL);
- create_proc_read_entry("rx_miss", 0, tdm_stats, proc_rx_miss_read, NULL);
- create_proc_read_entry("tx_miss", 0, tdm_stats, proc_tx_miss_read, NULL);
- create_proc_read_entry("rx_over", 0, tdm_stats, proc_rx_over_read, NULL);
- create_proc_read_entry("tx_under", 0, tdm_stats, proc_tx_under_read, NULL);
+ if (tdm_stats != NULL) {
+ create_proc_read_entry("tdm_init", 0, tdm_stats, proc_tdm_init_read, NULL);
+ create_proc_read_entry("rx_miss", 0, tdm_stats, proc_rx_miss_read, NULL);
+ create_proc_read_entry("tx_miss", 0, tdm_stats, proc_tx_miss_read, NULL);
+ create_proc_read_entry("rx_over", 0, tdm_stats, proc_rx_over_read, NULL);
+ create_proc_read_entry("tx_under", 0, tdm_stats, proc_tx_under_read, NULL);
+#ifdef CONFIG_MV_TDM_EXT_STATS
+ create_proc_read_entry("tdm_extended_stats", 0, tdm_stats, proc_dump_ext_stats, NULL);
+#endif
+ }
TRC_REC("Marvell Telephony Driver Loaded Successfully\n");
@@ -278,12 +338,12 @@
void tdm_if_exit(void)
{
/* Check if already stopped */
- if(!irq_init && !pcm_enable && !tdm_init)
+ if (!irq_init && !pcm_enable && !tdm_init)
return;
TRC_REC("->%s\n",__FUNCTION__);
- if(irq_init) {
+ if (irq_init) {
/* Release interrupt */
#ifndef CONFIG_MV_PHONE_USE_FIQ_PROCESSING
free_irq(irqnr, NULL);
@@ -294,26 +354,29 @@
}
/* Stop PCM data sampling */
- if(pcm_enable)
+ if (pcm_enable)
tdm_if_pcm_stop();
- if(tdm_init) {
+ if (tdm_init) {
#ifdef CONFIG_MV_TDM_SUPPORT
mvTdmRelease();
#else
mvCommUnitRelease();
#endif
+ /* Remove proc directory & entries */
+ remove_proc_entry("tdm_init", tdm_stats);
+ remove_proc_entry("rx_miss", tdm_stats);
+ remove_proc_entry("tx_miss", tdm_stats);
+ remove_proc_entry("rx_over", tdm_stats);
+ remove_proc_entry("tx_under", tdm_stats);
+#ifdef CONFIG_MV_TDM_EXT_STATS
+ remove_proc_entry("tdm_extended_stats", tdm_stats);
+#endif
+ remove_proc_entry("tdm", NULL);
+
tdm_init = 0;
}
- /* Remove proc directory & entries */
- remove_proc_entry("tdm_init", tdm_stats);
- remove_proc_entry("rx_miss", tdm_stats);
- remove_proc_entry("tx_miss", tdm_stats);
- remove_proc_entry("rx_over", tdm_stats);
- remove_proc_entry("tx_under", tdm_stats);
- remove_proc_entry("tdm", NULL);
-
TRC_REC("<-%s\n",__FUNCTION__);
/* Dump output and release Marvell trace resources */
@@ -328,8 +391,10 @@
TRC_REC("->%s\n",__FUNCTION__);
spin_lock_irqsave(&tdm_if_lock, flags);
- if(!pcm_enable) {
+ if (!pcm_enable) {
rxBuff = txBuff = NULL;
+ pcm_stop_flag = 0;
+ pcm_stop_status = 0;
pcm_enable = 1;
#ifdef CONFIG_MV_TDM_SUPPORT
mvTdmPcmStart();
@@ -350,9 +415,8 @@
TRC_REC("->%s\n",__FUNCTION__);
spin_lock_irqsave(&tdm_if_lock, flags);
- if(pcm_enable) {
+ if (pcm_enable) {
pcm_enable = 0;
- rxBuff = txBuff = NULL;
#ifdef CONFIG_MV_TDM_SUPPORT
mvTdmPcmStop();
#else
@@ -369,12 +433,15 @@
{
MV_TDM_INT_INFO tdm_int_info;
unsigned int int_type;
+#ifdef CONFIG_MV_TDM_SUPPORT
+ int ret;
+#endif
TRC_REC("->%s\n",__FUNCTION__);
/* Extract interrupt information from low level ISR */
#ifdef CONFIG_MV_TDM_SUPPORT
- mvTdmIntLow(&tdm_int_info);
+ ret = mvTdmIntLow(&tdm_int_info);
#else
mvCommUnitIntLow(&tdm_int_info);
#endif
@@ -383,13 +450,34 @@
/*device_id = tdm_int_info.cs;*/
/* Nothing to do - return */
- if(int_type == MV_EMPTY_INT)
+ if (int_type == MV_EMPTY_INT)
goto out;
+#ifdef CONFIG_MV_TDM_SUPPORT
+ if ((ret == -1) && (pcm_stop_status == 0)) {
+ pcm_stop_status = 1;
+
+ /* If Rx/Tx tasklets already scheduled, let them do the work. */
+ if ((!rxBuff) && (!txBuff)) {
+ TRC_REC("Stopping the TDM\n");
+ tdm_if_pcm_stop();
+ pcm_stop_flag = 0;
+ tasklet_hi_schedule(&tdm_if_stop_tasklet);
+ } else {
+ TRC_REC("Some tasklet is running, mark pcm_stop_flag\n");
+ pcm_stop_flag = 1;
+ }
+ }
+
+ /* Restarting PCM, skip Rx/Tx handling */
+ if (pcm_stop_status)
+ goto skip_rx_tx;
+#endif
+
/* Support multiple interrupt handling */
/* RX interrupt */
- if(int_type & MV_RX_INT) {
- if(rxBuff != NULL) {
+ if (int_type & MV_RX_INT) {
+ if (rxBuff != NULL) {
rx_miss++;
TRC_REC("%s: Warning, missed Rx buffer processing !!!\n",__FUNCTION__);
}
@@ -407,8 +495,8 @@
}
/* TX interrupt */
- if(int_type & MV_TX_INT) {
- if(txBuff != NULL) {
+ if (int_type & MV_TX_INT) {
+ if (txBuff != NULL) {
tx_miss++;
TRC_REC("%s: Warning, missed Tx buffer processing !!!\n",__FUNCTION__);
}
@@ -425,17 +513,20 @@
}
}
+#ifdef CONFIG_MV_TDM_SUPPORT
+skip_rx_tx:
+#endif
/* PHONE interrupt */
- if(int_type & MV_PHONE_INT) {
+ if (int_type & MV_PHONE_INT) {
/* TBD */
}
/* ERROR interrupt */
- if(int_type & MV_ERROR_INT) {
- if(int_type & MV_RX_ERROR_INT)
+ if (int_type & MV_ERROR_INT) {
+ if (int_type & MV_RX_ERROR_INT)
rx_over++;
- if(int_type & MV_TX_ERROR_INT)
+ if (int_type & MV_TX_ERROR_INT)
tx_under++;
}
@@ -451,8 +542,10 @@
static void tdm_if_pcm_rx_process(unsigned long arg)
#endif
{
+ unsigned long flags;
+
TRC_REC("->%s\n",__FUNCTION__);
- if(pcm_enable) {
+ if (pcm_enable) {
if(rxBuff == NULL) {
TRC_REC("%s: Error, empty Rx processing\n",__FUNCTION__);
return;
@@ -460,10 +553,10 @@
/* Fill TDM Rx aggregated buffer */
#ifdef CONFIG_MV_TDM_SUPPORT
- if(mvTdmRx(rxBuff) == MV_OK)
+ if (mvTdmRx(rxBuff) == MV_OK)
tdm_if_register_ops->tdm_if_pcm_ops.pcm_rx_callback(rxBuff, buff_size); /* Dispatch Rx handler */
#else
- if(mvCommUnitRx(rxBuff) == MV_OK) {
+ if (mvCommUnitRx(rxBuff) == MV_OK) {
tdm_if_register_ops->tdm_if_pcm_ops.pcm_rx_callback(rxBuff, buff_size); /* Dispatch Rx handler */
/* Since data buffer is shared among MCDMA and CPU, need to invalidate
before it accessed by MCDMA */
@@ -474,10 +567,22 @@
printk("%s: could not fill Rx buffer\n",__FUNCTION__);
}
-
+
+ spin_lock_irqsave(&tdm_if_lock, flags);
+
/* Clear rxBuff for next iteration */
rxBuff = NULL;
+#ifdef CONFIG_MV_TDM_SUPPORT
+ if ((pcm_stop_flag == 1) && !txBuff) {
+ TRC_REC("Stopping TDM from Rx tasklet\n");
+ tdm_if_pcm_stop();
+ pcm_stop_flag = 0;
+ tasklet_hi_schedule(&tdm_if_stop_tasklet);
+ }
+#endif
+ spin_unlock_irqrestore(&tdm_if_lock, flags);
+
TRC_REC("<-%s\n",__FUNCTION__);
return;
}
@@ -489,10 +594,12 @@
static void tdm_if_pcm_tx_process(unsigned long arg)
#endif
{
+ unsigned long flags;
+
TRC_REC("->%s\n",__FUNCTION__);
- if(pcm_enable) {
- if(txBuff == NULL) {
+ if (pcm_enable) {
+ if (txBuff == NULL) {
TRC_REC("%s: Error, empty Tx processing\n",__FUNCTION__);
return;
}
@@ -500,7 +607,7 @@
/* Dispatch Tx handler */
tdm_if_register_ops->tdm_if_pcm_ops.pcm_tx_callback(txBuff, buff_size);
- if(test_enable == 0) {
+ if (test_enable == 0) {
/* Fill Tx aggregated buffer */
#ifdef CONFIG_MV_TDM_SUPPORT
if(mvTdmTx(txBuff) != MV_OK)
@@ -511,9 +618,21 @@
}
}
+ spin_lock_irqsave(&tdm_if_lock, flags);
+
/* Clear txBuff for next iteration */
txBuff = NULL;
+#ifdef CONFIG_MV_TDM_SUPPORT
+ if ((pcm_stop_flag == 1) && !rxBuff) {
+ TRC_REC("Stopping TDM from Tx tasklet\n");
+ tdm_if_pcm_stop();
+ pcm_stop_flag = 0;
+ tasklet_hi_schedule(&tdm_if_stop_tasklet);
+ }
+#endif
+ spin_unlock_irqrestore(&tdm_if_lock, flags);
+
TRC_REC("<-%s\n",__FUNCTION__);
return;
}
@@ -525,10 +644,39 @@
tdm_if_stats->tx_miss = tx_miss;
tdm_if_stats->rx_over = rx_over;
tdm_if_stats->tx_under = tx_under;
-
+#ifdef CONFIG_MV_TDM_EXT_STATS
+ mvTdmExtStatsGet(&tdm_if_stats->tdm_ext_stats);
+#endif
return;
}
+#ifdef CONFIG_MV_TDM_SUPPORT
+static void tdm_if_stop_channels(unsigned long arg)
+{
+ u32 max_poll = 0;
+ unsigned long flags;
+
+ TRC_REC("->%s\n",__FUNCTION__);
+
+ /* Wait for all channels to stop */
+ while (((MV_REG_READ(CH_ENABLE_REG(0)) & 0x101) || (MV_REG_READ(CH_ENABLE_REG(1)) & 0x101)) && (max_poll < 30)) {
+ mdelay(1);
+ max_poll++;
+ }
+
+ TRC_REC("Finished polling on channels disable\n");
+ if (max_poll >= 30)
+ printk("\n\npolling on channels disabling exceeded 30ms\n\n");
+
+ spin_lock_irqsave(&tdm_if_lock, flags);
+ tdm_if_pcm_start();
+ spin_unlock_irqrestore(&tdm_if_lock, flags);
+
+ TRC_REC("<-%s\n",__FUNCTION__);
+ return;
+}
+#endif
+
static int __init tdm_if_module_init(void)
{
/* The real init is done later */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.h
index 964cef0..a1f1634 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_phone/tdm/tdm_if.h
@@ -84,6 +84,9 @@
unsigned int tx_miss;
unsigned int rx_over;
unsigned int tx_under;
+#ifdef CONFIG_MV_TDM_EXT_STATS
+ MV_TDM_EXTENDED_STATS tdm_ext_stats;
+#endif
} tdm_if_stats_t;
typedef struct {
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.c
index 6bcf46b..3fad804 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.c
@@ -757,35 +757,82 @@
**
** onuEponLinkIsUp
** ____________________________________________________________________________
-**
+**
** DESCRIPTION: The function register Link Status callback function
-**
+**
** PARAMETERS: None
**
** OUTPUTS: None
**
** RETURNS: MV_TRUE or MV_FLASE
-**
+**
*******************************************************************************/
MV_BOOL onuEponLinkIsUp(void)
{
- MV_U32 mode;
+ MV_U32 mode;
- mode = onuEponDbModeGet();
+ mode = onuEponDbModeGet();
- if (onuEponForceTxDownStateGet(0) == MV_TRUE)
- return(MV_TRUE);
+ if (onuEponForceTxDownStateGet(0) == MV_TRUE)
+ {
+ return (MV_TRUE);
+ }
- if (mode == E_EPON_IOCTL_STD_MODE)
- {
- if (onuEponDbOnuStateGet(0) == ONU_EPON_03_OPERATION) return(MV_TRUE);
- else return(MV_FALSE);
- }
- else /* P2P */
- {
- if (onuEponDbOnuSignalDetectGet() == 1) return(MV_TRUE);
- else return(MV_FALSE);
- }
+ if (mode == E_EPON_IOCTL_STD_MODE)
+ {
+ if (onuEponDbOnuStateGet(0) == ONU_EPON_03_OPERATION)
+ {
+ return (MV_TRUE);
+ }
+ else
+ {
+ return (MV_FALSE);
+ }
+ }
+ else /* P2P */
+ {
+ if (onuEponDbOnuSignalDetectGet() == 1)
+ {
+ mvPonPrint(PON_PRINT_DEBUG, PON_API_MODULE,
+ "DEBUG: (%s:%d) onuPonLinkIsUp, UP\n", __FILE_DESC__, __LINE__);
+ return (MV_TRUE);
+ }
+ else
+ {
+ mvPonPrint(PON_PRINT_DEBUG, PON_API_MODULE,
+ "DEBUG: (%s:%d) onuPonLinkIsUp, DOWN\n", __FILE_DESC__, __LINE__);
+ return (MV_FALSE);
+ }
+ }
+}
+
+MV_STATUS mvEponApi2kSupportedSet(MV_U32 pkt2kSupported)
+{
+ MV_STATUS status;
+ MV_U32 devId;
+
+ devId = mvCtrlModelGet();
+ if (devId != MV_6601_DEV_ID)
+ {
+ return(MV_OK);
+ }
+
+ //status = mvOnuEponMacPcsRxEnableSet(EPON_PCS_CONFIG_RX_DISABLE);
+
+ if (pkt2kSupported == 1) /* 2K packet supported */
+ {
+ status |= mvOnuEponMacPcsFrameSizeLimitsSet(EPON_MAC_PCS_FRAME_SIZE_LIMIT_SIZE_2K_SUPP,
+ EPON_MAC_PCS_FRAME_SIZE_LIMIT_LATENCY_2K_SUPP);
+ status |= mvOnuEponMacRxpDataFifoThresholdSet(EPON_MAC_RXP_DATA_FIFO_THRESHOLD_2K_SUPP);
+ }
+ else if (pkt2kSupported == 0)
+ {
+ status |= mvOnuEponMacPcsFrameSizeLimitsSet(EPON_MAC_PCS_FRAME_SIZE_LIMIT_SIZE_DEF,
+ EPON_MAC_PCS_FRAME_SIZE_LIMIT_LATENCY_DEF);
+ status |= mvOnuEponMacRxpDataFifoThresholdSet(EPON_MAC_RXP_DATA_FIFO_THRESHOLD_DEF);
+ }
+
+ return (status);
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.h
index cd4eebd..9e23984 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuApi.h
@@ -142,6 +142,9 @@
MV_STATUS onuEponApiLinkStatusCallbackRegister(void);
MV_BOOL onuEponLinkIsUp(void);
+/* Config API */
+MV_STATUS mvEponApi2kSupportedSet(MV_U32 pkt2kSupported);
+
/* Macros
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.c
index 040d80b..c5bcf3b 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.c
@@ -2009,6 +2009,49 @@
/*******************************************************************************
**
+** onuEponDbP2PForceModeSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function sets EPON P2P Force mode in the database
+**
+** PARAMETERS: MV_U32 mode
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuEponDbP2PForceModeSet(MV_U32 forceMode)
+{
+ if (forceMode >= E_EPON_IOCTL_MAX_MODE_NUM)
+ return(MV_ERROR);
+
+ onuEponDb_s.onuEponGenTbl_s.onuEponP2PForceMode = forceMode;
+
+ return(MV_OK);
+}
+
+/*******************************************************************************
+**
+** onuEponDbP2PForceModeGet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function returns current EPON P2P Force mode
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_U32 mode
+**
+*******************************************************************************/
+MV_U32 onuEponDbP2PForceModeGet(void)
+{
+ return(onuEponDb_s.onuEponGenTbl_s.onuEponP2PForceMode);
+}
+
+/*******************************************************************************
+**
** onuEponDbPcsCfgSet
** ____________________________________________________________________________
**
@@ -2089,10 +2132,10 @@
/*******************************************************************************
**
-** onuEponDbXvrPolaritySet
+** onuEponDbBurstEnablePolaritySet
** ____________________________________________________________________________
**
-** DESCRIPTION: The function sets EPON XVR polarity register value in the database
+** DESCRIPTION: The function sets EPON XVR burst enable polarity value in the database
**
** PARAMETERS: MV_U32 val
**
@@ -2101,30 +2144,30 @@
** RETURNS: MV_OK or error
**
*******************************************************************************/
-MV_STATUS onuEponDbXvrPolaritySet(MV_U32 val)
+MV_STATUS onuEponDbBurstEnablePolaritySet(MV_U32 val)
{
- onuEponDb_s.onuEponGenTbl_s.onuEponXvrPolarity = val;
+ onuEponDb_s.onuEponGenTbl_s.onuEponXvrBurstEnPolarity = val;
return(MV_OK);
}
/*******************************************************************************
**
-** onuEponDbXvrPolarityGet
+** onuEponDbBurstEnablePolarityGet
** ____________________________________________________________________________
**
-** DESCRIPTION: The function returns EPON XVR polarity register value
+** DESCRIPTION: The function gets EPON XVR burst enable polarity value in the database
**
** PARAMETERS: None
**
** OUTPUTS: None
**
-** RETURNS: MV_U32 mode
+** RETURNS: polarity
**
*******************************************************************************/
-MV_U32 onuEponDbXvrPolarityGet(void)
+MV_U32 onuEponDbBurstEnablePolarityGet(void)
{
- return(onuEponDb_s.onuEponGenTbl_s.onuEponXvrPolarity);
+ return onuEponDb_s.onuEponGenTbl_s.onuEponXvrBurstEnPolarity;
}
/*******************************************************************************
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.h
index 120be03..df2003e 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuDb.h
@@ -353,10 +353,11 @@
DYINGGASPFUNC onuDgCallback;
LINKSTATUSFUNC onuLinkStatusCallback;
MV_U32 onuEponMode;
+ MV_U32 onuEponP2PForceMode;
MV_U32 onuEponPcsCfg;
MV_U32 onuEponOverHead;
MV_U32 onuEponPhyOutput;
- MV_U32 onuEponXvrPolarity;
+ MV_U32 onuEponXvrBurstEnPolarity;
}S_OnuEponGenTbl;
/* ONU EPON Data Path tables */
@@ -506,12 +507,14 @@
MV_STATUS onuEponDbModeSet(MV_U32 mode);
MV_U32 onuEponDbModeGet(void);
+MV_STATUS onuEponDbP2PForceModeSet(MV_U32 mode);
+MV_U32 onuEponDbP2PForceModeGet(void);
MV_STATUS onuEponDbPcsCfgSet(MV_U32 val);
MV_U32 onuEponDbPcsCfgGet(void);
MV_STATUS onuEponDbOverheadSet(MV_U32 val);
MV_U32 onuEponDbOverheadGet(void);
-MV_STATUS onuEponDbXvrPolaritySet(MV_U32 val);
-MV_U32 onuEponDbXvrPolarityGet(void);
+MV_STATUS onuEponDbBurstEnablePolaritySet(MV_U32 val);
+MV_U32 onuEponDbBurstEnablePolarityGet(void);
/* Macros
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuInit.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuInit.c
index 9c31f1f..5df06f0 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuInit.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuInit.c
@@ -139,6 +139,7 @@
return(MV_ERROR);
}
+ ponXvrFunc = EponXvrSDPolarityHighStatus;
/* init onu database */
rcode = onuEponDbInit();
if (rcode != MV_OK)
@@ -416,8 +417,7 @@
return(MV_ERROR);
}
- onuEponDbXvrPolaritySet(ONU_DEF_DDM_CFG_POLARITY_HIGH);
- mvOnuPonMacBurstEnablePolarityInit(ONU_DEF_DDM_CFG_POLARITY_HIGH);
+ onuEponDbBurstEnablePolaritySet(ONU_DEF_DDM_CFG_POLARITY_HIGH);
status = mvOnuEponMacGpmDiscoveryGrantLengthSet(0x26, /* grantLength */
0x06, /* addOffsetForCalc */
@@ -854,7 +854,6 @@
return(status);
}
-
/* Enable MAC */
status = mvOnuEponMacOnuRxEnableSet(ONU_RX_EN);
if (status != MV_OK)
@@ -940,7 +939,7 @@
}
/* re-set DDM polarity */
- status = mvOnuEponMacDdmTxPolaritySet(ONU_DEF_DDM_CFG_TX_EN_OR, ioctlInit->xvrPolarity);
+ status = mvOnuEponMacDdmTxPolaritySet(ONU_DEF_DDM_CFG_TX_EN_OR, ioctlInit->ponXvrBurstEnPolarity);
if (status != MV_OK)
{
mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
@@ -948,8 +947,9 @@
return(MV_ERROR);
}
- onuEponDbXvrPolaritySet(ioctlInit->xvrPolarity);
- mvOnuPonMacBurstEnablePolarityInit(ioctlInit->xvrPolarity);
+ ponXvrFunc = funcEponXvrSDStatus(ioctlInit->ponXvrPolarity);
+
+ onuP2PDbXvrBurstEnablePolaritySet(ioctlInit->p2pXvrBurstEnPolarity);
#ifndef PON_FPGA
/* enable onu dying gasp interrupt mask */
@@ -962,6 +962,14 @@
}
#endif /* PON_FPGA */
+ status = mvEponApi2kSupportedSet(ioctlInit->pkt2kSupported);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) mvEponApi2kSupportedSet\r\n", __FILE_DESC__, __LINE__);
+ return(status);
+ }
+
return(MV_OK);
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuIsr.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuIsr.c
index 733e8e8..654e56f 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuIsr.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuIsr.c
@@ -165,7 +165,7 @@
MV_U32 rxGenFecEn = 0;
MV_U32 interruptEvent = 0;
MV_U32 interruptStatus = 0;
-
+ LINKSTATUSFUNC linkStatusCallback;
#ifdef MV_EPON_HW_INTERRUPT
onuEponIsrLowRoutine(&interruptEvent, &interruptStatus);
@@ -178,12 +178,19 @@
/* ================= */
if (interruptEvent & ONU_EPON_XVR_SD_MASK) {
-
- state = (interruptStatus & ONU_EPON_XVR_SD_MASK) ? MV_FALSE : MV_TRUE;
+ state = ponXvrFunc(interruptStatus, ONU_EPON_XVR_SD_MASK);
if (state == MV_FALSE)
+ {
onuEponDbOnuSignalDetectSet(1); /* alarm is OFF */
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_INT_MODULE,
+ "DEBUG: (%s:%d) Signal Detect ON\n", __FILE_DESC__, __LINE__);
+ }
else if (state == MV_TRUE)
+ {
onuEponDbOnuSignalDetectSet(0);/* alarm is ON */
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_INT_MODULE,
+ "DEBUG: (%s:%d) Signal Detect OFF\n", __FILE_DESC__, __LINE__);
+ }
onuEponPonMngIntrAlarmHandler(ONU_EPON_XVR_SD_MASK, state);
@@ -203,10 +210,31 @@
"DEBUG: (%s:%d) ResetRandomStateMachine %s\n", __FILE_DESC__, __LINE__);
onuEponIsrResetRandomStateMachine();
- } else if (state == MV_TRUE) { /* alarm is ON */
-
- /* set EPON mode */
- onuEponDbModeSet(E_EPON_IOCTL_STD_MODE);
+ /* Call link status callback function */
+ if (onuEponDbModeGet() == E_EPON_IOCTL_P2P_MODE)
+ {
+ linkStatusCallback = onuEponDbLinkStatusCallbackGet();
+ if (linkStatusCallback != NULL)
+ {
+ linkStatusCallback(MV_TRUE);
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_INT_MODULE,
+ "DEBUG: (%s:%d) Notify link is UP\n", __FILE_DESC__, __LINE__);
+ }
+ }
+ }
+ else if (state == MV_TRUE) /* alarm is ON */
+ {
+ if (onuEponDbP2PForceModeGet())
+ {
+ /* set P2P mode */
+ onuEponDbModeSet(E_EPON_IOCTL_P2P_MODE);
+ }
+ else
+ {
+ /* set EPON mode */
+ onuEponDbModeSet(E_EPON_IOCTL_STD_MODE);
+ }
+
/* config PCS synchronization configuration - FEC disabled */
mvOnuEponMacPcsDelaySet(0x1C58);
/* clear Rx Ctrl message FIFO */
@@ -912,8 +940,22 @@
MV_U32 gpioGroup, gpioMask;
MV_U32 interruptMask;
MV_U32 polarity;
-
+ MV_U32 interruptStatus;
+ MV_U32 state;
LINKSTATUSFUNC linkStatusCallback;
+ /* Check for XVR SD interrupt status */
+ mvOnuEponMacPonInterruptGet(&interruptStatus);
+ interruptStatus &= 0xFFFF;
+
+ state = ponXvrFunc(interruptStatus, ONU_EPON_XVR_SD_MASK);
+ if (state == MV_FALSE)
+ {
+ onuEponDbOnuSignalDetectSet(1); /* alarm is OFF */
+ }
+ else if (state == MV_TRUE)
+ {
+ onuEponDbOnuSignalDetectSet(0);/* alarm is ON */
+ }
if (onuEponDbOnuSwRprtTimerTypeGet() == ONU_EPON_SW_DBA_RPRT_TIMER)
{
@@ -1108,7 +1150,7 @@
return(MV_ERROR);
}
- polarity = onuEponDbXvrPolarityGet();
+ polarity = onuP2PDbXvrBurstEnablePolarityGet();
/* XVR polarity */
/* XVR polarity == 0, Active High, transmit 1 to the line */
@@ -1123,7 +1165,7 @@
/* XVR polarity == 1, Active Low, write 0 for Force Value */
/* PHY control register - force enable value - according to polarity */
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_FORCE_BEN_IO_VAL, ~polarity, 0);
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_FORCE_BEN_IO_VAL, polarity, 0);
if (status != MV_OK)
{
mvPonPrint(PON_PRINT_ERROR, PON_ISR_MODULE,
@@ -1156,7 +1198,9 @@
linkStatusCallback = onuEponDbLinkStatusCallbackGet();
if (linkStatusCallback != NULL)
{
- linkStatusCallback(MV_TRUE);
+ linkStatusCallback(MV_TRUE);
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_INT_MODULE,
+ "DEBUG: (%s:%d) Notify link is UP\n", __FILE_DESC__, __LINE__);
}
#endif
@@ -1338,8 +1382,16 @@
}
}
- onuEponDbModeSet(E_EPON_IOCTL_STD_MODE);
-
+ if (onuEponDbP2PForceModeGet())
+ {
+ /* set P2P mode */
+ onuEponDbModeSet(E_EPON_IOCTL_P2P_MODE);
+ }
+ else
+ {
+ /* set EPON mode */
+ onuEponDbModeSet(E_EPON_IOCTL_STD_MODE);
+ }
if (onuEponDbOnuSwRprtTimerTypeGet() == ONU_EPON_SW_DBA_RPRT_TIMER)
{
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.c
index c889c69..e97ff32 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.c
@@ -627,7 +627,11 @@
if (linkStatusCallback != NULL)
{
if (onuEponForceTxDownStateGet(0) != MV_TRUE)
- linkStatusCallback(MV_FALSE);
+ {
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_INT_MODULE,
+ "DEBUG: (%s:%d) Notify link is DOWN\n", __FILE_DESC__, __LINE__);
+ linkStatusCallback(MV_FALSE);
+ }
}
if (onuEponDbOnuHoldoverStateGet() != ONU_HOLDOVER_NOT_ACTIVE)
@@ -924,6 +928,7 @@
mvPonPrint(PON_PRINT_ERROR, PON_MNG_MODULE,
"ERROR: (%s:%d) Handle Rx Ctrl Frame\n\r", __FILE_DESC__, __LINE__);
onuEponPmSwRxCountersAdd(TOTAL_MPCP_RX_ERROR_FRAME_CNT, 0);
+ return;
}
} while (status == MV_OK);
@@ -947,6 +952,7 @@
mvPonPrint(PON_PRINT_ERROR, PON_MNG_MODULE,
"ERROR: (%s:%d) Unsupported Frame\n\r", __FILE_DESC__, __LINE__);
+ return;
}
}
@@ -1999,6 +2005,8 @@
linkStatusCallback = onuEponDbLinkStatusCallbackGet();
if (linkStatusCallback != NULL)
{
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_INT_MODULE,
+ "DEBUG: (%s:%d) Notify link is UP\n", __FILE_DESC__, __LINE__);
linkStatusCallback(MV_TRUE);
}
@@ -3105,3 +3113,37 @@
return(status);
}
+/*******************************************************************************
+**
+** onuEponTimerTxPwrHndl
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function start / stop 1 sec timer that will disable Tx if
+** expired
+**
+** PARAMETERS: unsigned long data
+**
+** OUTPUTS: None
+**
+** RETURNS: None
+**
+*******************************************************************************/
+void onuEponTimerTxPwrHndl(unsigned long data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&onuPonIrqLock, flags);
+
+ onuPonResourceTbl_s.onuPonTxPwrTimerId.onuPonTimerActive = ONU_PON_TIMER_NOT_ACTIVE;
+
+ if (onuEponDbOnuStateGet(0) < ONU_EPON_03_OPERATION)
+ {
+ onuPonTxPowerOn(MV_FALSE);
+ }
+
+ onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonTxPwrTimerId));
+
+ spin_unlock_irqrestore(&onuPonIrqLock, flags);
+}
+
+
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.h
index 7db46f0..c5afad8 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/epon/eponOnuMngr.h
@@ -131,6 +131,8 @@
void onuEponPonMngTimerHwRprtTxModHndl(unsigned long data);
MV_STATUS onuEponPonMngTimerHwRprtCfg(MV_U32 t0_val, MV_U32 t0_time, MV_U32 t1_val, MV_U32 t1_time);
+void onuEponTimerTxPwrHndl(unsigned long data);
+
/* Macros
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.c
index d23c1ac..5442fac 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.c
@@ -165,7 +165,7 @@
** RETURNS: MV_TRUE or MV_FALSE
**
*******************************************************************************/
-MV_BOOL onuGponAllocIdMacAllocExistCheck(MV_U32 allocId, MV_U32 *entry)
+MV_BOOL onuGponAllocIdMacAllocExistCheck(MV_U32 allocId, MV_U32 *entry, MV_U32 *tcont)
{
MV_U32 iEntry;
MV_U32 macAllocId;
@@ -177,6 +177,7 @@
status = mvOnuGponMacRxBwMapGet(iEntry,&macAllocId,&valid,&tcontNum);
if ((status == MV_OK) && (macAllocId == allocId) && (valid == MV_TRUE)) {
*entry = iEntry;
+ *tcont = tcontNum;
return (MV_TRUE);
}
}
@@ -234,14 +235,24 @@
*******************************************************************************/
MV_STATUS onuGponAllocIdMacAdd(MV_U32 allocId, MV_U32 tcontId)
{
- MV_U32 entry;
- MV_BOOL exist;
+ MV_STATUS status = MV_OK;
+ MV_U32 entry;
+ MV_BOOL exist;
exist = onuGponAllocIdMacAllocFreeEntryGet(&entry);
if (exist == MV_FALSE)
return (MV_ERROR);
- return (mvOnuGponMacRxBwMapSet(entry, allocId, tcontId, MV_TRUE));
+ status = mvOnuGponMacRxBwMapSet(entry, allocId, tcontId, MV_TRUE);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ "ERROR: (%s:%d) onuGponAllocIdMacAdd, failed to add alloc Id(%d) entry(%d)\n",
+ __FILE_DESC__, __LINE__, allocId, entry);
+ return (status);
+ }
+
+ return (status);
}
/*******************************************************************************
@@ -264,13 +275,20 @@
MV_STATUS status;
MV_BOOL exist;
MV_U32 entry;
+ MV_U32 tcont;
MV_U32 newIdleTcontEntry;
MV_U32 freeTcontEntry;
MV_U32 entryAllocId;
MV_U32 bwMapEntry;
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) AllocIdMacConnect, AllocId(%d), Tcont(%d)\n",
+ __FILE_DESC__, __LINE__, allocId, tcontNum);
+#endif /* MV_GPON_DEBUG_PRINT */
+
/* validate that requested alloc-Id is configured in HW and is valid */
- exist = onuGponAllocIdMacAllocExistCheck(allocId, &entry);
+ exist = onuGponAllocIdMacAllocExistCheck(allocId, &entry, &tcont);
if (exist != MV_TRUE) {
mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
"ERROR: (%s:%d) onuGponAllocIdMacConnect, alloc Id(%d) entry(%d)\n",
@@ -300,7 +318,7 @@
onuGponDbBwIdleAllocGet(newIdleTcontEntry, &entryAllocId);
if (entryAllocId != PON_ONU_ALLOC_NOT_EXIST) {
/* Check if this idle Alloc ID exists in the HW table */
- exist = onuGponAllocIdMacAllocExistCheck(entryAllocId, &bwMapEntry);
+ exist = onuGponAllocIdMacAllocExistCheck(entryAllocId, &bwMapEntry, &tcont);
if (exist == MV_TRUE) {
/* re-assign this Alloc ID to the new idle Tcont in HW */
status = mvOnuGponMacRxBwMapSet(bwMapEntry, entryAllocId, onuIdleAllocTcont, MV_TRUE);
@@ -323,7 +341,25 @@
} /* tcontNum == onuIdleAllocTcont */
/* update input Alloc-Id and T-Cont in the HW */
- return (mvOnuGponMacRxBwMapSet(entry, allocId, tcontNum, MV_TRUE));
+ status = mvOnuGponMacRxBwMapSet(entry, allocId, tcontNum, MV_TRUE);
+
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) AllocIdMacConnect, tpm_active_tcont, Tcont(%d)\n",
+ __FILE_DESC__, __LINE__, tcontNum);
+#endif /* MV_GPON_DEBUG_PRINT */
+
+ printk("TCONT (%d) active, Connect\n", tcontNum);
+ status = onuGponWqTcontActivate(tcontNum);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ "ERROR: (%s:%d) onuGponAllocIdMacAdd, failed to schedule T-Cont(%d) activate in WQ\n",
+ __FILE_DESC__, __LINE__, tcontNum);
+ return (status);
+ }
+
+ return (status);
}
/*******************************************************************************
@@ -334,32 +370,56 @@
** DESCRIPTION: The function reconnect alloc-Id to idle tcont
**
** PARAMETERS: MV_U32 allocId
+** MV_U32 tcontNum
**
** OUTPUTS: None
**
** RETURNS: MV_OK or error
**
*******************************************************************************/
-MV_STATUS onuGponAllocIdMacReconnect(MV_U32 allocId)
+MV_STATUS onuGponAllocIdMacReconnect(MV_U32 allocId, MV_U32 tcontNum)
{
MV_BOOL exist;
MV_STATUS status = MV_OK;
MV_U32 entry;
MV_U32 onuId;
- MV_U32 tcontNum;
+ MV_U32 tcont;
+ MV_U32 tcontFreeNum;
+
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) AllocIdMacReconnect, AllocId(%d), Tcont(%d)\n",
+ __FILE_DESC__, __LINE__, allocId, tcontNum);
+#endif /* MV_GPON_DEBUG_PRINT */
/* Get free entry */
- exist = onuGponAllocIdMacAllocExistCheck(allocId, &entry);
+ exist = onuGponAllocIdMacAllocExistCheck(allocId, &entry, &tcont);
if (exist != MV_TRUE)
return (MV_ERROR);
- exist = onuGponDbBwTcontFreeGet(allocId, &tcontNum);
+ exist = onuGponDbBwTcontFreeGet(allocId, &tcontFreeNum);
if (exist != MV_TRUE)
- onuIdleAllocTcont = tcontNum;
+ onuIdleAllocTcont = tcontFreeNum;
/* Check if default Alloc Id */
onuId = onuGponDbOnuIdGet();
if (allocId != onuId) {
+
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) AllocIdMacReconnect, tpm_deactive_tcont, Tcont(%d)\n",
+ __FILE_DESC__, __LINE__, tcontNum);
+#endif /* MV_GPON_DEBUG_PRINT */
+
+ // printk("TCONT (%d) flush, Reconnect\n", tcontNum);
+ // status = onuGponWqTcontFlush(tcontNum);
+ // if (status != MV_OK)
+ //{
+ // mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ // "ERROR: (%s:%d) onuGponAllocIdMacReconnect, failed to schedule T-Cont(%d) flush in WQ\n",
+ // __FILE_DESC__, __LINE__, tcontNum);
+ //}
+
/* Set Alloc Id to T-Cont in the GMAC hardware */
status = mvOnuGponMacRxBwMapSet(entry, allocId, onuIdleAllocTcont, MV_TRUE);
}
@@ -385,18 +445,48 @@
{
MV_U32 onuId;
MV_U32 entry;
+ MV_U32 tcont;
MV_BOOL exist;
MV_STATUS status = MV_OK;
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) AllocIdMacDisconnect, AllocId(%d)\n",
+ __FILE_DESC__, __LINE__, allocId);
+#endif /* MV_GPON_DEBUG_PRINT */
+
/* Check if already exist */
- exist = onuGponAllocIdMacAllocExistCheck(allocId, &entry);
+ exist = onuGponAllocIdMacAllocExistCheck(allocId, &entry, &tcont);
if (exist == MV_FALSE)
return (MV_ERROR);
/* Check if default Alloc Id */
onuId = onuGponDbOnuIdGet();
if (allocId != onuId)
+ {
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) tpm_deactive_tcont, Tcont(%d)\n",
+ __FILE_DESC__, __LINE__, tcont);
+#endif /* MV_GPON_DEBUG_PRINT */
+
+ printk("TCONT (%d) flush, Disconnect\n", tcont);
+ status = onuGponWqTcontFlush(tcont);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ "ERROR: (%s:%d) onuGponAllocIdMacDisconnect, failed to schedule T-Cont(%d) flush in WQ\n",
+ __FILE_DESC__, __LINE__, tcont);
+ }
+
status = mvOnuGponMacRxBwMapSet(entry, 0, 0, MV_FALSE);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ "ERROR: (%s:%d) onuGponAllocIdMacDisconnect, failed to disconnect Alloc Id(%d), T-Cont(%d)\n",
+ __FILE_DESC__, __LINE__, allocId, tcont);
+ }
+ }
return (status);
}
@@ -487,6 +577,10 @@
/* =============== */
/* configured in the T-Cont table and BW MAP */
if (allocId == onuId) {
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) Alloc ID Assign, default alloc Id(%d) set to T-Cont 0(def)\n", __FILE_DESC__, __LINE__, allocId);
+#endif /* MV_GPON_DEBUG_PRINT */
/* Set default Alloc Id to T-Cont table */
status = onuGponDbBwTcontAlloc(PON_ONU_DEFAULT_ALLOC_TCONT, allocId);
if (status != MV_OK) {
@@ -553,6 +647,7 @@
MV_U32 tcontNum;
MV_BOOL allocIdExist;
MV_BOOL valid;
+
#ifdef MV_GPON_DEBUG_PRINT
mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
"DEBUG: (%s:%d) De-Assign Alloc ID, alloc Id(%d)\n", __FILE_DESC__, __LINE__, allocId);
@@ -605,6 +700,41 @@
/*******************************************************************************
**
+** onuGponAllocIdFreeAllBuffers
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function release all buffers assigned to All Alloc IDs
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK
+**
+*******************************************************************************/
+MV_STATUS onuGponAllocIdFreeAllBuffers(void)
+{
+ MV_STATUS status;
+ MV_U32 tcontNum = 0xFF;
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) release All T-Conts buffers, tpm_deactive_tcont\n", __FILE_DESC__, __LINE__);
+#endif /* MV_GPON_DEBUG_PRINT */
+
+ printk("TCONT flush, FreeAllBuffers\n");
+ status = onuGponWqTcontFlush(tcontNum);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ "ERROR: (%s:%d) onuGponAllocIdFreeAllBuffers, failed to schedule All T-Cont flush in WQ\n",
+ __FILE_DESC__, __LINE__, tcontNum);
+ }
+
+ return(status);
+}
+
+/*******************************************************************************
+**
** onuGponAllocIdDeAssignAll
** ____________________________________________________________________________
**
@@ -620,17 +750,17 @@
MV_STATUS onuGponAllocIdDeAssignAll(void)
{
#ifdef MV_GPON_DEBUG_PRINT
- mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
- "DEBUG: (%s:%d) De-Assign All Alloc IDs and T-Conts\n", __FILE_DESC__, __LINE__);
+ mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
+ "DEBUG: (%s:%d) De-Assign All Alloc IDs and T-Conts\n", __FILE_DESC__, __LINE__);
#endif /* MV_GPON_DEBUG_PRINT */
- onuGponDbBwAllocInit();
- onuGponAllocIdMacInit();
- onuGponAllocIdInit(0x00FF);
+ onuGponDbBwAllocInit();
+ onuGponAllocIdMacInit();
+ onuGponAllocIdInit(0x00FF);
- sendNotifyToMng = MV_FALSE;
+ sendNotifyToMng = MV_FALSE;
- return (MV_OK);
+ return (MV_OK);
}
/*******************************************************************************
@@ -788,7 +918,7 @@
exist = onuGponDbBwAllocExist(allocId);
if (exist == MV_TRUE) {
/* Clear T-Cont in hardware in case T-Cont is not connected to default Alloc-Id (== ONU ID) */
- status = onuGponAllocIdMacReconnect(allocId);
+ status = onuGponAllocIdMacReconnect(allocId, tcontNum);
if (status != MV_OK) {
mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
"ERROR: (%s:%d) onuGponAllocIdMacReconnect, alloc Id(%d)\n",
@@ -834,6 +964,7 @@
MV_U32 iEntry;
MV_BOOL exist;
MV_STATUS status;
+ MV_U32 tcontNum = 0xFF;
#ifdef MV_GPON_DEBUG_PRINT
mvPonPrint(PON_PRINT_DEBUG, PON_ALLOC_MODULE,
@@ -847,6 +978,16 @@
onuGponAllocIdTcontClear(iEntry);
}
+ printk("TCONT flush, Clear All\n");
+ status = onuGponWqTcontFlush(tcontNum);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_ALLOC_MODULE,
+ "ERROR: (%s:%d) onuGponAllocIdTcontClearAll, failed to schedule All T-Cont flush in WQ\n",
+ __FILE_DESC__, __LINE__);
+ }
+
+
return (MV_OK);
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.h
index 0e5e6e1..14d2f5c 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlloc.h
@@ -103,6 +103,7 @@
MV_STATUS onuGponAllocIdTcontSet(MV_U32 allocId, MV_U32 tcontNum);
MV_STATUS onuGponAllocIdTcontClear(MV_U32 tcontNum);
MV_STATUS onuGponAllocIdDeAssignAll(void);
+MV_STATUS onuGponAllocIdFreeAllBuffers(void);
MV_STATUS onuGponAllocIdTcontClearAll(void);
MV_U32 onuGponIdleAllocIdTcontGet(void);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlrm.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlrm.c
index c328cfb..e20431d 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlrm.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuAlrm.c
@@ -166,6 +166,9 @@
onuGponApmTbl_s.onuGponAlarmTbl_s.onuGponAlarmTbl[alarm] = state;
+ if (onuGponDbOnuStateGet() == ONU_GPON_06_POPUP)
+ return (MV_OK);
+
if (state == ONU_GPON_ALARM_OFF)
{
l_onuGponCurrentAlarmState &= ~(1 << alarm);
@@ -371,7 +374,8 @@
linkStatusCallback(MV_FALSE);
}
- onuPonTxPowerOn(MV_FALSE);
+ // onuPonTxPowerOn(MV_FALSE);
+ onuPonTxPowerTimerStateSet(MV_TRUE);
onuGponSrvcStatusNotify(GPON_ONU_STATUS_DISCONNECTED);
mvPonPrint(PON_PRINT_INFO, PON_ALARM_MODULE, "=========================\n");
mvPonPrint(PON_PRINT_INFO, PON_ALARM_MODULE, "== Downstream sync Off ==\n");
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c
index b25a37d..7f54bbc 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.c
@@ -120,13 +120,19 @@
** MV_U8 *password
** MV_BOOL disabled
** MV_U32 sn_src
+** MV_U32 fecHyst
**
** OUTPUTS: None
**
** RETURNS: MV_OK or error
**
*******************************************************************************/
-MV_STATUS onuGponApiInit(MV_U8 *serialNumber, MV_U8 *password, MV_BOOL disabled, MV_U32 sn_src)
+MV_STATUS onuGponApiInit(MV_U8 *serialNumber,
+ MV_U8 *password,
+ MV_BOOL disabled,
+ MV_U32 sn_src,
+ MV_U32 fecHyst,
+ MV_U32 couplingMode)
{
MV_STATUS rcode;
MV_U32 i;
@@ -155,6 +161,22 @@
return rcode;
}
+ rcode = mvOnuGponMacRxFecHysteresisSet(fecHyst);
+ if (rcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_API_MODULE,
+ "ERROR: (%s:%d) mvOnuGponMacRxFecHysteresisSet", __FILE_DESC__, __LINE__);
+ return rcode;
+ }
+
+ rcode = onuGponApiCouplingModeSet(couplingMode);
+ if (rcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_API_MODULE,
+ "ERROR: (%s:%d) mvOnuGponMacCouplingModeSet", __FILE_DESC__, __LINE__);
+ return rcode;
+ }
+
rcode = onuGponSrvcRangingRandomInit();
if (rcode != MV_OK)
{
@@ -1494,9 +1516,6 @@
return(rcode);
}
- onuGponDbXvrPolaritySet(burstConfigSet->polarity);
- mvOnuPonMacBurstEnablePolarityInit(burstConfigSet->polarity);
-
return(rcode);
}
@@ -2109,7 +2128,47 @@
return mvOnuGponMacRxFecStatusGet(fecMode);
}
+/*******************************************************************************
+**
+** mvGponAipCouplingModeSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function configures the coupling mode
+**
+** PARAMETERS: MV_U32 couplingMode 0 : DC, 1 : AC
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or MV_ERROR
+**
+*******************************************************************************/
+MV_STATUS onuGponApiCouplingModeSet(MV_U32 couplingMode)
+{
+ MV_STATUS status;
+ MV_U32 devId;
+ MV_U32 burstMode = 0;
+ MV_U32 burstTime = 0;
+ MV_U8 dataPattern1 = 0;
+ MV_U8 dataPattern2 = 0;
+ devId = mvCtrlModelGet();
+ if (devId != MV_6601_DEV_ID)
+ {
+ return(MV_OK);
+ }
+
+ if (couplingMode == 1) /* AC coupling mode */
+ {
+ burstMode = GPON_TX_AC_COUPL_BUST_MODE_0;
+ burstTime = GPON_TX_AC_COUPL_PREACT_BURST_TIME;
+ dataPattern1 = GPON_TX_AC_COUPL_DATA_PATTERN_1;
+ dataPattern2 = GPON_TX_AC_COUPL_DATA_PATTERN_2;
+ }
+
+ status = mvOnuGponMacTxConfigAcCouplingSet(burstMode, burstTime, dataPattern1, dataPattern2);
+
+ return (status);
+}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.h
index 962e2d7..a7b03e1 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuApi.h
@@ -169,7 +169,12 @@
/* Init API
------------------------------------------------------------------------------*/
-MV_STATUS onuGponApiInit(MV_U8 *serialNumber, MV_U8 *password, MV_BOOL disabled, MV_U32 sn_src);
+MV_STATUS onuGponApiInit(MV_U8 *serialNumber,
+ MV_U8 *password,
+ MV_BOOL disabled,
+ MV_U32 sn_src,
+ MV_U32 fecHyst,
+ MV_U32 couplingMode);
/* Notify API
------------------------------------------------------------------------------*/
@@ -232,6 +237,7 @@
MV_U32 onuGponApiUponDebugGet(void);
MV_STATUS onuGponApiAdminStateSet(MV_U32 mode);
MV_STATUS onuGponApiFecStatusGet(MV_U32 *fecMode);
+MV_STATUS onuGponApiCouplingModeSet(MV_U32 couplingMode);
/* Sn Mask API
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.c
index 8e48a4b..391bc35 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.c
@@ -165,8 +165,7 @@
onuGponDbRateSet(GPON_FRAME_DELINEATION_FR);
/* set gpon xvr polarity to default value */
- onuGponDbXvrPolaritySet(ONU_PON_XVR_POLARITY_ACT_HIGH);
-
+
/* set onu init status to be MV_FALSE */
onuGponDbInitSet(MV_FALSE);
@@ -904,46 +903,6 @@
/*******************************************************************************
**
-** onuGponDbXvrPolaritySet
-** ____________________________________________________________________________
-**
-** DESCRIPTION: The function set ONU XVR polarity in the database
-**
-** PARAMETERS: MV_U32 rate
-**
-** OUTPUTS: None
-**
-** RETURNS: MV_OK
-**
-*******************************************************************************/
-MV_STATUS onuGponDbXvrPolaritySet(MV_U32 polarity)
-{
- onuGponDb_s.onuGponGenTbl_s.onuGponXvrPolarity = polarity;
-
- return(MV_OK);
-}
-
-/*******************************************************************************
-**
-** onuGponDbXvrPolarityGet
-** ____________________________________________________________________________
-**
-** DESCRIPTION: The function return onu polarity
-**
-** PARAMETERS: None
-**
-** OUTPUTS: None
-**
-** RETURNS: onu Rate
-**
-*******************************************************************************/
-MV_U32 onuGponDbXvrPolarityGet(void)
-{
- return(onuGponDb_s.onuGponGenTbl_s.onuGponXvrPolarity);
-}
-
-/*******************************************************************************
-**
** onuGponDbAlarmNotifySet
** ____________________________________________________________________________
**
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.h
index 33aafa7..535b6ea 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuDb.h
@@ -122,7 +122,7 @@
MV_U32 onuGponOnuIdOverrideEn; /* ONU ID Overeide Enable*/
MV_U32 onuGponOnuIdOverrideVal; /* ONU ID Overeide value*/
MV_U32 onuGponRate;
- MV_U32 onuGponXvrPolarity;
+ MV_U32 onuGponP2pXvrBurstEnPolarity;
GPONFUNCPTR onuGponStateAndEventTbl[ONU_GPON_NUM_OF_EVENTS][ONU_GPON_NUM_OF_STATES];
MV_BOOL onuGponInit; /* Is ONU initialized? */
MV_BOOL omccValid;
@@ -276,8 +276,6 @@
MV_STATUS onuGponDbOmccPortOverrideValueSet(MV_U32 omccPort);
MV_STATUS onuGponDbRateSet(MV_U32 rate);
MV_U32 onuGponDbRateGet (void);
-MV_STATUS onuGponDbXvrPolaritySet(MV_U32 rate);
-MV_U32 onuGponDbXvrPolarityGet (void);
MV_BOOL onuGponDbdGaspEnGet(void);
MV_STATUS onuGponDbdGaspEnSet(MV_BOOL dGaspEn);
MV_STATUS onuGponDbAlarmNotifySet(ALARMNOTIFYFUNC alarmCallback);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuInit.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuInit.c
index a360076..5fef02d 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuInit.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuInit.c
@@ -142,6 +142,7 @@
return(MV_ERROR);
}
+ ponXvrFunc = GponXvrSDPolarityHighStatus;
/* init onu database */
rcode = onuGponDbInit();
if (rcode != MV_OK)
@@ -514,9 +515,6 @@
return(rcode);
}
- onuGponDbXvrPolaritySet(GPON_BURST_EN_P);
- mvOnuPonMacBurstEnablePolarityInit(GPON_BURST_EN_P);
-
rcode = mvOnuGponMacTxTxEnableCounterThresholdSet(GPON_BURST_THRESHOLD);
if (rcode != MV_OK)
{
@@ -661,6 +659,72 @@
/*******************************************************************************
**
+** onuGponAsicUtmBitmapInit
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function init UTM Active TX Bitmap
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuGponAsicUtmBitmapInit(void)
+{
+ MV_STATUS status;
+
+ status = mvOnuGponMacUtmActiveTxBitmapSet(GPON_UTM_ACTIVE_TX_BITMAP);
+ if (status == MV_OK) {
+ status = mvOnuGponMacUtmActiveTxBitmapValidSet(GPON_UTM_ACTIVE_TX_BITMAP_VALID);
+ if (status != MV_OK)
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) mvOnuGponMacUtmActiveTxBitmapValidSet\n\r", __FILE_DESC__, __LINE__);
+ } else
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) mvOnuGponMacUtmActiveTxBitmapSet\n\r", __FILE_DESC__, __LINE__);
+
+ return(status);
+}
+
+/*******************************************************************************
+**
+** onuGponAsicGseTransmitThresholdInit
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function init GSE Transmit Threshold
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuGponAsicGseTransmitThresholdInit(void)
+{
+ MV_STATUS status;
+ MV_U32 threshold;
+
+ threshold = ((GPON_GST_TX_DATA_THRESHOLD << GPON_GST_TX_DATA_SHIFT) |
+ GPON_GST_TX_IDLE_THRESHOLD);
+
+
+ status = mvOnuGponMacTxGseTransCounterThresholdSet(threshold);
+ if (status != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) mvOnuGponMacUtmActiveTxBitmapValidSet\n\r", __FILE_DESC__, __LINE__);
+ return(status);
+ }
+
+ return(MV_OK);
+
+}
+
+/*******************************************************************************
+**
** onuGponAsicInit
** ____________________________________________________________________________
**
@@ -776,7 +840,21 @@
return(rcode);
}
+ rcode = onuGponAsicGseTransmitThresholdInit();
+ if (rcode != MV_OK) {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) onuGponAsicGseTransmitThresholdInit\n\r", __FILE_DESC__, __LINE__);
+ return(rcode);
+ }
+
if (devId == MV_6601_DEV_ID) {
+ rcode = onuGponAsicUtmBitmapInit();
+ if (rcode != MV_OK) {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) onuGponAsicUtmBitmapInit\n", __FILE_DESC__, __LINE__);
+ return(MV_ERROR);
+ }
+
/* GPON is always works in legacy mode */
MV_REG_WRITE(NETA_LEGACY_DBA_REG(MV_PON_PORT_ID), 0);
}
@@ -1036,7 +1114,7 @@
/* ================ Init App Section ===================== */
/* ======================================================= */
onuGponApiSnMaskConfig(MV_FALSE, MV_FALSE);
- onuGponApiInit(serialNumber, password, disabledSnState,0);
+ onuGponApiInit(serialNumber, password, disabledSnState,0, 1, 0);
/* XVR reset sequence */
mvOnuGponMacXvrReset(0);
@@ -1127,7 +1205,12 @@
/* ======================================================= */
/* ================ Init App Section ===================== */
/* ======================================================= */
- onuGponApiInit(onuInit->serialNum, onuInit->password, disabledSnState, onuInit->serialNumSource);
+ onuGponApiInit(onuInit->serialNum,
+ onuInit->password,
+ disabledSnState,
+ onuInit->serialNumSource,
+ onuInit->fecHyst,
+ onuInit->couplingMode);
onuGponDbGemResetSet(onuInit->clearGem == 0 ? MV_FALSE : MV_TRUE);
onuGponDbTcontResetSet(onuInit->clearTcont == 0 ? MV_FALSE : MV_TRUE);
onuGponDbGemRestoreSet(onuInit->restoreGem == 0 ? MV_FALSE : MV_TRUE);
@@ -1148,7 +1231,7 @@
/* ======================================================= */
/* ================ PON XVR polarity Section ============= */
/* ======================================================= */
- rcode = mvOnuGponMacTxBurstEnPolaritySet(onuInit->xvrPolarity);
+ rcode = mvOnuGponMacTxBurstEnPolaritySet(onuInit->ponXvrBurstEnPolarity);
if (rcode != MV_OK)
{
mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
@@ -1156,8 +1239,9 @@
return(rcode);
}
- onuGponDbXvrPolaritySet(onuInit->xvrPolarity);
- mvOnuPonMacBurstEnablePolarityInit(onuInit->xvrPolarity);
+ ponXvrFunc = funcGponXvrSDStatus(onuInit->ponXvrPolarity);
+
+ onuP2PDbXvrBurstEnablePolaritySet(onuInit->p2pXvrBurstEnPolarity);
#ifndef PON_FPGA
/* ========================================================== */
@@ -1209,9 +1293,9 @@
if (devId != MV_6601_DEV_ID)
return(MV_OK);
- return(mvOnuGponMacTxConfigAcCouplingSet(GPON_TX_AC_COUPL_BUST_MODE_0,
- GPON_TX_AC_COUPL_PREACT_BURST_TIME,
- GPON_TX_AC_COUPL_DATA_PATTERN_1,
- GPON_TX_AC_COUPL_DATA_PATTERN_2));
+ return (mvOnuGponMacTxConfigAcCouplingSet(GPON_TX_AC_COUPL_BUST_MODE_0,
+ GPON_TX_AC_COUPL_PREACT_BURST_TIME,
+ GPON_TX_AC_COUPL_DATA_PATTERN_1,
+ GPON_TX_AC_COUPL_DATA_PATTERN_2));
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuIsr.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuIsr.c
index 37d9de2..6555274 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuIsr.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuIsr.c
@@ -147,7 +147,7 @@
** onuGponIsrXvrResetTimerHndl
** ____________________________________________________________________________
**
-** DESCRIPTION: The function is called by the GPON Iterrupt handler to execute
+** DESCRIPTION: The function is called by the GPON Interrupt handler to execute
** XVR reset sequence in case of a problem with XVR signal detect
**
** PARAMETERS: unsigned long data
@@ -256,6 +256,8 @@
*interruptEvent = (g_onuGponCurrentInterrupt >> ONU_GPON_EVENT_SHIFT) & ONU_GPON_INTERRUPTS;
*interruptStatus = (g_onuGponCurrentInterrupt ) & ONU_GPON_INTERRUPTS;
+ onuGponSyncLog(ONU_GPON_LOG_INTERRUPT, g_onuGponCurrentInterrupt, 0, 0);
+
g_onuGponCurrentInterrupt = 0;
#ifdef MV_GPON_PERFORMANCE_CHECK
@@ -296,6 +298,41 @@
__FILE_DESC__, __LINE__, interruptEvent, interruptStatus, timer);
#endif
+ if (interruptEvent & ONU_GPON_XVR_SIGNAL_DETECT_STATUS_MASK)
+ {
+ state = ponXvrFunc(interruptStatus, ONU_GPON_XVR_SIGNAL_DETECT_STATUS_MASK);
+
+ if (state == MV_TRUE)
+ {
+ onuGponPonMngIntrAlarmHandler(ONU_PON_MNGR_LOS_ALARM, MV_FALSE);
+ /* Set signal detect to ON */
+ onuGponDbOnuSignalDetectSet(1);
+
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_MODULE,
+ "DEBUG: (%s:%d) Set signal detect to ON = 1 \n", __FILE_DESC__, __LINE__);
+#endif /* MV_GPON_DEBUG_PRINT */
+#ifndef PON_FPGA
+ onuGponIsrXvrReset();
+ onuGponIsrXvrResetStateSet(MV_TRUE);
+ //onuGponPonMngIntrMessageHandler();
+#endif /* PON_FPGA */
+ }
+ else if (state == MV_FALSE)
+ {
+ onuGponPonMngIntrAlarmHandler(ONU_PON_MNGR_LOS_ALARM, MV_TRUE);
+ /* Set signal detect to OFF */
+ onuGponDbOnuSignalDetectSet(0);
+
+#ifdef MV_GPON_DEBUG_PRINT
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_MODULE,
+ "DEBUG: (%s:%d) Set signal detect to OFF = 0\n", __FILE_DESC__, __LINE__);
+#endif /* MV_GPON_DEBUG_PRINT */
+ }
+
+ onuGponSyncLog(ONU_GPON_LOG_INTERRUPT_XVR_SD, state, 0, 0);
+ }
+
if (interruptEvent & ONU_GPON_LOS_ALARM_MASK)
{
// state = (interruptStatus & ONU_GPON_LOS_ALARM_MASK) ? MV_TRUE : MV_FALSE;
@@ -307,6 +344,8 @@
state = (interruptStatus & ONU_GPON_LOF_ALARM_MASK) ? MV_TRUE : MV_FALSE;
onuGponPonMngIntrAlarmHandler(ONU_PON_MNGR_LOF_ALARM, state);
+ onuGponSyncLog(ONU_GPON_LOG_INTERRUPT_LOF, state, 0, 0);
+
// if (state == MV_TRUE)
// {
// /* Set DS Sync Ind to OFF */
@@ -380,42 +419,10 @@
if (interruptEvent & ONU_GPON_PHY_SIGNAL_DETECT_STATUS_MASK)
{
#ifdef MV_GPON_DEBUG_PRINT
- mvPonPrint(PON_PRINT_DEBUG, PON_ISR_MODULE,
+ mvPonPrint(PON_PRINT_DEBUG, PON_ISR_MODULE,
"DEBUG: (%s:%d) Event 0x%x - Not supported\n", __FILE_DESC__, __LINE__, interruptEvent);
#endif /* MV_GPON_DEBUG_PRINT */
}
-
- if (interruptEvent & ONU_GPON_XVR_SIGNAL_DETECT_STATUS_MASK)
- {
- state = (interruptStatus & ONU_GPON_XVR_SIGNAL_DETECT_STATUS_MASK) ? MV_TRUE : MV_FALSE;
-
- if (state == MV_TRUE)
- {
- onuGponPonMngIntrAlarmHandler(ONU_PON_MNGR_LOS_ALARM, MV_FALSE);
- /* Set signal detect to ON */
- onuGponDbOnuSignalDetectSet(1);
-
-#ifdef MV_GPON_DEBUG_PRINT
- mvPonPrint(PON_PRINT_DEBUG, PON_ISR_MODULE,
- "DEBUG: (%s:%d) Set signal detect to ON = 1 \n", __FILE_DESC__, __LINE__);
-#endif /* MV_GPON_DEBUG_PRINT */
-#ifndef PON_FPGA
- onuGponIsrXvrReset();
- onuGponPonMngIntrMessageHandler();
-#endif /* PON_FPGA */
- }
- else if (state == MV_FALSE)
- {
- onuGponPonMngIntrAlarmHandler(ONU_PON_MNGR_LOS_ALARM, MV_TRUE);
- /* Set signal detect to OFF */
- onuGponDbOnuSignalDetectSet(0);
-
-#ifdef MV_GPON_DEBUG_PRINT
- mvPonPrint(PON_PRINT_DEBUG, PON_ISR_MODULE,
- "DEBUG: (%s:%d) Set signal detect to OFF = 0\n", __FILE_DESC__, __LINE__);
-#endif /* MV_GPON_DEBUG_PRINT */
- }
- }
}
}
@@ -477,12 +484,19 @@
MV_STATUS status;
MV_U32 onuState;
MV_U32 initDone;
+ MV_U32 durationStart = 0;
+ MV_U32 durationEnd = 0;
+
onuState = onuGponDbOnuStateGet();
if ((onuState == ONU_GPON_01_INIT) ||
- ((onuState == ONU_GPON_07_EMERGANCY_STOP) && (onuGponAsicAlarmStatusGet() == ONU_GPON_ALARM_ON)) ||
- ((onuState == ONU_GPON_06_POPUP)))
+ ((onuState == ONU_GPON_07_EMERGANCY_STOP) && (onuGponAsicAlarmStatusGet() == ONU_GPON_ALARM_ON)) ||
+ ((onuState == ONU_GPON_06_POPUP) && ((onuGponAlarmGet(ONU_GPON_ALARM_LOS) == ONU_GPON_ALARM_OFF) &&
+ (onuGponAlarmGet(ONU_GPON_ALARM_LOF) == ONU_GPON_ALARM_ON))))
{
+ asicOntGlbRegReadNoCheck(mvAsicReg_GPON_GEN_MICRO_SEC_CNT, &durationStart, 0);
+ onuGponSyncLog(ONU_GPON_LOG_INTERRUPT_SERDES_START, 0, 0, 0);
+
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x1, 0);
if (status != MV_OK)
return(status);
@@ -493,11 +507,17 @@
if (status != MV_OK)
return(status);
+ asicOntGlbRegReadNoCheck(mvAsicReg_GPON_GEN_MICRO_SEC_CNT, &durationEnd, 0);
+ if (abs((durationEnd - durationStart)) >= 6000)
+ return (MV_OK);
+
} while (initDone == 0);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x0, 0);
if (status != MV_OK)
return(status);
+
+ onuGponSyncLog(ONU_GPON_LOG_INTERRUPT_SERDES_STOP, 0, 0, 0);
}
else
{
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.c
index 71f0803..139e964 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.c
@@ -364,6 +364,7 @@
MV_U32 onuState;
GPONFUNCPTR ptrFunc;
S_OnuGponGenTbl *onuGponGenTbl_p = &(onuGponDb_s.onuGponGenTbl_s);
+ MV_U32 *msgData_p = msgData;
/* get onu Id */
appOnuId = onuGponDbOnuIdGet();
@@ -389,6 +390,9 @@
{
(*ptrFunc)(onuId, msgId, msgData);
}
+
+ onuGponSyncLog(ONU_GPON_LOG_MSG, onuId, msgId, 0);
+ onuGponSyncLog(ONU_GPON_LOG_MSG_CONTENT, *(msgData_p), *(msgData_p + 1), *(msgData_p + 2));
}
/* handle invalid messages */
else
@@ -536,12 +540,6 @@
onuPonResourceTbl_s.onuPonSwFIFOTimerId.onuPonTimerActive = ONU_PON_TIMER_NOT_ACTIVE;
- if (onuGponDbOnuStateGet() == ONU_GPON_05_OPERATION)
- {
- spin_unlock_irqrestore(&onuPonIrqLock, flags);
- return;
- }
-
/* Call PM handler */
mvOnuGponFifoAuditTimerExpireHndl();
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.h
index 8e54d99..d63cf1d 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngr.h
@@ -175,6 +175,7 @@
void onuGponPonMngTimerT01ExpireHndl(void);
void onuGponPonMngTimerT02ExpireHndl(void);
void onuGponPonMngTimerPeeExpireHndl(void);
+void onuGponTimerTxPwrHndl(unsigned long data);
/* Alarm Functions */
void onuGponPonMngGenCritAlarm(E_OnuGponAlarmType alarmType_e, MV_U8 dummyVal, MV_U8 *dummyPtr);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngrStateMachine.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngrStateMachine.c
index 5248f2b..f645b34 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngrStateMachine.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuMngrStateMachine.c
@@ -102,6 +102,7 @@
------------------------------------------------------------------------------*/
MV_STATUS onuGponPonMngrUpdateState(MV_U32 newState);
MV_STATUS onuGponPonMngClearOnuInfo(void);
+MV_STATUS onuGponPonMngClearOnuBuffers(void);
MV_STATUS onuGponPonMngClearOnuTconts(void);
MV_STATUS onuGponPonMngClearOnuPorts(void);
MV_STATUS onuGponPonMngClearOnuId(void);
@@ -165,13 +166,9 @@
#endif /* PON_FPGA */
/* stop onu periodic timers */
- if (g_periodicTimerState != MV_FALSE)
- {
- onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonPmTimerId));
- onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonSwFIFOTimerId));
- mvOnuGponMacMessageCleanSwFifo();
- g_periodicTimerState = MV_FALSE;
- }
+ onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonPmTimerId));
+ onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonSwFIFOTimerId));
+ mvOnuGponMacMessageCleanSwFifo();
}
if (newState == ONU_GPON_02_STANDBY)
@@ -182,13 +179,12 @@
#endif /* PON_FPGA */
/* start onu periodic timers */
- if (g_periodicTimerState != MV_TRUE)
- {
- onuPonTimerEnable(&(onuPonResourceTbl_s.onuPonPmTimerId));
- onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonSwFIFOTimerId));
- mvOnuGponMacMessageCleanSwFifo();
- g_periodicTimerState = MV_TRUE;
- }
+ onuPonTimerEnable(&(onuPonResourceTbl_s.onuPonPmTimerId));
+ onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonSwFIFOTimerId));
+ mvOnuGponMacMessageCleanSwFifo();
+
+ /* stop onu gpon xvr reset timer */
+ onuGponIsrXvrResetStateSet(MV_FALSE);
}
rcode = onuGponPonMngPreambleSet(newState);
@@ -224,6 +220,8 @@
return(rcode);
}
+ onuGponSyncLog(ONU_GPON_LOG_STATE, asicNewState, 0, 0);
+
/* update database */
onuGponDbOnuStateSet(newState);
@@ -237,6 +235,34 @@
/*******************************************************************************
**
+** onuGponPonMngClearOnuBuffers
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function reset onu buffers to its default state
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuGponPonMngClearOnuBuffers(void)
+{
+ MV_STATUS rcode;
+
+ rcode = onuGponAllocIdFreeAllBuffers();
+ if (rcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_SM_MODULE,
+ "ERROR: (%s:%d) onuGponPonMngClearOnuBuffers\n", __FILE_DESC__, __LINE__);
+ }
+
+ return(MV_OK);
+}
+
+/*******************************************************************************
+**
** onuGponPonMngClearOnuInfo
** ____________________________________________________________________________
**
@@ -268,6 +294,14 @@
"ERROR: (%s:%d) onuGponPonMngClearOnuTconts\n", __FILE_DESC__, __LINE__); return(rcode);
}
+ rcode = onuGponPonMngClearOnuBuffers();
+ if (rcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_SM_MODULE,
+ "ERROR: (%s:%d) onuGponPonMngClearOnuBuffers\n", __FILE_DESC__, __LINE__);
+ return;
+ }
+
rcode = onuGponPonMngClearOnuId();
if (rcode != MV_OK)
{
@@ -1067,6 +1101,9 @@
finalDelay = M_ONU_GPON_RANG_MSG_FINAL_DELAY(msgDelay);
equalizationDelay = M_ONU_GPON_RANG_MSG_EQUAL_DELAY(msgDelay);
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O4, Message: equalizationDelay(%d:0x%x), finalDelay(%d:0x%x)\n",
+ __FILE_DESC__, __LINE__, equalizationDelay, equalizationDelay, finalDelay, finalDelay);
/* sync state */
/* ========== */
@@ -1100,6 +1137,11 @@
/* update database */
onuGponDbEqualizationDelaySet(msgDelay);
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O4, Calc: equalizationDelay(%d:0x%x), finalDelay(%d:0x%x)\n",
+ __FILE_DESC__, __LINE__, equalizationDelay, equalizationDelay, finalDelay, finalDelay);
+
+
/* alarm handling */
/* ============== */
onuGponAlarmSet(ONU_GPON_ALARM_SUF, ONU_GPON_ALARM_OFF);
@@ -1138,16 +1180,33 @@
/* get current delay */
currentDelay = onuGponDbEqualizationDelayGet();
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Current equalization Delay from DB(%d:0x%x)\n",
+ __FILE_DESC__, __LINE__, currentDelay, currentDelay);
+
/* Reduce Equlization delay */
if (currentDelay > msgDelay)
{
changeDelay = currentDelay - msgDelay;
+
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Current equalization Delay(0x%x) > Message equalization Delay(0x%x), change(0x%x)\n",
+ __FILE_DESC__, __LINE__, currentDelay, msgDelay, changeDelay);
+
mvOnuGponMacTxFinalDelayGet(&currFinalDelay);
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Final delay from DB (0x%x)\n",
+ __FILE_DESC__, __LINE__, currFinalDelay);
+
/* Check if can change the TX Final Delay only */
if (changeDelay <= currFinalDelay)
{
finalDelay = currFinalDelay - changeDelay;
+
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Change delay <= Final delay, updated final delay, finalDelay = currFinalDelay - changeDelay, (0x%x)\n",
+ __FILE_DESC__, __LINE__, finalDelay);
}
else
{
@@ -1156,6 +1215,10 @@
"ERROR: (%s:%d) Change Range delay while O5 - Update EqD\n", __FILE_DESC__, __LINE__);
#endif /* MV_GPON_DEBUG_PRINT */
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Change > Final delay, updated equalization delay\n",
+ __FILE_DESC__, __LINE__);
+
/* calc delay */
finalDelay = M_ONU_GPON_RANG_MSG_FINAL_DELAY(msgDelay) + (MV_U32)GPON_TX_FINAL_DELAY_FD;
equalizationDelay = M_ONU_GPON_RANG_MSG_EQUAL_DELAY(msgDelay);
@@ -1168,6 +1231,10 @@
__FILE_DESC__, __LINE__, equalizationDelay);
return;
}
+
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Updated: equalizationDelay(%d:0x%x), finalDelay(%d:0x%x)\n",
+ __FILE_DESC__, __LINE__, equalizationDelay, equalizationDelay, finalDelay, finalDelay);
}
rcode = mvOnuGponMacTxFinalDelaySet(finalDelay);
@@ -1184,12 +1251,25 @@
else if (currentDelay < msgDelay)
{
changeDelay = msgDelay - currentDelay;
+
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Current equalization Delay(0x%x) < Message equalization Delay(0x%x), change(0x%x)\n",
+ __FILE_DESC__, __LINE__, currentDelay, msgDelay, changeDelay);
+
mvOnuGponMacTxFinalDelayGet(&currFinalDelay);
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Final delay from DB (0x%x)\n",
+ __FILE_DESC__, __LINE__, currFinalDelay);
+
/* Check if can change the TX Final Delay only */
if (changeDelay + currFinalDelay > GPON_TX_FINAL_DELAY_MAX)
{
finalDelay = currFinalDelay + changeDelay;
+
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Change delay + current Final delay > MAX Final delay(0x3F), updated final delay, finalDelay = currFinalDelay + changeDelay, (0x%x)\n",
+ __FILE_DESC__, __LINE__, finalDelay);
}
else
{
@@ -1198,6 +1278,10 @@
"DEBUG: (%s:%d) Change Range delay while O5 - Update EqD\n", __FILE_DESC__, __LINE__);
#endif /* MV_GPON_DEBUG_PRINT */
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Change delay + Final delay < MAX Final delay = 0x3F, updated equalization delay\n",
+ __FILE_DESC__, __LINE__);
+
/* calc delay */
finalDelay = M_ONU_GPON_RANG_MSG_FINAL_DELAY(msgDelay) + (MV_U32)GPON_TX_FINAL_DELAY_FD;
equalizationDelay = M_ONU_GPON_RANG_MSG_EQUAL_DELAY(msgDelay);
@@ -1213,6 +1297,11 @@
}
}
+ mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
+ "Range Debug Info: (%s:%d), State O5, Updated: equalizationDelay(%d:0x%x), finalDelay(%d:0x%x)\n",
+ __FILE_DESC__, __LINE__, equalizationDelay, equalizationDelay, finalDelay, finalDelay);
+
+
rcode = mvOnuGponMacTxFinalDelaySet(finalDelay);
if (rcode != MV_OK)
{
@@ -1375,6 +1464,8 @@
if ((disableStatus == GPON_ONU_DISABLE) && (isSnMatch == MV_TRUE) &&
(onuState != ONU_GPON_07_EMERGANCY_STOP)) {
+ onuPonTxPowerOn(MV_FALSE);
+
/* clear onu information */
/* ===================== */
rcode = onuGponPonMngClearOnuInfo();
@@ -1425,6 +1516,8 @@
((disableStatus == GPON_ONU_ENABLE_ONU) && (isSnMatch == MV_TRUE))) &&
(onuState == ONU_GPON_07_EMERGANCY_STOP)) {
+ onuPonTxPowerOn(MV_TRUE);
+
/* alarm handling */
/* ============== */
onuGponAlarmSet(ONU_GPON_ALARM_DIS, ONU_GPON_ALARM_OFF);
@@ -1634,8 +1727,8 @@
mvPonPrint(PON_PRINT_DEBUG, PON_SM_STATE_MODULE,
"[US PLOAM] PASSWORD, onuId(%d), msgId(%d), msg[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]\n",
srcOnuId, msgId,
- msgData[0], msgData[1], msgData[2], msgData[3], msgData[4],
- msgData[5], msgData[6], msgData[7], msgData[8], msgData[9]);
+ password [0], password [1], password [2], password [3], password [4],
+ password [5], password [6], password [7], password [8], password [9]);
#endif /* MV_GPON_DEBUG_PRINT */
#ifdef MV_GPON_PERFORMANCE_CHECK
@@ -1849,6 +1942,8 @@
/* stop onu gpon pon mng T02 timer */
onuPonTimerDisable(&(onuPonResourceTbl_s.onuGponT02_TimerId));
+ /* stop onu gpon xvr reset timer */
+ onuGponIsrXvrResetStateSet(MV_FALSE);
if (onuId == ONU_GPON_BROADCAST_ONU_ID) /* Broadcast ONU-ID */
{
@@ -2766,6 +2861,10 @@
else
mvPonPrint(PON_PRINT_ERROR, PON_SM_MODULE,
"ERROR: (%s:%d) wrong start to T02\n", __FILE_DESC__, __LINE__);
+#ifndef PON_FPGA
+ /* start xvr reset timer */
+ onuGponIsrXvrResetStateSet(MV_TRUE);
+#endif /* PON_FPGA */
#ifdef MV_GPON_DEBUG_PRINT
mvPonPrint(PON_PRINT_DEBUG, PON_SM_MODULE, "===========\n");
@@ -2827,7 +2926,6 @@
/* alarm handling */
/* ============== */
- if (onuGponDbOnuStateGet() != ONU_GPON_06_POPUP)
onuGponAlarmSet(alarmType_e, ONU_GPON_ALARM_ON);
}
@@ -3044,5 +3142,36 @@
return(MV_OK);
}
+/*******************************************************************************
+**
+** onuGponTimerTxPwrHndl
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function is called by the GPON handler in the case of DS
+** sync off to start 1 sec timer that will disable Tx if expired
+**
+** PARAMETERS: unsigned long data
+**
+** OUTPUTS: None
+**
+** RETURNS: None
+**
+*******************************************************************************/
+void onuGponTimerTxPwrHndl(unsigned long data)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&onuPonIrqLock, flags);
+
+ onuPonResourceTbl_s.onuPonTxPwrTimerId.onuPonTimerActive = ONU_PON_TIMER_NOT_ACTIVE;
+
+ if (onuGponDbOnuStateGet() < ONU_GPON_02_STANDBY)
+ {
+ onuPonTxPowerOn(MV_FALSE);
+ }
+
+ onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonTxPwrTimerId));
+
+ spin_unlock_irqrestore(&onuPonIrqLock, flags);
+}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.c
index 654bd6d..044f589 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.c
@@ -78,6 +78,7 @@
/* Include Files
------------------------------------------------------------------------------*/
#include "gponOnuHeader.h"
+#include "tpm_api.h"
/* Local Constant
------------------------------------------------------------------------------*/
@@ -100,7 +101,20 @@
/* Local Variables
------------------------------------------------------------------------------*/
-
+S_OnuGponLogEntry onuGponLogDb[ONU_GPON_LOG_SIZE + 1];
+MV_32 onuGponLogDbEntryIndex = 0;
+MV_32 onuGponLogDbEntryCount = 0;
+MV_BOOL onuGponLogEnable = MV_FALSE;
+
+MV_32 onuGponTcontFlushState[8] = {TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE,
+ TCONT_FLUSH_READY_STATE};
+
/* Export Functions
------------------------------------------------------------------------------*/
MV_STATUS onuGponSrvcGenCrcTable(void);
@@ -1076,3 +1090,333 @@
return(MV_OK);
}
+/*******************************************************************************
+**
+** SYNC LOG SECTION
+**
+********************************************************************************/
+
+/*******************************************************************************
+**
+** onuGponSyncLogEnable
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function enable log mechanism to start record events
+**
+** PARAMETERS: MV_U32 enable
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+void onuGponSyncLogEnable(MV_U32 enable)
+{
+ if (enable == 0)
+ {
+ onuGponLogEnable = MV_FALSE;
+
+ onuGponLogDbEntryCount = 0;
+ onuGponLogDbEntryIndex = 0;
+ }
+ else
+ {
+ onuGponLogEnable = MV_TRUE;
+ }
+}
+
+/*******************************************************************************
+**
+** onuGponSyncLog
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function logs records into the cyclic log buffer
+**
+** PARAMETERS: MV_U32 event, MV_U32 data1, MV_U32 data2, MV_U32 data3
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+void onuGponSyncLog(MV_U32 event, MV_U32 data1, MV_U32 data2, MV_U32 data3)
+{
+ MV_U32 currentState;
+ MV_U32 timeStamp;
+
+ if (onuGponLogEnable != MV_TRUE)
+ {
+ return;
+ }
+
+ currentState = onuGponDbOnuStateGet();
+ asicOntGlbRegReadNoCheck(mvAsicReg_GPON_GEN_MICRO_SEC_CNT, &timeStamp, 0);
+
+ if (onuGponLogDbEntryIndex == ONU_GPON_LOG_SIZE)
+ {
+ onuGponLogDbEntryIndex = 0;
+ }
+
+ /* save log information */
+ onuGponLogDb[onuGponLogDbEntryIndex].event = event;
+ onuGponLogDb[onuGponLogDbEntryIndex].state = currentState;
+ onuGponLogDb[onuGponLogDbEntryIndex].time = timeStamp;
+ onuGponLogDb[onuGponLogDbEntryIndex].dataVal1 = data1;
+ onuGponLogDb[onuGponLogDbEntryIndex].dataVal2 = data2;
+ onuGponLogDb[onuGponLogDbEntryIndex].dataVal3 = data3;
+
+ onuGponLogDbEntryIndex++;
+
+ /* The max number of counter is 512 */
+ if (onuGponLogDbEntryCount < ONU_GPON_LOG_SIZE)
+ {
+ onuGponLogDbEntryCount++;
+ }
+}
+
+/*******************************************************************************
+**
+** onuGponSyncLogPrint
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function print the records placed in the log
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+void onuGponSyncLogPrint(void)
+{
+ MV_32 index;
+ MV_U32 printEntry;
+ MV_BOOL logEnabled;
+
+ logEnabled = onuGponLogEnable;
+ onuGponLogEnable = MV_FALSE;
+
+ printk("=======GPON LOG has %d items=======\r\n", onuGponLogDbEntryCount);
+
+ for (index = 0; index < onuGponLogDbEntryCount; index++)
+ {
+ if ((onuGponLogDbEntryIndex - index) > 0)
+ {
+ printEntry = onuGponLogDbEntryIndex - index - 1;
+ }
+ else
+ {
+ printEntry = ((MV_U32)ONU_GPON_LOG_SIZE - 1) - (index - onuGponLogDbEntryIndex);
+ }
+
+ switch(onuGponLogDb[printEntry].event)
+ {
+ case ONU_GPON_LOG_MSG:
+ printk("[%03d] PLOAM message, state=%d, time=%08x, onuId=%d, msgId=%d\n", printEntry,
+ onuGponLogDb[printEntry].state,
+ onuGponLogDb[printEntry].time,
+ onuGponLogDb[printEntry].dataVal1,
+ onuGponLogDb[printEntry].dataVal2);
+ break;
+
+ case ONU_GPON_LOG_MSG_CONTENT:
+ printk("[%03d] PLOAM message, data=0x%08x%08x%08x\n", printEntry,
+ onuGponLogDb[printEntry].dataVal1,
+ onuGponLogDb[printEntry].dataVal2,
+ onuGponLogDb[printEntry].dataVal3);
+ break;
+
+ case ONU_GPON_LOG_INTERRUPT:
+ printk("[%03d] Interrupt, state=%d, time=%08x, event&status=0x%08x\n", printEntry,
+ onuGponLogDb[printEntry].state,
+ onuGponLogDb[printEntry].time,
+ onuGponLogDb[printEntry].dataVal1);
+ break;
+
+ case ONU_GPON_LOG_INTERRUPT_XVR_SD:
+ printk("[%03d] LOS Interrupt, state=%d, time=%08x, status=%d\n", printEntry,
+ onuGponLogDb[printEntry].state,
+ onuGponLogDb[printEntry].time,
+ onuGponLogDb[printEntry].dataVal1);
+ break;
+
+ case ONU_GPON_LOG_INTERRUPT_LOF:
+ printk("[%03d] LOF Interrupt, state=%d, time=%08x, status=%d\n", printEntry,
+ onuGponLogDb[printEntry].state,
+ onuGponLogDb[printEntry].time,
+ onuGponLogDb[printEntry].dataVal1);
+ break;
+
+ case ONU_GPON_LOG_INTERRUPT_SERDES_START:
+ printk("[%03d] SERDES Start, state=%d, time=%08x\n", printEntry,
+ onuGponLogDb[printEntry].state,
+ onuGponLogDb[printEntry].time);
+ break;
+
+ case ONU_GPON_LOG_INTERRUPT_SERDES_STOP:
+ printk("[%03d] Interrupt, state=%d, time=%08x\n", printEntry,
+ onuGponLogDb[printEntry].state,
+ onuGponLogDb[printEntry].time);
+ break;
+
+ case ONU_GPON_LOG_STATE:
+ printk("[%03d] State, state=%d, time=%08x\n", printEntry,
+ onuGponLogDb[printEntry].dataVal1,
+ onuGponLogDb[printEntry].time);
+ break;
+
+ default:
+ printk("[%03d] Other\r\n", printEntry);
+ break;
+ }
+ }
+
+ onuGponLogDbEntryCount = 0;
+ onuGponLogDbEntryIndex = 0;
+
+ onuGponLogEnable = logEnabled;
+}
+
+/*******************************************************************************
+**
+** T-CONT FLUSH SECTION
+**
+********************************************************************************/
+
+/*******************************************************************************
+**
+** onuGponWqTcontFlush
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function schedule T-Cont queue flush work to the T-Cont
+** work queue
+**
+** PARAMETERS: MV_U32 tcont
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuGponWqTcontFlush(MV_U32 tcont)
+{
+ MV_STATUS rcode;
+
+ if (tcont != 0xFF)
+ rcode = queue_work(gponTcontFlushWq.ponWq, (struct work_struct *)&gponTcontCleanWork[tcont]);
+ else
+ rcode = queue_work(gponTcontFlushWq.ponWq, (struct work_struct *)&gponTcontCleanAllWork);
+
+ if(rcode == 0)
+ return(MV_ERROR);
+
+ return(MV_OK);
+}
+
+/*******************************************************************************
+**
+** onuGponWqTcontActivate
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function schedule T-Cont queue activate work to the T-Cont
+** work queue
+**
+** PARAMETERS: MV_U32 tcont
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuGponWqTcontActivate(MV_U32 tcont)
+{
+ MV_STATUS rcode;
+
+ rcode = queue_work(gponTcontFlushWq.ponWq, (struct work_struct *)&gponTcontActiveWork[tcont]);
+ if(rcode == 0)
+ return(MV_ERROR);
+
+ return(MV_OK);
+}
+
+/*******************************************************************************
+**
+** onuGponWqTcontFunc
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function process incoming work to the T-Cont work queue
+**
+** PARAMETERS: struct work_struct *work
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+void onuGponWqTcontFunc(struct work_struct *work)
+{
+ S_onuPonWork *currentWork = (S_onuPonWork *)work;
+ MV_U32 tcont = currentWork->param;
+ MV_U32 index = 0;
+
+ MV_U8 *stateText[] = {"",
+ "Ready State ",
+ "Running State ",
+ "Blocking State"};
+
+ /* Handle T-Cont Clear */
+ /* =================== */
+ if (currentWork->action == TCONT_CLEAN_EVENT)
+ {
+ if (onuGponTcontFlushState[tcont] == TCONT_FLUSH_RUNNING_STATE)
+ {
+ onuGponTcontFlushState[tcont] = TCONT_FLUSH_BLOCKING_STATE;
+ tpm_deactive_tcont(tcont);
+ printk("TCONT (%d) CLEAN_EVENT\n", tcont);
+ onuGponTcontFlushState[tcont] = TCONT_FLUSH_READY_STATE;
+ }
+ else
+ {
+ printk("Received TCONT_CLEAN_EVENT while in T-CONT(%d) state(%s)\n", tcont, stateText[onuGponTcontFlushState[tcont]]);
+ }
+ }
+
+ /* Handle All T-Cont Clear */
+ /* ======================= */
+ else if (currentWork->action == TCONT_CLEAN_ALL_EVENT)
+ {
+ for (tcont = 0; tcont < 8; tcont++)
+ {
+ if (onuGponTcontFlushState[tcont] == TCONT_FLUSH_RUNNING_STATE)
+ {
+ onuGponTcontFlushState[tcont] = TCONT_FLUSH_BLOCKING_STATE;
+ tpm_deactive_tcont(tcont);
+ printk("TCONT (%d) CLEAN_EVENT\n", tcont);
+ onuGponTcontFlushState[tcont] = TCONT_FLUSH_READY_STATE;
+ }
+ else
+ {
+ printk("Received TCONT_CLEAN_EVENT while in T-CONT(%d) state(%s)\n", tcont, stateText[onuGponTcontFlushState[tcont]]);
+ }
+ }
+ }
+
+ /* Handle T-Cont Activate */
+ /* ====================== */
+ else if (currentWork->action == TCONT_ACTIVE_EVENT)
+ {
+ if (onuGponTcontFlushState[tcont] == TCONT_FLUSH_READY_STATE)
+ {
+ onuGponTcontFlushState[tcont] = TCONT_FLUSH_RUNNING_STATE;
+ tpm_active_tcont(tcont);
+ printk("TCONT (%d) ACTIVE_EVENT\n", tcont);
+ }
+ else
+ {
+ printk("Received TCONT_ACTIVE_EVENT while in T-CONT state(%s)\n", stateText[onuGponTcontFlushState[tcont]]);
+ }
+ }
+
+ return;
+}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.h
index 839e60c..ed08b2d 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/core/gpon/gponOnuSrvc.h
@@ -80,11 +80,29 @@
------------------------------------------------------------------------------*/
/* Definitions
-------------------------------------------------------------------------------*/
+------------------------------------------------------------------------------*/
+#define ONU_GPON_LOG_INTERRUPT (1)
+#define ONU_GPON_LOG_INTERRUPT_XVR_SD (2)
+#define ONU_GPON_LOG_INTERRUPT_LOF (3)
+#define ONU_GPON_LOG_INTERRUPT_SERDES_START (4)
+#define ONU_GPON_LOG_INTERRUPT_SERDES_STOP (5)
+#define ONU_GPON_LOG_STATE (6)
+#define ONU_GPON_LOG_MSG (7)
+#define ONU_GPON_LOG_MSG_CONTENT (8)
-/* Enums
-------------------------------------------------------------------------------*/
-
+#define ONU_GPON_LOG_SIZE (512)
+
+#define TCONT_CLEAN_EVENT (0)
+#define TCONT_CLEAN_ALL_EVENT (1)
+#define TCONT_ACTIVE_EVENT (2)
+
+#define TCONT_FLUSH_READY_STATE (1)
+#define TCONT_FLUSH_RUNNING_STATE (2)
+#define TCONT_FLUSH_BLOCKING_STATE (3)
+
+/* Enums
+------------------------------------------------------------------------------*/
+
/* Typedefs
------------------------------------------------------------------------------*/
typedef struct
@@ -93,8 +111,22 @@
MV_U32 blockSize;
}S_DbrBlockSize;
+typedef struct
+{
+ MV_U16 event;
+ MV_U16 state;
+ MV_U32 time;
+ MV_U32 dataVal1;
+ MV_U32 dataVal2;
+ MV_U32 dataVal3;
+}S_OnuGponLogEntry;
+
/* Global variables
------------------------------------------------------------------------------*/
+extern S_onuPonWork gponTcontCleanWork[8];
+extern S_onuPonWork gponTcontCleanAllWork;
+extern S_onuPonWork gponTcontActiveWork[8];
+extern S_onuPonWorkQueue gponTcontFlushWq;
/* Global functions
------------------------------------------------------------------------------*/
@@ -112,6 +144,14 @@
MV_STATUS onuGponSrvcDbrBlockSizeSet(MV_U32 blockSize, MV_U32 *actualBlockSize);
MV_STATUS onuGponSrvcRangingRandomInit(void);
+void onuGponSyncLog(MV_U32 event, MV_U32 data1, MV_U32 data2, MV_U32 data3);
+void onuGponSyncLogEnable(MV_U32 enable);
+void onuGponSyncLogPrint(void);
+
+extern void onuGponWqTcontFunc(struct work_struct *work);
+extern MV_STATUS onuGponWqTcontFlush(MV_U32 tcont);
+extern MV_STATUS onuGponWqTcontActivate(MV_U32 tcont);
+
/* Macros
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.c
index d847357..e5baf82 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.c
@@ -898,8 +898,14 @@
}
spin_lock_irqsave(&onuPonIrqLock, flags);
- if (ioctlState) status = mvP2PStart();
- else status = mvP2PStop();
+ if (ioctlState)
+ {
+ status = mvP2PStart();
+ }
+ else
+ {
+ status = mvP2PStop();
+ }
spin_unlock_irqrestore(&onuPonIrqLock, flags);
if (status != MV_OK)
@@ -908,6 +914,29 @@
ret = 0;
break;
+ /* ====== MVEPON_IOCTL_P2P_ FORCE_MODE_SET ==================== */
+ case MVEPON_IOCTL_P2P_FORCE_MODE_SET:
+ if (copy_from_user(&ioctlState, (MV_U32*)arg, sizeof(MV_U32)))
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_API_MODULE,
+ "ERROR: (%s:%d) copy_from_user failed\n", __FILE_DESC__, __LINE__);
+ goto ioctlErr;
+ }
+
+ spin_lock_irqsave(&onuPonIrqLock, flags);
+
+ onuEponDbP2PForceModeSet(ioctlState);
+
+ spin_unlock_irqrestore(&onuPonIrqLock, flags);
+
+ if (status != MV_OK)
+ {
+ goto ioctlErr;
+ }
+
+ ret = 0;
+ break;
+
/* ====== MVEPON_IOCTL_TDM_QUE_CFG ==================== */
case MVEPON_IOCTL_TDM_QUE_CFG:
if(copy_from_user(&ioctlTdmQueue, (S_EponIoctlTdmQueue*)arg, sizeof(S_EponIoctlTdmQueue)))
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.h
index 0cdb12f..d73b4e3 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsMI.h
@@ -94,9 +94,10 @@
#define MVEPON_IOCTL_HOLDOVER_RPRT _IOW(MVPON_IOCTL_MAGIC, 10, unsigned int)
#define MVEPON_IOCTL_SILENCE _IOW(MVPON_IOCTL_MAGIC, 11, unsigned int)
#define MVEPON_IOCTL_P2P_SET _IOW(MVPON_IOCTL_MAGIC, 12, unsigned int)
-#define MVEPON_IOCTL_TDM_QUE_CFG _IOW(MVPON_IOCTL_MAGIC, 13, unsigned int)
-#define MVEPON_IOCTL_ALARM_GET _IOR(MVPON_IOCTL_MAGIC, 14, unsigned int)
-#define MVEPON_IOCTL_ROGUE_ONU_SET _IOW(MVPON_IOCTL_MAGIC, 15, unsigned int)
+#define MVEPON_IOCTL_P2P_FORCE_MODE_SET _IOW(MVPON_IOCTL_MAGIC, 13, unsigned int)
+#define MVEPON_IOCTL_TDM_QUE_CFG _IOW(MVPON_IOCTL_MAGIC, 14, unsigned int)
+#define MVEPON_IOCTL_ALARM_GET _IOR(MVPON_IOCTL_MAGIC, 15, unsigned int)
+#define MVEPON_IOCTL_ROGUE_ONU_SET _IOW(MVPON_IOCTL_MAGIC, 16, unsigned int)
#define EPON_MAX_NUM_OF_MAC (8)
#define EPON_MAX_NUM_OF_QUEUE (8)
@@ -224,8 +225,12 @@
/* Init */
typedef struct
{
- MV_U32 xvrPolarity;
+ MV_U32 ponXvrBurstEnPolarity;
+ MV_U32 ponXvrPolarity;
+ MV_U32 p2pXvrBurstEnPolarity;
+ MV_U32 p2pXvrPolarity;
MV_U32 dgPolarity;
+ MV_U32 pkt2kSupported;
MV_U8 macAddr[EPON_MAX_NUM_OF_MAC][EPON_MAC_LEN];
}S_EponIoctlInit;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsUI.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsUI.c
index e425751..ce98eb1 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsUI.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/epon/eponOnuLnxKsUI.c
@@ -894,6 +894,7 @@
"limits\n");
off += mvOsSPrintf(buf+off, " echo [threshold] > rxDataFifoThresh - Configure RX Parser Data FIFO "
"threshold\n");
+ off += mvOsSPrintf(buf+off, " echo [pkt2kSupported] > pkt2kEn - Configure 2K packet supported\r\n");
off += mvOsSPrintf(buf+off, " echo [txMask][txP][serdesP][xvrP][burstEn] > ddmTxPolarity - Configure "
" DDM Polarity settings\n");
}
@@ -906,6 +907,7 @@
off += mvOsSPrintf(buf+off, " cat pcsFrameLimits - dump PCS Frame Size Limits\n");
off += mvOsSPrintf(buf+off, " cat rxDataFifoThresh - dump RX Parser Data FIFO "
"threshold\n");
+ off += mvOsSPrintf(buf+off, " cat pkt2kEn - dump 2K packet supported registers\r\n");
}
off += mvOsSPrintf(buf+off, "============================================================================\n");
@@ -1408,6 +1410,7 @@
}
else
{
+ onuPonTxPowerOn(MV_TRUE);
onuPonPatternBurstOn(pattern, (MV_BOOL)burst, period, duration);
}
}
@@ -1518,6 +1521,68 @@
/*******************************************************************************
**
+** onuEponUiCfgSetPkt2kEnable
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function configures 2K packet supported
+**
+** PARAMETERS: MV_U32 enable - 2K packet supported enable or disable
+**
+** OUTPUTS: none
+**
+** RETURNS: void
+**
+*******************************************************************************/
+void onuEponUiCfgSetPkt2kEnable(MV_U32 enable)
+{
+ /* Before setting register, needs to disable Rx */
+ mvOnuEponMacPcsRxEnableSet(EPON_PCS_CONFIG_RX_DISABLE);
+
+ mvEponApi2kSupportedSet(enable);
+
+ /* After setting register, enable Rx */
+ mvOnuEponMacPcsRxEnableSet(EPON_PCS_CONFIG_RX_ENABLE);
+}
+
+/*******************************************************************************
+**
+** onuEponUiCfgShowPkt2kEnable
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function shows 2K packet supported
+**
+** PARAMETERS: char *buf
+**
+** OUTPUTS: char *buf
+**
+** RETURNS: offset of buf
+**
+*******************************************************************************/
+int onuEponUiCfgShowPkt2kEnable(char* buf)
+{
+ int off = 0;
+ MV_STATUS status;
+ MV_U32 frameSizeLimitSize;
+ MV_U32 frameSizeLimitLatency;
+ MV_U32 dataFifoThreshold;
+
+ status = mvOnuEponMacPcsFrameSizeLimitsGet(&frameSizeLimitSize, &frameSizeLimitLatency);
+ status |= mvOnuEponMacRxpDataFifoThresholdGet(&dataFifoThreshold);
+
+ if (status != MV_OK)
+ off += mvOsSPrintf(buf+off, "Failed to obtain 2K packet support related register value!\r\n");
+ else {
+ off += mvOsSPrintf(buf+off, "\r\n");
+ off += mvOsSPrintf(buf+off, "PcsFrameSizeLimitSize = %#d\r\n", frameSizeLimitSize);
+ off += mvOsSPrintf(buf+off, "PcsFrameSizeLimitLatency = %#d\r\n", frameSizeLimitLatency);
+ off += mvOsSPrintf(buf+off, "DataFifoThreshold = %#d\r\n", dataFifoThreshold);
+ }
+
+ return(off);
+}
+
+/*******************************************************************************
+**
** onuEponUiCfgSetDdmTxPolarity
** ____________________________________________________________________________
**
@@ -1790,6 +1855,11 @@
return(onuEponUiCfgShowPcsFrameLimits(buf));
else if (!strcmp(name, "rxDataFifoThresh"))
return(onuEponUiCfgShowRxDataFifoThresh(buf));
+ else if (!strcmp(name, "pkt2kEn"))
+ {
+ return onuEponUiCfgShowPkt2kEnable(buf);
+ }
+
}
return 0;
@@ -1857,6 +1927,10 @@
onuEponUiCfgSetPcsFrameLimits((MV_U32)param1, (MV_U32)param2);
else if (!strcmp(name, "rxDataFifoThresh"))
onuEponUiCfgSetRxDataFifoThresh((MV_U32)param1);
+ else if (!strcmp(name, "pkt2kEn"))
+ {
+ onuEponUiCfgSetPkt2kEnable((MV_U32)param1);
+ }
else if (!strcmp(name, "ddmTxPolarity")) /* txEnable, txPol, serdesPol, xvrPol, burstEn */
onuEponUiCfgSetDdmTxPolarity((MV_U32)param1,(MV_U32)param2,(MV_U32)param3,
(MV_U32)param4,(MV_U32)param5);
@@ -1895,8 +1969,9 @@
static DEVICE_ATTR(pcsFrameLimits, S_IWUSR | S_IRUSR, cfg_show, cfg_store);
static DEVICE_ATTR(rxDataFifoThresh, S_IWUSR | S_IRUSR, cfg_show, cfg_store);
static DEVICE_ATTR(ddmTxPolarity, S_IWUSR, cfg_show, cfg_store);
+static DEVICE_ATTR(pkt2kEn, S_IWUSR | S_IRUSR, cfg_show, cfg_store);
static DEVICE_ATTR(helpCfg, S_IRUSR, cfg_show, cfg_store);
-
+
static struct attribute *cfg_attrs[] = {
&dev_attr_rxEn.attr,
&dev_attr_txEn.attr,
@@ -1918,8 +1993,9 @@
&dev_attr_pattern.attr,
&dev_attr_printMask.attr,
&dev_attr_pcsFrameLimits.attr,
- &dev_attr_rxDataFifoThresh.attr,
+ &dev_attr_rxDataFifoThresh.attr,
&dev_attr_ddmTxPolarity.attr,
+ &dev_attr_pkt2kEn.attr,
&dev_attr_helpCfg.attr,
NULL
};
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.c
index 457c5e7..0b0ac0b 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.c
@@ -270,6 +270,25 @@
/*******************************************************************************
**
+** onuGponMiClearTcontConfig
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function clears the specifid tcont configuration
+**
+** PARAMETERS: MV_U32 tcont
+**
+** OUTPUTS: None
+**
+** RETURNS: None
+**
+*******************************************************************************/
+MV_STATUS onuGponMiClearTcontConfig(MV_U32 tcont)
+{
+ return (onuGponApiTcontClear(tcont));
+}
+
+/*******************************************************************************
+**
** onuGponMiGem
** ____________________________________________________________________________
**
@@ -378,8 +397,7 @@
spin_unlock_irqrestore(&onuPonIrqLock, flags);
if(status != MV_OK)
goto ioctlErr;
- onuGponDbXvrPolaritySet(ioctlXvr.polarity);
- mvOnuPonMacBurstEnablePolarityInit(ioctlXvr.polarity);
+
ret = 0;
break;
@@ -413,6 +431,27 @@
ret = 0;
break;
+ /* ====== MVGPON_IOCTL_DATA_TCONT_CLEAR ======== */
+ case MVGPON_IOCTL_DATA_TCONT_CLEAR:
+ if(copy_from_user(&ioctlData, (S_GponIoctlData*)arg, sizeof(S_GponIoctlData)))
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_API_MODULE,
+ "ERROR: (%s:%d) copy_from_user failed\n", __FILE_DESC__, __LINE__);
+ goto ioctlErr;
+ }
+
+ spin_lock_irqsave(&onuPonIrqLock, flags);
+ status = onuGponMiClearTcontConfig(ioctlData.tcont);
+ spin_unlock_irqrestore(&onuPonIrqLock, flags);
+ if(status != MV_OK)
+ {
+ goto ioctlErr;
+ }
+
+ ret = 0;
+
+ break;
+
/* ====== MVGPON_IOCTL_GEMPORT_STATE_SET ======= */
case MVGPON_IOCTL_GEMPORT_STATE_SET:
if(copy_from_user(&ioctlData, (S_GponIoctlData*)arg, sizeof(S_GponIoctlData)))
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.h
index d091673..1a9f589 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsMI.h
@@ -84,16 +84,17 @@
#define MVGPON_IOCTL_INIT _IOW(MVPON_IOCTL_MAGIC, 1, unsigned int)
#define MVGPON_IOCTL_BEN_INIT _IOW(MVPON_IOCTL_MAGIC, 2, unsigned int)
#define MVGPON_IOCTL_DATA_TCONT_CONFIG _IOW(MVPON_IOCTL_MAGIC, 3, unsigned int)
-#define MVGPON_IOCTL_DATA_TCONT_RESET _IO(MVPON_IOCTL_MAGIC, 4)
-#define MVGPON_IOCTL_INFO _IOR(MVPON_IOCTL_MAGIC, 5, unsigned int)
-#define MVGPON_IOCTL_ALARM _IOR(MVPON_IOCTL_MAGIC, 6, unsigned int)
-#define MVGPON_IOCTL_PM _IOR(MVPON_IOCTL_MAGIC, 7, unsigned int)
-#define MVGPON_IOCTL_GEM _IOW(MVPON_IOCTL_MAGIC, 8, unsigned int)
-#define MVGPON_IOCTL_GEMPORT_PM_CONFIG _IOW(MVPON_IOCTL_MAGIC, 9, unsigned int)
-#define MVGPON_IOCTL_GEMPORT_PM_GET _IOR(MVPON_IOCTL_MAGIC, 10, unsigned int)
-#define MVGPON_IOCTL_GEMPORT_PM_RESET _IOW(MVPON_IOCTL_MAGIC, 11, unsigned int)
-#define MVGPON_IOCTL_GEMPORT_STATE_GET _IOW(MVPON_IOCTL_MAGIC, 12, unsigned int)
-#define MVGPON_IOCTL_GEMPORT_STATE_SET _IOW(MVPON_IOCTL_MAGIC, 13, unsigned int)
+#define MVGPON_IOCTL_DATA_TCONT_CLEAR _IOR(MVPON_IOCTL_MAGIC, 4, unsigned int)
+#define MVGPON_IOCTL_DATA_TCONT_RESET _IO(MVPON_IOCTL_MAGIC, 5)
+#define MVGPON_IOCTL_INFO _IOR(MVPON_IOCTL_MAGIC, 6, unsigned int)
+#define MVGPON_IOCTL_ALARM _IOR(MVPON_IOCTL_MAGIC, 7, unsigned int)
+#define MVGPON_IOCTL_PM _IOR(MVPON_IOCTL_MAGIC, 8, unsigned int)
+#define MVGPON_IOCTL_GEM _IOW(MVPON_IOCTL_MAGIC, 9, unsigned int)
+#define MVGPON_IOCTL_GEMPORT_PM_CONFIG _IOW(MVPON_IOCTL_MAGIC, 10, unsigned int)
+#define MVGPON_IOCTL_GEMPORT_PM_GET _IOR(MVPON_IOCTL_MAGIC, 11, unsigned int)
+#define MVGPON_IOCTL_GEMPORT_PM_RESET _IOW(MVPON_IOCTL_MAGIC, 12, unsigned int)
+#define MVGPON_IOCTL_GEMPORT_STATE_GET _IOW(MVPON_IOCTL_MAGIC, 13, unsigned int)
+#define MVGPON_IOCTL_GEMPORT_STATE_SET _IOW(MVPON_IOCTL_MAGIC, 14, unsigned int)
#define ONU_GPON_DEBUG_STATE (0xFF)
@@ -227,7 +228,12 @@
MV_U32 clearTcont;
MV_U32 restoreGem;
MV_U32 dgPolarity;
- MV_U32 xvrPolarity;
+ MV_U32 ponXvrBurstEnPolarity;
+ MV_U32 ponXvrPolarity;
+ MV_U32 p2pXvrBurstEnPolarity;
+ MV_U32 p2pXvrPolarity;
+ MV_U32 fecHyst;
+ MV_U32 couplingMode; /* AC Coupling Mode */
}S_GponIoctlInfo;
typedef struct
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsUI.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsUI.c
index 7467f76..d3bf5ef 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsUI.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/gpon/gponOnuLnxKsUI.c
@@ -88,6 +88,7 @@
/* Global Variables
------------------------------------------------------------------------------*/
+extern MV_BOOL onuGponLogEnable;
/* Local Variables
------------------------------------------------------------------------------*/
@@ -2373,6 +2374,59 @@
return(off);
}
+/*******************************************************************************
+**
+** onuGponUiDebugManagerActiveTxBitmapSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function configures UTM Active TX Bitmap
+**
+** PARAMETERS: MV_U32 bitmap - bitmap
+** MV_U32 valid - valid
+**
+** OUTPUTS: None
+**
+** RETURNS: None
+**
+*******************************************************************************/
+void onuGponUiDebugManagerActiveTxBitmapSet(MV_U32 bitmap, MV_U32 valid)
+{
+ mvOnuGponMacUtmActiveTxBitmapSet(bitmap);
+ mvOnuGponMacUtmActiveTxBitmapValidSet(valid);
+}
+
+/*******************************************************************************
+**
+** onuGponUiDebugManagerActiveTxBitmapGet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function prints UTM Active TX bitmap
+**
+** PARAMETERS: char *buf
+**
+** OUTPUTS: char *buf
+**
+** RETURNS: None
+**
+*******************************************************************************/
+int onuGponUiDebugManagerActiveTxBitmapGet(char *buf)
+{
+
+ int off = 0;
+ MV_U32 bitmap, valid;
+ MV_STATUS status;
+
+
+ status = mvOnuGponMacUtmActiveTxBitmapConfigGet(&bitmap, &valid);
+
+ if (status != MV_OK)
+ off += mvOsSPrintf(buf+off, "Failed to obtain UTM Active TX bitmap!\n");
+ else
+ off += mvOsSPrintf(buf+off, "UTM Active TX bitmap = %#x valid = %d\n", bitmap, valid);
+
+ return(off);
+}
+
/*******************************************************************************
**
@@ -2607,8 +2661,10 @@
off += mvOsSPrintf(buf+off, " echo 0 > clearFifoCnts - clear all SW FIFO counters\n");
off += mvOsSPrintf(buf+off, " echo [enable(1) or disable(0)] > fifoSupport - config US SW FIFO support\n");
if (devId == MV_6601_DEV_ID){
- off += mvOsSPrintf(buf+off, " echo [Mode] [Time] [Pattern1] [Pattern2] > acCoupling - "
- "configure TX AC Coupling parameters\n");
+ off += mvOsSPrintf(buf+off, " echo [Mode] [Burst_Time] [Pattern1] [Pattern2] > acCoupling - "
+ "configure TX AC Coupling parameters\r\n");
+ off += mvOsSPrintf(buf+off, " echo [Bitmap] [Valid] > activeTxBm - "
+ "configure UTM Active TX Bitmap\n");
}
off += mvOsSPrintf(buf+off, "============================================================================\n");
off += mvOsSPrintf(buf+off, "Display Commands: cat <file>\n");
@@ -2618,6 +2674,8 @@
if (devId == MV_6601_DEV_ID){
off += mvOsSPrintf(buf+off, " cat acCoupling - "
"dump TX AC Coupling parameters\n");
+ off += mvOsSPrintf(buf+off, " cat activeTxBm - "
+ "show UTM Active TX Bitmap\n");
}
off += mvOsSPrintf(buf+off, "============================================================================\n");
@@ -2903,11 +2961,14 @@
void onuGponUiCfgSetPatternBurst(MV_U32 enable,MV_U32 pattern, MV_U32 burst, MV_U32 duration, MV_U32 period)
{
- if (enable == 0) {
- onuPonPatternBurstOff();
+ if (enable == 0)
+ {
+ onuPonPatternBurstOff();
}
- else{
- onuPonPatternBurstOn(pattern, (MV_BOOL)burst, period, duration);
+ else
+ {
+ onuPonTxPowerOn(MV_TRUE);
+ onuPonPatternBurstOn(pattern, (MV_BOOL)burst, period, duration);
}
}
@@ -3127,6 +3188,43 @@
}
+/*******************************************************************************
+**
+** onuGponUiSyncLogEnable
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function
+**
+** PARAMETERS: MV_U32 enable
+**
+** OUTPUTS: None
+**
+** RETURNS: None
+**
+*******************************************************************************/
+void onuGponUiSyncLogEnable(MV_U32 enable)
+{
+ onuGponSyncLogEnable(enable);
+}
+
+/*******************************************************************************
+**
+** onuGponUiSyncLogPrint
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: None
+**
+*******************************************************************************/
+void onuGponUiSyncLogPrint(void)
+{
+ onuGponSyncLogPrint();
+}
/*******************************************************************************
**
@@ -3184,14 +3282,33 @@
"config T01 timer interval in mS\n");
off += mvOsSPrintf(buf+off, " echo [T02 Interval] > t02IntervalCfg - "
"config T02 timer interval in mS\n");
+ off += mvOsSPrintf(buf+off, " echo [0] > syncLogEnable - Enable or Disable record GPON range log\n");
off += mvOsSPrintf(buf+off, "============================================================================\n");
off += mvOsSPrintf(buf+off, "Display Commands: cat <file>\n");
off += mvOsSPrintf(buf+off, "============================================================================\n");
off += mvOsSPrintf(buf+off, " cat printMask - dump printing options\n");
+ off += mvOsSPrintf(buf+off, " cat syncLogEnable - dump GPON range log enable status\n");
+ off += mvOsSPrintf(buf+off, " cat syncLog - print GPON range log\n");
return(off);
}
+int onuGponUiSyncLogEnableShow()
+{
+ printk("The Sync Log is ");
+
+ if (onuGponLogEnable == MV_TRUE)
+ {
+ printk("enabled\r\n");
+ }
+ else
+ {
+ printk("disabled\r\n");
+ }
+
+ return 0;
+}
+
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
@@ -3227,6 +3344,10 @@
return ponOnuPrintStatus(buf);
else if (!strcmp(name, "helpMisc"))
return onuGponUiMiscHelpShow(buf);
+ else if (!strcmp(name, "syncLogEnable")) /* sync log enable or disable */
+ onuGponUiSyncLogEnableShow();
+ else if (!strcmp(name, "syncLog")) /* sync log stop */
+ onuGponUiSyncLogPrint();
return 0;
}
@@ -3287,6 +3408,8 @@
onuGponUiT01IntervalConfig((MV_U32)param1);
else if (!strcmp(name, "t02IntervalCfg")) /* T02 interval in mS */
onuGponUiT02IntervalConfig((MV_U32)param1);
+ else if (!strcmp(name, "syncLogEnable")) /* sync log enable or disable */
+ onuGponUiSyncLogEnable((MV_U32)param1);
else
printk(KERN_ERR "%s: illegal operation <%s>\n", __func__, attr->attr.name);
@@ -3318,6 +3441,8 @@
static DEVICE_ATTR(helpMisc, S_IRUSR, misc_show, misc_store);
static DEVICE_ATTR(t01IntervalCfg, S_IWUSR, misc_show, misc_store);
static DEVICE_ATTR(t02IntervalCfg, S_IWUSR, misc_show, misc_store);
+static DEVICE_ATTR(syncLogEnable, S_IRUSR | S_IWUSR, misc_show, misc_store);
+static DEVICE_ATTR(syncLog, S_IRUSR, misc_show, misc_store);
static struct attribute *misc_attrs[] = {
&dev_attr_serialNumCfg.attr,
@@ -3340,6 +3465,8 @@
&dev_attr_adminCfg.attr,
&dev_attr_t01IntervalCfg.attr,
&dev_attr_t02IntervalCfg.attr,
+ &dev_attr_syncLogEnable.attr,
+ &dev_attr_syncLog.attr,
NULL
};
@@ -3378,6 +3505,8 @@
else if (devId == MV_6601_DEV_ID) {
if (!strcmp(name, "acCoupling"))
return onuGponUiDebugManagerAcCouplingGet(buf);
+ else if (!strcmp(name, "activeTxBm"))
+ return onuGponUiDebugManagerActiveTxBitmapGet(buf);
}
return 0;
}
@@ -3435,9 +3564,11 @@
else if (!strcmp(name, "fifoSupport")) /* enable/disable */
onuGponUiDebugManagerFifoSupportSet((MV_U32)param1);
else if (devId == MV_6601_DEV_ID) {
- if (!strcmp(name, "acCoupling")) /* mode, time, pattern1, pattern2 */
- onuGponUiDebugManagerAcCouplingSet((MV_U32)param1, (MV_U32)param2, (MV_U32)param3,
- (MV_U32)param4);
+ if (!strcmp(name, "acCoupling"))
+ /* mode, time, pattern1, pattern2 */
+ onuGponUiDebugManagerAcCouplingSet((MV_U32)param1, (MV_U32)param2, (MV_U32)param3, (MV_U32)param4);
+ else if (!strcmp(name, "activeTxBm")) /* bitmap, valid */
+ onuGponUiDebugManagerActiveTxBitmapSet((MV_U32)param1, (MV_U32)param2);
else
printk(KERN_ERR "%s: illegal operation <%s>\n", __func__, attr->attr.name);
} else
@@ -3467,6 +3598,8 @@
static DEVICE_ATTR(ploamBurstCfg, S_IWUSR, protocol_show, protocol_store);
static DEVICE_ATTR(clearFifoCnts, S_IWUSR, protocol_show, protocol_store);
static DEVICE_ATTR(fifoSupport, S_IWUSR, protocol_show, protocol_store);
+static DEVICE_ATTR(acCoupling, S_IRUSR | S_IWUSR, protocol_show, protocol_store);
+static DEVICE_ATTR(activeTxBm, S_IRUSR | S_IWUSR, protocol_show, protocol_store);
static DEVICE_ATTR(helpProto, S_IRUSR, protocol_show, protocol_store);
static struct attribute *protocol_attrs[] = {
@@ -3486,6 +3619,8 @@
&dev_attr_ploamBurstCfg.attr,
&dev_attr_clearFifoCnts.attr,
&dev_attr_fifoSupport.attr,
+ &dev_attr_acCoupling.attr,
+ &dev_attr_activeTxBm.attr,
&dev_attr_helpProto.attr,
NULL
};
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/ponOnuLnxKsMI.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/ponOnuLnxKsMI.h
index 620bcb0..9cc5566 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/ponOnuLnxKsMI.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/perf/ponOnuLnxKsMI.h
@@ -105,7 +105,6 @@
int (*cdevIoctl)(struct inode *, struct file *, unsigned int, unsigned long);
} S_PonFunctions;
-
typedef struct {
E_PonDriverMode drvMode;
int devOpen;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuBoard.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuBoard.c
index d1d245f..7d5cd97 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuBoard.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuBoard.c
@@ -1,479 +1,541 @@
-/*******************************************************************************
-Copyright (C) Marvell International Ltd. and its affiliates
-
-This software file (the "File") is owned and distributed by Marvell
-International Ltd. and/or its affiliates ("Marvell") under the following
-alternative licensing terms. Once you have made an election to distribute the
-File under one of the following license alternatives, please (i) delete this
-introductory statement regarding license alternatives, (ii) delete the two
-license alternatives that you have not elected to use and (iii) preserve the
-Marvell copyright notice above.
-
-********************************************************************************
-Marvell Commercial License Option
-
-If you received this File from Marvell and you have entered into a commercial
-license agreement (a "Commercial License") with Marvell, the File is licensed
-to you under the terms of the applicable Commercial License.
-
-********************************************************************************
-Marvell GPL License Option
-
-If you received this File from Marvell, you may opt to use, redistribute and/or
-modify this File in accordance with the terms and conditions of the General
-Public License Version 2, June 1991 (the "GPL License"), a copy of which is
-available along with the File in the license.txt file or by writing to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
-on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-
-THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
-DISCLAIMED. The GPL License provides additional details about this warranty
-disclaimer.
-********************************************************************************
-Marvell BSD License Option
-
-If you received this File from Marvell, you may opt to use, redistribute and/or
-modify this File under the following licensing terms.
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-******************************************************************************/
-
-/******************************************************************************
-** FILE : eponOnuBoard.c **
-** **
-** DESCRIPTION : This file implements ONU Board specific **
-*******************************************************************************
-* *
-* MODIFICATION HISTORY: *
-* *
-* 29Oct06 Oren Ben Hayun created *
-* =========================================================================== *
-******************************************************************************/
-
-/* Include Files
-------------------------------------------------------------------------------*/
-#include "ponOnuHeader.h"
-
-/* Local Constant
-------------------------------------------------------------------------------*/
-
-/* Global Variables
-------------------------------------------------------------------------------*/
-
-/* Global functions
-------------------------------------------------------------------------------*/
-
-/* Local Variables
-------------------------------------------------------------------------------*/
-
-/* Export Functions
-------------------------------------------------------------------------------*/
-
-/* Local Functions
-------------------------------------------------------------------------------*/
-
-#ifndef PON_FPGA
-/*******************************************************************************
-**
-** onuEponSerdesPowerUpSeq
-** ____________________________________________________________________________
-**
-** DESCRIPTION: The function set serdes
-**
-** PARAMETERS: None
-**
-** OUTPUTS: None
-**
-** RETURNS: MV_OK or error
-**
-*******************************************************************************/
-MV_STATUS onuEponSerdesPowerUpSeq(void)
-{
- MV_STATUS status;
- MV_U32 rxReady = 0;
- MV_U32 txReady = 0;
- MV_U32 initDone;
- MV_U32 temp;
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_Pll, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_RX, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_TX, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- // asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0, &temp, 0);
- // temp &= ~(0x7);
- // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0, temp, 0);
- // if (status != MV_OK)
- // return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_SEL_GEPON, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_REF_CLK_25M, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(40);
-
- asicOntMiscRegRead(mvAsicReg_PON_SERDES_INTERNAL_PASSWORD, &temp, 0);
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_PASSWORD, temp | 0x76, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_EN_LOOP_TIMING, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_PON_SELECT, 0x3, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_Pll, 0x1, 0);
- // if (status != MV_OK)
- // return(status);
- //
- // mvOsDelay(40);
- //
- // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_RX, 0x1, 0);
- // if (status != MV_OK)
- // return(status);
- //
- // mvOsDelay(10);
- //
- // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_TX, 0x1, 0);
- // if (status != MV_OK)
- // return(status);
-
- asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0, &temp, 0);
- temp |= (0x7);
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0, temp, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(20);
-
- temp = 0;
- do
- {
- temp++;
-
- status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_READY_TX, &txReady, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_READY_RX, &rxReady, 0);
- if (status != MV_OK)
- return(status);
-
- if ((temp % 10) == 0)
- {
- return (MV_FAIL);
- }
-
- } while ((txReady == 0) || (rxReady == 0));
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- temp = 0;
- do
- {
- temp++;
-
- status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_INIT_DONE, &initDone, 0);
- if (status != MV_OK)
- return(status);
-
- if ((temp % 10) == 0)
- {
- return (MV_FAIL);
- }
-
- mvOsDelay(10);
-
- } while (initDone == 0);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- return(MV_OK);
-}
-
-/*******************************************************************************
-**
-** onuEponSerdesInit
-** ____________________________________________________________________________
-**
-** DESCRIPTION: The function set serdes
-**
-** PARAMETERS: None
-**
-** OUTPUTS: None
-**
-** RETURNS: MV_OK or error
-**
-*******************************************************************************/
-MV_STATUS onuEponSerdesInit(void)
-{
- MV_STATUS status;
- MV_U32 loop = 0;
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- /* Put PON MAC to Reset */
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- /* Switch to new PON MAC */
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 1, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Take PON MAC out of Reset */
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
-
- /* EPON configuration of XVR SD is done by LSP code (mvBoardEnvSpec.h, mvCtrlEnvLib.c) */
-
- /* EPON configuration/SerDes power up and init sequence */
- /* ========================================================= */
-
- do
- {
- loop++;
-
- status = onuEponSerdesPowerUpSeq();
- if (status == MV_ERROR) return(status);
- else if (status == MV_OK) break;
-
- } while (loop < 10);
-
- if (loop >= 10)
- {
- mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE, "======================================\n");
- mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE, "========= Serdes Not Sync !!! ========\n");
- mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE, "======================================\n");
- }
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST_TX_DOUT, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_OPEN_TX_DOOR, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- mvOsDelay(10);
-
- // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x0, 0);
- // if (status != MV_OK)
- // return(status);
- //
- // mvOsDelay(10);
-
- return(MV_OK);
-}
-
-#if 0 /* only for pon mode switch without Reset */
-/*******************************************************************************
-**
-** onuEponSwitchOver
-** ____________________________________________________________________________
-**
-** DESCRIPTION: The function switch between EPON and GPON
-**
-** PARAMETERS: None
-**
-** OUTPUTS: None
-**
-** RETURNS: MV_OK or error
-**
-*******************************************************************************/
-MV_STATUS onuEponSwitchOver(void)
-{
- MV_STATUS status;
-
- /* STOP Traffic */
-
-
- /* Close TX EN */
- printk("onuPonSwitchOver - Close TX EN\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Put PON MAC to Reset */
- printk("onuPonSwitchOver - Put PON MAC to Reset\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Switch to new PON MAC */
- printk("onuPonSwitchOver - Switch to new PON MAC - EPON\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Take PON MAC out of Reset */
- printk("onuPonSwitchOver - Take PON MAC out of Reset\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Re-init Serdes */
- printk("onuPonSwitchOver - Re-init Serdes\n\r");
-
- printk("onuPonSwitchOver - Put PON MAC to Reset\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
-
- printk("onuPonSerdeSwitchOverInit - Serdes CLK EN\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Take PON MAC out of Reset */
- printk("onuPonSwitchOver - Take PON MAC out of Reset\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
- if (status != MV_OK)
- return(status);
-
- /* Open TX EN */
- printk("onuPonSwitchOver - Open TX EN\n\r");
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x0, 0);
- if (status != MV_OK)
- return(status);
-
- return(MV_OK);
-}
-#endif
-#endif /* PON_FPGA */
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+This software file (the "File") is owned and distributed by Marvell
+International Ltd. and/or its affiliates ("Marvell") under the following
+alternative licensing terms. Once you have made an election to distribute the
+File under one of the following license alternatives, please (i) delete this
+introductory statement regarding license alternatives, (ii) delete the two
+license alternatives that you have not elected to use and (iii) preserve the
+Marvell copyright notice above.
+
+********************************************************************************
+Marvell Commercial License Option
+
+If you received this File from Marvell and you have entered into a commercial
+license agreement (a "Commercial License") with Marvell, the File is licensed
+to you under the terms of the applicable Commercial License.
+
+********************************************************************************
+Marvell GPL License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED. The GPL License provides additional details about this warranty
+disclaimer.
+********************************************************************************
+Marvell BSD License Option
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of Marvell nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+/******************************************************************************
+** FILE : eponOnuBoard.c **
+** **
+** DESCRIPTION : This file implements ONU Board specific **
+*******************************************************************************
+* *
+* MODIFICATION HISTORY: *
+* *
+* 29Oct06 Oren Ben Hayun created *
+* =========================================================================== *
+******************************************************************************/
+
+/* Include Files
+------------------------------------------------------------------------------*/
+#include "ponOnuHeader.h"
+
+/* Local Constant
+------------------------------------------------------------------------------*/
+
+/* Global Variables
+------------------------------------------------------------------------------*/
+
+/* Global functions
+------------------------------------------------------------------------------*/
+
+/* Local Variables
+------------------------------------------------------------------------------*/
+
+/* Export Functions
+------------------------------------------------------------------------------*/
+
+/* Local Functions
+------------------------------------------------------------------------------*/
+
+#ifndef PON_FPGA
+/*******************************************************************************
+**
+** onuEponSerdesPowerUpSeq
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function set serdes
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuEponSerdesPowerUpSeq(void)
+{
+ MV_STATUS status;
+ MV_U32 rxReady = 0;
+ MV_U32 txReady = 0;
+ MV_U32 initDone;
+ MV_U32 temp;
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_Pll, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_RX, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_TX, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ // asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0, &temp, 0);
+ // temp &= ~(0x7);
+ // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0, temp, 0);
+ // if (status != MV_OK)
+ // return(status);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_SEL_GEPON, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_REF_CLK_25M, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ asicOntMiscRegRead(mvAsicReg_PON_SERDES_INTERNAL_PASSWORD, &temp, 0);
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_PASSWORD, temp | 0x76, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_EN_LOOP_TIMING, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_PON_SELECT, 0x3, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_Pll, 0x1, 0);
+ // if (status != MV_OK)
+ // return(status);
+ //
+ // mvOsDelay(40);
+ //
+ // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_RX, 0x1, 0);
+ // if (status != MV_OK)
+ // return(status);
+ //
+ // mvOsDelay(10);
+ //
+ // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_TX, 0x1, 0);
+ // if (status != MV_OK)
+ // return(status);
+
+ asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0, &temp, 0);
+ temp |= (0x7);
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0, temp, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ temp = 0;
+ do
+ {
+ temp++;
+
+ status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_READY_TX, &txReady, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_READY_RX, &rxReady, 0);
+ if (status != MV_OK)
+ return(status);
+
+ if ((temp % 10) == 0)
+ {
+ return (MV_FAIL);
+ }
+
+ } while ((txReady == 0) || (rxReady == 0));
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ temp = 0;
+ do
+ {
+ temp++;
+
+ status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_INIT_DONE, &initDone, 0);
+ if (status != MV_OK)
+ return(status);
+
+ if ((temp % 10) == 0)
+ {
+ return (MV_FAIL);
+ }
+
+ mvOsDelay(40);
+
+ } while (initDone == 0);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ return(MV_OK);
+}
+
+/*******************************************************************************
+**
+** onuEponSerdesInit
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function set serdes
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuEponSerdesInit(void)
+{
+ MV_STATUS status;
+ MV_U32 loop = 0;
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* PON MAC init to GPON mode */
+ /* ========================= */
+
+ /* Put PON MAC to Reset */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* Switch to new PON MAC */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* Take PON MAC out of Reset */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* PON MAC init to EPON mode */
+ /* ========================= */
+
+ /* Put PON MAC to Reset */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* Switch to new PON MAC */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* Take PON MAC out of Reset */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* EPON configuration of XVR SD is done by LSP code (mvBoardEnvSpec.h, mvCtrlEnvLib.c) */
+
+ /* EPON configuration/SerDes power up and init sequence */
+ /* ========================================================= */
+
+ do
+ {
+ loop++;
+
+ status = onuEponSerdesPowerUpSeq();
+ if (status == MV_ERROR) return(status);
+ else if (status == MV_OK) break;
+
+ } while (loop < 10);
+
+ if (loop >= 10)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE, "======================================\n");
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE, "========= Serdes Not Sync !!! ========\n");
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE, "======================================\n");
+ }
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST_TX_DOUT, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_OPEN_TX_DOOR, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ // status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x0, 0);
+ // if (status != MV_OK)
+ // return(status);
+ //
+ // mvOsDelay(10);
+
+ return(MV_OK);
+}
+
+#if 0 /* only for pon mode switch without Reset */
+/*******************************************************************************
+**
+** onuEponSwitchOver
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function switch between EPON and GPON
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuEponSwitchOver(void)
+{
+ MV_STATUS status;
+
+ /* STOP Traffic */
+
+
+ /* Close TX EN */
+ printk("onuPonSwitchOver - Close TX EN\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ /* Put PON MAC to Reset */
+ printk("onuPonSwitchOver - Put PON MAC to Reset\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ /* Switch to new PON MAC */
+ printk("onuPonSwitchOver - Switch to new PON MAC - EPON\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ /* Take PON MAC out of Reset */
+ printk("onuPonSwitchOver - Take PON MAC out of Reset\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ /* Re-init Serdes */
+ printk("onuPonSwitchOver - Re-init Serdes\n\r");
+
+ printk("onuPonSwitchOver - Put PON MAC to Reset\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+
+ printk("onuPonSerdeSwitchOverInit - Serdes CLK EN\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ /* Take PON MAC out of Reset */
+ printk("onuPonSwitchOver - Take PON MAC out of Reset\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ /* Open TX EN */
+ printk("onuPonSwitchOver - Open TX EN\n\r");
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ return(MV_OK);
+}
+#endif
+#endif /* PON_FPGA */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuLnxKsOs.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuLnxKsOs.c
index f7bbfcf..af3d3e5 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuLnxKsOs.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/epon/eponOnuLnxKsOs.c
@@ -269,6 +269,19 @@
}
}
+ /* onu pon TX Power timer */
+ retcode = onuPonTimerCreate(&(onuPonResourceTbl_s.onuPonTxPwrTimerId), /* timer Id */
+ "pon_txPwr", /* timer description */
+ (PTIMER_FUNCPTR)onuEponTimerTxPwrHndl, /* timer function */
+ ONU_PON_TIMER_NOT_ACTIVE, /* timer active (run) state */
+ ONU_PON_TIMER_TX_PWR_INTERVAL, /* init value */
+ 0); /* periodic value */
+ if (retcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) pon Tx Power timer create\n", __FILE_DESC__, __LINE__);
+ return(MV_ERROR);
+ }
/* Interrupt */
/* ========= */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuBoard.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuBoard.c
index b7be4fc..f678ec9 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuBoard.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuBoard.c
@@ -235,19 +235,19 @@
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_Pll, 0x0, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_RX, 0x0, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_TX, 0x0, 0);
if (status != MV_OK)
@@ -263,11 +263,12 @@
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_REF_CLK_25M, 0x1, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RST, 0x0, 0);
if (status != MV_OK)
@@ -280,19 +281,19 @@
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_EN_LOOP_TIMING, 0x1, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_PON_SELECT, 0x0, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
// status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_PU_Pll, 0x1, 0);
// if (status != MV_OK)
@@ -316,7 +317,7 @@
if (status != MV_OK)
return(status);
- mvOsDelay(20);
+ mvOsDelay(40);
temp = 0;
do
@@ -327,7 +328,7 @@
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegRead(mvAsicReg_PON_SERDES_PHY_CTRL_0_READY_RX, &rxReady, 0);
if (status != MV_OK)
@@ -340,13 +341,13 @@
} while ((txReady == 0) || (rxReady == 0));
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x1, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
temp = 0;
do
@@ -362,17 +363,17 @@
return (MV_FAIL);
}
- mvOsDelay(10);
+ mvOsDelay(40);
} while (initDone == 0);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_0_RX_INIT, 0x0, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
return(MV_OK);
}
@@ -400,37 +401,97 @@
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x0, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
+ /* PON MAC init to EPON mode */
+ /* ========================= */
+
/* Put PON MAC to Reset */
status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
/* Switch to new PON MAC */
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 0, 0);
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 1, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x1, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
/* Take PON MAC out of Reset */
status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
if (status != MV_OK)
return(status);
+ mvOsDelay(40);
+
+ /* PON MAC init to GPON mode */
+ /* ========================= */
+
+ /* Put PON MAC to Reset */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* Switch to new PON MAC */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_XPON_CTRL, 0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x0, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_GPON_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
+ /* Take PON MAC out of Reset */
+ status = asicOntMiscRegWrite(mvAsicReg_PON_MAC_SW_RESET_CTRL, 0x1, 0);
+ if (status != MV_OK)
+ return(status);
+
+ mvOsDelay(40);
+
/* GPON configuration of XVR SD is done by LSP code (mvBoardEnvSpec.h, mvCtrlEnvLib.c) */
/* ================================= */
@@ -459,31 +520,31 @@
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_INTERNAL_OPEN_TX_DOOR, 0x0, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x0, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_SEL, 0x1, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_CLK_EN, 0x1, 0);
if (status != MV_OK)
return(status);
- mvOsDelay(10);
+ mvOsDelay(40);
// status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_BEN_IO_EN, 0x0, 0);
// if (status != MV_OK)
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.c
index 25f8155..86b921c 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.c
@@ -88,6 +88,10 @@
/* Global Variables
------------------------------------------------------------------------------*/
+S_onuPonWork gponTcontCleanWork[8];
+S_onuPonWork gponTcontCleanAllWork;
+S_onuPonWork gponTcontActiveWork[8];
+S_onuPonWorkQueue gponTcontFlushWq;
/* Global functions
------------------------------------------------------------------------------*/
@@ -116,6 +120,50 @@
/*******************************************************************************
**
+** onuPonWqInit
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function allocates GPON work queue and init two work
+** structures for TCONT clean and activate
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuPonWqInit(void)
+{
+ MV_U32 tcontIndex;
+
+ gponTcontFlushWq.ponWq = create_workqueue("gponTcontFlushWQ");
+ if (gponTcontFlushWq.ponWq)
+ {
+ for (tcontIndex = 0; tcontIndex < 8; tcontIndex++)
+ {
+ INIT_WORK((struct work_struct *) &gponTcontCleanWork[tcontIndex], onuGponWqTcontFunc);
+ gponTcontCleanWork[tcontIndex].action = TCONT_CLEAN_EVENT;
+ gponTcontCleanWork[tcontIndex].param = tcontIndex;
+
+ INIT_WORK((struct work_struct *) &gponTcontActiveWork[tcontIndex], onuGponWqTcontFunc);
+ gponTcontActiveWork[tcontIndex].action = TCONT_ACTIVE_EVENT;
+ gponTcontActiveWork[tcontIndex].param = tcontIndex;
+ }
+
+ INIT_WORK((struct work_struct *) &gponTcontCleanAllWork, onuGponWqTcontFunc);
+ gponTcontCleanAllWork.action = TCONT_CLEAN_ALL_EVENT;
+
+ printk("STARTING PON WORK QUEUE!!!!!\n");
+
+ return(MV_OK);
+ }
+
+ return(MV_ERROR);
+}
+
+/*******************************************************************************
+**
** onuGponRtosResourceInit
** ____________________________________________________________________________
**
@@ -235,6 +283,29 @@
return(MV_ERROR);
}
+ /* onu pon TX Power timer */
+ retcode = onuPonTimerCreate(&(onuPonResourceTbl_s.onuPonTxPwrTimerId), /* timer Id */
+ "pon_txPwr", /* timer description */
+ (PTIMER_FUNCPTR)onuGponTimerTxPwrHndl, /* timer function */
+ ONU_PON_TIMER_NOT_ACTIVE, /* timer active (run) state */
+ ONU_PON_TIMER_TX_PWR_INTERVAL, /* init value */
+ 0); /* periodic value */
+ if (retcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) pon Tx Power timer create\n", __FILE_DESC__, __LINE__);
+ return(MV_ERROR);
+ }
+
+ /* Work Queue */
+ /* ========== */
+ retcode = onuPonWqInit();
+ if (retcode != MV_OK)
+ {
+ mvPonPrint(PON_PRINT_ERROR, PON_INIT_MODULE,
+ "ERROR: (%s:%d) pon work queue create\n", __FILE_DESC__, __LINE__);
+ return(MV_ERROR);
+ }
/* Interrupt */
/* ========= */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.h
index ca4b7e3..be40786 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/gpon/gponOnuLnxKsOs.h
@@ -89,6 +89,13 @@
/* Typedefs
------------------------------------------------------------------------------*/
+/* Global variables
+------------------------------------------------------------------------------*/
+extern S_onuPonWork gponTcontCleanWork[8];
+extern S_onuPonWork gponTcontCleanAllWork;
+extern S_onuPonWork gponTcontActiveWork[8];
+extern S_onuPonWorkQueue gponTcontFlushWq;
+
/* Global functions
------------------------------------------------------------------------------*/
/* Init API */
@@ -97,9 +104,12 @@
extern MV_STATUS onuGponRtosResourceRelease(void);
/* Interrupt API */
-extern MV_STATUS onuGponIrqRegister(S_onuPonIrq *irqId);
+extern MV_STATUS onuGponIrqRegister(S_onuPonIrq *irqId);
extern MV_STATUS onuGponIrqTaskletInit(S_onuPonIrq *irqId);
+/* Work queue API */
+extern void onuGponWqTcontInit(void);
+
/* Macros
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c
index 153bf20..0a3d36e 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.c
@@ -83,7 +83,8 @@
/* Global Variables
------------------------------------------------------------------------------*/
-MV_U32 ponXvrPolarity;
+S_OnuP2PDb onuP2PDb_s;
+t_ponXvrFuncPtr ponXvrFunc;
/* Global functions
------------------------------------------------------------------------------*/
@@ -383,25 +384,48 @@
return(status);
}
-/*******************************************************************************
-**
-** mvOnuPonMacBurstEnablePolarityInit
-** ____________________________________________________________________________
-**
-** DESCRIPTION: The function init Burst Enable XVR polarity
-**
-** PARAMETERS: MV_U32 polarity
-**
-** OUTPUTS: None
-**
-** RETURNS: MV_OK or error
-**
-*******************************************************************************/
-MV_STATUS mvOnuPonMacBurstEnablePolarityInit(MV_U32 polarity)
+MV_STATUS EponXvrSDPolarityHighStatus(MV_U32 interruptStatus, MV_U32 statusMask)
{
- ponXvrPolarity = polarity;
+ return ((interruptStatus & statusMask) ? MV_FALSE : MV_TRUE);
+}
- return(MV_OK);
+MV_STATUS EponXvrSDPolarityLowStatus(MV_U32 interruptStatus, MV_U32 statusMask)
+{
+ return ((~interruptStatus & statusMask) ? MV_FALSE : MV_TRUE);
+}
+
+MV_STATUS GponXvrSDPolarityHighStatus(MV_U32 interruptStatus, MV_U32 statusMask)
+{
+ return ((interruptStatus & statusMask) ? MV_TRUE : MV_FALSE);
+}
+
+MV_STATUS GponXvrSDPolarityLowStatus(MV_U32 interruptStatus, MV_U32 statusMask)
+{
+ return ((~interruptStatus & statusMask) ? MV_TRUE : MV_FALSE);
+}
+
+t_ponXvrFuncPtr funcEponXvrSDStatus(MV_U32 polarity)
+{
+ if (polarity == 0)
+ {
+ return EponXvrSDPolarityHighStatus;
+ }
+ else
+ {
+ return EponXvrSDPolarityLowStatus;
+ }
+}
+
+t_ponXvrFuncPtr funcGponXvrSDStatus(MV_U32 polarity)
+{
+ if (polarity == 0)
+ {
+ return GponXvrSDPolarityHighStatus;
+ }
+ else
+ {
+ return GponXvrSDPolarityLowStatus;
+ }
}
/*******************************************************************************
@@ -521,7 +545,7 @@
return(MV_ERROR);
}
- polarity = ponXvrPolarity;
+ polarity = onuP2PDbXvrBurstEnablePolarityGet();
/* XVR polarity */
/* XVR polarity == 0, Active High, transmit 1 to the line */
@@ -535,10 +559,8 @@
/* XVR polarity == 0, Active High, write 1 for Force Value */
/* XVR polarity == 1, Active Low, write 0 for Force Value */
- trans_value = ((on == MV_TRUE) ? (~polarity) : (polarity));
-
/* PHY control register - force enable value - according to polarity */
- status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_FORCE_BEN_IO_VAL, trans_value, 0);
+ status = asicOntMiscRegWrite(mvAsicReg_PON_SERDES_PHY_CTRL_1_FORCE_BEN_IO_VAL, polarity, 0);
if (status != MV_OK) {
mvPonPrint(PON_PRINT_ERROR, PON_ISR_MODULE,
"ERROR: asicOntMiscRegWrite failed for PON phy ctrl force value %d\n\r",
@@ -772,6 +794,36 @@
/*******************************************************************************
**
+** onuPonTxPowerTimerStateSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function enable / disable TX power off timer
+**
+** PARAMETERS: MV_BOOL mode - MV_TRUE - start timer
+** MV_FALSE - stop timer
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuPonTxPowerTimerStateSet(MV_BOOL mode)
+{
+ MV_STATUS rcode = MV_OK;
+
+ if (mode == MV_TRUE)
+ {
+ onuPonTimerEnable(&(onuPonResourceTbl_s.onuPonTxPwrTimerId));
+ }
+ else
+ {
+ onuPonTimerDisable(&(onuPonResourceTbl_s.onuPonTxPwrTimerId));
+ }
+
+ return (rcode);
+}
+
+/*******************************************************************************
+**
** onuPonTxPowerOn
** ____________________________________________________________________________
**
@@ -848,4 +900,44 @@
return(status);
}
+/*******************************************************************************
+**
+** onuP2PDbXvrBurstEnablePolaritySet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function sets EPON XVR polarity register value in the database
+**
+** PARAMETERS: MV_U32 val
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS onuP2PDbXvrBurstEnablePolaritySet(MV_U32 val)
+{
+ onuP2PDb_s.onuP2PGenTbl_s.xvrBurstEnPolarity = val;
+
+ return(MV_OK);
+}
+
+/*******************************************************************************
+**
+** onuP2PDbXvrBurstEnablePolarityGet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function returns EPON XVR polarity register value
+**
+** PARAMETERS: None
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_U32 mode
+**
+*******************************************************************************/
+MV_U32 onuP2PDbXvrBurstEnablePolarityGet(void)
+{
+ return onuP2PDb_s.onuP2PGenTbl_s.xvrBurstEnPolarity;
+}
+
#endif /* PON_FPGA */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.h
index 1231b55..1077443 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuBoard.h
@@ -125,11 +125,27 @@
ACTIVE_LED_ON = 3
}E_OnuPonLedActivation;
+/* Struct
+------------------------------------------------------------------------------*/
+/* ONU P2P Database */
+typedef struct
+{
+ MV_U32 xvrBurstEnPolarity;
+ MV_U32 xvrPolarity;
+} S_OnuP2PGenTbl;
+
+typedef struct
+{
+ S_OnuP2PGenTbl onuP2PGenTbl_s;
+} S_OnuP2PDb;
+
/* Typedefs
------------------------------------------------------------------------------*/
+typedef MV_STATUS (*t_ponXvrFuncPtr)(MV_U32, MV_U32);
/* Global variables
------------------------------------------------------------------------------*/
+extern t_ponXvrFuncPtr ponXvrFunc;
/* Global functions
------------------------------------------------------------------------------*/
@@ -146,6 +162,17 @@
void onuPonPatternBurstTimerHndl(void);
MV_STATUS onuPonTxPowerOn(MV_BOOL txOn);
MV_STATUS onuPonTxPowerControlInit(void);
+MV_STATUS onuPonTxPowerTimerStateSet(MV_BOOL mode);
+
+MV_STATUS EponXvrSDPolarityHighStatus(MV_U32 interruptStatus, MV_U32 statusMask);
+MV_STATUS EponXvrSDPolarityLowStatus(MV_U32 interruptStatus, MV_U32 statusMask);
+MV_STATUS GponXvrSDPolarityHighStatus(MV_U32 interruptStatus, MV_U32 statusMask);
+MV_STATUS GponXvrSDPolarityLowStatus(MV_U32 interruptStatus, MV_U32 statusMask);
+t_ponXvrFuncPtr funcEponXvrSDStatus(MV_U32 polarity);
+t_ponXvrFuncPtr funcGponXvrSDStatus(MV_U32 polarity);
+
+MV_STATUS onuP2PDbXvrBurstEnablePolaritySet(MV_U32 val);
+MV_U32 onuP2PDbXvrBurstEnablePolarityGet(void);
#endif /* PON_FPGA */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuLnxKsOs.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuLnxKsOs.h
index a1e3869..e5b3293 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuLnxKsOs.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_pon/plat/ponOnuLnxKsOs.h
@@ -98,6 +98,7 @@
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
+#include <linux/workqueue.h>
#include "mvTypes.h"
#include "mvCommon.h"
@@ -177,7 +178,7 @@
#define ONU_PON_TIMER_PM_INTERVAL (1000) /* 1 sec */
#define ONU_PON_TIMER_PEE_INTERVAL (3000) /* 3 sec */
#define ONU_PON_TIMER_PON_EVT_CLEAN_INTERVAL (5000) /* 5 sec */
-#define ONU_PON_TIMER_XVR_RST_INTERVAL (450) /* 450 msec */
+#define ONU_PON_TIMER_XVR_RST_INTERVAL (10) /* 10 msec */
#define ONU_PON_TIMER_MPCP_INTERVAL (1000) /* 1 sec */
#define ONU_PON_TIMER_RPRT_INTERVAL (1) /* 1 msec */
#define ONU_PON_TIMER_HW_RPRT_T0_INTERVAL (2) /* 2 msec */
@@ -186,6 +187,7 @@
#define ONU_PON_TIMER_SILENCE_INTERVAL (60000) /* 60 sec */
#define ONU_PON_TIMER_TX_MOD_INTERVAL (1) /* 1 msec */
#define ONU_PON_TIMER_EVENT_MISS_INTERVAL (10) /* 10 msec */
+#define ONU_PON_TIMER_TX_PWR_INTERVAL (1000) /* 1 sec */
#define ONU_PON_TIMER_ACTIVE (1)
#define ONU_PON_TIMER_NOT_ACTIVE (0)
@@ -221,6 +223,20 @@
struct tasklet_struct onuPonTasklet;
}S_onuPonIrq;
+
+/* Work queue */
+typedef struct
+{
+ struct work_struct ponWork;
+ int action;
+ int param;
+}S_onuPonWork;
+
+typedef struct
+{
+ struct workqueue_struct *ponWq;
+}S_onuPonWorkQueue;
+
/* ONU GPON resource table */
typedef struct
{
@@ -236,7 +252,8 @@
S_OnuPonTimer onuPonIsrMissTimerId; /* ONU EPON ISR Miss timer */
S_OnuPonTimer onuPonHoldoverTimerId; /* ONU EPON Holdover timer */
S_OnuPonTimer onuPonSilenceTimerId[8]; /* ONU EPON Silence timer */
-
+
+ S_OnuPonTimer onuPonTxPwrTimerId; /* ONU PON TX Power timer */
S_OnuPonTimer onuPonPmTimerId; /* ONU PON PM timer */
S_OnuPonTimer onuPonPatternBurstTimerId; /* ONU PON Pattern Burst timer */
#ifndef PON_FPGA
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.c
index 5c27c0d..2f46bee 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.c
@@ -46,6 +46,66 @@
static uint8_t weight_arr[4] = {0};
extern GT_QD_DEV *qd_dev;
+/*******************************************************************************
+* mv_switch_find_vid_entry_sw
+*
+* DESCRIPTION:
+* The API find expected VTU entry in sw_vlan_tbl.
+*
+* INPUTS:
+* vtuEntry - VTU entry, supply VID
+*
+* OUTPUTS:
+* vtuEntry - VTU entry, store entry info if found
+* found - find expected entry or not
+*
+* RETURNS:
+* On success - GT_OK.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_find_vid_entry_sw(GT_VTU_ENTRY *vtuEntry, GT_BOOL *found)
+{
+ if (vtuEntry == NULL || found == NULL)
+ return GT_BAD_PARAM;
+
+ if (sw_vlan_tbl[vtuEntry->vid].members) {/* if members not 0, this vid entry exist in HW andd SW */
+ memcpy(vtuEntry, &sw_vlan_tbl[vtuEntry->vid].vtu_entry, sizeof(GT_VTU_ENTRY));
+ *found = GT_TRUE;
+ } else {
+ *found = GT_FALSE;
+ }
+
+ return GT_OK;
+}
+
+/*******************************************************************************
+* mv_switch_record_vid_entry_sw
+*
+* DESCRIPTION:
+* The API store expected VTU entry in sw_vlan_tbl.
+*
+* INPUTS:
+* vtuEntry - VTU entry
+*
+* OUTPUTS:
+* None
+*
+* RETURNS:
+* On success - GT_OK.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_record_vid_entry_sw(GT_VTU_ENTRY *vtuEntry)
+{
+ if (vtuEntry == NULL)
+ return GT_BAD_PARAM;
+ memcpy(&sw_vlan_tbl[vtuEntry->vid].vtu_entry, vtuEntry, sizeof(GT_VTU_ENTRY));
+
+ return GT_OK;
+}
/*******************************************************************************
* mv_switch_prv_port_add_vid
@@ -54,7 +114,10 @@
* The API adds a VID to the list of the allowed VIDs per lport.
*
* INPUTS:
-* vid - VLAN id.
+* lport - logic port id to set
+* vid - vlan id
+* gmac0Idx - port GMAC0 connects to, if its value is 0xFFFF, do not care GMAC0 port
+* eMode - egress mode
*
* OUTPUTS:
* None.
@@ -69,7 +132,10 @@
*******************************************************************************/
int32_t mv_switch_prv_port_add_vid
(
- uint16_t vid
+ uint32_t lport,
+ uint16_t vid,
+ uint16_t gmac0Idx,
+ uint8_t eMode
)
{
GT_STATUS rc = GT_OK;
@@ -80,17 +146,14 @@
memset(&tmpVtuEntry,0,sizeof(GT_VTU_ENTRY));
tmpVtuEntry.vid = vid;
- rc = gvtuFindVidEntry(qd_dev, &tmpVtuEntry, &found);
- if ( (rc != GT_OK) && (rc != GT_NO_SUCH) )
- {
- printk(KERN_ERR "%s:%d:==ERROR==gvtuFindVidEntry failed rc[0x%x]\r\n",
+ rc = mv_switch_find_vid_entry_sw(&tmpVtuEntry, &found);
+ if (rc != GT_OK) {
+ printk(KERN_ERR "%s:%d:==ERROR==mv_switch_find_vid_entry_sw failed rc[0x%x]\r\n",
__FUNCTION__, __LINE__, rc);
return GT_FAIL;
}
- printk(KERN_DEBUG "%s: found[%d]\n\r", __FUNCTION__,found);
-
if (found == GT_FALSE)/* VTU entry does not exist */
{
/* Add new VTU entry with VLAN ID vid with lport as members of the Vlan vid. */
@@ -115,7 +178,16 @@
for (port=0; port < qd_dev->numOfPorts; port++)
{
if (sw_vlan_tbl[vid].members & (1 << port)){
- tmpVtuEntry.vtuData.memberTagP[port] = sw_vlan_tbl[vid].egr_mode[port];
+ if (port == lport)
+ tmpVtuEntry.vtuData.memberTagP[port] = eMode;/* update egress mode only */
+ else
+ tmpVtuEntry.vtuData.memberTagP[port] = sw_vlan_tbl[vid].egr_mode[port];
+ }
+ else if (port == lport) {
+ tmpVtuEntry.vtuData.memberTagP[port] = eMode;
+ }
+ else if (gmac0Idx == port) {/* add GMAC_0 to VLAN if gmac0Idx valid */
+ tmpVtuEntry.vtuData.memberTagP[port] = MEMBER_EGRESS_UNMODIFIED;
}
else{
tmpVtuEntry.vtuData.memberTagP[port] = NOT_A_MEMBER;
@@ -132,6 +204,15 @@
return GT_FAIL;
}
+ /* Record HW VT entry info to sw_vlan_tbl */
+ rc = mv_switch_record_vid_entry_sw(&tmpVtuEntry);
+ if (rc != GT_OK) {
+ printk(KERN_ERR "%s:%d:==ERROR==mv_switch_record_vid_entry_sw failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ return GT_FAIL;
+ }
+
return rc;
}
@@ -168,21 +249,25 @@
GT_U8 port_idx;
uint32_t isVlanMember = 0;
- memset(&tmpVtuEntry,0,sizeof(GT_VTU_ENTRY));
- tmpVtuEntry.vid = vid;
-
- rc = gvtuFindVidEntry(qd_dev, &tmpVtuEntry, &found);
- if ( (rc != GT_OK) && (rc != GT_NO_SUCH) )
- {
- printk(KERN_ERR "%s:%d:==ERROR==gvtuFindVidEntry failed rc[0x%x]\r\n",
- __FUNCTION__, __LINE__, rc);
-
- rc = GT_FAIL;
- goto out_func;
- }
+ /* Find vid in sw_vlan_tbl first */
+ if (!(sw_vlan_tbl[vid].members & (1 << port)))
+ found = GT_FALSE;
if (found == GT_TRUE) /* VTU entry exist */
{
+ memset(&tmpVtuEntry,0,sizeof(GT_VTU_ENTRY));
+ tmpVtuEntry.vid = vid;
+ /* Read SW VT to get necessary entry info */
+ rc = mv_switch_find_vid_entry_sw(&tmpVtuEntry, &found);
+ if ( (rc != GT_OK) && (rc != GT_NO_SUCH) )
+ {
+ printk(KERN_ERR "%s:%d:==ERROR==mv_switch_find_vid_entry_sw failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ rc = GT_FAIL;
+ goto out_func;
+ }
+
/* 1. Mark the lport as NOT_A_MEMBER. */
tmpVtuEntry.vtuData.memberTagP[port] = NOT_A_MEMBER;
@@ -210,6 +295,15 @@
goto out_func;
}
+ /* Record HW VT entry info to sw_vlan_tbl */
+ rc = mv_switch_record_vid_entry_sw(&tmpVtuEntry);
+ if (rc != GT_OK) {
+ printk(KERN_ERR "%s:%d:==ERROR==mv_switch_record_vid_entry_sw failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ return GT_FAIL;
+ }
+
sw_vlan_tbl[vid].members &= ~(((uint32_t)0x1) << (port));/* Delete port from VID DB */
}
else/* Delete VTU */
@@ -229,7 +323,7 @@
}
else /* VTU entry does not exist in search */
{
- printk(KERN_ERR "%s:%d:==ERROR== No Such VID\r\n",__FUNCTION__,__LINE__);
+ printk(KERN_ERR "%s:%d:==ERROR== No Such VID in Port(%d) Vlan List\r\n",__FUNCTION__,__LINE__, port);
rc = GT_FAIL;
goto out_func;
@@ -1249,60 +1343,8 @@
)
{
GT_STATUS rc = GT_OK;
- uint32_t port;
- uint32_t port_bm;
- /* Verify whether the port is already a member of this VID */
- port_bm = (uint32_t)(1 << lport);
- if ( !(sw_vlan_tbl[vid].members & port_bm) )
- {
- /* All fallback ports are also added to this VLAN in order
- to support traffic on this VLAN with all fallback ports */
- for(port = 0; port < qd_dev->numOfPorts; port++)
- {
- if (port == lport)
- {
- sw_vlan_tbl[vid].members |= port_bm;
- sw_vlan_tbl[vid].egr_mode[port] = MEMBER_EGRESS_UNMODIFIED;
- }
- else
- {
- #if 0
- if (sw_ports_tbl[port].port_mode == GT_FALLBACK && \
- !(sw_vlan_tbl[vid].members & (1 << port)))
- {
- sw_vlan_tbl[vid].members |= (uint32_t)(1 << port);
- sw_vlan_tbl[vid].egr_mode[port] = MEMBER_EGRESS_UNMODIFIED;
- }
- #endif
- }
- }
-
- /*if (sw_ports_tbl[gmac0Idx].port_mode == GT_FALLBACK &&
- !(sw_vlan_tbl[vid].members & (1 << gmac0Idx)))*/
- /* Always add GMAC_0 to VLAN */
- if (!(sw_vlan_tbl[vid].members & (1 << gmac0Idx)))
- {
- sw_vlan_tbl[vid].members |= (uint32_t)(1 << gmac0Idx);
- sw_vlan_tbl[vid].egr_mode[gmac0Idx] = MEMBER_EGRESS_UNMODIFIED;
- }
-
- rc = mv_switch_prv_port_add_vid(vid);
- if (rc != GT_OK)
- {
- printk(KERN_ERR "%s:%d:==ERROR== failed rc[0x%x]\r\n",
- __FUNCTION__, __LINE__, rc);
-
- rc = GT_FAIL;
- }
- }
-
- /* Add the specified port to the SW Port table */
- if (sw_ports_tbl[lport].vlan_blong[vid] == SW_PORT_NOT_BELONG)
- {
- sw_ports_tbl[lport].cnt++;
- sw_ports_tbl[lport].vlan_blong[vid] = SW_PORT_BELONG;
- }
+ rc = mv_switch_port_add_vid_set_egrs_mode(lport, vid, gmac0Idx, MEMBER_EGRESS_UNMODIFIED);
return rc;
}
@@ -1410,14 +1452,14 @@
memset(&vtuEntry, 0, sizeof(GT_VTU_ENTRY));
vtuEntry.vid = vid;
- rc = gvtuFindVidEntry(qd_dev, &vtuEntry, &found);
+ rc = mv_switch_find_vid_entry_sw(&vtuEntry, &found);
if (rc != GT_OK && rc != GT_NO_SUCH)
{
- printk(KERN_ERR"%s:%d:==ERROR==gvtuFindVidEntry failed rc[0x%x]\r\n",
+ printk(KERN_ERR"%s:%d:==ERROR==mv_switch_find_vid_entry_sw failed rc[0x%x]\r\n",
__FUNCTION__, __LINE__, rc);
return GT_FAIL;
- }
+ }
printk(KERN_DEBUG "%s: found[%d]\n\r", __FUNCTION__, found);
@@ -1431,6 +1473,15 @@
return GT_FAIL;
}
+
+ /* Record HW VT entry info to sw_vlan_tbl */
+ rc = mv_switch_record_vid_entry_sw(&vtuEntry);
+ if (rc != GT_OK) {
+ printk(KERN_ERR "%s:%d:==ERROR==mv_switch_record_vid_entry_sw failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ return GT_FAIL;
+ }
}
else
{
@@ -1614,18 +1665,20 @@
if ( sw_vlan_tbl[vlan_idx].members &&
!(sw_vlan_tbl[vlan_idx].members & port_bm))
{
- sw_vlan_tbl[vlan_idx].members |= port_bm;
- sw_vlan_tbl[vlan_idx].egr_mode[port] = MEMBER_EGRESS_UNMODIFIED;
-
/* Update VTU table */
- rc |= mv_switch_prv_port_add_vid(vlan_idx);
+ rc |= mv_switch_prv_port_add_vid(port, vlan_idx, 0xFFFF, MEMBER_EGRESS_UNMODIFIED);
if (rc != GT_OK)
{
printk(KERN_ERR
"%s:%d:==ERROR== failed to add port [%d] to VLAN [%d]\r\n",
__FUNCTION__,__LINE__,port, vlan_idx);
+ return rc;
}
+
+ sw_vlan_tbl[vlan_idx].members |= port_bm;
+ sw_vlan_tbl[vlan_idx].egr_mode[port] = MEMBER_EGRESS_UNMODIFIED;
+
}
}
@@ -4978,6 +5031,7 @@
return rc;
}
memset(sw_vlan_tbl, 0, sizeof(sw_vlan_tbl));
+
for(port = 0; port < qd_dev->numOfPorts; port++)
{
memset(&(sw_ports_tbl[port].vlan_blong), 0, sizeof(sw_ports_tbl[port].vlan_blong));
@@ -5021,6 +5075,205 @@
}
/*******************************************************************************
+* mv_switch_set_port_speed_duplex_mode
+*
+* DESCRIPTION:
+* This routine will disable auto-negotiation and set the PHY port speed and duplex mode.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+*
+* speed - PHY_SPEED_10_MBPS -10 Mbps
+* PHY_SPEED_100_MBPS -100 Mbps
+* PHY_SPEED_1000_MBPS -100 Mbps.
+* enable - Enable/Disable full duplex mode.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_set_port_speed_duplex_mode
+(
+IN GT_LPORT port,
+IN GT_PHY_SPEED speed,
+IN GT_BOOL enable
+)
+{
+ GT_STATUS rc = GT_OK;
+
+ rc = gprtSetPortSpeedDuplexMode(qd_dev, port, speed, enable);
+ if (rc != GT_OK)
+ {
+ printk(KERN_ERR "%s:%d:==ERROR==gprtSetPortSpeedDuplexMode failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ rc = GT_FAIL;
+ }
+
+ return rc;
+}
+
+/*******************************************************************************
+* mv_switch_set_port_forced_fc_value
+*
+* DESCRIPTION:
+* This routine will set forced flow control value when forced flow control enabled.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+*
+* enable-
+*
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_set_port_forced_fc_value
+(
+IN GT_LPORT port,
+IN GT_BOOL enable
+)
+{
+ GT_STATUS rc = GT_OK;
+
+ rc = gpcsSetFCValue(qd_dev, port, enable);
+ if (rc != GT_OK)
+ {
+ printk(KERN_ERR "%s:%d:==ERROR==gpcsSetFCValue failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ rc = GT_FAIL;
+ }
+
+ return rc;
+}
+
+/*******************************************************************************
+* mv_switch_set_port_forced_flow_control
+*
+* DESCRIPTION:
+* This routine will enable/disable forced flow control state.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+*
+* enable-
+*
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_set_port_forced_flow_control
+(
+IN GT_LPORT port,
+IN GT_BOOL enable
+)
+{
+ GT_STATUS rc = GT_OK;
+
+ rc = gpcsSetForcedFC(qd_dev, port, enable);
+ if (rc != GT_OK)
+ {
+ printk(KERN_ERR "%s:%d:==ERROR==gpcsSetForcedFC failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ rc = GT_FAIL;
+ }
+
+ return rc;
+}
+
+/*******************************************************************************
+* mv_switch_port_add_vid_set_egrs_mode
+*
+* DESCRIPTION:
+* The API adds a VID to the list of the allowed VIDs per lport
+* and sets the egress mode for the port.
+*
+* INPUTS:
+* lport - logic port id to set
+* vid - vlan id
+* gmac0Idx - port GMAC0 connects to
+* eMode - egress mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case see tpm_error_code_t.
+*
+* COMMENTS:
+* MEMBER_EGRESS_UNMODIFIED - 0
+* NOT_A_MEMBER - 1
+* MEMBER_EGRESS_UNTAGGED - 2
+* MEMBER_EGRESS_TAGGED - 3
+*
+*******************************************************************************/
+int32_t mv_switch_port_add_vid_set_egrs_mode
+(
+ IN uint32_t lport,
+ IN uint16_t vid,
+ IN uint16_t gmac0Idx,
+ IN uint8_t eMode
+)
+{
+ GT_STATUS rc = GT_OK;
+ uint32_t port_bm;
+
+ /* Verify whether the port is already a member of this VID */
+ port_bm = (uint32_t)(1 << lport);
+ if (!((sw_vlan_tbl[vid].members & port_bm) && (sw_vlan_tbl[vid].egr_mode[lport] == eMode)))
+ {
+ rc = mv_switch_prv_port_add_vid(lport, vid, gmac0Idx, eMode);
+ if (rc != GT_OK)
+ {
+ printk(KERN_ERR "%s:%d:==ERROR== failed rc[0x%x]\r\n",
+ __FUNCTION__, __LINE__, rc);
+
+ return GT_FAIL;
+ }
+
+ /* add port to vid's member bit map and set port egress mode */
+ sw_vlan_tbl[vid].members |= port_bm;
+ sw_vlan_tbl[vid].egr_mode[lport] = eMode;
+
+ /* Always add GMAC_0 to VLAN */
+ if (!(sw_vlan_tbl[vid].members & (1 << gmac0Idx)))
+ {
+ sw_vlan_tbl[vid].members |= (uint32_t)(1 << gmac0Idx);
+ sw_vlan_tbl[vid].egr_mode[gmac0Idx] = MEMBER_EGRESS_UNMODIFIED;
+ }
+ }
+
+ /* Add the specified port to the SW Port table */
+ if (sw_ports_tbl[lport].vlan_blong[vid] == SW_PORT_NOT_BELONG)
+ {
+ sw_ports_tbl[lport].cnt++;
+ sw_ports_tbl[lport].vlan_blong[vid] = SW_PORT_BELONG;
+ }
+
+ return rc;
+}
+
+/*******************************************************************************
* mv_switch_drv_init
*
* DESCRIPTION:
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.h
index 18c3fb9..a2da3e0 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_switch/mv_switch_wrap.h
@@ -51,7 +51,6 @@
#define SW_QOS_NUM_OF_TAG_PRI (7)
#define SW_QOS_DSCP_MAX (64)
-
/* LPort data base*/
typedef struct _sw_port_info_type_t
{
@@ -62,8 +61,9 @@
typedef struct _sw_vlan_tbl_type
{
- uint32_t members; /* bitmap of the ports max number of ports 32 */
+ uint32_t members; /* bitmap of the ports max number of ports 32, if its value is 0, indicates that the VID do not exist in HW */
uint8_t egr_mode[SW_MAX_PORTS_NUM]; /* egress mode of each port */
+ GT_VTU_ENTRY vtu_entry; /* Add this member to record HW VT info to SW table, descrease access time for VT table */
}sw_vlan_tbl_type;
/* auto negotiation type */
@@ -78,13 +78,57 @@
}sw_autoneg_type_t;
/*******************************************************************************
+* mv_switch_find_vid_entry_sw
+*
+* DESCRIPTION:
+* The API find expected VTU entry in sw_vlan_tbl.
+*
+* INPUTS:
+* vtuEntry - VTU entry, supply VID
+*
+* OUTPUTS:
+* vtuEntry - VTU entry, store entry info if found
+* found - find expected entry or not
+*
+* RETURNS:
+* On success - GT_OK.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_find_vid_entry_sw(GT_VTU_ENTRY *vtuEntry, GT_BOOL *found);
+
+/*******************************************************************************
+* mv_switch_record_vid_entry_sw
+*
+* DESCRIPTION:
+* The API store expected VTU entry in sw_vlan_tbl.
+*
+* INPUTS:
+* vtuEntry - VTU entry
+*
+* OUTPUTS:
+* None
+*
+* RETURNS:
+* On success - GT_OK.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_record_vid_entry_sw(GT_VTU_ENTRY *vtuEntry);
+
+/*******************************************************************************
* mv_switch_prv_port_add_vid
*
* DESCRIPTION:
* The API adds a VID to the list of the allowed VIDs per lport.
*
* INPUTS:
-* vid - VLAN id.
+* lport - logic port id to set
+* vid - vlan id
+* gmac0Idx - port GMAC0 connects to, if its value is 0xFFFF, do not care GMAC0 port
+* eMode - egress mode
*
* OUTPUTS:
* None.
@@ -99,7 +143,10 @@
*******************************************************************************/
int32_t mv_switch_prv_port_add_vid
(
- uint16_t vid
+ uint32_t lport,
+ uint16_t vid,
+ uint16_t gmac0Idx,
+ uint8_t eMode
);
/*******************************************************************************
@@ -2842,6 +2889,125 @@
);
/*******************************************************************************
+* mv_switch_set_port_speed_duplex_mode
+*
+* DESCRIPTION:
+* This routine will disable auto-negotiation and set the PHY port speed and duplex mode.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+*
+* speed - PHY_SPEED_10_MBPS -10 Mbps
+* PHY_SPEED_100_MBPS -100 Mbps
+* PHY_SPEED_1000_MBPS -100 Mbps.
+* enable - Enable/Disable full duplex mode.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_set_port_speed_duplex_mode
+(
+IN GT_LPORT port,
+IN GT_PHY_SPEED speed,
+IN GT_BOOL enable
+);
+
+/*******************************************************************************
+* mv_switch_set_port_forced_fc_value
+*
+* DESCRIPTION:
+* This routine will set forced flow control value when forced flow control enabled.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+*
+* enable-
+*
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_set_port_forced_fc_value
+(
+IN GT_LPORT port,
+IN GT_BOOL enable
+);
+
+/*******************************************************************************
+* mv_switch_set_port_forced_flow_control
+*
+* DESCRIPTION:
+* This routine will enable/disable forced flow control state.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+*
+* enable-
+*
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t mv_switch_set_port_forced_flow_control
+(
+IN GT_LPORT port,
+IN GT_BOOL enable
+);
+
+/*******************************************************************************
+* mv_switch_port_add_vid_set_egrs_mode
+*
+* DESCRIPTION:
+* The API adds a VID to the list of the allowed VIDs per lport
+* and sets the egress mode for the port.
+*
+* INPUTS:
+* lport - logic port id to set
+* vid - vlan id
+* gmac0Idx - port GMAC0 connects to
+* eMode - egress mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case see tpm_error_code_t.
+*
+* COMMENTS:
+* MEMBER_EGRESS_UNMODIFIED - 0
+* NOT_A_MEMBER - 1
+* MEMBER_EGRESS_UNTAGGED - 2
+* MEMBER_EGRESS_TAGGED - 3
+*
+*******************************************************************************/
+int32_t mv_switch_port_add_vid_set_egrs_mode
+(
+ IN uint32_t lport,
+ IN uint16_t vid,
+ IN uint16_t gmac0Idx,
+ IN uint8_t eMode
+);
+
+/*******************************************************************************
* mv_switch_drv_init
*
* DESCRIPTION:
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.c
index 970597b..a3a5319 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.c
@@ -289,8 +289,8 @@
* |TPM_L2_PARSE_PPP_PROT|TPM_L2_PARSE_GEMPORT)
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for L2 API:
-* TPM_PARSE_FLAG_TAG1_MASK|TPM_PARSE_FLAG_TAG2_MASK|
-* TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_TAG2_TRUE|TPM_PARSE_FLAG_TAG2_FALSE
* l2_key - Information to create a parsing key for the rule.
* Some pointers may be NULL depending on the parse_rule_bm.
* pkt_frw - Information for packet forwarding decision.
@@ -365,8 +365,10 @@
* TPM_L2_PARSE_ETYPE|TPM_L2_PARSE_PPPOE_SES|TPM_L2_PARSE_PPP_PROT
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for L3 API:
-* TPM_PARSE_FLAG_TAG1_MASK|TPM_PARSE_FLAG_TAG2_MASK|
-* TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_TAG2_TRUE|TPM_PARSE_FLAG_TAG2_FALSE|
+* TPM_PARSE_FLAG_MTM_TRUE|TPM_PARSE_FLAG_MTM_FALSE|
+* TPM_PARSE_FLAG_TO_CPU_TRUE|TPM_PARSE_FLAG_TO_CPU_FALSE
* l3_key - Structure for PPPoE proto or ether type. In order to define a rule for
* any ether type, the ether type value should be set to 0xFFFF
* action_drop - If this stage is dropping the packet.
@@ -513,7 +515,10 @@
* |TPM_IPv4_PARSE_PROTO|TPM_PARSE_L4_SRC|TPM_PARSE_L4_DST
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for IPv4 API:
-* TPM_PARSE_FLAG_TAG1_MASK|TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_MTM_TRUE|TPM_PARSE_FLAG_MTM_FALSE|
+* TPM_PARSE_FLAG_TO_CPU_TRUE|TPM_PARSE_FLAG_TO_CPU_FALSE|
+* TPM_PARSE_FLAG_PPPOE_TRUE|TPM_PARSE_FLAG_PPPOE_FALSE
* ipv4_key - Information to create an IPv4 parsing key for the rule.
* Some pointers may be NULL depending on the parse_rule_bm.
* pkt_frwd - Information for packet forwarding decision.
@@ -612,7 +617,8 @@
* rule_num - Entry index to be added in the current ACL
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for IPv6 NH API:
-* TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_MTM_TRUE|TPM_PARSE_FLAG_MTM_FALSE|
+* TPM_PARSE_FLAG_TO_CPU_TRUE|TPM_PARSE_FLAG_TO_CPU_FALSE|
* nh - Information to create a NH parsing key for the rule.
* pkt_frwd - Information for packet forwarding decision.
* rule_action - Action associated to the rule = drop/set target/set packet modification/to CPU
@@ -702,7 +708,10 @@
* possible values for IPv6 GEN API: 0
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for IPv6 GEN API:
-* TPM_PARSE_FLAG_TAG1_MASK|TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_MTM_TRUE|TPM_PARSE_FLAG_MTM_FALSE|
+* TPM_PARSE_FLAG_TO_CPU_TRUE|TPM_PARSE_FLAG_TO_CPU_FALSE|
+* TPM_PARSE_FLAG_PPPOE_TRUE|TPM_PARSE_FLAG_PPPOE_FALSE
* ipv6_gen_key - Information to create an IPv6 gen parsing key for the rule.
* Some pointers may be NULL depending on the parse_rule_bm.
* pkt_frwd - Information for packet forwarding decision.
@@ -810,7 +819,10 @@
* possible values for IPv6 DIP API: TPM_IPv6_PARSE_DIP
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for IPv6 DIP API:
-* TPM_PARSE_FLAG_TAG1_MASK|TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_MTM_TRUE|TPM_PARSE_FLAG_MTM_FALSE|
+* TPM_PARSE_FLAG_TO_CPU_TRUE|TPM_PARSE_FLAG_TO_CPU_FALSE|
+* TPM_PARSE_FLAG_PPPOE_TRUE|TPM_PARSE_FLAG_PPPOE_FALSE
* ipv6_dip_key - Information to create an IPv6 DIP parsing key for the rule.
* Some pointers may be NULL depending on the parse_rule_bm.
* pkt_frwd - Information for packet forwarding decision.
@@ -920,7 +932,9 @@
* possible values for L4 API: TPM_PARSE_L4_SRC|TPM_PARSE_L4_DST
* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
* possible values for L4 API:
-* TPM_PARSE_FLAG_MTM_MASK|TPM_PARSE_FLAG_TO_CPU_MASK
+* TPM_PARSE_FLAG_MTM_TRUE|TPM_PARSE_FLAG_MTM_FALSE|
+* TPM_PARSE_FLAG_TO_CPU_TRUE|TPM_PARSE_FLAG_TO_CPU_FALSE|
+* TPM_PARSE_FLAG_L4_TCP|TPM_PARSE_FLAG_L4_UDP
* l4_key - Information to create an L4 parsing key for the rule.
* Some pointers may be NULL depending on the parse_rule_bm.
* pkt_frwd - Information for packet forwarding decision.
@@ -1149,6 +1163,83 @@
EXPORT_SYMBOL(tpm_del_ipv6_l4_ports_5t_rule);
+/*******************************************************************************
+* tpm_set_active_wan()
+*
+* DESCRIPTION: Set active WAN port
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* active_wan - active wan, GMAC0, GMAC1, PON
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_set_active_wan(uint32_t owner_id,
+ tpm_gmacs_enum_t active_wan)
+{
+ tpm_error_code_t tpm_ret;
+
+ tpm_ret = tpm_proc_set_active_wan(active_wan);
+ if(TPM_OK != tpm_ret) {
+ TPM_OS_ERROR(TPM_DB_MOD, "set active wan has failed with error code (%d)\n", tpm_ret);
+ return tpm_ret;
+ }
+
+ return (TPM_OK);
+}
+EXPORT_SYMBOL(tpm_set_active_wan);
+/*******************************************************************************
+* tpm_hot_swap_profile()
+*
+* DESCRIPTION: Swap profile and update all the ACL rules according to
+* the new profile
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* profile_id - the new profile that system is swapping to
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_hot_swap_profile(uint32_t owner_id,
+ tpm_eth_complex_profile_t profile_id)
+{
+#ifdef CONFIG_MV_ETH_WAN_SWAP
+
+ tpm_error_code_t ret_code, busy_ret_code;
+
+ /* Check API_type Busy */
+ ret_code = tpm_proc_check_all_api_busy();
+ if (ret_code != TPM_OK)
+ return(ret_code);
+
+ ret_code = tpm_proc_hot_swap_profile(owner_id, profile_id);
+
+ busy_ret_code = tpm_proc_all_api_busy_done();
+
+ RET_BUSY_ERROR(ret_code, busy_ret_code);
+#else
+ TPM_OS_ERROR(TPM_DB_MOD, "hot swap profile feature is not supported on this product!\n");
+ return TPM_OK;
+
+#endif /* CONFIG_MV_ETH_WAN_SWAP */
+
+}
+EXPORT_SYMBOL(tpm_hot_swap_profile);
+
/******************************************************************************/
/********************************** MC handling APIs **************************/
/******************************************************************************/
@@ -1198,7 +1289,8 @@
return(ret_code);
ret_code = tpm_proc_add_ipv4_mc_stream(owner_id, stream_num, igmp_mode, mc_stream_pppoe,
- vid, ipv4_src_add, ipv4_dst_add, ignore_ipv4_src, dest_port_bm);
+ vid, ipv4_src_add, ipv4_dst_add, ignore_ipv4_src,
+ TPM_INVALID_QUEUE, dest_port_bm);
busy_ret_code = tpm_proc_api_busy_done(TPM_API_IPV4_MC, stream_num);
@@ -1207,6 +1299,62 @@
EXPORT_SYMBOL(tpm_add_ipv4_mc_stream);
/*******************************************************************************
+* tpm_add_ipv4_mc_stream_set_queue()
+*
+* DESCRIPTION: Creates a new IPv4 MC stream with dest Queue.
+* It is APIs caller responsibility to maintain the correct number of
+* each stream number.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* stream_num - MC stream number.
+* vid - VLAN ID (0-4095). If set to 4096 - stream is untagged.
+* If set to 0xFFFF - do not care.
+* ipv4_src_add - IPv4 source IP address in network order.
+* ipv4_src_add - IPv4 destination IP address in network order.
+* ignore_ipv4_src - when set to 1 - the IP source is not part of the key.
+* dest_queue - destination queue number.
+* dest_port_bm - bitmap which includes all destination UNI ports.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_add_ipv4_mc_stream_set_queue(uint32_t owner_id,
+ uint32_t stream_num,
+ tpm_mc_igmp_mode_t igmp_mode,
+ uint8_t mc_stream_pppoe,
+ uint16_t vid,
+ uint8_t ipv4_src_add[4],
+ uint8_t ipv4_dst_add[4],
+ uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
+ tpm_trg_port_type_t dest_port_bm)
+{
+ tpm_error_code_t ret_code, busy_ret_code;
+
+ /* Check API_type Busy */
+ ret_code = tpm_proc_check_api_busy(TPM_API_IPV4_MC, stream_num);
+ if (ret_code != TPM_OK)
+ return(ret_code);
+
+ ret_code = tpm_proc_add_ipv4_mc_stream(owner_id, stream_num, igmp_mode, mc_stream_pppoe,
+ vid, ipv4_src_add, ipv4_dst_add, ignore_ipv4_src,
+ dest_queue, dest_port_bm);
+
+ busy_ret_code = tpm_proc_api_busy_done(TPM_API_IPV4_MC, stream_num);
+
+ RET_BUSY_ERROR(ret_code, busy_ret_code);
+}
+EXPORT_SYMBOL(tpm_add_ipv4_mc_stream_set_queue);
+
+/*******************************************************************************
* tpm_updt_ipv4_mc_stream()
*
* DESCRIPTION: Updates an existing IPv4 MC stream.
@@ -1319,7 +1467,8 @@
return(ret_code);
ret_code = tpm_proc_add_ipv6_mc_stream(owner_id, stream_num, igmp_mode, mc_stream_pppoe,
- vid, ipv6_src_add, ipv6_dst_add, ignore_ipv6_src, dest_port_bm);
+ vid, ipv6_src_add, ipv6_dst_add, ignore_ipv6_src,
+ TPM_INVALID_QUEUE, dest_port_bm);
busy_ret_code = tpm_proc_api_busy_done(TPM_API_IPV6_MC, stream_num);
@@ -1330,6 +1479,64 @@
EXPORT_SYMBOL(tpm_add_ipv6_mc_stream);
/*******************************************************************************
+* tpm_add_ipv6_mc_stream_set_queue()
+*
+* DESCRIPTION: Creates a new ipv6 MC stream with specified destination queue number.
+* It is APIs caller responsibility to maintain the correct number of
+* each stream number.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* stream_num - MC stream number.
+* vid - VLAN ID (0-4095). If set to 4096 - stream is untagged.
+* If set to 0xFFFF - do not care.
+* ipv6_src_add - ipv6 source IP address in network order.
+* ipv6_dst_add - ipv6 destination IP address in network order.
+* ignore_ipv6_src - when set to 1 - the IP source is not part of the key.
+* dest_queue - destination queue number.
+* dest_port_bm - bitmap which includes all destination UNI ports.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_add_ipv6_mc_stream_set_queue(uint32_t owner_id,
+ uint32_t stream_num,
+ tpm_mc_igmp_mode_t igmp_mode,
+ uint8_t mc_stream_pppoe,
+ uint16_t vid,
+ uint8_t ipv6_src_add[16],
+ uint8_t ipv6_dst_add[16],
+ uint8_t ignore_ipv6_src,
+ uint16_t dest_queue,
+ tpm_trg_port_type_t dest_port_bm)
+{
+ tpm_error_code_t ret_code, busy_ret_code;
+
+ /* Check API_type Busy */
+ ret_code = tpm_proc_check_api_busy(TPM_API_IPV6_MC, stream_num);
+ if (ret_code != TPM_OK)
+ return(ret_code);
+
+ ret_code = tpm_proc_add_ipv6_mc_stream(owner_id, stream_num, igmp_mode, mc_stream_pppoe,
+ vid, ipv6_src_add, ipv6_dst_add, ignore_ipv6_src,
+ dest_queue, dest_port_bm);
+
+
+ busy_ret_code = tpm_proc_api_busy_done(TPM_API_IPV6_MC, stream_num);
+
+ RET_BUSY_ERROR(ret_code, busy_ret_code);
+
+}
+EXPORT_SYMBOL(tpm_add_ipv6_mc_stream_set_queue);
+
+/*******************************************************************************
* tpm_updt_ipv6_mc_stream()
*
* DESCRIPTION: Updates an existing ipv6 MC stream.
@@ -1515,16 +1722,43 @@
* COMMENTS:
*
*******************************************************************************/
-tpm_error_code_t tpm_loop_detect_add_channel(uint32_t owner_id)
+tpm_error_code_t tpm_loop_detect_add_channel(uint32_t owner_id, tpm_ether_type_key_t ety)
{
tpm_error_code_t ret_code;
- ret_code = tpm_proc_loop_detect_add_channel(owner_id);
+ ret_code = tpm_proc_loop_detect_add_channel(owner_id, ety);
return ret_code;
}
EXPORT_SYMBOL(tpm_loop_detect_add_channel);
/*******************************************************************************
+* tpm_loop_detect_del_channel()
+*
+* DESCRIPTION: remove a communication channel for loop detection management protocol.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_loop_detect_del_channel(uint32_t owner_id)
+{
+ tpm_error_code_t ret_code;
+
+ ret_code = tpm_proc_loop_detect_del_channel(owner_id);
+ return ret_code;
+}
+EXPORT_SYMBOL(tpm_loop_detect_del_channel);
+
+/*******************************************************************************
* tpm_oam_loopback_add_channel()
*
* DESCRIPTION: Establishes a communication channel for the OAM remote loopback.
@@ -2939,7 +3173,7 @@
* according to the case - see tpm_error_code_t.
*
* COMMENTS:
-*
+*
*
*******************************************************************************/
tpm_error_code_t tpm_flush_atu(uint32_t owner_id, tpm_flush_atu_type_t flush_type, uint16_t db_num)
@@ -3170,3 +3404,207 @@
}
EXPORT_SYMBOL(tpm_mac_learn_entry_num_get);
+/*******************************************************************************
+* tpm_set_gmac_loopback()
+*
+* DESCRIPTION: The API enable/disable loopback mode of gmac.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* gmac -
+* enable - 1 for enable, 0 for disable
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_set_gmac_loopback (uint32_t owner_id,
+ tpm_gmacs_enum_t gmac,
+ uint8_t enable)
+{
+ tpm_error_code_t ret_code = TPM_RC_OK;
+
+ ret_code = tpm_init_gmac_loopback(gmac, enable);
+
+ return (ret_code);
+}
+EXPORT_SYMBOL(tpm_set_gmac_loopback);
+
+/*******************************************************************************
+* tpm_add_ds_load_balance_rule()
+*
+* DESCRIPTION: The API adds DS load balance PnC rules to set target port to GMAC0 or GMAC1
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* rule_num - Entry index to be added in the current ACL
+* parse_rule_bm - Bitmap containing the significant flags for parsing fields of the packet.
+* possible values for L2 API:
+* TPM_L2_PARSE_MAC_DA|TPM_L2_PARSE_MAC_SA|TPM_L2_PARSE_ONE_VLAN_TAG
+* |TPM_L2_PARSE_TWO_VLAN_TAG|TPM_L2_PARSE_ETYPE|TPM_L2_PARSE_PPPOE_SES
+* |TPM_L2_PARSE_PPP_PROT|TPM_L2_PARSE_GEMPORT)
+* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
+* possible values for L2 API:
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_TAG2_TRUE|TPM_PARSE_FLAG_TAG2_FALSE
+* l2_key - Information to create a parsing key for the rule.
+* Some pointers may be NULL depending on the parse_rule_bm.
+* tgrt_port - target Port: GMAC0, GMAC1 or CPU
+*
+* OUTPUTS:
+* rule_idx - Unique rule identification number which is used when deleting the rule.
+* (this is not the rule_num)
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_add_ds_load_balance_rule(uint32_t owner_id,
+ uint32_t rule_num,
+ uint32_t *rule_idx,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_ds_load_balance_tgrt_t tgrt_port)
+{
+ tpm_error_code_t ret_code, busy_ret_code;
+
+ /* Check API_section Busy */
+ ret_code = tpm_proc_check_api_busy(TPM_API_DS_LOAD_BALANCE, rule_num);
+ if (ret_code != TPM_OK)
+ return(ret_code);
+
+ ret_code = tpm_proc_add_ds_load_balance_acl_rule(owner_id, rule_num, rule_idx,
+ parse_rule_bm, parse_flags_bm, l2_key, tgrt_port);
+
+ busy_ret_code = tpm_proc_api_busy_done(TPM_API_DS_LOAD_BALANCE, rule_num);
+ RET_BUSY_ERROR(ret_code, busy_ret_code);
+}
+EXPORT_SYMBOL(tpm_add_ds_load_balance_rule);
+
+/*******************************************************************************
+* tpm_del_ds_load_balance_rule()
+*
+* DESCRIPTION: The API delete CPU egress loopback modification and PnC rules for
+* specific Tcont/queue/gem_port
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* rule_idx - Unique rule idenitifcation number specifying the rule to be deleted.
+*
+* OUTPUTS:
+* NONE
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_del_ds_load_balance_rule(uint32_t owner_id, uint32_t rule_idx)
+{
+ tpm_error_code_t ret_code;
+ ret_code = tpm_proc_del_ds_load_balance_acl_rule(owner_id, rule_idx, TPM_EXT_CALL);
+ return (ret_code);
+}
+EXPORT_SYMBOL(tpm_del_ds_load_balance_rule);
+
+/*******************************************************************************
+* tpm_xlate_uni_2_switch_port()
+*
+* DESCRIPTION: The API translates TPM logic UNI port into Switch port.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* uni_port - TPM logic port that need to be translated.
+*
+* OUTPUTS:
+* switch_port - switch port.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_xlate_uni_2_switch_port (uint32_t owner_id,
+ tpm_src_port_type_t uni_port,
+ uint32_t *switch_port)
+{
+ tpm_error_code_t ret_code = TPM_RC_OK;
+
+ *switch_port = tpm_db_eth_port_switch_port_get(uni_port);
+ if (TPM_DB_ERR_PORT_NUM == *switch_port)
+ ret_code = ERR_SRC_PORT_INVALID;
+
+ return (ret_code);
+}
+EXPORT_SYMBOL(tpm_xlate_uni_2_switch_port);
+/*******************************************************************************
+* tpm_active_tcont()
+*
+* DESCRIPTION: Function used to enable hwf to certain tcont.
+*
+* INPUTS:
+* tcont_num
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_active_tcont(uint32_t tcont_num)
+{
+ tpm_error_code_t ret_code;
+
+ /* active tcont hwf */
+ ret_code = tpm_proc_hwf_admin_set(TPM_ENUM_PMAC, tcont_num, true);
+
+ return ret_code;
+}
+EXPORT_SYMBOL(tpm_active_tcont);
+/*******************************************************************************
+* tpm_deactive_tcont()
+*
+* DESCRIPTION: Function used to disable hwf to certain tcont.
+*
+* INPUTS:
+* tcont_num
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_deactive_tcont(uint32_t tcont_num)
+{
+ tpm_error_code_t ret_code;
+ /* deactive tcont hwf */
+ ret_code = tpm_proc_hwf_admin_set(TPM_ENUM_PMAC, tcont_num, false);
+
+ return ret_code;
+}
+EXPORT_SYMBOL(tpm_deactive_tcont);
+
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.h
index ffa8aa3..11fdd2d 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_api.h
@@ -777,6 +777,45 @@
tpm_trg_port_type_t dest_port_bm);
/*******************************************************************************
+* tpm_add_ipv4_mc_stream_set_queue()
+*
+* DESCRIPTION: Creates a new IPv4 MC stream with dest Queue.
+* It is APIs caller responsibility to maintain the correct number of
+* each stream number.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* stream_num - MC stream number.
+* vid - VLAN ID (0-4095). If set to 4096 - stream is untagged.
+* If set to 0xFFFF - do not care.
+* ipv4_src_add - IPv4 source IP address in network order.
+* ipv4_src_add - IPv4 destination IP address in network order.
+* ignore_ipv4_src - when set to 1 - the IP source is not part of the key.
+* dest_queue - destination queue number.
+* dest_port_bm - bitmap which includes all destination UNI ports.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_add_ipv4_mc_stream_set_queue(uint32_t owner_id,
+ uint32_t stream_num,
+ tpm_mc_igmp_mode_t igmp_mode,
+ uint8_t mc_stream_pppoe,
+ uint16_t vid,
+ uint8_t ipv4_src_add[4],
+ uint8_t ipv4_dst_add[4],
+ uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
+ tpm_trg_port_type_t dest_port_bm);
+
+/*******************************************************************************
* tpm_updt_ipv4_mc_stream()
*
* DESCRIPTION: Updates an existing IPv4 MC stream.
@@ -860,6 +899,45 @@
tpm_trg_port_type_t dest_port_bm);
/*******************************************************************************
+* tpm_add_ipv6_mc_stream_set_queue()
+*
+* DESCRIPTION: Creates a new ipv6 MC stream with dest Queue.
+* It is APIs caller responsibility to maintain the correct number of
+* each stream number.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* stream_num - MC stream number.
+* vid - VLAN ID (0-4095). If set to 4096 - stream is untagged.
+* If set to 0xFFFF - do not care.
+* ipv6_src_add - ipv6 source IP address in network order.
+* ipv6_dst_add - ipv6 destination IP address in network order.
+* ignore_ipv6_src - when set to 1 - the IP source is not part of the key.
+* dest_queue - destination queue number.
+* dest_port_bm - bitmap which includes all destination UNI ports.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_add_ipv6_mc_stream_set_queue(uint32_t owner_id,
+ uint32_t stream_num,
+ tpm_mc_igmp_mode_t igmp_mode,
+ uint8_t mc_stream_pppoe,
+ uint16_t vid,
+ uint8_t ipv6_src_add[16],
+ uint8_t ipv6_dst_add[16],
+ uint8_t ignore_ipv6_src,
+ uint16_t dest_queue,
+ tpm_trg_port_type_t dest_port_bm);
+
+/*******************************************************************************
* tpm_updt_ipv6_mc_stream()
*
* DESCRIPTION: Updates an existing ipv6 MC stream.
@@ -1155,7 +1233,27 @@
* COMMENTS:
*
*******************************************************************************/
-tpm_error_code_t tpm_loop_detect_add_channel(uint32_t owner_id);
+tpm_error_code_t tpm_loop_detect_add_channel(uint32_t owner_id, tpm_ether_type_key_t ety);
+
+/*******************************************************************************
+* tpm_loop_detect_del_channel()
+*
+* DESCRIPTION: remove a communication channel for loop detection management protocol.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_loop_detect_del_channel(uint32_t owner_id);
/******************************************************************************/
/********************************** Configuration retrieval APIs **************/
@@ -1928,6 +2026,62 @@
uint32_t dport,
tpm_sw_mirror_type_t mode,
bool enable);
+/*******************************************************************************
+* tpm_sw_set_trunk_ports
+*
+* DESCRIPTION:
+* This function creates trunk ports and trunk id on switch
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* trunk_id - valid from 0x0 to 0xf
+* ports_mask - mask for real switch port, not logical port like TPM_SRC_PORT_UNI_0.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_set_trunk_ports
+(
+ uint32_t owner_id,
+ uint32_t trunk_id,
+ uint32_t ports_mask
+);
+/*******************************************************************************
+* tpm_sw_set_trunk_mask
+*
+* DESCRIPTION:
+* This function sets trunk mask on switch
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* mask_num - trunk mask number, valid from 0 to 7.
+* trunk_mask - mask for real switch port, not logical port like TPM_SRC_PORT_UNI_0.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_set_trunk_mask
+(
+ uint32_t owner_id,
+ uint32_t mask_num,
+ uint32_t trunk_mask
+);
/*******************************************************************************
* tpm_sw_get_port_mirror
@@ -2061,7 +2215,7 @@
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
-* allow_tagged - set to 1 = discard tagged packets per lport
+* drop_tagged - set to 1 = drop tagged packets per lport
* set to 0 = allow tagged packets per lport.
*
* OUTPUTS:
@@ -2077,7 +2231,7 @@
*******************************************************************************/
tpm_error_code_t tpm_sw_set_port_tagged(uint32_t owner_id,
tpm_src_port_type_t src_port,
- uint8_t allow_tagged);
+ uint8_t drop_tagged);
/*******************************************************************************
* tpm_sw_get_port_tagged
@@ -2113,7 +2267,7 @@
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
-* allow_untagged - set to 1 = discard untagged packets per lport
+* drop_untagged - set to 1 = drop untagged packets per lport
* set to 0 = alow untagged packets per lport.
*
* OUTPUTS:
@@ -2129,7 +2283,7 @@
*******************************************************************************/
tpm_error_code_t tpm_sw_set_port_untagged(uint32_t owner_id,
tpm_src_port_type_t src_port,
- uint8_t allow_untagged);
+ uint8_t drop_untagged);
/*******************************************************************************
* tpm_sw_get_port_untagged
@@ -3528,7 +3682,7 @@
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
* port - The logical port number
-* tpm_swport_pm_3 - Holds PM data
+* tpm_swport_pm_3_all_t - Holds PM data
*
* OUTPUTS:
* PM data is supplied structure.
@@ -3540,7 +3694,7 @@
*******************************************************************************/
tpm_error_code_t tpm_sw_pm_3_read(uint32_t owner_id,
tpm_src_port_type_t port,
- tpm_swport_pm_3_t *tpm_swport_pm_3);
+ tpm_swport_pm_3_all_t *tpm_swport_pm_3);
/*******************************************************************************
* tpm_sw_clear_port_counter
@@ -3574,7 +3728,7 @@
* owner_id - APP owner id should be used for all API calls.
* src_port - The packet originating source port, could be any UNI port:
* precedence - precedence of this CnM rule, from 0 to 7
-* l2_parse_rule_bm
+* l2_parse_rule_bm
* ipv4_parse_rule_bm
* - Bitmap containing the significant flags for parsing fields of the packet.
* l2_key
@@ -3805,6 +3959,228 @@
*******************************************************************************/
tpm_error_code_t tpm_mac_learn_entry_num_get(uint32_t *entry_num);
+/*******************************************************************************
+* tpm_add_ds_load_balance_rule()
+*
+* DESCRIPTION: The API adds DS load balance PnC rules to set target port to GMAC0 or GMAC1
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* rule_num - Entry index to be added in the current ACL
+* parse_rule_bm - Bitmap containing the significant flags for parsing fields of the packet.
+* possible values for L2 API:
+* TPM_L2_PARSE_MAC_DA|TPM_L2_PARSE_MAC_SA|TPM_L2_PARSE_ONE_VLAN_TAG
+* |TPM_L2_PARSE_TWO_VLAN_TAG|TPM_L2_PARSE_ETYPE|TPM_L2_PARSE_PPPOE_SES
+* |TPM_L2_PARSE_PPP_PROT|TPM_L2_PARSE_GEMPORT)
+* parse_flags_bm - Bitmap containing the significant flags result of the primary ACL filtering.
+* possible values for L2 API:
+* TPM_PARSE_FLAG_TAG1_TRUE|TPM_PARSE_FLAG_TAG1_FLASE|
+* TPM_PARSE_FLAG_TAG2_TRUE|TPM_PARSE_FLAG_TAG2_FALSE
+* l2_key - Information to create a parsing key for the rule.
+* Some pointers may be NULL depending on the parse_rule_bm.
+* tgrt_port - target Port: GMAC0, GMAC1 or CPU
+*
+* OUTPUTS:
+* rule_idx - Unique rule identification number which is used when deleting the rule.
+* (this is not the rule_num)
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_add_ds_load_balance_rule(uint32_t owner_id,
+ uint32_t rule_num,
+ uint32_t *rule_idx,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_ds_load_balance_tgrt_t tgrt_port);
+
+/*******************************************************************************
+* tpm_del_ds_load_balance_rule()
+*
+* DESCRIPTION: The API delete CPU egress loopback modification and PnC rules for
+* specific Tcont/queue/gem_port
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* rule_idx - Unique rule idenitifcation number specifying the rule to be deleted.
+*
+* OUTPUTS:
+* NONE
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_del_ds_load_balance_rule(uint32_t owner_id, uint32_t rule_idx);
+
+/*******************************************************************************
+* tpm_set_active_wan()
+*
+* DESCRIPTION: Set active WAN port
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* active_wan - active wan, GMAC0, GMAC1, PON
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_set_active_wan(uint32_t owner_id,
+ tpm_gmacs_enum_t active_wan);
+/*******************************************************************************
+* tpm_hot_swap_profile()
+*
+* DESCRIPTION: Swap profile and update all the ACL rules according to
+* the new profile
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* profile_id - the new profile that system is swapping to
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_hot_swap_profile(uint32_t owner_id,
+ tpm_eth_complex_profile_t profile_id);
+
+/*******************************************************************************
+* tpm_xlate_uni_2_switch_port()
+*
+* DESCRIPTION: The API translates TPM logic UNI port into Switch port.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* uni_port - TPM logic port that need to be translated.
+*
+* OUTPUTS:
+* switch_port - switch port.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_xlate_uni_2_switch_port (uint32_t owner_id,
+ tpm_src_port_type_t uni_port,
+ uint32_t *switch_port);
+
+/*******************************************************************************
+* tpm_set_gmac_loopback()
+*
+* DESCRIPTION: The API enable/disable loopback mode of gmac.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* gmac -
+* enable - 1 for enable, 0 for disable
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None
+*
+*******************************************************************************/
+tpm_error_code_t tpm_set_gmac_loopback (uint32_t owner_id,
+ tpm_gmacs_enum_t gmac,
+ uint8_t enable);
+
+/*******************************************************************************
+* tpm_sw_port_add_vid_set_egrs_mode
+*
+* DESCRIPTION:
+* The API adds a VID to the list of the allowed VIDs per UNI port,
+* and sets the egress mode for the port.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
+* vid - vlan id
+* eMode - egress mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case see tpm_error_code_t.
+*
+* COMMENTS:
+* MEMBER_EGRESS_UNMODIFIED - 0
+* NOT_A_MEMBER - 1
+* MEMBER_EGRESS_UNTAGGED - 2
+* MEMBER_EGRESS_TAGGED - 3
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_port_add_vid_set_egrs_mode (uint32_t owner_id,
+ tpm_src_port_type_t port,
+ uint16_t vid,
+ uint8_t eMode);
+/*******************************************************************************
+* tpm_active_tcont()
+*
+* DESCRIPTION: Function used to enable hwf to certain tcont.
+*
+* INPUTS:
+* tcont_num
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_active_tcont(uint32_t tcont_num);
+/*******************************************************************************
+* tpm_deactive_tcont()
+*
+* DESCRIPTION: Function used to disable hwf to certain tcont.
+*
+* INPUTS:
+* tcont_num
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_deactive_tcont(uint32_t tcont_num);
+
/* OLD API functions */
#define tpm_add_l2_prim_acl_rule tpm_add_l2_rule
#define tpm_add_l3_type_acl_rule tpm_add_l3_type_rule
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_counter.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_counter.c
index 8aed74f..05e468a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_counter.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_counter.c
@@ -507,28 +507,9 @@
tpm_pnc_ranges_t l_range_id;
int32_t ret_code = TPM_RC_OK;
- /* Check whether the API group is supported, currently only support three types */
- if ((api_type != TPM_API_L2_PRIM) && (api_type != TPM_API_L3_TYPE)
- && (api_type != TPM_API_IPV4)) {
- TPM_OS_ERROR(TPM_PNCL_MOD, "api_type[%d] is not supported \n", api_type);
- return ERR_GENERAL;
- }
-
/* Convert to API section ID */
- switch (api_type) {
- case TPM_API_L2_PRIM:
- l_api_section = TPM_L2_PRIM_ACL;
- break;
- case TPM_API_L3_TYPE:
- l_api_section = TPM_L3_TYPE_ACL;
- break;
- case TPM_API_IPV4:
- l_api_section = TPM_IPV4_ACL;
- break;
- default:
- l_api_section = TPM_IPV4_ACL;
- break;
- }
+ ret_code = tpm_db_api_section_get_from_api_type(api_type, &l_api_section);
+ IF_ERROR(ret_code);
/* Get PnC range ID */
ret_code = tpm_db_api_section_main_pnc_get(l_api_section, &l_range_id);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_cpu_port_fc.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_cpu_port_fc.c
index 1075e6b..568c868 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_cpu_port_fc.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_cpu_port_fc.c
@@ -84,9 +84,14 @@
#include "tpm_common.h"
#include "tpm_header.h"
#include "tpm_cpu_port_fc.h"
+#include "dbg-trace.h"
static tpm_fc_info_t fc_info;
+extern int mv_enable_fc_events(void*, unsigned long);
+extern void mv_disable_fc_events(void);
+void tpm_fc_hr_timer_handler(void);
+
/*******************************************************************************
**
** tpm_fc_rate_limit
@@ -194,7 +199,7 @@
void tpm_fc_set_config(tpm_fc_cfg_t *cfg)
{
tpm_init_fc_params_t db_fc_conf;
-
+
fc_info.cfg.thresh_high = cfg->thresh_high;
fc_info.cfg.thresh_low = cfg->thresh_low;
fc_info.cfg.port = cfg->port;
@@ -209,12 +214,12 @@
/* update DB with new settings */
tpm_db_fc_conf_get(&db_fc_conf);
-
+
db_fc_conf.port = cfg->tx_port;
db_fc_conf.tgt_port = cfg->tgt_port;
db_fc_conf.thresh_high = cfg->thresh_high;
db_fc_conf.thresh_low = cfg->thresh_low;
- db_fc_conf.tx_port = cfg->tx_port;
+ db_fc_conf.tx_port = cfg->tx_port;
db_fc_conf.tx_queue = cfg->tx_queue;
tpm_db_fc_conf_set(&db_fc_conf);
@@ -238,7 +243,7 @@
{
MV_U32 ns_period = us_period * 1000;
tpm_init_fc_params_t db_fc_conf;
-
+
if (ns_period < us_period)
return (MV_ERROR);
@@ -248,6 +253,7 @@
tpm_db_fc_conf_set(&db_fc_conf);
fc_info.cfg.hrt_hit_time = ktime_set(0, ns_period);
+ mv_enable_fc_events(&tpm_fc_hr_timer_handler, ns_period);
return (MV_OK);
}
@@ -289,9 +295,16 @@
** RETURNS: hr_timer_RESTART
**
*******************************************************************************/
+#if 0
static enum hrtimer_restart tpm_fc_hr_timer_handler(struct hrtimer *timer)
{
ktime_t current_time = timer->base->get_time();
+#else
+void tpm_fc_hr_timer_handler(void)
+{
+ ktime_t current_time = ktime_get_real();
+#endif
+
s64 current_time_ns = ktime_to_ns(current_time);
s64 last_hit_ns = ktime_to_ns(fc_info.hrt_last_hit);
s64 time_slip_ns;
@@ -299,13 +312,16 @@
#ifdef TPM_FC_DEBUG
fc_info.stat.hrt_hits_num++;
+ if (fc_info.stat.hrt_hits_num < 100)
+ TRC_REC("Hit %ld\n", fc_info.stat.hrt_hits_num);
+
if ((fc_info.cfg.oneshot_count != 0) && (fc_info.oneshot_stat.hrt_hits_num < fc_info.cfg.oneshot_count))
fc_info.oneshot_stat.hrt_hits_num++;
#endif
-
+#if 0
/* Update timer for the next hit at the beginning for better precision */
hrtimer_forward(timer, current_time, fc_info.cfg.hrt_hit_time);
-
+#endif
/* First compute the real timer period */
time_slip_ns = current_time_ns - last_hit_ns;
@@ -327,8 +343,11 @@
/* Flow Control the port */
tpm_fc_rate_limit();
-
+#if 0
return (HRTIMER_RESTART);
+#else
+ return;
+#endif
}
#endif
@@ -364,7 +383,7 @@
if (time_slip_ns > fc_info.oneshot_stat.hrt_lost_max_ns)
fc_info.oneshot_stat.hrt_lost_max_ns = time_slip_ns;
-
+
if (time_slip_ns >= (hit_time_ns << 1))
fc_info.oneshot_stat.hrt_lost_200_up++;
else if (time_slip_ns >= (hit_time_ns + (hit_time_ns >> 1)))
@@ -383,8 +402,9 @@
/* Flow Control the port */
tpm_fc_rate_limit();
-
+#if 0
return (HRTIMER_RESTART);
+#endif
}
@@ -414,9 +434,12 @@
if (true == fc_is_running) {
MV_U32 phy_addr = mvBoardPhyAddrGet(fc_info.cfg.tgt_port);
MV_U32 reg_val;
-
+
+#if 0
hrtimer_cancel(&fc_info.hr_timer);
-
+#else
+ mv_disable_fc_events();
+#endif
reg_val = MV_REG_READ(NETA_GMAC_AN_CTRL_REG(fc_info.cfg.tgt_port));
reg_val |= NETA_ENABLE_FLOW_CONTROL_AUTO_NEG_MASK;
reg_val &= ~NETA_SET_FLOW_CONTROL_MASK;
@@ -429,10 +452,11 @@
fc_info.magic = 0;
config_change = true;
}
-
+
#ifdef TPM_FC_DEBUG
fc_info.cfg.oneshot_count = 0;
#endif
+ TRC_RELEASE();
}
else
{
@@ -448,13 +472,17 @@
/* set FC running indication */
fc_info.magic = TPM_FC_MAGIC_NUMBER;
-
+
/* save the current time in the last hit */
fc_info.hrt_last_hit = ktime_get_real();
+#if 0
hrtimer_init(&fc_info.hr_timer, CLOCK_REALTIME, HRTIMER_MODE_REL);
fc_info.hr_timer.function = &tpm_fc_hr_timer_handler;
hrtimer_start(&fc_info.hr_timer, fc_info.cfg.hrt_hit_time, HRTIMER_MODE_REL);
-
+#else
+ //TRC_INIT();
+ mv_enable_fc_events(&tpm_fc_hr_timer_handler, ktime_to_ns(fc_info.cfg.hrt_hit_time));
+#endif
config_change = true;
}
}
@@ -523,9 +551,9 @@
TPM_OS_DEBUG(TPM_MTU_MOD, "SW port FC disabled!\n");
tpm_fc_enable(MV_FALSE);
}
-
+
memset(&fc_info, 0, sizeof(tpm_fc_info_t));
-
+
ns_q_sample_freq = db_fc_conf.queue_sample_freq * 1000;
if (ns_q_sample_freq < db_fc_conf.queue_sample_freq)
@@ -534,7 +562,7 @@
fc_info.cfg.hrt_hit_time = ktime_set(0, ns_q_sample_freq);
fc_info.cfg.thresh_high = db_fc_conf.thresh_high;
fc_info.cfg.thresh_low = db_fc_conf.thresh_low;
- fc_info.cfg.port = db_fc_conf.port;
+ fc_info.cfg.port = db_fc_conf.port;
fc_info.cfg.tgt_port = db_fc_conf.tgt_port;
fc_info.cfg.tgt_port_changed = MV_TRUE;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_ctc_cm.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_ctc_cm.c
index e87c85f..44b119a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_ctc_cm.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_ctc_cm.c
@@ -124,7 +124,8 @@
if (l2_parse_rule_bm)
ret_code = tpm_proc_add_l2_cnm_rule(owner_id, src_port, precedence, l2_parse_rule_bm, l2_key,
- ipv4_key_idx, pkt_frwd, pkt_act, pbits, rule_index);
+ ipv4_parse_rule_bm, ipv4_key, ipv4_key_idx, pkt_frwd,
+ pkt_act, pbits, rule_index);
else if (ipv4_parse_rule_bm)
ret_code = tpm_proc_add_ipv4_cnm_rule(owner_id, src_port, precedence, ipv4_parse_rule_bm,
ipv4_key, pkt_frwd, pkt_act, pbits, rule_index);
@@ -235,7 +236,7 @@
}
if (l2_parse_rule_bm & ~(TPM_L2_PARSE_MAC_DA | TPM_L2_PARSE_MAC_SA | TPM_L2_PARSE_ONE_VLAN_TAG |
- TPM_L2_PARSE_ETYPE)) {
+ TPM_L2_PARSE_TWO_VLAN_TAG | TPM_L2_PARSE_ETYPE)) {
TPM_OS_ERROR(TPM_CTC_CM_MOD, "l2_parse_rule_bm (%d) is invalid!\n", l2_parse_rule_bm);
return(ERR_PARSE_MAP_INVALID);
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c
index ffa53d0..426528a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.c
@@ -109,6 +109,7 @@
/* TODO - change to static variable after updating print functions */
tpm_db_t tpm_db;
+tpm_db_hot_swap_bak_db_t hot_swap_bak_db;
static uint32_t mem_alloc_start_ind;
@@ -155,6 +156,8 @@
uint8_t tpm_db_mc_igmp_proxy_sa_mac[6];
uint8_t tpm_db_mc_igmp_proxy_sa_mac_valid;
+static uint32_t tpm_db_global_rule_idx = 1000;
+
/* Function Declarations */
int32_t tpm_db_api_freeentry_get(tpm_api_sections_t api_section, int32_t *index);
int32_t tpm_db_api_entry_ind_get(tpm_api_sections_t api_section, uint32_t rule_num, int32_t *index);
@@ -277,6 +280,19 @@
}
return (TPM_DB_ERR_PORT_NUM);
}
+uint32_t tpm_db_rule_index_get(void)
+{
+ return tpm_db_global_rule_idx;
+}
+int32_t tpm_db_rule_index_set(uint32_t rule_index)
+{
+ tpm_db_global_rule_idx = rule_index;
+ return TPM_DB_OK;
+}
+void tpm_db_rule_index_incrs(void)
+{
+ tpm_db_global_rule_idx++;
+}
bool tpm_db_gmac1_lpbk_en_get(void)
{
return tpm_db.func_profile.gmac1_loopback_en;
@@ -293,6 +309,22 @@
{
tpm_db.func_profile.cpu_wan_loopback_en = en;
}
+bool tpm_db_ds_load_bal_en_get(void)
+{
+ return tpm_db.func_profile.ds_load_bal_en;
+}
+void tpm_db_ds_load_bal_en_set(bool en)
+{
+ tpm_db.func_profile.ds_load_bal_en = en;
+}
+bool tpm_db_switch_active_wan_en_get(void)
+{
+ return tpm_db.func_profile.switch_active_wan_en;
+}
+void tpm_db_switch_active_wan_en_set(bool en)
+{
+ tpm_db.func_profile.switch_active_wan_en = en;
+}
int32_t tpm_db_get_valid_uni_ports_num(uint32_t *num_ports)
{
@@ -406,6 +438,7 @@
gmac0 = 0,
gmac1 = 0;
int32_t ret_code;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
switch(tpm_db.eth_cmplx_profile)
{
@@ -456,7 +489,7 @@
break;
case TPM_PON_G1_WAN_G0_INT_SWITCH:
- if (TPM_ENUM_PMAC == tpm_db.init_misc.backup_wan) {
+ if (TPM_ENUM_GMAC_1 == tpm_db.init_misc.active_wan) {
pon = TPM_GMAC_FUNC_NONE;
gmac1 = TPM_GMAC_FUNC_WAN;
}else{
@@ -467,7 +500,7 @@
break;
case TPM_PON_G1_WAN_G0_SINGLE_PORT:
- if (TPM_ENUM_PMAC == tpm_db.init_misc.backup_wan) {
+ if (TPM_ENUM_GMAC_1 == tpm_db.init_misc.active_wan) {
pon = TPM_GMAC_FUNC_NONE;
gmac1 = TPM_GMAC_FUNC_WAN;
}else{
@@ -478,7 +511,7 @@
break;
case TPM_PON_G0_WAN_G1_INT_SWITCH:
- if (TPM_ENUM_PMAC == tpm_db.init_misc.backup_wan) {
+ if (TPM_ENUM_GMAC_0 == tpm_db.init_misc.active_wan) {
pon = TPM_GMAC_FUNC_NONE;
gmac0 = TPM_GMAC_FUNC_WAN;
}else{
@@ -489,7 +522,7 @@
break;
case TPM_PON_G0_WAN_G1_SINGLE_PORT:
- if (TPM_ENUM_PMAC == tpm_db.init_misc.backup_wan) {
+ if (TPM_ENUM_GMAC_0 == tpm_db.init_misc.active_wan) {
pon = TPM_GMAC_FUNC_NONE;
gmac0 = TPM_GMAC_FUNC_WAN;
}else{
@@ -508,11 +541,21 @@
case TPM_PON_WAN_G0_G1_LPBK:
pon = TPM_GMAC_FUNC_WAN;
- gmac0 = TPM_GMAC_FUNC_LAN_UNI;
+ gmac0 = TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI;
gmac1 = TPM_GMAC_FUNC_LAN;
break;
+ case TPM_PON_WAN_G0_G1_DUAL_LAN:
+ pon = TPM_GMAC_FUNC_WAN;
+ gmac0 = TPM_GMAC_FUNC_LAN_UNI;
+ gmac1 = TPM_GMAC_FUNC_LAN_UNI;
+ break;
}
+ /* when ds load balance on G0 and G1 is enabled, G0/1 are both LAN */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable)
+ gmac1 = TPM_GMAC_FUNC_LAN;
+
ret_code = tpm_db_gmac_func_set(TPM_ENUM_PMAC, pon);
IF_ERROR(ret_code);
ret_code = tpm_db_gmac_func_set(TPM_ENUM_GMAC_0, gmac0);
@@ -549,6 +592,7 @@
case TPM_PON_G0_WAN_G1_SINGLE_PORT:
case TPM_PON_G1_WAN_G0_SINGLE_PORT:
+ case TPM_PON_WAN_G0_G1_DUAL_LAN:
tpm_db.max_uni_port_nr = TPM_SRC_PORT_UNI_1;
break;
@@ -585,8 +629,8 @@
uint32_t dst_port, trg_port_uni_any_bmp = 0;
tpm_src_port_type_t src_port;
- for (dst_port = TPM_TRG_UNI_0, src_port = TPM_SRC_PORT_UNI_0;
- dst_port <= TPM_TRG_UNI_7;
+ for (dst_port = TPM_TRG_UNI_0, src_port = TPM_SRC_PORT_UNI_0;
+ dst_port <= TPM_TRG_UNI_7;
dst_port = (dst_port << 1), src_port += 1) {
/* if port is valid */
@@ -609,6 +653,21 @@
return false;
}
+int32_t tpm_db_target_to_gmac(tpm_pnc_trg_t pnc_target, tpm_gmacs_enum_t *gmac)
+{
+ if (TPM_PNC_TRG_GMAC0 == pnc_target)
+ *gmac = TPM_ENUM_GMAC_0;
+ else if (TPM_PNC_TRG_GMAC1 == pnc_target)
+ *gmac = TPM_ENUM_GMAC_1;
+ else if (TPM_PNC_TRG_CPU == pnc_target) {
+ TPM_OS_ERROR(TPM_DB_MOD, "target to CPU, no GMAC valid\n");
+ return TPM_DB_ERR_INV_INPUT;
+ } else
+ *gmac = TPM_ENUM_PMAC;
+
+ return TPM_DB_OK;
+}
+
/*******************************************************************************
* tpm_db_to_lan_gmac_get()
*
@@ -646,8 +705,10 @@
continue;
if (!tpm_db_gmac1_lpbk_en_get()) {
if (TPM_GMAC_FUNC_LAN == tpm_db.gmac_func[i] ||
- TPM_GMAC_FUNC_LAN_UNI == tpm_db.gmac_func[i])
+ TPM_GMAC_FUNC_LAN_UNI == tpm_db.gmac_func[i]) {
gmac_vec |= (TPM_ENUM_GMAC_0 == i) ? TPM_PNC_TRG_GMAC0 : TPM_PNC_TRG_GMAC1;
+ break;/* target only one, no others */
+ }
} else {
gmac_vec |= TPM_PNC_TRG_GMAC0;
break;
@@ -955,6 +1016,31 @@
}
/*******************************************************************************
+* tpm_db_gmac_conn_conf_get()
+*
+* DESCRIPTION: Function to get GMAC connection information from DB
+*
+* INPUTS:
+* gmac - GMAC port
+*
+* OUTPUTS:
+* gmac_port_conf - connection info
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK.
+*
+*******************************************************************************/
+int32_t tpm_db_gmac_conn_conf_get(tpm_gmacs_enum_t gmac, tpm_init_gmac_conn_conf_t *gmac_port_conf)
+{
+ if (NULL == gmac_port_conf)
+ return (TPM_DB_ERR_INV_INPUT);
+
+ memcpy(gmac_port_conf, &tpm_db.gmac_port_conf[gmac], sizeof(tpm_init_gmac_conn_conf_t));
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
* tpm_db_gmac_tcont_llid_set()
*
* DESCRIPTION: Function to set the GMAC connection and T-CONTs in the DB
@@ -1299,7 +1385,7 @@
{
if ((gmac >= TPM_MAX_NUM_GMACS) || (queue_num >= TPM_MAX_NUM_RX_QUEUE))
return (TPM_DB_ERR_INV_INPUT);
-
+
tpm_db.gmac_rx[gmac].rx_queue[queue_num].queue_size = queue_size;
tpm_db.gmac_rx[gmac].rx_queue[queue_num].valid = TPM_DB_VALID;
@@ -1456,10 +1542,10 @@
/*******************************************************************************
* tpm_db_gmac_lpk_queue_get()
*
-* DESCRIPTION: Function to get the queue id used to do gmac loopback on MC
-*
+* DESCRIPTION: Function to get the queue id used to do gmac loopback on MC, min queue id for data traffic,
+* max queue id for MAC learning
* INPUTS:
-* None
+* queue_type - queue type for GMAC1 loopback, for data traffic or for MAC learning
* OUTPUTS:
* gmac - gmac on which loopback is done
* queue_idx - queue index which do loopback
@@ -1467,12 +1553,15 @@
* On success, the function returns TPM_DB_OK. On error different types are returned
* according to the case - see tpm_db_err_t.
*******************************************************************************/
-uint32_t tpm_db_gmac_lpk_queue_get(tpm_gmacs_enum_t *gmac, uint32_t *queue_idx)
+uint32_t tpm_db_gmac_lpk_queue_get(tpm_gmacs_enum_t *gmac,
+ uint32_t *queue_idx,
+ tpm_db_gmac1_lpk_queue_type_t queue_type)
{
uint32_t queue_id, q_valid, gmac_id;
tpm_db_txq_owner_t queue_owner, lpk_queue_owner = TPM_Q_OWNER_GMAC0;
tpm_db_gmac_func_t lpk_gmac_func;
tpm_db_tx_mod_t tx_mod;
+ uint32_t q_expected = TPM_MAX_NUM_TX_QUEUE;
/*check input parameters*/
if (NULL == gmac || NULL == queue_idx) {
@@ -1509,21 +1598,25 @@
if (TPM_DB_OK != tpm_db_gmac_tx_q_conf_get(tx_mod, queue_id, &q_valid, NULL,
&queue_owner, NULL, NULL, NULL))
continue;
- if (q_valid == TPM_TRUE && queue_owner == lpk_queue_owner)
- break;
+ if (q_valid == TPM_TRUE && queue_owner == lpk_queue_owner) {
+ q_expected = queue_id;
+ if (TPM_GMAC1_QUEUE_DATA_TRAFFIC == queue_type)
+ break;
+ else if (TPM_GMAC1_QUEUE_MAC_LEARN_TRAFFIC == queue_type)
+ continue;
+ }
}
- if (queue_id >= TPM_MAX_NUM_TX_QUEUE) {
- TPM_OS_ERROR(TPM_DB_MOD, "Invalid Tx queue %d of GMAC1 assigned to GMAC0 \n", queue_id);
+ if (q_expected >= TPM_MAX_NUM_TX_QUEUE) {
+ TPM_OS_ERROR(TPM_DB_MOD, "Invalid Tx queue %d of GMAC1 assigned to GMAC0 \n", q_expected);
return ERR_SW_TM_QUEUE_INVALID;
}
*gmac = gmac_id;
- *queue_idx = queue_id;
+ *queue_idx = q_expected;
return (TPM_DB_OK);
}
-
/*******************************************************************************
* tpm_db_pnc_rng_create()
*
@@ -1849,6 +1942,9 @@
case TPM_API_CPU_LOOPBACK:
*api_section = TPM_CPU_LOOPBACK_ACL;
break;
+ case TPM_API_DS_LOAD_BALANCE:
+ *api_section = TPM_DS_LOAD_BALANCE_ACL;
+ break;
case TPM_API_L2_PRIM:
*api_section = TPM_L2_PRIM_ACL;
break;
@@ -1900,6 +1996,9 @@
case TPM_CPU_LOOPBACK_ACL:
*api_type = TPM_API_CPU_LOOPBACK;
break;
+ case TPM_DS_LOAD_BALANCE_ACL:
+ *api_type = TPM_API_DS_LOAD_BALANCE;
+ break;
case TPM_L2_PRIM_ACL:
*api_type = TPM_API_L2_PRIM;
break;
@@ -2477,6 +2576,53 @@
return (TPM_DB_OK);
}
+
+/*******************************************************************************
+* tpm_db_igmp_set_snoop_enable()
+*
+* DESCRIPTION: Set IGMP snoop enable
+*
+* INPUTS:
+* igmp_snoop_enable - IGMP snoop enable
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_igmp_set_snoop_enable(uint32_t igmp_snoop_enable)
+{
+ tpm_db.igmp_def.igmp_snoop_enable = igmp_snoop_enable;
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_igmp_get_snoop_enable()
+*
+* DESCRIPTION: Get IGMP snoop enable
+*
+* INPUTS:
+*
+* OUTPUTS:
+* igmp_snoop_enable - IGMP snoop enable
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_igmp_get_snoop_enable(uint32_t *igmp_snoop_enable)
+{
+ *igmp_snoop_enable = tpm_db.igmp_def.igmp_snoop_enable;
+ return (TPM_DB_OK);
+}
+
/*******************************************************************************
* tpm_db_omci_type_set()
*
@@ -2897,7 +3043,7 @@
}
/*******************************************************************************
-* tpm_db_backup_wan_set()
+* tpm_db_active_wan_set()
*
* DESCRIPTION: Set WAN technology
*
@@ -2912,14 +3058,14 @@
* COMMENTS:
*
*******************************************************************************/
-int32_t tpm_db_backup_wan_set(tpm_gmacs_enum_t backup_wan)
+int32_t tpm_db_active_wan_set(tpm_gmacs_enum_t active_wan)
{
- tpm_db.init_misc.backup_wan = backup_wan;
+ tpm_db.init_misc.active_wan = active_wan;
return (TPM_DB_OK);
}
/*******************************************************************************
-* tpm_db_backup_wan_get()
+* tpm_db_active_wan_get()
*
* DESCRIPTION: Set WAN technology
*
@@ -2934,36 +3080,9 @@
* COMMENTS:
*
*******************************************************************************/
-int32_t tpm_db_backup_wan_get(tpm_gmacs_enum_t *backup_wan)
-{
- *backup_wan = tpm_db.init_misc.backup_wan;
- return (TPM_DB_OK);
-}
-
tpm_gmacs_enum_t tpm_db_active_wan_get()
{
- switch (tpm_db.eth_cmplx_profile) {
- case TPM_PON_G1_WAN_G0_INT_SWITCH:
- return (tpm_db.init_misc.backup_wan == TPM_ENUM_PMAC) ? TPM_ENUM_GMAC_1 : TPM_ENUM_PMAC;
-
- case TPM_PON_G0_WAN_G1_INT_SWITCH:
- return (tpm_db.init_misc.backup_wan == TPM_ENUM_PMAC) ? TPM_ENUM_GMAC_0 : TPM_ENUM_PMAC;
-
- case TPM_PON_G0_WAN_G1_SINGLE_PORT:
- return (tpm_db.init_misc.backup_wan == TPM_ENUM_PMAC) ? TPM_ENUM_GMAC_0 : TPM_ENUM_PMAC;
-
- case TPM_PON_G1_WAN_G0_SINGLE_PORT:
- return (tpm_db.init_misc.backup_wan == TPM_ENUM_PMAC) ? TPM_ENUM_GMAC_1 : TPM_ENUM_PMAC;
-
- case TPM_G0_WAN_G1_INT_SWITCH:
- return TPM_ENUM_GMAC_0;
-
- case TPM_G1_WAN_G0_INT_SWITCH:
- return TPM_ENUM_GMAC_1;
-
- default:
- return TPM_ENUM_PMAC;
- }
+ return tpm_db.init_misc.active_wan;
}
/*******************************************************************************
@@ -4214,10 +4333,10 @@
tpm_db_mod_conn_t *mod_con, tpm_db_pnc_conn_t *pnc_con, uint32_t *rule_idx)
{
int32_t ind;
- static uint32_t l_rule_idx = 1000;
tpm_pnc_ranges_t range_id = 0;
tpm_db_pnc_range_conf_t rangConf;
int32_t ret_code;
+ uint32_t l_rule_idx;
TPM_OS_DEBUG(TPM_DB_MOD, " api_section(%d), - rule_num(%d)\n", api_section, rule_num);
@@ -4240,6 +4359,7 @@
memcpy(&(API_ENT_I(api_section, ind).pnc_tbl_conn), pnc_con, sizeof(tpm_db_pnc_conn_t));
API_ENT_I(api_section, ind).bi_dir = bi_dir;
+ l_rule_idx = tpm_db_rule_index_get();
if (TPM_RANGE_TYPE_ACL == rangConf.range_type)
API_ENT_I(api_section, ind).rule_idx = l_rule_idx;
else
@@ -4262,7 +4382,7 @@
if (TPM_RANGE_TYPE_ACL == rangConf.range_type) {
*rule_idx = l_rule_idx;
- l_rule_idx++;
+ tpm_db_rule_index_incrs();
} else
*rule_idx = rule_num;
@@ -4675,6 +4795,34 @@
return (TPM_DB_OK);
}
+int32_t tpm_db_api_entry_update_rule_idx(tpm_api_sections_t api_section,
+ uint32_t rule_idx_pre,
+ uint32_t rule_idx_new)
+{
+ int32_t ind;
+ int32_t ret_code;
+ uint32_t rule_num = 0;
+
+ TPM_OS_DEBUG(TPM_DB_MOD, " api_section(%d), - rule_num(%d)\n", api_section, rule_num);
+
+ /* Get the rule_num */
+ ret_code = tpm_db_api_rulenum_get(api_section, rule_idx_pre, &rule_num);
+ if (ret_code == TPM_DB_ERR_REC_NOT_EXIST) {
+ TPM_OS_ERROR(TPM_DB_MOD, " The rule non-exist!\n");
+ return ERR_RULE_IDX_INVALID;
+ }
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "with rule_num(%d)\n", rule_num);
+
+ tpm_db_api_entry_ind_get(api_section, rule_num, &ind);
+ if (ind == -1)
+ return (TPM_DB_ERR_REC_NOT_EXIST);
+
+ /* update rule_index */
+ API_ENT_I(api_section, ind).rule_idx = rule_idx_new;
+
+ return (TPM_DB_OK);
+}
+
/*******************************************************************************
* tpm_db_api_rulenum_get()
*
@@ -5514,7 +5662,7 @@
{
uint32_t entry_id, first_free = TPM_MC_MAX_MAC_NUM;
uint32_t port_nr;
-
+
for (entry_id = 0; entry_id < TPM_MC_MAX_MAC_NUM; entry_id++) {
if (tpm_db_mc_mac_table[entry_id] != NULL) {
if (!memcmp(tpm_db_mc_mac_table[entry_id]->mac_addr, mac_addr, 6 * sizeof(uint8_t)))
@@ -5616,12 +5764,12 @@
default:
return 0;
}
-
+
if (TRG_UNI(uni_port)) {
if (port_nr < TPM_MAX_NUM_UNI_PORTS)
return tpm_db_mc_mac_table[entry_id]->user_num[port_nr];
}
-
+
return 0;
}
@@ -5910,7 +6058,7 @@
/* reset IPv6 MC rule */
memset(tpm_db.ipv6_mc_stream, 0, sizeof(tpm_db.ipv6_mc_stream));
-
+
}
int32_t tpm_db_mc_vlan_get_ai_bit_by_vid(uint32_t mc_vlan, uint32_t *ai_bit)
{
@@ -6550,7 +6698,7 @@
if (tpm_db_mod2_jump_split_mod_all_entry_bm[gmac_port][i] & mask) {
/* this is a split mod pmt entry */
tpm_db_mod2_jump_split_mod_occupied_entry_bm[gmac_port][i] &= ~mask;
- }
+ }
else {
tpm_db_mod2_jump_occupied_entry_bm[gmac_port][i] &= ~mask;
}
@@ -7257,7 +7405,7 @@
for (i = 0; i < TPM_DB_SPLIT_MOD_NUM_VLANS_MAX; i++) {
if (tpm_db.split_mod_conf.gmac_vlan_conf[gmac_port].split_mod_vlan[i].valid)
- vlan_num++;
+ vlan_num++;
}
return vlan_num;
@@ -7289,7 +7437,7 @@
vlan_out = &mod_data->vlan_mod.vlan2_out;
else
vlan_out = &mod_data->vlan_mod.vlan1_out;
-
+
if (0 == vlan_out->pbit_mask)
/* pbit AS_IS */
pbit_index = 0;
@@ -7298,9 +7446,9 @@
if (next_free != 1)
pbit_index++;
}
-
+
next_free += pbit_index;
-
+
if (next_free != TPM_MOD2_NULL_ENT_IDX) {
tpm_db_mod2_jump_pmt_info[gmac_port][next_free].status = TPM_MOD_ENTRY_BOOKED;
@@ -7325,17 +7473,17 @@
TPM_OS_ERROR(TPM_DB_MOD, "already has %d num_vlans\n", vlan_num - TPM_DB_SPLIT_MOD_INIT_VLANS_NUM);
return TPM_DB_ERR_DB_TBL_FULL;
}
-
+
for (i = 0; i < TPM_DB_SPLIT_MOD_NUM_VLANS_MAX; i++) {
- if (tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[i].valid)
+ if (tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[i].valid)
continue;
//here finds a spot
tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[i].valid = 1;
-
+
if (mod_data->vlan_mod.vlan1_out.vid_mask)
tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[i].vlan_1 = mod_data->vlan_mod.vlan1_out.vid;
-
+
if (mod_data->vlan_mod.vlan2_out.vid_mask)
tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[i].vlan_2 = mod_data->vlan_mod.vlan2_out.vid;
@@ -7356,11 +7504,11 @@
int32_t tpm_db_mod2_split_mod_get_vlan_index(tpm_gmacs_enum_t port, tpm_pkt_mod_t *mod_data, uint32_t *index)
{
uint32_t i;
- //printk("input: port: %d, vlan_op: %d, vlan1: %d(%d), vlan2: %d(%d)\n",
+ //printk("input: port: %d, vlan_op: %d, vlan1: %d(%d), vlan2: %d(%d)\n",
//port, mod_data->vlan_mod.vlan_op, mod_data->vlan_mod.vlan1_out.vid, mod_data->vlan_mod.vlan1_out.vid_mask,
//mod_data->vlan_mod.vlan2_out.vid, mod_data->vlan_mod.vlan2_out.vid_mask);
for (i = 0; i < TPM_DB_SPLIT_MOD_NUM_VLANS_MAX; i++) {
- //printk("output: port: %d, vlan_op: %d, vlan1: %d, vlan2: %d\n",
+ //printk("output: port: %d, vlan_op: %d, vlan1: %d, vlan2: %d\n",
//tpm_db.split_mod_conf.gmac_vlan_conf[i].gmac_port, tpm_db.split_mod_conf.gmac_vlan_conf[i].vlan_op,
//tpm_db.split_mod_conf.gmac_vlan_conf[i].vlan_1, tpm_db.split_mod_conf.gmac_vlan_conf[i].vlan_2);
if (!tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[i].valid)
@@ -7424,7 +7572,7 @@
return TPM_DB_OK;
}
-int32_t tpm_db_mod2_split_mod_decrease_vlan_user_num(tpm_gmacs_enum_t port,
+int32_t tpm_db_mod2_split_mod_decrease_vlan_user_num(tpm_gmacs_enum_t port,
uint32_t vlan_index,
uint32_t *user_num)
{
@@ -7432,12 +7580,12 @@
TPM_OS_ERROR(TPM_DB_MOD, "Invalid port: %d\n", port);
return TPM_DB_ERR_INV_INPUT;
}
-
+
if (vlan_index >= TPM_DB_SPLIT_MOD_NUM_VLANS_MAX) {
TPM_OS_ERROR(TPM_DB_MOD, "Invalid vlan_index: %d\n", vlan_index);
return TPM_DB_ERR_INV_INPUT;
}
-
+
if (!tpm_db.split_mod_conf.gmac_vlan_conf[port].split_mod_vlan[vlan_index].valid) {
TPM_OS_ERROR(TPM_DB_MOD, "Invalid vlan entry: %d\n", vlan_index);
return TPM_DB_ERR_INV_INPUT;
@@ -7755,7 +7903,7 @@
split_jump_entries = 16 * 2/*init added*/ +
(split_vlan_num - 1) * 16/*internal VLAN*/ +
split_pbit_num + 1/*last VLAN*/;
- split_jump_free_entries = 2 * (15 - split_pbit_num)/*init occupy*/ +
+ split_jump_free_entries = 2 * (15 - split_pbit_num)/*init occupy*/ +
(split_vlan_num - 1) * (16 - split_pbit_num - 1)/*internal VLAN*/;
}
@@ -7955,7 +8103,7 @@
}
memset(tpm_db_mod2_jump_occupied_entry_bm[port], 0, bm_size);
tpm_db_mod2_jump_occupied_entry_bm[port][0] |= 0x1;
-
+
if (tpm_db_mod2_jump_split_mod_occupied_entry_bm[port] != NULL) {
vfree(tpm_db_mod2_jump_split_mod_occupied_entry_bm[port]);
tpm_db_mod2_jump_split_mod_occupied_entry_bm[port] = NULL;
@@ -7986,11 +8134,11 @@
TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "SPLIT_MOD_DISABLED\n");
return(TPM_OK);
}
-
+
vlan_nums = tpm_db_split_mod_get_num_vlans();
p_bits_nums = TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX;
-
+
tpm_db_mod2_jump_area_cfg.next_free[port] = p_bits_nums + 1;
//tpm_db_mod2_jump_area_cfg.next_split[port] = 16;
@@ -9156,7 +9304,7 @@
if (key_array[key_id].valid == TPM_FALSE)
return TPM_DB_ERR_REC_STATUS_ERR;
- user_num = tpm_db_get_ipv6_gen_key_user_num(key_id);
+ user_num = tpm_db_get_ipv6_dip_key_user_num(key_id);
if (user_num == 0)
memset(&key_array[key_id], 0, sizeof(tpm_db_ipv6_dip_key_t));
@@ -10262,9 +10410,41 @@
}
int32_t tpm_db_set_gmac_rate_limit(tpm_db_tx_mod_t gmac_i,
+ uint32_t bucket_size,
+ uint32_t rate_limit,
+ uint32_t prio)
+{
+ /*check param*/
+ if (gmac_i >= TPM_MAX_NUM_TX_PORTS)
+ return (TPM_DB_ERR_INV_INPUT);
+
+ tpm_db.gmac_tx[gmac_i].bucket_size = bucket_size;
+ tpm_db.gmac_tx[gmac_i].rate_limit = rate_limit;
+ tpm_db.gmac_tx[gmac_i].prio = prio;
+
+ return TPM_DB_OK;
+}
+
+int32_t tpm_db_get_gmac_rate_limit(tpm_gmacs_enum_t gmac_i,
+ uint32_t *bucket_size,
+ uint32_t *rate_limit,
+ uint32_t *prio)
+{
+ /*check param*/
+ if (gmac_i >= TPM_MAX_NUM_TX_PORTS)
+ return (TPM_DB_ERR_INV_INPUT);
+
+ *bucket_size = tpm_db.gmac_tx[gmac_i].bucket_size;
+ *rate_limit = tpm_db.gmac_tx[gmac_i].rate_limit;
+ *prio = tpm_db.gmac_tx[gmac_i].prio;
+
+ return TPM_DB_OK;
+}
+int32_t tpm_db_set_gmac_q_rate_limit(tpm_db_tx_mod_t gmac_i,
uint32_t queue,
uint32_t bucket_size,
- uint32_t rate_limit)
+ uint32_t rate_limit,
+ uint32_t wrr)
{
/*check param*/
if (gmac_i >= TPM_MAX_NUM_TX_PORTS)
@@ -10275,14 +10455,16 @@
tpm_db.gmac_tx[gmac_i].tx_queue[queue].bucket_size = bucket_size;
tpm_db.gmac_tx[gmac_i].tx_queue[queue].rate_limit = rate_limit;
+ tpm_db.gmac_tx[gmac_i].tx_queue[queue].wrr = wrr;
return TPM_DB_OK;
}
-int32_t tpm_db_get_gmac_rate_limit(tpm_gmacs_enum_t gmac_i,
+int32_t tpm_db_get_gmac_q_rate_limit(tpm_gmacs_enum_t gmac_i,
uint32_t queue,
uint32_t *bucket_size,
- uint32_t *rate_limit)
+ uint32_t *rate_limit,
+ uint32_t *wrr)
{
/*check param*/
if (gmac_i >= TPM_MAX_NUM_TX_PORTS)
@@ -10293,6 +10475,7 @@
*bucket_size = tpm_db.gmac_tx[gmac_i].tx_queue[queue].bucket_size;
*rate_limit = tpm_db.gmac_tx[gmac_i].tx_queue[queue].rate_limit;
+ *wrr = tpm_db.gmac_tx[gmac_i].tx_queue[queue].wrr;
return TPM_DB_OK;
}
@@ -10312,9 +10495,9 @@
return TPM_DB_OK;
}
-int32_t tpm_db_get_ipv4_pre_filter_key(tpm_src_port_type_t src_port,
- uint32_t key_idx,
- tpm_parse_fields_t *parse_rule_bm,
+int32_t tpm_db_get_ipv4_pre_filter_key(tpm_src_port_type_t src_port,
+ uint32_t key_idx,
+ tpm_parse_fields_t *parse_rule_bm,
tpm_ipv4_acl_key_t *ipv4_key)
{
tpm_db_cnm_ipv4_pre_filter_key_t *key = NULL;
@@ -10466,6 +10649,354 @@
return TPM_DB_OK;
}
+
+/*******************************************************************************
+* tpm_db_mac_learn_mod_idx_set()
+*
+* DESCRIPTION: Set mac leanring pmt mod index, just for mac learning
+*
+* INPUTS:
+* mod_idx
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_mac_learn_mod_idx_set(uint32_t mod_idx)
+{
+ tpm_db.mac_learn_mod_idx = mod_idx;
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_mac_learn_mod_idx_get()
+*
+* DESCRIPTION: Get mac leanring pmt mod index, just for mac learning
+*
+* INPUTS:
+* mod_idx
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_mac_learn_mod_idx_get(uint32_t *mod_idx)
+{
+ *mod_idx = tpm_db.mac_learn_mod_idx;
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_ds_mac_based_trunk_enable_set()
+*
+* DESCRIPTION: Set ds_mac_based_trunk_enable
+*
+* INPUTS:
+* enable - ds_mac_based_trunk_enable
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_ds_mac_based_trunk_enable_set(tpm_db_ds_mac_based_trunk_enable_t enable)
+{
+ tpm_db.ds_mac_based_trunk_enable = enable;
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_ds_mac_based_trunk_enable_get()
+*
+* DESCRIPTION: Get ds_mac_based_trunk_enable
+*
+* INPUTS:
+*
+* OUTPUTS:
+* enable - ds_mac_based_trunk_enable
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_ds_mac_based_trunk_enable_get(tpm_db_ds_mac_based_trunk_enable_t *enable)
+{
+ *enable = tpm_db.ds_mac_based_trunk_enable;
+
+ return (TPM_DB_OK);
+}
+int32_t tpm_db_api_data_backup(void)
+{
+ memcpy(hot_swap_bak_db.api_ent_mem_area_bak, tpm_db.api_ent_mem_area, sizeof(tpm_db.api_ent_mem_area));
+ memcpy(hot_swap_bak_db.api_section_bak, tpm_db.api_section, sizeof(tpm_db.api_section));
+ memcpy(hot_swap_bak_db.mc_vid_port_cfg_bak, tpm_db.mc_vid_port_cfg, sizeof(tpm_db.mc_vid_port_cfg));
+ memcpy(hot_swap_bak_db.gmac_tx_bak, tpm_db.gmac_tx, sizeof(tpm_db.gmac_tx));
+ memcpy(hot_swap_bak_db.igmp_proxy_sa_mac, tpm_db_mc_igmp_proxy_sa_mac, 6);
+ hot_swap_bak_db.igmp_proxy_sa_mac_valid = tpm_db_mc_igmp_proxy_sa_mac_valid;
+ hot_swap_bak_db.switch_init = tpm_db.func_profile.switch_init;
+
+ return (TPM_DB_OK);
+}
+int32_t tpm_db_api_data_rcvr(void)
+{
+ memcpy(tpm_db.mc_vid_port_cfg, hot_swap_bak_db.mc_vid_port_cfg_bak, sizeof(tpm_db.mc_vid_port_cfg));
+ memcpy(tpm_db.gmac_tx, hot_swap_bak_db.gmac_tx_bak, sizeof(tpm_db.gmac_tx));
+ memcpy(tpm_db_mc_igmp_proxy_sa_mac, hot_swap_bak_db.igmp_proxy_sa_mac, 6);
+ tpm_db_mc_igmp_proxy_sa_mac_valid = hot_swap_bak_db.igmp_proxy_sa_mac_valid;
+ tpm_db.func_profile.switch_init = hot_swap_bak_db.switch_init;
+
+ return (TPM_DB_OK);
+}
+void tpm_db_exchange_value(uint32_t *v1, uint32_t *v2)
+{
+ uint32_t tmp;
+
+ tmp = *v1;
+ *v1 = *v2;
+ *v2 = tmp;
+
+ return;
+}
+int32_t tpm_db_wan_lan_rate_limit_exchange_db(tpm_db_gmac_tx_t *gmac_tx)
+{
+ int32_t queue;
+
+ for (queue = 0; queue < TPM_MAX_NUM_TX_QUEUE; queue++) {
+ tpm_db_exchange_value(&(gmac_tx[TPM_TX_MOD_GMAC0].tx_queue[queue].bucket_size),
+ &(gmac_tx[TPM_TX_MOD_GMAC1].tx_queue[queue].bucket_size));
+ tpm_db_exchange_value(&(gmac_tx[TPM_TX_MOD_GMAC0].tx_queue[queue].rate_limit),
+ &(gmac_tx[TPM_TX_MOD_GMAC1].tx_queue[queue].rate_limit));
+ tpm_db_exchange_value(&(gmac_tx[TPM_TX_MOD_GMAC0].tx_queue[queue].wrr),
+ &(gmac_tx[TPM_TX_MOD_GMAC1].tx_queue[queue].wrr));
+ }
+
+ tpm_db_exchange_value(&(gmac_tx[TPM_TX_MOD_GMAC0].bucket_size),
+ &(gmac_tx[TPM_TX_MOD_GMAC1].bucket_size));
+ tpm_db_exchange_value(&(gmac_tx[TPM_TX_MOD_GMAC0].rate_limit),
+ &(gmac_tx[TPM_TX_MOD_GMAC1].rate_limit));
+ tpm_db_exchange_value(&(gmac_tx[TPM_TX_MOD_GMAC0].prio),
+ &(gmac_tx[TPM_TX_MOD_GMAC1].prio));
+
+ return (TPM_DB_OK);
+}
+int32_t tpm_db_wan_lan_rate_limit_exchange(void)
+{
+ tpm_db_wan_lan_rate_limit_exchange_db(tpm_db.gmac_tx);
+ tpm_db_wan_lan_rate_limit_exchange_db(hot_swap_bak_db.gmac_tx_bak);
+ return (TPM_DB_OK);
+}
+
+int32_t tpm_db_api_section_bak_num_entries_get(tpm_api_sections_t api_section, uint32_t *num_entries)
+{
+ if (hot_swap_bak_db.api_section_bak[api_section].valid == TPM_DB_INVALID) {
+ printk("api_section: %d is not valid\n", api_section);
+ *num_entries = 0;
+ } else
+ *num_entries = hot_swap_bak_db.api_section_bak[api_section].num_valid_entries;
+
+ printk("api_section: %d, number_valid: %d\n", api_section, *num_entries);
+ return (TPM_DB_OK);
+}
+int32_t tpm_db_api_section_bak_ent_tbl_get(tpm_api_sections_t api_sec, tpm_db_api_entry_t *api_ent_mem_area, uint32_t index)
+{
+ if (ILLEGAL_API_SEC(api_sec))
+ IF_ERROR_I(TPM_DB_ERR_REC_NOT_EXIST, api_sec);
+
+ if (NULL == api_ent_mem_area)
+ return (TPM_DB_ERR_INV_INPUT);
+
+ memcpy(api_ent_mem_area,
+ &hot_swap_bak_db.api_ent_mem_area_bak[(hot_swap_bak_db.api_section_bak[api_sec].table_start) + index],
+ sizeof(tpm_db_api_entry_t));
+
+ return (TPM_DB_OK);
+}
+int32_t tpm_db_api_entry_bak_get_next(tpm_api_sections_t api_section,
+ int32_t cur_rule,
+ int32_t *next_rule)
+{
+ int32_t ind = -1;
+ int32_t i;
+ uint32_t min_rule, l_next_rule = ~0;
+ tpm_db_api_entry_t *api_tbl;
+
+ api_tbl = &(hot_swap_bak_db.api_ent_mem_area_bak[hot_swap_bak_db.api_section_bak[api_section].table_start]);
+
+ if (cur_rule <= -1)
+ min_rule = 0;
+ else
+ min_rule = cur_rule + 1;
+
+ /*TPM_OS_DEBUG(TPM_DB_MOD, "min_rule(%d) \n", min_rule); */
+
+ for (i = 0; i <= hot_swap_bak_db.api_section_bak[api_section].last_valid_index; i++) {
+ if (((api_tbl + i)->valid == TPM_DB_VALID) &&
+ ((api_tbl + i)->rule_num >= min_rule) && ((api_tbl + i)->rule_num < l_next_rule)) {
+ l_next_rule = (api_tbl + i)->rule_num;
+ ind = i;
+ TPM_OS_INFO(TPM_DB_MOD, "rule_num(%d), rule_idx(%d) update\n", (api_tbl + i)->rule_num, (api_tbl + i)->rule_idx);
+ } else
+ TPM_OS_INFO(TPM_DB_MOD, "rule_num(%d), rule_idx(%d) \n", (api_tbl + i)->rule_num, (api_tbl + i)->rule_idx);
+ }
+
+ /*TPM_OS_DEBUG(TPM_DB_MOD, "l_next_rule(%d) ind(%d) \n", l_next_rule, ind); */
+
+ if ((l_next_rule < (uint32_t) (~0)) && (ind != -1)) {
+ *next_rule = ind;
+ } else /* Not found */
+ *next_rule = -1;
+
+ TPM_OS_INFO(TPM_DB_MOD, "next_rule(%d) \n", *next_rule);
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_max_uni_port_nr_get()
+*
+* DESCRIPTION: Get max UNI port number
+*
+* INPUTS:
+*
+* OUTPUTS:
+* max_uni_port_nr - max UNI port number
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_max_uni_port_nr_get(uint32_t *max_uni_port_nr)
+{
+ *max_uni_port_nr = tpm_db.max_uni_port_nr + 1;
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_gmac_uni_egr_rate_limit_set()
+*
+* DESCRIPTION: Set GMAC UNI egress rate limit
+*
+* INPUTS:
+* port - GMAC UNI port to do rate limit
+* rate_limit - rate limit value
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_gmac_uni_egr_rate_limit_set(tpm_src_port_type_t port, uint32_t rate_limit)
+{
+ tpm_db.gmac_uni_egr_rate_limit[port] = rate_limit;
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_gmac_uni_egr_rate_limit_get()
+*
+* DESCRIPTION: Get GMAC UNI egress rate limit
+*
+* INPUTS:
+* port - GMAC UNI port to do rate limit
+* OUTPUTS:
+* rate_limit - rate limit value, if value got is 0, means no rate limit set
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_gmac_uni_egr_rate_limit_get(tpm_src_port_type_t port, uint32_t *rate_limit)
+{
+ if (NULL == rate_limit)
+ return (TPM_DB_ERR_INV_INPUT);
+
+ *rate_limit = tpm_db.gmac_uni_egr_rate_limit[port];
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_gmac_lpk_uni_ingr_rate_limit_set()
+*
+* DESCRIPTION: Set GMAC UNI ingress rate limit only with loopback mode
+*
+* INPUTS:
+* port - GMAC UNI port to do rate limit
+* rate_limit - rate limit value
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_gmac_lpk_uni_ingr_rate_limit_set(tpm_src_port_type_t port, tpm_db_gmac_lpk_uni_ingr_rate_limit_t rate_limit)
+{
+ tpm_db.gmac_lpk_uni_ingr_rate_limit[port].count_mode = rate_limit.count_mode;
+ tpm_db.gmac_lpk_uni_ingr_rate_limit[port].cir = rate_limit.cir;
+ tpm_db.gmac_lpk_uni_ingr_rate_limit[port].cbs = rate_limit.cbs;
+ tpm_db.gmac_lpk_uni_ingr_rate_limit[port].ebs = rate_limit.ebs;
+
+ return (TPM_DB_OK);
+}
+
+/*******************************************************************************
+* tpm_db_gmac_lpk_uni_ingr_rate_limit_get()
+*
+* DESCRIPTION: Get GMAC UNI ingress rate limit with loopback mode
+*
+* INPUTS:
+* port - GMAC UNI port to do rate limit
+* OUTPUTS:
+* rate_limit - rate limit value, if value got is 0, means no rate limit set
+* RETURNS:
+* On success, the function returns TPM_DB_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_db_gmac_lpk_uni_ingr_rate_limit_get(tpm_src_port_type_t port, tpm_db_gmac_lpk_uni_ingr_rate_limit_t *rate_limit)
+{
+ if (NULL == rate_limit)
+ return (TPM_DB_ERR_INV_INPUT);
+
+ memcpy(rate_limit,
+ &tpm_db.gmac_lpk_uni_ingr_rate_limit[port],
+ sizeof(tpm_db_gmac_lpk_uni_ingr_rate_limit_t));
+
+ return (TPM_DB_OK);
+}
+
/*******************************************************************************
* tpm_db_init()
*
@@ -10514,6 +11045,7 @@
for (i = TPM_SRC_PORT_UNI_0; i <= TPM_SRC_PORT_UNI_7; i++)
tpm_db.igmp_def.frwd_mode[i] = TPM_IGMP_FRWD_MODE_DROP;
tpm_db.igmp_def.cpu_queue = 0;
+ tpm_db.igmp_def.igmp_snoop_enable = TPM_FALSE;
tpm_db.igmp_def.mc_lpbk_enable[TPM_IP_VER_4] = TPM_FALSE;
tpm_db.igmp_def.mc_lpbk_enable[TPM_IP_VER_6] = TPM_FALSE;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h
index 0ada80e..a526cfd 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_db.h
@@ -113,7 +113,8 @@
TPM_GMAC_FUNC_WAN,
TPM_GMAC_FUNC_LAN_AND_WAN,
TPM_GMAC_FUNC_VIRT_UNI,
- TPM_GMAC_FUNC_LAN_UNI
+ TPM_GMAC_FUNC_LAN_UNI,
+ TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI /* For Media Convert Loopback mode */
} tpm_db_gmac_func_t;
typedef enum {
@@ -131,6 +132,11 @@
TPM_PNC_RNG_LAST_INIT_TRAP /* Last entry in PnC range is hardcoded to TRAP to CPU */
} tpm_db_pnc_rng_last_ent_t;
+typedef enum {
+ TPM_GMAC1_QUEUE_DATA_TRAFFIC,
+ TPM_GMAC1_QUEUE_MAC_LEARN_TRAFFIC,
+}tpm_db_gmac1_lpk_queue_type_t;
+
typedef tpm_init_sched_t tpm_db_sched_t;
typedef tpm_init_port_admin_t tpm_db_port_admin_t;
typedef tpm_init_port_speed_t tpm_db_port_speed_t;
@@ -155,6 +161,7 @@
typedef tpm_init_ctc_cm_enable_t tpm_db_ctc_cm_enable_t;
typedef tpm_init_split_mod_mode_t tpm_db_split_mod_mode_t;
typedef tpm_ctc_cm_ipv6_parse_win_t tpm_db_ctc_cm_ipv6_parse_win_t;
+typedef tpm_init_ds_mac_based_trunk_enable_t tpm_db_ds_mac_based_trunk_enable_t;
/*************************************************************/
/* DEFINITIONS */
@@ -452,7 +459,7 @@
uint32_t pnc_init_debug_port;
uint32_t oam_loopback_channel_configured;
tpm_db_pon_type_t pon_type;
- tpm_gmacs_enum_t backup_wan;
+ tpm_gmacs_enum_t active_wan;
tpm_db_mh_src_t ds_mh_set_conf;
@@ -475,6 +482,7 @@
/* Structure holds the IGMP/MLD settings */
typedef struct {
+ uint32_t igmp_snoop_enable;
uint32_t frwd_mode[TPM_MAX_NUM_PORTS];
uint32_t cpu_queue;
tpm_mc_filter_mode_t filter_mode;
@@ -511,11 +519,15 @@
uint32_t queue_weight;
uint32_t bucket_size;
uint32_t rate_limit;
+ uint32_t wrr;
} tpm_db_gmac_txq_t;
/*Structure defines the details of a Packet Processor Tx component */
typedef struct {
uint32_t valid; /* Defines if the Tx component is used */
+ uint32_t bucket_size;
+ uint32_t rate_limit;
+ uint32_t prio;
tpm_db_gmac_txq_t tx_queue[TPM_MAX_NUM_TX_QUEUE]; /* Config. of each of the 8 Tx queue of this Tx component */
} tpm_db_gmac_tx_t;
@@ -635,6 +647,7 @@
uint8_t group_addr[16];
uint8_t src_addr[16];
uint8_t ignore_src_addr;
+ uint16_t dest_queue;
uint32_t dest_port_bm;
uint32_t u4_entry;
} tpm_db_ipv6_mc_stream_entry_t;
@@ -702,6 +715,23 @@
} tpm_db_cnm_ipv4_pre_filter_t;
typedef struct {
+ /* api_ent_mem_area backup used for hot swap profile feature */
+ tpm_db_api_entry_t api_ent_mem_area_bak[TPM_DB_API_ENTRIES_TBL_SIZE];
+
+ /* API section backup used for hot swap profile feature */
+ tpm_db_api_section_t api_section_bak[TPM_MAX_NUM_API_SECTIONS];
+
+ /* MC VID setting backup */
+ tpm_mc_vid_cfg_t mc_vid_port_cfg_bak[TPM_MC_VID_NUM_MAX];
+ tpm_db_gmac_tx_t gmac_tx_bak[TPM_MAX_NUM_TX_PORTS];
+
+ uint32_t igmp_proxy_sa_mac[6];
+ uint32_t igmp_proxy_sa_mac_valid;
+
+ bool switch_init;
+}tpm_db_hot_swap_bak_db_t;
+
+typedef struct {
tpm_db_ctc_cm_enable_t enable;
tpm_db_ctc_cm_ipv6_parse_win_t ipv6_parse_win;
/* init value from XML */
@@ -717,12 +747,21 @@
bool switch_init;
bool gmac1_loopback_en;
bool cpu_wan_loopback_en;
+ bool ds_load_bal_en;
+ bool switch_active_wan_en;
tpm_db_ety_dsa_enable_t ety_dsa_enable;
tpm_init_virt_uni_t virt_uni_info;
} tpm_db_func_profile_t;
typedef struct {
+ tpm_limit_mode_t count_mode;
+ uint32_t cir;
+ uint32_t cbs;
+ uint32_t ebs;
+} tpm_db_gmac_lpk_uni_ingr_rate_limit_t;
+
+typedef struct {
/* Physical chip config */
tpm_eth_complex_profile_t eth_cmplx_profile;
tpm_src_port_type_t max_uni_port_nr;
@@ -798,7 +837,6 @@
tpm_db_ipv6_mc_stream_entry_t ipv6_mc_stream[TPM_MC_MAX_STREAM_NUM];
tpm_db_split_mod_t split_mod_conf;
-
/* Array indicates which API's are currently called for synch purposes.
When API is not in called, invalid=-1 When API is called, it will set it's rule_num */
int32_t tpm_busy_apis[TPM_MAX_API_TYPES][TPM_MAX_PARALLEL_API_CALLS];
@@ -807,6 +845,15 @@
/* func profile, based on chip type and board profile */
tpm_db_func_profile_t func_profile;
+ /* MC MAC learning pmt mod index */
+ uint32_t mac_learn_mod_idx;
+
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
+
+ /* To record GMAC UNI egress rate limit */
+ uint32_t gmac_uni_egr_rate_limit[TPM_MAX_NUM_UNI_PORTS];
+ /* To record GMAC LPK UNI ingress rate limit */
+ tpm_db_gmac_lpk_uni_ingr_rate_limit_t gmac_lpk_uni_ingr_rate_limit[TPM_MAX_NUM_UNI_PORTS];
} tpm_db_t;
typedef struct {
@@ -816,6 +863,7 @@
uint16_t vid;
uint8_t group_addr[4];
uint8_t src_addr[4];
+ uint16_t dest_queue;
uint32_t dest_port_bm;
uint32_t u4_entry;
} tpm_db_mc_stream_entry_t;
@@ -866,12 +914,14 @@
int32_t tpm_db_trg_port_switch_port_get(tpm_trg_port_type_t ext_port);
int32_t tpm_db_eth_port_conf_set(tpm_init_eth_port_conf_t *eth_port_conf);
int32_t tpm_db_gmac_conn_conf_set(tpm_init_gmac_conn_conf_t *gmac_port_conf, uint32_t arr_size);
+int32_t tpm_db_gmac_conn_conf_get(tpm_gmacs_enum_t gmac, tpm_init_gmac_conn_conf_t *gmac_port_conf);
/* GMAC Config */
int32_t tpm_db_gmac_tcont_llid_set(uint32_t num_tcont_llid);
int32_t tpm_db_gmac_conn_get(tpm_gmacs_enum_t gmac, tpm_db_gmac_conn_t *gmac_con);
int32_t tpm_db_gmac_mh_en_conf_set(tpm_gmacs_enum_t gmac, uint32_t mh_en);
int32_t tpm_db_gmac_mh_en_conf_get(tpm_gmacs_enum_t gmac, uint32_t *mh_en);
+int32_t tpm_db_target_to_gmac(tpm_pnc_trg_t pnc_target, tpm_gmacs_enum_t *gmac);
int32_t tpm_db_gmac_bm_bufs_conf_set(tpm_gmacs_enum_t gmac, uint32_t large_pkt_buffers,
uint32_t small_pkt_buffers);
int32_t tpm_db_gmac_bm_bufs_conf_get(tpm_gmacs_enum_t gmac, uint32_t *valid, uint32_t *large_pkt_buffers,
@@ -897,7 +947,9 @@
int32_t tpm_db_gmac_tx_val_set(tpm_db_tx_mod_t tx_mod);
uint32_t tpm_db_gmac_tx_val_get(tpm_db_tx_mod_t tx_mod);
-uint32_t tpm_db_gmac_lpk_queue_get(tpm_gmacs_enum_t *gmac, uint32_t *queue_idx);
+uint32_t tpm_db_gmac_lpk_queue_get(tpm_gmacs_enum_t *gmac,
+ uint32_t *queue_idx,
+ tpm_db_gmac1_lpk_queue_type_t queue_type);
/* RX queues Config */
int32_t tpm_db_gmac_rx_val_set(tpm_gmacs_enum_t gmac);
@@ -930,6 +982,8 @@
int32_t tpm_db_igmp_get_port_frwd_mode(uint32_t port, uint32_t *mode);
int32_t tpm_db_igmp_set_cpu_queue(uint32_t queue);
int32_t tpm_db_igmp_get_cpu_queue(uint32_t *queue);
+int32_t tpm_db_igmp_get_snoop_enable(uint32_t *igmp_snoop_enable);
+int32_t tpm_db_igmp_set_snoop_enable(uint32_t igmp_snoop_enable);
/* MISC */
int32_t tpm_db_omci_type_set(uint32_t omci_etype);
@@ -953,8 +1007,7 @@
int32_t tpm_db_ds_mh_set_conf_set(tpm_db_mh_src_t ds_mh_set_conf);
int32_t tpm_db_ds_mh_get_conf_set(tpm_db_mh_src_t *ds_mh_set_conf);
-int32_t tpm_db_backup_wan_set(tpm_gmacs_enum_t backup_wan);
-int32_t tpm_db_backup_wan_get(tpm_gmacs_enum_t *backup_wan);
+int32_t tpm_db_active_wan_set(tpm_gmacs_enum_t active_wan);
tpm_gmacs_enum_t tpm_db_active_wan_get(void);
#if 0 /*Keep to be added in future version */
@@ -1032,6 +1085,9 @@
tpm_db_pnc_conn_t *pnc_con);
int32_t tpm_db_api_tcam_num_get(tpm_api_sections_t api_section, uint32_t rule_idx, uint32_t *tcam_num);
+int32_t tpm_db_api_entry_update_rule_idx(tpm_api_sections_t api_section,
+ uint32_t rule_idx_pre,
+ uint32_t rule_idx_new);
int32_t tpm_db_api_rulenum_get(tpm_api_sections_t api_section, uint32_t rule_idx, uint32_t *rule_num);
int32_t tpm_db_api_rulenum_get_from_l2_key(tpm_api_sections_t api_section, tpm_parse_fields_t parse_rule_bm,
tpm_l2_acl_key_t *l2_key, uint32_t *rule_num);
@@ -1045,6 +1101,7 @@
int32_t tpm_db_api_entry_val_get_next(tpm_api_sections_t api_section, int32_t cur_rule, int32_t *next_rule,
uint32_t *rule_idx, uint32_t *bi_dir, tpm_rule_entry_t *api_data,
tpm_db_mod_conn_t *mod_con, tpm_db_pnc_conn_t *pnc_con);
+int32_t tpm_db_rule_index_set(uint32_t rule_index);
int32_t tpm_db_api_entry_invalidate(tpm_api_sections_t api_section, uint32_t rule_num);
int32_t tpm_db_api_entry_ind_get(tpm_api_sections_t api_section, uint32_t rule_num, int32_t *index);
int32_t tpm_db_api_tcam_rule_idx_get(tpm_api_sections_t api_section, uint32_t tcam_num, uint32_t *rule_idx);
@@ -1116,13 +1173,15 @@
int32_t tpm_db_mod2_get_chain_id_by_pmt_entry(tpm_gmacs_enum_t gmac_port, uint16_t entry_id,
tpm_chain_type_t *chain_type, uint16_t *chain_id);
uint16_t tpm_db_mod2_get_next_free_jump_entry(tpm_gmacs_enum_t gmac_port);
+uint8_t tpm_db_mod2_rollback_chain_entry(tpm_gmacs_enum_t gmac_port, tpm_chain_type_t chain_type,
+ uint16_t chain_id, uint8_t on_failure);
uint16_t tpm_db_mod2_get_next_split_mod_free_jump_entry(tpm_gmacs_enum_t gmac_port, tpm_pkt_mod_t *mod_data);
//void tpm_db_mod2_update_split_mod_next_free_jump_entry(tpm_gmacs_enum_t gmac_port);
int32_t tpm_db_mod2_split_mod_insert_vlan(tpm_gmacs_enum_t port, tpm_pkt_mod_t *mod_data);
int32_t tpm_db_mod2_split_mod_get_vlan_index(tpm_gmacs_enum_t port, tpm_pkt_mod_t *mod_data, uint32_t *index);
int32_t tpm_db_mod2_split_mod_increase_vlan_user_num(tpm_gmacs_enum_t port, tpm_pkt_mod_t *mod_data);
-int32_t tpm_db_mod2_split_mod_decrease_vlan_user_num(tpm_gmacs_enum_t port,
+int32_t tpm_db_mod2_split_mod_decrease_vlan_user_num(tpm_gmacs_enum_t port,
uint32_t vlan_index,
uint32_t *user_num);
void tpm_db_mod2_set_multicast_mh_state(uint8_t enable);
@@ -1334,13 +1393,23 @@
int32_t tpm_db_dec_ipv4_pre_filter_key_user_num(tpm_src_port_type_t src_port, uint32_t key_idx);
int32_t tpm_db_get_ipv4_pre_filter_key_user_num(tpm_src_port_type_t src_port, uint32_t key_idx, uint32_t *num_users);
int32_t tpm_db_set_gmac_rate_limit(tpm_db_tx_mod_t gmac_i,
+ uint32_t bucket_size,
+ uint32_t rate_limit,
+ uint32_t prio);
+int32_t tpm_db_get_gmac_rate_limit(tpm_gmacs_enum_t gmac_i,
+ uint32_t *bucket_size,
+ uint32_t *rate_limit,
+ uint32_t *prio);
+int32_t tpm_db_set_gmac_q_rate_limit(tpm_db_tx_mod_t gmac_i,
uint32_t queue,
uint32_t bucket_size,
- uint32_t rate_limit);
-int32_t tpm_db_get_gmac_rate_limit(tpm_gmacs_enum_t gmac_i,
+ uint32_t rate_limit,
+ uint32_t wrr);
+int32_t tpm_db_get_gmac_q_rate_limit(tpm_gmacs_enum_t gmac_i,
uint32_t queue,
uint32_t *bucket_size,
- uint32_t *rate_limit);
+ uint32_t *rate_limit,
+ uint32_t *wrr);
int32_t tpm_db_fc_conf_set(tpm_init_fc_params_t *port_fc_conf);
int32_t tpm_db_fc_conf_get(tpm_init_fc_params_t *port_fc_conf);
/* switch_init */
@@ -1353,6 +1422,30 @@
void tpm_db_gmac1_lpbk_en_set(bool en);
bool tpm_db_cpu_wan_lpbk_en_get(void);
void tpm_db_cpu_wan_lpbk_en_set(bool en);
+bool tpm_db_ds_load_bal_en_get(void);
+void tpm_db_ds_load_bal_en_set(bool en);
+bool tpm_db_switch_active_wan_en_get(void);
+void tpm_db_switch_active_wan_en_set(bool en);
+int32_t tpm_db_api_data_backup(void);
+int32_t tpm_db_api_data_rcvr(void);
+int32_t tpm_db_api_section_bak_num_entries_get(tpm_api_sections_t api_section, uint32_t *num_entries);
+int32_t tpm_db_api_section_bak_ent_tbl_get(tpm_api_sections_t api_sec, tpm_db_api_entry_t *api_ent_mem_area, uint32_t index);
+int32_t tpm_db_api_entry_bak_get_next(tpm_api_sections_t api_section,
+ int32_t cur_rule,
+ int32_t *next_rule);
+int32_t tpm_db_wan_lan_rate_limit_exchange(void);
+
+int32_t tpm_db_mac_learn_mod_idx_set(uint32_t mod_idx);
+int32_t tpm_db_mac_learn_mod_idx_get(uint32_t *mod_idx);
+int32_t tpm_db_ds_mac_based_trunk_enable_set(tpm_db_ds_mac_based_trunk_enable_t enable);
+int32_t tpm_db_ds_mac_based_trunk_enable_get(tpm_db_ds_mac_based_trunk_enable_t *enable);
+
+int32_t tpm_db_max_uni_port_nr_get(uint32_t *max_uni_port_nr);
+
+int32_t tpm_db_gmac_uni_egr_rate_limit_set(tpm_src_port_type_t port, uint32_t rate_limit);
+int32_t tpm_db_gmac_uni_egr_rate_limit_get(tpm_src_port_type_t port, uint32_t *rate_limit);
+int32_t tpm_db_gmac_lpk_uni_ingr_rate_limit_set(tpm_src_port_type_t port, tpm_db_gmac_lpk_uni_ingr_rate_limit_t rate_limit);
+int32_t tpm_db_gmac_lpk_uni_ingr_rate_limit_get(tpm_src_port_type_t port, tpm_db_gmac_lpk_uni_ingr_rate_limit_t *rate_limit);
#ifdef __cplusplus
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.c
index d484f8d..4cf3632 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.c
@@ -140,7 +140,8 @@
"PON_G0_WAN_G1_INT_SWITCH", "PON_WAN_DUAL_MAC_EXT_SWITCH",
"PON_WAN_G1_MNG_EXT_SWITCH", "PON_WAN_G0_SINGLE_PORT",
"PON_WAN_G1_SINGLE_PORT", "PON_G1_WAN_G0_SINGLE_PORT",
- "PON_G0_WAN_G1_SINGLE_PORT", "PON_WAN_G0_G1_LPBK"};
+ "PON_G0_WAN_G1_SINGLE_PORT", "PON_WAN_G0_G1_LPBK",
+ "TPM_PON_WAN_G0_G1_DUAL_LAN"};
static tpm_pnc_range_lookup_map_t pnc_range_lookup_tbl[TPM_MAX_NUM_RANGES] = {
/* Range_num lu_id last_range valid */
@@ -148,6 +149,7 @@
{TPM_PNC_MAC_LEARN, 0, 1, 1},
{TPM_PNC_CPU_WAN_LPBK_US, 0, 0, 1},
{TPM_PNC_NUM_VLAN_TAGS, 0, 0, 1},
+ {TPM_PNC_DS_LOAD_BALANCE, 0, 0, 1},
{TPM_PNC_MULTI_LPBK, 0, 0, 1},
{TPM_PNC_VIRT_UNI, 0, 0, 1},
{TPM_PNC_LOOP_DET_US, 0, 0, 1},
@@ -156,13 +158,14 @@
{TPM_PNC_IGMP, 2, 0, 1},
{TPM_PNC_IPV4_MC_DS, 2, 0, 1},
{TPM_PNC_IPV4_MAIN, 2, 1, 1},
- {TPM_PNC_TCP_FLAG, 3, 1, 1},
+ {TPM_PNC_IPV4_TCP_FLAG, 3, 1, 1},
{TPM_PNC_TTL, 4, 1, 1},
{TPM_PNC_IPV4_PROTO, 5, 0, 1},
{TPM_PNC_IPV4_FRAG, 5, 0, 1},
{TPM_PNC_IPV4_LEN, 5, 1, 1},
{TPM_PNC_IPV6_NH, 6, 1, 1},
{TPM_PNC_IPV6_L4_MC_DS, 7, 1, 1},
+ {TPM_PNC_IPV6_TCP_FLAG, 7, 1, 1},
{TPM_PNC_IPV6_L4, 7, 1, 1},
{TPM_PNC_IPV6_HOPL, 8, 1, 1},
{TPM_PNC_IPV6_MC_SIP, 8, 1, 1},
@@ -179,6 +182,15 @@
};
+bool tpm_init_check_gmac_init(tpm_gmacs_enum_t gmac_i)
+{
+ /* Check Port Available or not */
+ if (mvNetaPortCheck(gmac_i) || (NULL == mvNetaPortHndlGet(gmac_i))) {
+ return false;
+ }
+ return true;
+}
+
bool tpm_init_gmac_in_gateway_mode(tpm_gmacs_enum_t gmac_i)
{
struct eth_port *pp = NULL;
@@ -275,9 +287,10 @@
tpm_init.eth_cmplx_profile = tpm_init_params->eth_cmplx_profile;
memcpy(&(tpm_init.gmac_port_conf), &(tpm_init_params->gmac_port_conf),
sizeof(tpm_init.gmac_port_conf));
- tpm_init.backup_wan = tpm_init_params->backup_wan;
+ tpm_init.active_wan = tpm_init_params->active_wan;
memcpy(&(tpm_init.split_mod_config), &(tpm_init_params->split_mod_config), sizeof(tpm_init_split_mod_params_t));
tpm_init.switch_init = tpm_init_params->switch_init;
+ tpm_init.ds_mac_based_trunk_enable = tpm_init_params->ds_mac_based_trunk_enable;
}
void tpm_init_pon_type_get(void)
@@ -557,12 +570,18 @@
|| tpm_init.eth_cmplx_profile == TPM_PON_WAN_G1_SINGLE_PORT
|| tpm_init.eth_cmplx_profile == TPM_PON_G1_WAN_G0_SINGLE_PORT
|| tpm_init.eth_cmplx_profile == TPM_PON_G0_WAN_G1_SINGLE_PORT
- || tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK)
+ || tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK
+ || tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_DUAL_LAN)
tpm_init.switch_init = 0;
else
tpm_init.switch_init = 1;
}
}
+void tpm_init_ds_mac_based_trunk_enable_get(void)
+{
+ if (tpm_init.ds_mac_based_trunk_enable == MV_TPM_UN_INITIALIZED_INIT_PARAM)
+ tpm_init.ds_mac_based_trunk_enable = TPM_DS_MAC_BASED_TRUNK_DISABLED;
+}
void tpm_init_ipv6_5t_enable_get(void)
{
@@ -577,7 +596,7 @@
{
uint32_t i,j, off = 0;
char buff[1024];
- uint32_t profile[8]= {0};
+ uint32_t profile[7]= {0};
off += sprintf(buff+off, "\nSelected Eth Complex Profile: %s", prof_str_tlb[tpm_init.eth_cmplx_profile]);
off += sprintf(buff+off, "\nHW enabled options:\n\t");
@@ -596,33 +615,33 @@
break;
case TPM_PON_WAN_G0_INT_SWITCH:
- profile[0] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_FE3PHY | ESC_OPT_GEPHY_SW_P0;
+ profile[0] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY;
profile[1] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_QSGMII;
profile[2] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_QSGMII | ESC_OPT_RGMIIA_SW_P6;
- profile[3] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_FE3PHY | ESC_OPT_RGMIIA_SW_P6;
+ profile[3] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_FE3PHY;
break;
case TPM_PON_WAN_G1_LAN_G0_INT_SWITCH:
- profile[0] = ESC_OPT_RGMIIA_MAC1 | ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY;
- profile[1] = ESC_OPT_RGMIIA_MAC1 | ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_QSGMII;
+ profile[0] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_MAC1 | ESC_OPT_FE3PHY;
+ profile[1] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_MAC1 | ESC_OPT_QSGMII;
profile[2] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_FE3PHY;
- profile[3] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_FE3PHY;
+ profile[3] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_FE3PHY | ESC_OPT_RGMIIA_SW_P6;
profile[4] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_QSGMII;
+ profile[5] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_QSGMII | ESC_OPT_RGMIIA_SW_P6;
break;
case TPM_G0_WAN_G1_INT_SWITCH:
profile[0] = ESC_OPT_RGMIIB_MAC0 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY;
- profile[1] = ESC_OPT_RGMIIB_MAC0 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_QSGMII;
+ profile[1] = ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_RGMIIB_MAC0 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_QSGMII;
break;
case TPM_G1_WAN_G0_INT_SWITCH:
profile[0] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_MAC1 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY;
- profile[1] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_MAC1 | ESC_OPT_FE3PHY;
- profile[2] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_MAC1 | ESC_OPT_QSGMII;
- profile[3] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_FE3PHY;
- profile[4] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_FE3PHY;
- profile[5] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_QSGMII;
- profile[6] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_QSGMII | ESC_OPT_RGMIIA_SW_P6;
+ profile[1] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_RGMIIA_MAC1 | ESC_OPT_QSGMII;
+ profile[2] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_FE3PHY;
+ profile[3] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_FE3PHY;
+ profile[4] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_QSGMII;
+ profile[5] = ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_MAC1 | ESC_OPT_QSGMII | ESC_OPT_RGMIIA_SW_P6;
break;
case TPM_PON_G1_WAN_G0_INT_SWITCH:
@@ -657,11 +676,9 @@
break;
case TPM_PON_G1_WAN_G0_SINGLE_PORT:
- profile[0] = ESC_OPT_RGMIIB_MAC0 | ESC_OPT_RGMIIA_MAC1;
- break;
-
case TPM_PON_G0_WAN_G1_SINGLE_PORT:
profile[0] = ESC_OPT_RGMIIB_MAC0 | ESC_OPT_RGMIIA_MAC1;
+ profile[1] = ESC_OPT_GEPHY_MAC1 | ESC_OPT_RGMIIA_MAC0;
break;
case TPM_PON_WAN_G0_G1_LPBK:
@@ -672,6 +689,9 @@
if (RD_88F6601_MC_ID == mvBoardIdGet())
profile[0] = ESC_OPT_GEPHY_MAC0;
break;
+ case TPM_PON_WAN_G0_G1_DUAL_LAN:
+ profile[0] = ESC_OPT_GEPHY_MAC0 | ESC_OPT_RGMIIA_MAC1;
+ break;
}
off += sprintf(buff+off, "\nProfile supported options:\n");
@@ -692,7 +712,6 @@
TPM_OS_ERROR(TPM_INIT_MOD, "%s", buff);
}
-
static uint32_t tpm_init_eth_cmplx_update_conf(void)
{
uint32_t i;
@@ -701,9 +720,12 @@
if (hwEthCmplx & (ESC_OPT_AUTO | ESC_OPT_ILLEGAL))
{
TPM_OS_ERROR(TPM_INIT_MOD, "\n Illegal values in mvBoardEthComplexConfigGet 0x%x\n", hwEthCmplx);
- return TPM_FAIL;
+ return TPM_FAIL;
}
+ /* do not check SATA */
+ hwEthCmplx &= (~ESC_OPT_SATA);
+
if (tpm_init.eth_cmplx_profile == MV_TPM_UN_INITIALIZED_INIT_PARAM) {
if (TPM_VALID_ENABLED == tpm_init.validation_en){
TPM_OS_ERROR(TPM_INIT_MOD, "\n ETH COMPLEX PROFILE - missing initialization\n");
@@ -711,6 +733,9 @@
}
}
+ if (MV_TPM_UN_INITIALIZED_INIT_PARAM == tpm_init.active_wan)
+ tpm_init.active_wan = TPM_ENUM_PMAC;
+
/* set default values for all ports and GMACs */
switch (tpm_init.eth_cmplx_profile)
{
@@ -718,7 +743,7 @@
if (!VALID_ONLY((ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY), hwEthCmplx) &&
!VALID_ONLY((ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_QSGMII), hwEthCmplx) &&
!VALID_ONLY((ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_QSGMII | ESC_OPT_RGMIIA_SW_P6), hwEthCmplx) &&
- !VALID_ONLY((ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_MAC1_2_SW_P5| ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_FE3PHY), hwEthCmplx))
+ !VALID_ONLY((ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_RGMIIA_SW_P6 | ESC_OPT_FE3PHY), hwEthCmplx))
goto setup_err;
tpm_init.gmac_port_conf[0].valid = TPM_TRUE;
@@ -890,7 +915,7 @@
goto virt_uni_err;
if (!VALID_ONLY((ESC_OPT_RGMIIB_MAC0 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY), hwEthCmplx) &&
- !VALID_ONLY((ESC_OPT_RGMIIB_MAC0 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_QSGMII), hwEthCmplx))
+ !VALID_ONLY((ESC_OPT_RGMIIA_SW_P6 |ESC_OPT_RGMIIB_MAC0 | ESC_OPT_MAC1_2_SW_P5 | ESC_OPT_QSGMII), hwEthCmplx))
goto setup_err;
tpm_init.pon_type = TPM_NONE;
@@ -907,13 +932,13 @@
tpm_init.gmac_port_conf[2].port_src = TPM_SRC_PORT_WAN;
for (i = 0; i < TPM_MAX_NUM_ETH_PORTS; i++)
- if (TPM_TRUE == tpm_init.eth_port_conf[i].valid){
+ if (TPM_TRUE == tpm_init.eth_port_conf[i].valid){
tpm_init.eth_port_conf[i].int_connect = TPM_INTCON_SWITCH;
if (HW_OPT_ON(ESC_OPT_QSGMII, hwEthCmplx) &&
(tpm_init.eth_port_conf[i].switch_port >= 0) &&
(tpm_init.eth_port_conf[i].switch_port <= 3))
- tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_QSGMII;
+ tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_QSGMII;
else if (HW_OPT_ON(ESC_OPT_GEPHY_SW_P0, hwEthCmplx) &&
(tpm_init.eth_port_conf[i].switch_port == 0))
tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_GE_PHY;
@@ -987,7 +1012,6 @@
}
if (VALID_ONLY((ESC_OPT_RGMIIA_MAC1 | ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_GEPHY_SW_P0 | ESC_OPT_FE3PHY), hwEthCmplx) ||
- VALID_ONLY((ESC_OPT_RGMIIA_MAC1 | ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_FE3PHY), hwEthCmplx) ||
VALID_ONLY((ESC_OPT_RGMIIA_MAC1 | ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_QSGMII), hwEthCmplx)){
for (i = 0; i < TPM_MAX_NUM_ETH_PORTS; i++){
if (TPM_FALSE == tpm_init.eth_port_conf[i].valid){
@@ -1019,9 +1043,6 @@
break;
case TPM_PON_G1_WAN_G0_INT_SWITCH:
- if (MV_TPM_UN_INITIALIZED_INIT_PARAM == tpm_init.backup_wan)
- tpm_init.backup_wan = TPM_ENUM_GMAC_1;
-
if (1 == tpm_init.virt_uni_info.enabled)
goto virt_uni_err;
@@ -1091,9 +1112,6 @@
break;
case TPM_PON_G0_WAN_G1_INT_SWITCH:
- if (MV_TPM_UN_INITIALIZED_INIT_PARAM == tpm_init.backup_wan)
- tpm_init.backup_wan = TPM_ENUM_GMAC_1;
-
if (1 == tpm_init.virt_uni_info.enabled)
goto virt_uni_err;
@@ -1114,13 +1132,13 @@
for (i = 0; i < TPM_MAX_NUM_ETH_PORTS; i++)
- if (TPM_TRUE == tpm_init.eth_port_conf[i].valid){
+ if (TPM_TRUE == tpm_init.eth_port_conf[i].valid){
tpm_init.eth_port_conf[i].int_connect = TPM_INTCON_SWITCH;
if (HW_OPT_ON(ESC_OPT_QSGMII, hwEthCmplx) &&
(tpm_init.eth_port_conf[i].switch_port >= 0) &&
(tpm_init.eth_port_conf[i].switch_port <= 3))
- tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_QSGMII;
+ tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_QSGMII;
else if (HW_OPT_ON(ESC_OPT_GEPHY_SW_P0, hwEthCmplx) &&
(tpm_init.eth_port_conf[i].switch_port == 0))
tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_GE_PHY;
@@ -1269,20 +1287,10 @@
if (1 == tpm_init.virt_uni_info.enabled)
goto virt_uni_err;
- if ((TPM_ENUM_GMAC_0 != tpm_init.backup_wan) && (TPM_ENUM_GMAC_1 != tpm_init.backup_wan) &&
- (TPM_ENUM_PMAC != tpm_init.backup_wan)) {
- TPM_OS_ERROR(TPM_INIT_MOD, "\n tpm_init.backup_wan (%x) is not set\n",
- tpm_init.backup_wan);
- goto setup_err;
- }
-
if (!VALID_ONLY((ESC_OPT_RGMIIB_MAC0 | ESC_OPT_RGMIIA_MAC1), hwEthCmplx) &&
!VALID_ONLY((ESC_OPT_GEPHY_MAC1 | ESC_OPT_RGMIIA_MAC0), hwEthCmplx))
goto setup_err;
- if (MV_TPM_UN_INITIALIZED_INIT_PARAM == tpm_init.backup_wan)
- tpm_init.backup_wan = TPM_ENUM_GMAC_1;
-
tpm_init.gmac_port_conf[0].valid = TPM_TRUE;
tpm_init.gmac_port_conf[0].port_src = TPM_SRC_PORT_UNI_0;
@@ -1321,19 +1329,10 @@
if (1 == tpm_init.virt_uni_info.enabled)
goto virt_uni_err;
- if ((TPM_ENUM_GMAC_0 != tpm_init.backup_wan) && (TPM_ENUM_GMAC_1 != tpm_init.backup_wan) &&
- (TPM_ENUM_PMAC != tpm_init.backup_wan)) {
- TPM_OS_ERROR(TPM_INIT_MOD, "\n tpm_init.backup_wan (%x) is not set\n",
- tpm_init.backup_wan);
- goto setup_err;
- }
if (!VALID_ONLY((ESC_OPT_RGMIIB_MAC0 | ESC_OPT_RGMIIA_MAC1), hwEthCmplx) &&
!VALID_ONLY((ESC_OPT_GEPHY_MAC1 | ESC_OPT_RGMIIA_MAC0), hwEthCmplx))
goto setup_err;
- if (MV_TPM_UN_INITIALIZED_INIT_PARAM == tpm_init.backup_wan)
- tpm_init.backup_wan = TPM_ENUM_GMAC_0;
-
tpm_init.gmac_port_conf[0].valid = TPM_TRUE;
tpm_init.gmac_port_conf[0].port_src = TPM_SRC_PORT_WAN;
@@ -1390,12 +1389,45 @@
i = 0;
tpm_init.eth_port_conf[i].valid = TPM_TRUE;
tpm_init.eth_port_conf[i].port_src = TPM_SRC_PORT_UNI_0;
- tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_RGMII1;
+ tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_GE_PHY;
tpm_init.eth_port_conf[i].int_connect = TPM_INTCON_GMAC0;
i++;
for (; i < TPM_MAX_NUM_ETH_PORTS; i++)
tpm_init.eth_port_conf[i].valid = TPM_FALSE;
break;
+ case TPM_PON_WAN_G0_G1_DUAL_LAN:
+ if (1 == tpm_init.virt_uni_info.enabled)
+ goto virt_uni_err;
+
+ /* FIXME - Add correct condition, after answers from lsp team. */
+ /*if (!VALID_ONLY((ESC_OPT_GEPHY_MAC0 | ESC_OPT_RGMIIA_MAC1), hwEthCmplx))
+ goto setup_err;*/
+
+ tpm_init.gmac_port_conf[0].valid = TPM_TRUE;
+ tpm_init.gmac_port_conf[0].port_src = TPM_SRC_PORT_UNI_0;
+ tpm_init.gmac_port_conf[0].conn = TPM_GMAC_CON_GE_PHY;
+
+ tpm_init.gmac_port_conf[1].valid = TPM_TRUE;
+ tpm_init.gmac_port_conf[1].port_src = TPM_SRC_PORT_UNI_1;
+ tpm_init.gmac_port_conf[1].conn = TPM_GMAC_CON_RGMII1;
+
+ tpm_init.gmac_port_conf[2].valid = TPM_TRUE;
+ tpm_init.gmac_port_conf[2].port_src = TPM_SRC_PORT_WAN;
+
+ i = 0;
+ tpm_init.eth_port_conf[i].valid = TPM_TRUE;
+ tpm_init.eth_port_conf[i].port_src = TPM_SRC_PORT_UNI_0;
+ tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_GE_PHY;
+ tpm_init.eth_port_conf[i].int_connect = TPM_INTCON_GMAC0;
+ i++;
+ tpm_init.eth_port_conf[i].valid = TPM_TRUE;
+ tpm_init.eth_port_conf[i].port_src = TPM_SRC_PORT_UNI_1;
+ tpm_init.eth_port_conf[i].chip_connect = TPM_CONN_RGMII1;
+ tpm_init.eth_port_conf[i].int_connect = TPM_INTCON_GMAC1;
+ i++;
+ for (; i < TPM_MAX_NUM_ETH_PORTS; i++)
+ tpm_init.eth_port_conf[i].valid = TPM_FALSE;
+ break;
}
return TPM_OK;
@@ -1502,6 +1534,7 @@
tpm_init_ety_dsa_enable_get();
tpm_init_split_mod_get();
tpm_init_switch_init_get();
+ tpm_init_ds_mac_based_trunk_enable_get();
return (TPM_OK);
}
@@ -1519,116 +1552,118 @@
uint32_t cpu_owner = 0;
/********************************************************************/
- if (tpm_init.validation_en == TPM_VALID_ENABLED) {
- /******************** EPON/GPON system - check num of LLID / TCONT : legal values: 1..8 *********************/
- if ((tpm_init.pon_type == TPM_EPON) || (tpm_init.pon_type == TPM_GPON)) {
- if ((tpm_init.num_tcont_llid <= 0) || (tpm_init.num_tcont_llid > 8)) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n TCONT/LLID: illegal value(%d) => legal values <1-8>.\n",
- tpm_init.num_tcont_llid);
- return (TPM_FAIL);
- }
- }
- /***** EPON case: validate vs .config value for EPON *****/
- if (tpm_init.pon_type == TPM_EPON) {
- min_tcont_llid = min(TPM_GPON_MAX_NUM_OF_T_CONTS, TPM_EPON_MAX_MAC_NUM);
- if (tpm_init.num_tcont_llid > min_tcont_llid) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n LLID: illegal value(%d) => max legal value defined in kernel is %d.\n",
- tpm_init.num_tcont_llid, TPM_EPON_MAX_MAC_NUM);
- return (TPM_FAIL);
- }
- }
- /***** GPON case: validate vs .config value for GPON *****/
- if (tpm_init.pon_type == TPM_GPON) {
- if (tpm_init.num_tcont_llid > TPM_GPON_MAX_NUM_OF_T_CONTS) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n TCONT: illegal value(%d) => max legal value defined in kernel is %d.\n",
- tpm_init.num_tcont_llid, TPM_GPON_MAX_NUM_OF_T_CONTS);
- return (TPM_FAIL);
- }
- }
-#if 0 /*Keep to be added in future version */
- /******************** Debug port setting - validation **********************************/
- if ((tpm_init.deb_port_valid != 0) && (tpm_init.deb_port_valid != 1)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Debug port valid is wrong => legal values <0=invalid/1=valid>. \n");
- return (TPM_FAIL);
- }
- if ((tpm_init.deb_port_valid == 1) &&
- ((tpm_init.deb_port < TPM_SRC_PORT_UNI_0) || (tpm_init.deb_port > TPM_SRC_PORT_UNI_3))) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Bad debug port => legal values <TPM_SRC_PORT_UNI_0-TPM_SRC_PORT_UNI_3>. \n");
- return (TPM_FAIL);
- }
-#endif
- /********************* pon type validation *********************************************/
- /* for FPGA systems - the WAN tech is defined as TPM_NONE */
- if (tpm_init.pon_type > TPM_NONE) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n pon type: wrong init value(%d) => legal values "
- "<%d=TPM_EPON/%d=TPM_GPON/%d=TPM_P2P/%d=TPM_NONE>. \n",
- tpm_init.pon_type, TPM_EPON, TPM_GPON, TPM_P2P, TPM_NONE);
- return (TPM_FAIL);
- }
+ if (tpm_init.validation_en != TPM_VALID_ENABLED)
+ return TPM_OK;
- /********************* CFG PNC PARSE validation *******************************************/
- if ((tpm_init.cfg_pnc_parse < TPM_CFG_PNC_PARSE_DISABLED)
- || (tpm_init.cfg_pnc_parse > TPM_CFG_PNC_PARSE_ENABLED)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n CFG PNC parse: wrong init value(%d) => legal values <0=DISABLED/1=ENABLED. \n",
- tpm_init.cfg_pnc_parse);
+ /******************** EPON/GPON system - check num of LLID / TCONT : legal values: 1..8 *********************/
+ if ((tpm_init.pon_type == TPM_EPON) || (tpm_init.pon_type == TPM_GPON)) {
+ if ((tpm_init.num_tcont_llid <= 0) || (tpm_init.num_tcont_llid > 8)) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n TCONT/LLID: illegal value(%d) => legal values <1-8>.\n",
+ tpm_init.num_tcont_llid);
return (TPM_FAIL);
}
- /* get the config_pnc_parser value */
- config_pnc_parser_val = mv_eth_ctrl_pnc_get();
+ }
+ /***** EPON case: validate vs .config value for EPON *****/
+ if (tpm_init.pon_type == TPM_EPON) {
+ min_tcont_llid = min(TPM_GPON_MAX_NUM_OF_T_CONTS, TPM_EPON_MAX_MAC_NUM);
+ if (tpm_init.num_tcont_llid > min_tcont_llid) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n LLID: illegal value(%d) => max legal value defined in kernel is %d.\n",
+ tpm_init.num_tcont_llid, TPM_EPON_MAX_MAC_NUM);
+ return (TPM_FAIL);
+ }
+ }
+ /***** GPON case: validate vs .config value for GPON *****/
+ if (tpm_init.pon_type == TPM_GPON) {
+ if (tpm_init.num_tcont_llid > TPM_GPON_MAX_NUM_OF_T_CONTS) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n TCONT: illegal value(%d) => max legal value defined in kernel is %d.\n",
+ tpm_init.num_tcont_llid, TPM_GPON_MAX_NUM_OF_T_CONTS);
+ return (TPM_FAIL);
+ }
+ }
+#if 0 /*Keep to be added in future version */
+/******************** Debug port setting - validation **********************************/
+ if ((tpm_init.deb_port_valid != 0) && (tpm_init.deb_port_valid != 1)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Debug port valid is wrong => legal values <0=invalid/1=valid>. \n");
+ return (TPM_FAIL);
+ }
+ if ((tpm_init.deb_port_valid == 1) &&
+ ((tpm_init.deb_port < TPM_SRC_PORT_UNI_0) || (tpm_init.deb_port > TPM_SRC_PORT_UNI_3))) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Bad debug port => legal values <TPM_SRC_PORT_UNI_0-TPM_SRC_PORT_UNI_3>. \n");
+ return (TPM_FAIL);
+ }
+#endif
+ /********************* pon type validation *********************************************/
+ /* for FPGA systems - the WAN tech is defined as TPM_NONE */
+ if (tpm_init.pon_type > TPM_NONE) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n pon type: wrong init value(%d) => legal values "
+ "<%d=TPM_EPON/%d=TPM_GPON/%d=TPM_P2P/%d=TPM_NONE>. \n",
+ tpm_init.pon_type, TPM_EPON, TPM_GPON, TPM_P2P, TPM_NONE);
+ return (TPM_FAIL);
+ }
+
+ /********************* CFG PNC PARSE validation *******************************************/
+ if ((tpm_init.cfg_pnc_parse < TPM_CFG_PNC_PARSE_DISABLED)
+ || (tpm_init.cfg_pnc_parse > TPM_CFG_PNC_PARSE_ENABLED)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n CFG PNC parse: wrong init value(%d) => legal values <0=DISABLED/1=ENABLED. \n",
+ tpm_init.cfg_pnc_parse);
+ return (TPM_FAIL);
+ }
+ /* get the config_pnc_parser value */
+ config_pnc_parser_val = mv_eth_ctrl_pnc_get();
/* logical validation */
#ifdef CONFIG_MV_ETH_PNC
- if (tpm_init.cfg_pnc_parse == 0) {
- if (config_pnc_parser_val == 0) {
- /* the intention is to give the control to mv neta PNC configuration
- do not permit moving from 0 to 1 */
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n CFG PNC bad value: PNC in LSP cannot move from 0 to 1 \n");
- return (TPM_FAIL);
- } else {
- /* config_pnc_parser == 1 */
- /* nothing to do - the control is in LSP config */
- }
- }
- if (tpm_init.cfg_pnc_parse == 1) {
- if (config_pnc_parser_val == 0) {
- /* nothing to do - the control is in TPM */
- } else { /* config_pnc_parser == 1 */
- /* set the config_pnc_parser to 0 - control is set to TPM */
- rc = mv_eth_ctrl_pnc(0);
- if (rc != 0) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Failed to SET the config PNC parse parameter. \n");
- return (TPM_FAIL);
- }
- }
- }
-#else
- /* if compilation flag is turned off - there are no relevant functions for PNC_PARSER
- therefore do not permit the flag to be 0 - meaning the LSP is taking the responsibility */
- if (tpm_init.cfg_pnc_parse == 0) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n CFG PNC bad value: PNC in LSP does not support PNC PARSER \n");
+ if (tpm_init.cfg_pnc_parse == 0) {
+ if (config_pnc_parser_val == 0) {
+ /* the intention is to give the control to mv neta PNC configuration
+ do not permit moving from 0 to 1 */
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n CFG PNC bad value: PNC in LSP cannot move from 0 to 1 \n");
return (TPM_FAIL);
} else {
- if (config_pnc_parser_val == 0) {
- /*do nothing */
- } else {
- /* set the config_pnc_parser to 0 - control is set to TPM */
- rc = mv_eth_ctrl_pnc(0);
- if (rc != 0) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Failed to SET the config PNC parse parameter. \n");
- return (TPM_FAIL);
- }
+ /* config_pnc_parser == 1 */
+ /* nothing to do - the control is in LSP config */
+ }
+ }
+ if (tpm_init.cfg_pnc_parse == 1) {
+ if (config_pnc_parser_val == 0) {
+ /* nothing to do - the control is in TPM */
+ } else { /* config_pnc_parser == 1 */
+ /* set the config_pnc_parser to 0 - control is set to TPM */
+ rc = mv_eth_ctrl_pnc(0);
+ if (rc != 0) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Failed to SET the config PNC parse parameter. \n");
+ return (TPM_FAIL);
}
}
+ }
+#else
+ /* if compilation flag is turned off - there are no relevant functions for PNC_PARSER
+ therefore do not permit the flag to be 0 - meaning the LSP is taking the responsibility */
+ if (tpm_init.cfg_pnc_parse == 0) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n CFG PNC bad value: PNC in LSP does not support PNC PARSER \n");
+ return (TPM_FAIL);
+ } else {
+ if (config_pnc_parser_val == 0) {
+ /*do nothing */
+ } else {
+ /* set the config_pnc_parser to 0 - control is set to TPM */
+ rc = mv_eth_ctrl_pnc(0);
+ if (rc != 0) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Failed to SET the config PNC parse parameter. \n");
+ return (TPM_FAIL);
+ }
+ }
+ }
#endif
/********************* CPU loopback type validation ********************************************/
@@ -1639,451 +1674,485 @@
tpm_init.cpu_loopback);
return (TPM_FAIL);
}
+ if (tpm_init.cpu_loopback == TPM_CPU_LOOPBACK_ENABLED) {
+ if (tpm_init.gmac_port_conf[1].valid == TPM_TRUE &&
+ tpm_init.gmac_port_conf[1].port_src != TPM_SRC_PORT_ILLEGAL) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n CPU loopback not supported for GMAC function \n");
+ return (TPM_FAIL);
+ }
+ }
/********************* TRACE DEBUG INFO validation *******************************************/
- if (tpm_init.trace_debug_info == 0) {
- TPM_OS_WARN(TPM_INIT_MOD,
- "\n TRACE DEBUG info: init value is %d - no ERRORs will be displayed. \n ",
- tpm_init.trace_debug_info);
- }
+ if (tpm_init.trace_debug_info == 0) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ "\n TRACE DEBUG info: init value is %d - no ERRORs will be displayed. \n ",
+ tpm_init.trace_debug_info);
+ }
/********************* IGMP snooping validation *********************************************/
- if ((tpm_init.igmp_snoop != 0) && (tpm_init.igmp_snoop != 1)) {
+ if ((tpm_init.igmp_snoop != 0) && (tpm_init.igmp_snoop != 1)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n IGMP snooping: wrong init value(%d) => legal values <0=disabled/1=enabled>. \n",
+ tpm_init.igmp_snoop);
+ return (TPM_FAIL);
+ }
+ if (tpm_init.igmp_snoop == 1) {
+ if (tpm_init.igmp_cpu_queue > 7) {
TPM_OS_FATAL(TPM_INIT_MOD,
- "\n IGMP snooping: wrong init value(%d) => legal values <0=disabled/1=enabled>. \n",
- tpm_init.igmp_snoop);
+ "\n IGMP snooping: wrong CPU queue(%d) => legal values <0-7>. \n",
+ tpm_init.igmp_cpu_queue);
return (TPM_FAIL);
}
- if (tpm_init.igmp_snoop == 1) {
- if (tpm_init.igmp_cpu_queue > 7) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n IGMP snooping: wrong CPU queue(%d) => legal values <0-7>. \n",
- tpm_init.igmp_cpu_queue);
- return (TPM_FAIL);
- }
- }
+ }
/********************* Multicast validation *********************************************/
- if (tpm_init.mc_setting.per_uni_vlan_xlat) {
- if (tpm_init.mc_setting.filter_mode != TPM_MC_COMBINED_IP_MAC_FILTER) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n multicast per uni vlan translation is not supported in filter_mode (%d). \n",
- tpm_init.mc_setting.filter_mode);
- return (TPM_FAIL);
- }
+ if (tpm_init.mc_setting.per_uni_vlan_xlat) {
+ if (tpm_init.mc_setting.filter_mode != TPM_MC_COMBINED_IP_MAC_FILTER) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n multicast per uni vlan translation is not supported in filter_mode (%d). \n",
+ tpm_init.mc_setting.filter_mode);
+ return (TPM_FAIL);
+ }
#if 0
- if (tpm_init.mc_setting.igmp_mode == TPM_MC_IGMP_SNOOPING && tpm_init.mc_setting.mc_pppoe_enable) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n multicast per uni vlan translation is not supported "
- "in igmp snooping over pppoe. \n");
- return(TPM_FAIL);
- }
+ if (tpm_init.mc_setting.igmp_mode == TPM_MC_IGMP_SNOOPING && tpm_init.mc_setting.mc_pppoe_enable) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n multicast per uni vlan translation is not supported "
+ "in igmp snooping over pppoe. \n");
+ return(TPM_FAIL);
+ }
#endif
- }
+ }
- /* check that igmp_cpu_queue is CPU's reserved queue */
- /* oct*>>> to do - if per system Q6 is the IGMP CPU - check in all GMACs that Q6 is of CPU ownership */
+ /* check that igmp_cpu_queue is CPU's reserved queue */
+ /* oct*>>> to do - if per system Q6 is the IGMP CPU - check in all GMACs that Q6 is of CPU ownership */
- if (tpm_init.mc_setting.mc_hwf_queue > 7) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n MC setting: wrong MC HWF queue(%d) => legal values <0-7>. \n",
- tpm_init.mc_setting.mc_hwf_queue);
- return (TPM_FAIL);
- }
+ if (tpm_init.mc_setting.mc_hwf_queue > 7) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n MC setting: wrong MC HWF queue(%d) => legal values <0-7>. \n",
+ tpm_init.mc_setting.mc_hwf_queue);
+ return (TPM_FAIL);
+ }
- if (tpm_init.mc_setting.mc_cpu_queue > 7) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n MC setting: wrong MC CPU queue(%d) => legal values <0-7>. \n",
- tpm_init.mc_setting.mc_cpu_queue);
- return (TPM_FAIL);
- }
+ if (tpm_init.mc_setting.mc_cpu_queue > 7) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n MC setting: wrong MC CPU queue(%d) => legal values <0-7>. \n",
+ tpm_init.mc_setting.mc_cpu_queue);
+ return (TPM_FAIL);
+ }
/********************** GMAC_0 connectivity validation *************************************/
- if ((tpm_init.gmac_port_conf[0].conn < TPM_GMAC_CON_DISC) || (tpm_init.gmac_port_conf[0].conn > TPM_GMAC_CON_GE_PHY)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC_0 connectivity: wrong init value(%d) => legal values <0-7> \n",
- tpm_init.gmac_port_conf[0].conn);
- return (TPM_FAIL);
- }
+ if ((tpm_init.gmac_port_conf[0].conn < TPM_GMAC_CON_DISC) || (tpm_init.gmac_port_conf[0].conn > TPM_GMAC_CON_GE_PHY)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC_0 connectivity: wrong init value(%d) => legal values <0-7> \n",
+ tpm_init.gmac_port_conf[0].conn);
+ return (TPM_FAIL);
+ }
/********************** GMAC_1 connectivity validation *************************************/
- if ((tpm_init.gmac_port_conf[1].conn < TPM_GMAC_CON_DISC) || (tpm_init.gmac_port_conf[1].conn > TPM_GMAC_CON_GE_PHY)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC_1 connectivity: wrong init value(%d) => legal values <0-7> \n",
- tpm_init.gmac_port_conf[1].conn);
- return (TPM_FAIL);
- }
+ if ((tpm_init.gmac_port_conf[1].conn < TPM_GMAC_CON_DISC) || (tpm_init.gmac_port_conf[1].conn > TPM_GMAC_CON_GE_PHY)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC_1 connectivity: wrong init value(%d) => legal values <0-7> \n",
+ tpm_init.gmac_port_conf[1].conn);
+ return (TPM_FAIL);
+ }
/********************** GMAC_0 MH enable validation *************************************/
- if ((tpm_init.gmac0_mh_en != 0) && (tpm_init.gmac0_mh_en != 1)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC_0 MH enable: wrong init value(%d) => legal values <0=disabled,1=enabled> \n",
- tpm_init.gmac0_mh_en);
- return (TPM_FAIL);
- }
- rc = tpm_init_check_gmac_mh_gtwy_mode(TPM_ENUM_GMAC_0, tpm_init.gmac0_mh_en);
- if (rc != TPM_OK) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC_0 is in GateWay mode, MH can not be disabled\n");
- return (TPM_FAIL);
- }
+ if ((tpm_init.gmac0_mh_en != 0) && (tpm_init.gmac0_mh_en != 1)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC_0 MH enable: wrong init value(%d) => legal values <0=disabled,1=enabled> \n",
+ tpm_init.gmac0_mh_en);
+ return (TPM_FAIL);
+ }
+ rc = tpm_init_check_gmac_mh_gtwy_mode(TPM_ENUM_GMAC_0, tpm_init.gmac0_mh_en);
+ if (rc != TPM_OK) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC_0 is in GateWay mode, MH can not be disabled\n");
+ return (TPM_FAIL);
+ }
/********************** GMAC_1 MH enable validation *************************************/
- if ((tpm_init.gmac1_mh_en != 0) && (tpm_init.gmac1_mh_en != 1)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC_1 MH enable: wrong init value(%d) => legal values <0=disabled,1=enabled> \n",
- tpm_init.gmac1_mh_en);
- return (TPM_FAIL);
- }
- rc = tpm_init_check_gmac_mh_gtwy_mode(TPM_ENUM_GMAC_1, tpm_init.gmac1_mh_en);
- if (rc != TPM_OK) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC_1 is in GateWay mode, MH can not be disabled\n");
- return (TPM_FAIL);
- }
+ if ((tpm_init.gmac1_mh_en != 0) && (tpm_init.gmac1_mh_en != 1)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC_1 MH enable: wrong init value(%d) => legal values <0=disabled,1=enabled> \n",
+ tpm_init.gmac1_mh_en);
+ return (TPM_FAIL);
+ }
+ rc = tpm_init_check_gmac_mh_gtwy_mode(TPM_ENUM_GMAC_1, tpm_init.gmac1_mh_en);
+ if (rc != TPM_OK) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC_1 is in GateWay mode, MH can not be disabled\n");
+ return (TPM_FAIL);
+ }
/********************** GMAC_ Buffer Mngmt Pool_sizes validation ***********************************/
- for (i = 0; i < sizeof(tpm_init.gmac_bp_bufs) / sizeof(tpm_init_gmac_bufs_t); i++) {
- if (tpm_init.gmac_bp_bufs[i].valid) {
- if (((tpm_init.gmac_bp_bufs[i].large_pkt_buffers != 0) &&
- (tpm_init.gmac_bp_bufs[i].large_pkt_buffers < MV_BM_POOL_CAP_MIN)) ||
- ((tpm_init.gmac_bp_bufs[i].small_pkt_buffers != 0) &&
- (tpm_init.gmac_bp_bufs[i].small_pkt_buffers < MV_BM_POOL_CAP_MIN))) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n GMAC%d BM Pool has too small buffer assigment "
- "large_buf %d, small_buf %d\n",
- i, tpm_init.gmac_bp_bufs[i].large_pkt_buffers,
- tpm_init.gmac_bp_bufs[i].small_pkt_buffers);
- return (TPM_FAIL);
- }
+ for (i = 0; i < sizeof(tpm_init.gmac_bp_bufs) / sizeof(tpm_init_gmac_bufs_t); i++) {
+ if (tpm_init.gmac_bp_bufs[i].valid) {
+ if (((tpm_init.gmac_bp_bufs[i].large_pkt_buffers != 0) &&
+ (tpm_init.gmac_bp_bufs[i].large_pkt_buffers < MV_BM_POOL_CAP_MIN)) ||
+ ((tpm_init.gmac_bp_bufs[i].small_pkt_buffers != 0) &&
+ (tpm_init.gmac_bp_bufs[i].small_pkt_buffers < MV_BM_POOL_CAP_MIN))) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n GMAC%d BM Pool has too small buffer assigment "
+ "large_buf %d, small_buf %d\n",
+ i, tpm_init.gmac_bp_bufs[i].large_pkt_buffers,
+ tpm_init.gmac_bp_bufs[i].small_pkt_buffers);
+ return (TPM_FAIL);
}
}
+ }
/********************** PNC MH enabled allow for DS *************************************/
- if ((tpm_init.ds_mh_set_conf != 0) && (tpm_init.ds_mh_set_conf != 1)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n PNC - DS MH allow: wrong init value(%d) => "
- "legal values <0=MH not allowed/DS,1=MH allowed/DS> \n",
- tpm_init.ds_mh_set_conf);
+ if ((tpm_init.ds_mh_set_conf != 0) && (tpm_init.ds_mh_set_conf != 1)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n PNC - DS MH allow: wrong init value(%d) => "
+ "legal values <0=MH not allowed/DS,1=MH allowed/DS> \n",
+ tpm_init.ds_mh_set_conf);
+ return (TPM_FAIL);
+ }
+
+ if (tpm_init.port_fc_conf.enabled) {
+ MV_U32 device_id = mvCtrlModelGet();
+
+ if (device_id != MV_6601_DEV_ID) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n port SW Flow-Control is not supported by this device");
return (TPM_FAIL);
}
- if (tpm_init.port_fc_conf.enabled) {
- MV_U32 device_id = mvCtrlModelGet();
-
- if (device_id != MV_6601_DEV_ID) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n port SW Flow-Control is not supported by this device");
- return (TPM_FAIL);
- }
-
- if ((tpm_init.port_fc_conf.port > TPM_MAX_GMAC) ||
- (tpm_init.port_fc_conf.tgt_port > TPM_MAX_GMAC) ||
- (tpm_init.port_fc_conf.tx_port > TPM_MAX_GMAC)){
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n port SW Flow-Control invalid port number:"
- "port=%d tgt_port=%d tx_port=%d\n",
- tpm_init.port_fc_conf.port,
- tpm_init.port_fc_conf.tgt_port,
- tpm_init.port_fc_conf.tx_port);
- return (TPM_FAIL);
- }
-
- if (tpm_init.port_fc_conf.tx_queue >= TPM_MAX_NUM_TX_QUEUE){
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n port SW Flow-Control invalid port number: tx_queue=%d",
- tpm_init.port_fc_conf.tx_queue);
- return (TPM_FAIL);
- }
+ if ((tpm_init.port_fc_conf.port > TPM_MAX_GMAC) ||
+ (tpm_init.port_fc_conf.tgt_port > TPM_MAX_GMAC) ||
+ (tpm_init.port_fc_conf.tx_port > TPM_MAX_GMAC)){
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n port SW Flow-Control invalid port number:"
+ "port=%d tgt_port=%d tx_port=%d\n",
+ tpm_init.port_fc_conf.port,
+ tpm_init.port_fc_conf.tgt_port,
+ tpm_init.port_fc_conf.tx_port);
+ return (TPM_FAIL);
}
+
+ if (tpm_init.port_fc_conf.tx_queue >= TPM_MAX_NUM_TX_QUEUE){
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n port SW Flow-Control invalid port number: tx_queue=%d",
+ tpm_init.port_fc_conf.tx_queue);
+ return (TPM_FAIL);
+ }
+ }
/********************** ethernet ports validation ******************************************/
- for (i = 0; i < TPM_MAX_NUM_ETH_PORTS; i++) {
- if (tpm_init.eth_port_conf[i].valid == TPM_TRUE) {
- if ((tpm_init.eth_port_conf[i].chip_connect < TPM_CONN_DISC) ||
- (tpm_init.eth_port_conf[i].chip_connect > TPM_CONN_RGMII2)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n ETH_port[(%d)]: chip_connect - wrong init value(%d)"
- " => legal values <0-5> \n",
- i, tpm_init.eth_port_conf[i].chip_connect);
- return (TPM_FAIL);
- }
- if ((tpm_init.eth_port_conf[i].int_connect < TPM_INTCON_GMAC0) ||
- (tpm_init.eth_port_conf[i].int_connect > TPM_INTCON_SWITCH)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n ETH_port[(%d)]: chip_connect - wrong init "
- "value(%d) => legal values <0-2> \n",
- i, tpm_init.eth_port_conf[i].int_connect);
- return (TPM_FAIL);
- }
- if ((tpm_init.eth_port_conf[i].int_connect == TPM_INTCON_SWITCH) &&
- (tpm_init.eth_port_conf[i].switch_port > 6)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n ETH_port[(%d)]: switch_port - wrong init "
- "value(%d) => legal values <0-6> \n",
- i, tpm_init.eth_port_conf[i].switch_port);
- return (TPM_FAIL);
- }
+ for (i = 0; i < TPM_MAX_NUM_ETH_PORTS; i++) {
+ if (tpm_init.eth_port_conf[i].valid == TPM_TRUE) {
+ if ((tpm_init.eth_port_conf[i].chip_connect < TPM_CONN_DISC) ||
+ (tpm_init.eth_port_conf[i].chip_connect > TPM_CONN_RGMII2)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n ETH_port[(%d)]: chip_connect - wrong init value(%d)"
+ " => legal values <0-5> \n",
+ i, tpm_init.eth_port_conf[i].chip_connect);
+ return (TPM_FAIL);
+ }
+ if ((tpm_init.eth_port_conf[i].int_connect < TPM_INTCON_GMAC0) ||
+ (tpm_init.eth_port_conf[i].int_connect > TPM_INTCON_SWITCH)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n ETH_port[(%d)]: chip_connect - wrong init "
+ "value(%d) => legal values <0-2> \n",
+ i, tpm_init.eth_port_conf[i].int_connect);
+ return (TPM_FAIL);
+ }
+ if ((tpm_init.eth_port_conf[i].int_connect == TPM_INTCON_SWITCH) &&
+ (tpm_init.eth_port_conf[i].switch_port > 6)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n ETH_port[(%d)]: switch_port - wrong init "
+ "value(%d) => legal values <0-6> \n",
+ i, tpm_init.eth_port_conf[i].switch_port);
+ return (TPM_FAIL);
+ }
- if ((tpm_init.eth_port_conf[i].int_connect == TPM_INTCON_SWITCH) &&
- (tpm_init.eth_port_conf[i].switch_port <= 6)) {
- num_uni_ports++;
- }
+ if ((tpm_init.eth_port_conf[i].int_connect == TPM_INTCON_SWITCH) &&
+ (tpm_init.eth_port_conf[i].switch_port <= 6)) {
+ num_uni_ports++;
}
}
+ }
/********************* Virtual UNI validation *************************************/
- if ((tpm_init.virt_uni_info.enabled < TPM_VIRT_UNI_DISABLED) ||
- (tpm_init.virt_uni_info.enabled > TPM_VIRT_UNI_ENABLED)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Virtual UNI: wrong init value(%d) => legal "
- "values <0=TPM_WIFI_VIRT_UNI_DISABLED/1=TPM_VIRT_UNI_ENABLED. \n",
- tpm_init.virt_uni_info.enabled);
- return (TPM_FAIL);
- }
- if (tpm_init.virt_uni_info.enabled == TPM_VIRT_UNI_ENABLED) {
- /*oct* - open this validation in next LSP - meantime it works only on RD */
+ if ((tpm_init.virt_uni_info.enabled < TPM_VIRT_UNI_DISABLED) ||
+ (tpm_init.virt_uni_info.enabled > TPM_VIRT_UNI_ENABLED)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Virtual UNI: wrong init value(%d) => legal "
+ "values <0=TPM_WIFI_VIRT_UNI_DISABLED/1=TPM_VIRT_UNI_ENABLED. \n",
+ tpm_init.virt_uni_info.enabled);
+ return (TPM_FAIL);
+ }
+ if (tpm_init.virt_uni_info.enabled == TPM_VIRT_UNI_ENABLED) {
+ /*oct* - open this validation in next LSP - meantime it works only on RD */
#if 0
- /* check that GMAC1 is connected to internal switch port #5 */
- rc = mvBoardIsInternalSwitchConnected(1);
- if (rc == 0) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n WiFi virtual UNI: feature ENABLED - GMAC1 "
- "is NOT HW-connected to Switch port #5. \n");
- return (TPM_FAIL);
- }
-#endif
- /* fail eth complex other than dual MAC */
- if (TPM_PON_WAN_DUAL_MAC_INT_SWITCH != tpm_init.eth_cmplx_profile)
- {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Virtual UNI suppoerted only by ethernet Complex %x (used %x) \n",
- TPM_PON_WAN_DUAL_MAC_INT_SWITCH, tpm_init.eth_cmplx_profile);
- return (TPM_FAIL);
- }
-
- /* currently support only UNI_VIRT port for WIFI virtual UNI port */
- if (tpm_init.virt_uni_info.uni_port != TPM_SRC_PORT_UNI_VIRT) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Virtual UNI: wrong port value(%d) => "
- "legal values <0-%d> - default value<%d. \n",
- tpm_init.virt_uni_info.uni_port, TPM_SRC_PORT_UNI_VIRT ,TPM_SRC_PORT_UNI_VIRT);
- return (TPM_FAIL);
- }
-
- num_uni_ports++;
-
- /* if feature enabled and missing PNC range in the xml - return ERROR */
- for (i = 0; i < TPM_MAX_NUM_RANGES; i++) {
- if (tpm_init.pnc_range[i].range_num == TPM_PNC_VIRT_UNI) {
- if (tpm_init.pnc_range[i].valid != TPM_TRUE) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Virtual UNI: feature ENABLED - missing "
- "PNC range <TPM_PNC_VIRT_UNI> in XML config file. \n");
- return (TPM_FAIL);
- }
- }
- } /* for */
- /* TODO: check all GMAC1 TX queues are owned by CPU */
-
- }
-
- /*if wifi feature enabled - end validation */
- /********************* PNC validations *****************************************************/
- found_ipv4_pre = found_cnm_main = TPM_FALSE;
- ipv4_pre_size = cnm_main_size = 0;
-
- /* Validate total number of Pnc Entries */
- for (i = 0; i < TPM_MAX_NUM_RANGES; i++) {
- if (tpm_init.pnc_range[i].valid == TPM_TRUE) {
- j += tpm_init.pnc_range[i].range_size;
- if (tpm_init.pnc_range[i].range_num >= TPM_MAX_NUM_RANGES) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "PNC range[%d]: range_num - wrong init value(%d) => "
- "legal values <0-%d>\n",
- i, tpm_init.pnc_range[i].range_num, TPM_MAX_RANGE);
- return (TPM_FAIL);
- }
- if (tpm_init.pnc_range[i].range_type > TPM_RANGE_TYPE_TABLE) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "PNC range[%d]: range_type - wrong init value(%d) => "
- "legal values <0=TYPE_ACL,1=TYPE_TABLE>\n",
- i, tpm_init.pnc_range[i].range_type);
- return (TPM_FAIL);
- }
- if ((tpm_init.pnc_range[i].cntr_grp < 0) || (tpm_init.pnc_range[i].cntr_grp > 3)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "PNC range[%d] cntr_grp - wrong init value(%d) => legal values <0-3>\n",
- i, tpm_init.pnc_range[i].cntr_grp);
- return (TPM_FAIL);
- }
- if ((tpm_init.pnc_range[i].lu_mask < 0) || (tpm_init.pnc_range[i].lu_mask > 1)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "PNC range[%d] lu_mask - wrong init value(%d) => legal values <0-1>\n",
- i, tpm_init.pnc_range[i].lu_mask);
- return (TPM_FAIL);
- }
- if (tpm_init.pnc_range[i].range_num == TPM_PNC_CNM_IPV4_PRE) {
- found_ipv4_pre = TPM_TRUE;
- ipv4_pre_size = tpm_init.pnc_range[i].range_size;
- } else if (tpm_init.pnc_range[i].range_num == TPM_PNC_CNM_MAIN) {
- found_cnm_main = TPM_TRUE;
- cnm_main_size = tpm_init.pnc_range[i].range_size;
- }
- }
- }
- if (j > TPM_PNC_SIZE) {
- TPM_OS_FATAL(TPM_INIT_MOD, "Sum of Pnc ranges(%d) is bigger than PnC size(%d)\n", j,
- TPM_PNC_SIZE);
+ /* check that GMAC1 is connected to internal switch port #5 */
+ rc = mvBoardIsInternalSwitchConnected(1);
+ if (rc == 0) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n WiFi virtual UNI: feature ENABLED - GMAC1 "
+ "is NOT HW-connected to Switch port #5. \n");
return (TPM_FAIL);
}
+#endif
+ /* fail eth complex other than dual MAC */
+ if (TPM_PON_WAN_DUAL_MAC_INT_SWITCH != tpm_init.eth_cmplx_profile)
+ {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Virtual UNI suppoerted only by ethernet Complex %x (used %x) \n",
+ TPM_PON_WAN_DUAL_MAC_INT_SWITCH, tpm_init.eth_cmplx_profile);
+ return (TPM_FAIL);
+ }
+
+ /* currently support only UNI_VIRT port for WIFI virtual UNI port */
+ if (tpm_init.virt_uni_info.uni_port != TPM_SRC_PORT_UNI_VIRT) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Virtual UNI: wrong port value(%d) => "
+ "legal values <0-%d> - default value<%d. \n",
+ tpm_init.virt_uni_info.uni_port, TPM_SRC_PORT_UNI_VIRT ,TPM_SRC_PORT_UNI_VIRT);
+ return (TPM_FAIL);
+ }
+
+ num_uni_ports++;
+
+ /* if feature enabled and missing PNC range in the xml - return ERROR */
+ for (i = 0; i < TPM_MAX_NUM_RANGES; i++) {
+ if (tpm_init.pnc_range[i].range_num == TPM_PNC_VIRT_UNI) {
+ if (tpm_init.pnc_range[i].valid != TPM_TRUE) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Virtual UNI: feature ENABLED - missing "
+ "PNC range <TPM_PNC_VIRT_UNI> in XML config file. \n");
+ return (TPM_FAIL);
+ }
+ }
+ } /* for */
+ /* TODO: check all GMAC1 TX queues are owned by CPU */
+
+ }
+
+ /*if wifi feature enabled - end validation */
+ /********************* PNC validations *****************************************************/
+ found_ipv4_pre = found_cnm_main = TPM_FALSE;
+ ipv4_pre_size = cnm_main_size = 0;
+
+ /* Validate total number of Pnc Entries */
+ for (i = 0; i < TPM_MAX_NUM_RANGES; i++) {
+ if (tpm_init.pnc_range[i].valid == TPM_TRUE) {
+ j += tpm_init.pnc_range[i].range_size;
+ if (tpm_init.pnc_range[i].range_num >= TPM_MAX_NUM_RANGES) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "PNC range[%d]: range_num - wrong init value(%d) => "
+ "legal values <0-%d>\n",
+ i, tpm_init.pnc_range[i].range_num, TPM_MAX_RANGE);
+ return (TPM_FAIL);
+ }
+ if (tpm_init.pnc_range[i].range_type > TPM_RANGE_TYPE_TABLE) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "PNC range[%d]: range_type - wrong init value(%d) => "
+ "legal values <0=TYPE_ACL,1=TYPE_TABLE>\n",
+ i, tpm_init.pnc_range[i].range_type);
+ return (TPM_FAIL);
+ }
+ if ((tpm_init.pnc_range[i].cntr_grp < 0) || (tpm_init.pnc_range[i].cntr_grp > 3)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "PNC range[%d] cntr_grp - wrong init value(%d) => legal values <0-3>\n",
+ i, tpm_init.pnc_range[i].cntr_grp);
+ return (TPM_FAIL);
+ }
+ if ((tpm_init.pnc_range[i].lu_mask < 0) || (tpm_init.pnc_range[i].lu_mask > 1)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "PNC range[%d] lu_mask - wrong init value(%d) => legal values <0-1>\n",
+ i, tpm_init.pnc_range[i].lu_mask);
+ return (TPM_FAIL);
+ }
+ if (tpm_init.pnc_range[i].range_num == TPM_PNC_CNM_IPV4_PRE) {
+ found_ipv4_pre = TPM_TRUE;
+ ipv4_pre_size = tpm_init.pnc_range[i].range_size;
+ } else if (tpm_init.pnc_range[i].range_num == TPM_PNC_CNM_MAIN) {
+ found_cnm_main = TPM_TRUE;
+ cnm_main_size = tpm_init.pnc_range[i].range_size;
+ }
+ }
+ }
+ if (j > TPM_PNC_SIZE) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "Sum of Pnc ranges(%d) is bigger than PnC size(%d)\n", j,
+ TPM_PNC_SIZE);
+ return (TPM_FAIL);
+ }
/********************* MOD validations *****************************************************/
- /* Validate TPM reserved modification entries */
+ /* Validate TPM reserved modification entries */
/********************* TX module validations *****************************************************/
- for (tx_mod = TPM_TX_MOD_GMAC0; tx_mod < TPM_MAX_NUM_TX_PORTS; (tx_mod)++) {
- /* validate gmac_tx - according to tpm_init.num_tcont_llid */
- if (tx_mod >= TPM_TX_MOD_PMAC_0) {
- if (((tx_mod - TPM_TX_MOD_GMAC1) > tpm_init.num_tcont_llid) &&
- (tpm_init.gmac_tx[tx_mod].valid == 1)) {
- tpm_init.gmac_tx[tx_mod].valid = 0;
- TPM_OS_WARN(TPM_INIT_MOD,
- " Illegal TCONT/LLID %d configuration - max legal value is %d.\n ",
- tx_mod, tpm_init.num_tcont_llid);
- }
- }
- for (i = 0; i < TPM_MAX_NUM_TX_QUEUE; i++) {
- if (tpm_init.gmac_tx[tx_mod].tx_queue[i].valid != 1)
- continue;
-
- if ((tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_owner < TPM_Q_OWNER_CPU) ||
- (tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_owner >= TPM_Q_OWNER_MAX)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "TX module queue [%d]: queue_owner - wrong init value(%d)"
- " => legal values <%d-%d>\n",
- tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_owner,
- TPM_Q_OWNER_CPU, TPM_Q_OWNER_PMAC);
- return (TPM_FAIL);
- }
- if (tpm_init.gmac_tx[tx_mod].tx_queue[i].owner_queue_num >= TPM_MAX_NUM_TX_QUEUE) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "TX module queue [%d]: owner_queue_num - wrong init value(%d) "
- "is bigger than maximum queue number (%d)\n",
- tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].owner_queue_num,
- TPM_MAX_NUM_TX_QUEUE - 1);
- return (TPM_FAIL);
- }
- if ((tpm_init.gmac_tx[tx_mod].tx_queue[i].sched_method < TPM_SCHED_SP) ||
- (tpm_init.gmac_tx[tx_mod].tx_queue[i].sched_method > TPM_SCHED_WRR)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "TX module queue [%d]: sched_method - wrong init value(%d) => "
- "legal values <%d-%d>\n\n",
- tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].owner_queue_num,
- TPM_SCHED_SP, TPM_SCHED_WRR);
- return (TPM_FAIL);
- }
- if (tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_weight > TPM_MAX_WRR_WEIGHT) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "TX module queue [%d]: queue_weight - wrong init value(%d) "
- "=> legal values <0-%d>\n\n",
- tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_weight,
- TPM_MAX_WRR_WEIGHT);
- return (TPM_FAIL);
- }
- }
- }
-
- /********* per GMAC - validate that default TCONT & Queue - are not set as HWF in xml *****/
- for (gmac_i = 0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
- rc = mv_eth_get_txq_cpu_def(gmac_i, &txp, &txq, 0);
- if (rc != 0) {
- TPM_OS_WARN(TPM_INIT_MOD, "\n Failed to GET the default queue per GMAC%d - rc= %d. \n",
- gmac_i, rc);
- continue;
- }
- if (gmac_i >= TPM_TX_MOD_PMAC_0) {
- if (tpm_init.gmac_tx[gmac_i + txp].tx_queue[txq].queue_owner != TPM_Q_OWNER_CPU) {
- TPM_OS_WARN(TPM_INIT_MOD,
- " Default TX queue(%d) per GMAC (%d) must not be set in "
- "hardware forwarding mode in config params.\n\n", txq, gmac_i);
- }
- } else {
- if (tpm_init.gmac_tx[gmac_i].tx_queue[txq].queue_owner != TPM_Q_OWNER_CPU) {
- TPM_OS_WARN(TPM_INIT_MOD,
- " Default TX queue(%d) per GMAC (%d) must not be set in "
- "hardware forwarding mode in config params.\n\n", txq, gmac_i);
- }
- }
- }
-
- /*****split mod setting validation******/
- if (tpm_init.split_mod_config.split_mod_enable == TPM_SPLIT_MOD_ENABLED) {
- if(tpm_init.split_mod_config.vlan_num > (TPM_DB_SPLIT_MOD_NUM_VLANS_MAX - TPM_DB_SPLIT_MOD_INIT_VLANS_NUM)) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Split Mod VLAN num %d, it should not larger than %d \n",
- tpm_init.split_mod_config.vlan_num, (TPM_DB_SPLIT_MOD_NUM_VLANS_MAX - TPM_DB_SPLIT_MOD_INIT_VLANS_NUM));
- return (TPM_FAIL);
- }
- if (tpm_init.split_mod_config.p_bit_num > TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX || tpm_init.split_mod_config.p_bit_num == TPM_DB_SPLIT_MOD_P_BIT_NO_SET) {
- TPM_OS_FATAL(TPM_INIT_MOD, "\n Split Mod P_bit number out of range.\n");
- return (TPM_FAIL);
- }
- for (i = 0; i < tpm_init.split_mod_config.p_bit_num; i++) {
- if(tpm_init.split_mod_config.p_bit[i] > TPM_DB_SPLIT_MOD_P_BIT_MAX) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Split Mod P_bit %d No Valid\n",
- tpm_init.split_mod_config.p_bit[i]);
- return (TPM_FAIL);
- }
- for (j = i + 1; j < tpm_init.split_mod_config.p_bit_num; j++) {
- if(tpm_init.split_mod_config.p_bit[i] == tpm_init.split_mod_config.p_bit[j]) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n Split Mod P_bit %d Repeat\n",
- tpm_init.split_mod_config.p_bit[i]);
- return (TPM_FAIL);
- }
- }
- }
- }
-
- /********************* CTC CNM validation *************************************/
- if (tpm_init.ctc_cm_enable != TPM_CTC_CM_DISABLED) {
- if (tpm_init.split_mod_config.split_mod_enable == TPM_SPLIT_MOD_DISABLED) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n CTC CM: CTC CnM is enabled while split modification is disabled! \n");
- return (TPM_FAIL);
- }
-
- if (!found_ipv4_pre) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n CTC CM: CTC CnM is enabled while CNM_IPV4_PRE range size is Zero! \n");
- return (TPM_FAIL);
- } else {
- exp_range_size = num_uni_ports * TPM_CNM_MAX_IPV4_PRE_FILTER_RULE_PER_PORT + 1;
- if (exp_range_size > ipv4_pre_size) {
- TPM_OS_WARN(TPM_INIT_MOD,
- "\n CTC CM: CNM IPV4 PRE FILTER is not enough for "
- "L2 & IPV4 combo rules (%d/%d) of %d UNI ports! \n",
- exp_range_size, ipv4_pre_size, num_uni_ports);
- }
- }
-
- if (!found_cnm_main) {
- TPM_OS_FATAL(TPM_INIT_MOD,
- "\n CTC CM: CTC CnM is enabled while CNM_MAIN range size is Zero! \n");
- return (TPM_FAIL);
- } else {
- exp_range_size = num_uni_ports * TPM_MAX_NUM_CTC_PRECEDENCE + 2;
- if (exp_range_size > cnm_main_size) {
- TPM_OS_WARN(TPM_INIT_MOD,
- "\n CTC CM: CNM MAIN is not enough for "
- "8 precedence rules (%d/%d) of %d UNI ports! \n",
- exp_range_size, cnm_main_size, num_uni_ports);
- }
- }
- } else {
- if (found_ipv4_pre) {
+ for (tx_mod = TPM_TX_MOD_GMAC0; tx_mod < TPM_MAX_NUM_TX_PORTS; (tx_mod)++) {
+ /* validate gmac_tx - according to tpm_init.num_tcont_llid */
+ if (tx_mod >= TPM_TX_MOD_PMAC_0) {
+ if (((tx_mod - TPM_TX_MOD_GMAC1) > tpm_init.num_tcont_llid) &&
+ (tpm_init.gmac_tx[tx_mod].valid == 1)) {
+ tpm_init.gmac_tx[tx_mod].valid = 0;
TPM_OS_WARN(TPM_INIT_MOD,
- "\n CTC CM: Since CTC CnM is disabled, CNM_IPV4_PRE range size should be Zero! \n");
+ " Illegal TCONT/LLID %d configuration - max legal value is %d.\n ",
+ tx_mod, tpm_init.num_tcont_llid);
}
- if (found_cnm_main) {
- TPM_OS_WARN(TPM_INIT_MOD,
- "\n CTC CM: Since CTC CnM is disabled, CNM_MAIN range size should be Zero! \n");
+ }
+ for (i = 0; i < TPM_MAX_NUM_TX_QUEUE; i++) {
+ if (tpm_init.gmac_tx[tx_mod].tx_queue[i].valid != 1)
+ continue;
+
+ if ((tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_owner < TPM_Q_OWNER_CPU) ||
+ (tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_owner >= TPM_Q_OWNER_MAX)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "TX module queue [%d]: queue_owner - wrong init value(%d)"
+ " => legal values <%d-%d>\n",
+ tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_owner,
+ TPM_Q_OWNER_CPU, TPM_Q_OWNER_PMAC);
+ return (TPM_FAIL);
+ }
+ if (tpm_init.gmac_tx[tx_mod].tx_queue[i].owner_queue_num >= TPM_MAX_NUM_TX_QUEUE) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "TX module queue [%d]: owner_queue_num - wrong init value(%d) "
+ "is bigger than maximum queue number (%d)\n",
+ tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].owner_queue_num,
+ TPM_MAX_NUM_TX_QUEUE - 1);
+ return (TPM_FAIL);
+ }
+ if ((tpm_init.gmac_tx[tx_mod].tx_queue[i].sched_method < TPM_SCHED_SP) ||
+ (tpm_init.gmac_tx[tx_mod].tx_queue[i].sched_method > TPM_SCHED_WRR)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "TX module queue [%d]: sched_method - wrong init value(%d) => "
+ "legal values <%d-%d>\n\n",
+ tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].owner_queue_num,
+ TPM_SCHED_SP, TPM_SCHED_WRR);
+ return (TPM_FAIL);
+ }
+ if (tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_weight > TPM_MAX_WRR_WEIGHT) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "TX module queue [%d]: queue_weight - wrong init value(%d) "
+ "=> legal values <0-%d>\n\n",
+ tx_mod, tpm_init.gmac_tx[tx_mod].tx_queue[i].queue_weight,
+ TPM_MAX_WRR_WEIGHT);
+ return (TPM_FAIL);
}
}
}
+ /********* per GMAC - validate that default TCONT & Queue - are not set as HWF in xml *****/
+ for (gmac_i = 0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
+ rc = mv_eth_get_txq_cpu_def(gmac_i, &txp, &txq, 0);
+ if (rc != 0) {
+ TPM_OS_WARN(TPM_INIT_MOD, "\n Failed to GET the default queue per GMAC%d - rc= %d. \n",
+ gmac_i, rc);
+ continue;
+ }
+ if (gmac_i >= TPM_TX_MOD_PMAC_0) {
+ if (tpm_init.gmac_tx[gmac_i + txp].tx_queue[txq].queue_owner != TPM_Q_OWNER_CPU) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ " Default TX queue(%d) per GMAC (%d) must not be set in "
+ "hardware forwarding mode in config params.\n\n", txq, gmac_i);
+ }
+ } else {
+ if (tpm_init.gmac_tx[gmac_i].tx_queue[txq].queue_owner != TPM_Q_OWNER_CPU) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ " Default TX queue(%d) per GMAC (%d) must not be set in "
+ "hardware forwarding mode in config params.\n\n", txq, gmac_i);
+ }
+ }
+ }
+
+ /*****split mod setting validation******/
+ if (tpm_init.split_mod_config.split_mod_enable == TPM_SPLIT_MOD_ENABLED) {
+ if(tpm_init.split_mod_config.vlan_num > (TPM_DB_SPLIT_MOD_NUM_VLANS_MAX - TPM_DB_SPLIT_MOD_INIT_VLANS_NUM)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Split Mod VLAN num %d, it should not larger than %d \n",
+ tpm_init.split_mod_config.vlan_num, (TPM_DB_SPLIT_MOD_NUM_VLANS_MAX - TPM_DB_SPLIT_MOD_INIT_VLANS_NUM));
+ return (TPM_FAIL);
+ }
+ if (tpm_init.split_mod_config.p_bit_num > TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX || tpm_init.split_mod_config.p_bit_num == TPM_DB_SPLIT_MOD_P_BIT_NO_SET) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n Split Mod P_bit number out of range.\n");
+ return (TPM_FAIL);
+ }
+ for (i = 0; i < tpm_init.split_mod_config.p_bit_num; i++) {
+ if(tpm_init.split_mod_config.p_bit[i] > TPM_DB_SPLIT_MOD_P_BIT_MAX) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Split Mod P_bit %d No Valid\n",
+ tpm_init.split_mod_config.p_bit[i]);
+ return (TPM_FAIL);
+ }
+ for (j = i + 1; j < tpm_init.split_mod_config.p_bit_num; j++) {
+ if(tpm_init.split_mod_config.p_bit[i] == tpm_init.split_mod_config.p_bit[j]) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n Split Mod P_bit %d Repeat\n",
+ tpm_init.split_mod_config.p_bit[i]);
+ return (TPM_FAIL);
+ }
+ }
+ }
+ }
+
+ /********************* CTC CNM validation *************************************/
+ if (tpm_init.ctc_cm_enable != TPM_CTC_CM_DISABLED) {
+ if (tpm_init.split_mod_config.split_mod_enable == TPM_SPLIT_MOD_DISABLED) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n CTC CM: CTC CnM is enabled while split modification is disabled! \n");
+ return (TPM_FAIL);
+ }
+
+ if (!found_ipv4_pre) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n CTC CM: CTC CnM is enabled while CNM_IPV4_PRE range size is Zero! \n");
+ return (TPM_FAIL);
+ } else {
+ exp_range_size = num_uni_ports * TPM_CNM_MAX_IPV4_PRE_FILTER_RULE_PER_PORT + 1;
+ if (exp_range_size > ipv4_pre_size) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ "\n CTC CM: CNM IPV4 PRE FILTER is not enough for "
+ "L2 & IPV4 combo rules (%d/%d) of %d UNI ports! \n",
+ exp_range_size, ipv4_pre_size, num_uni_ports);
+ }
+ }
+
+ if (!found_cnm_main) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n CTC CM: CTC CnM is enabled while CNM_MAIN range size is Zero! \n");
+ return (TPM_FAIL);
+ } else {
+ exp_range_size = num_uni_ports * TPM_MAX_NUM_CTC_PRECEDENCE + 2;
+ if (exp_range_size > cnm_main_size) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ "\n CTC CM: CNM MAIN is not enough for "
+ "8 precedence rules (%d/%d) of %d UNI ports! \n",
+ exp_range_size, cnm_main_size, num_uni_ports);
+ }
+ }
+ } else {
+ if (found_ipv4_pre) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ "\n CTC CM: Since CTC CnM is disabled, CNM_IPV4_PRE range size should be Zero! \n");
+ }
+ if (found_cnm_main) {
+ TPM_OS_WARN(TPM_INIT_MOD,
+ "\n CTC CM: Since CTC CnM is disabled, CNM_MAIN range size should be Zero! \n");
+ }
+ }
+
+ /********************* ds_mac_based_trunking validation *************************************/
+ if (tpm_init.ds_mac_based_trunk_enable == TPM_DS_MAC_BASED_TRUNK_ENABLED) {
+ if ( (tpm_init.cpu_loopback == TPM_CPU_LOOPBACK_ENABLED)
+ || (tpm_init.mc_setting.per_uni_vlan_xlat)
+ || (tpm_init.virt_uni_info.enabled == TPM_VIRT_UNI_ENABLED)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n when ds_mac_based_trunk is enabled, cpu_loopback, per_uni_vlan_xlat"
+ " and virt_uni can not be enabled! \n");
+ return (TPM_FAIL);
+ }
+
+ if ( (tpm_init.gmac0_mh_en == 0)
+ || (tpm_init.gmac1_mh_en == 0)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n when ds_mac_based_trunk is enabled, MH on GMAC0/1 must be enabled\n");
+ return (TPM_FAIL);
+ }
+
+ if ( (tpm_init.eth_cmplx_profile != TPM_PON_WAN_DUAL_MAC_INT_SWITCH)
+ && (tpm_init.eth_cmplx_profile != TPM_PON_WAN_DUAL_MAC_EXT_SWITCH)) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n when ds_mac_based_trunk is enabled, eth_cmplx_profile must be "
+ "TPM_PON_WAN_DUAL_MAC_INT_SWITCH"
+ " or TPM_PON_WAN_DUAL_MAC_EXT_SWITCH! \n");
+ return (TPM_FAIL);
+ }
+
+ }
/********************* No switch init(MC) validation *************************************/
if (tpm_init.switch_init == 0) {
if (tpm_init.virt_uni_info.enabled == TPM_VIRT_UNI_ENABLED) {
@@ -2116,7 +2185,8 @@
return (TPM_FAIL);
}
- if (tpm_init.pnc_range[TPM_PNC_MAC_LEARN].range_size == 0) {
+ if (tpm_init.pnc_range[TPM_PNC_MAC_LEARN].range_size == 0 &&
+ tpm_init.pnc_mac_learn_enable == TPM_PNC_MAC_LEARN_ENABLED) {
TPM_OS_FATAL(TPM_INIT_MOD,
"\n No Switch Init: PNC range[%d] size is 0! \n", TPM_PNC_MAC_LEARN);
return (TPM_FAIL);
@@ -2133,11 +2203,28 @@
TPM_OS_WARN(TPM_INIT_MOD,
"\n No Switch Init: MAC learn enabled, PNC range[%d] size is too small! \n", TPM_PNC_MAC_LEARN);
}
+
+ if (tpm_init.pnc_mac_learn_enable == TPM_PNC_MAC_LEARN_ENABLED &&
+ tpm_init.eth_cmplx_profile != TPM_PON_WAN_G0_G1_LPBK) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n PNC MAC learning not supported with profile (%d) \n",
+ tpm_init.eth_cmplx_profile);
+ return (TPM_FAIL);
+ }
+
+ if (tpm_init.ipv6_5t_enable == TPM_IPV6_5T_ENABLED &&
+ tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_DUAL_LAN) {
+ TPM_OS_FATAL(TPM_INIT_MOD,
+ "\n IPV6 5-tuple supported with profile (%d) \n",
+ tpm_init.eth_cmplx_profile);
+ return (TPM_FAIL);
+ }
} else if ((tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_SINGLE_PORT ||
tpm_init.eth_cmplx_profile == TPM_PON_WAN_G1_SINGLE_PORT ||
tpm_init.eth_cmplx_profile == TPM_PON_G1_WAN_G0_SINGLE_PORT ||
tpm_init.eth_cmplx_profile == TPM_PON_G0_WAN_G1_SINGLE_PORT ||
- tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK)
+ tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK ||
+ tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_DUAL_LAN)
&& tpm_init.switch_init == 1) {
TPM_OS_FATAL(TPM_INIT_MOD,
"\n Switch can not be Init at this profile: [%d]! \n", tpm_init.eth_cmplx_profile);
@@ -2190,6 +2277,26 @@
}
}
+ /* check all the loopback features */
+ if (tpm_init.mc_setting.per_uni_vlan_xlat) {
+ if (tpm_init.virt_uni_info.enabled != TPM_VIRT_UNI_ENABLED) {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n per_uni_vlan_xlat can not be supported when virt_uni is disabled\n");
+ return (TPM_FAIL);
+ }
+ }
+ if (tpm_init.cpu_loopback == TPM_CPU_LOOPBACK_ENABLED) {
+ if (tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK)
+ ;/* OK */
+ else if ( (tpm_init.gmac_port_conf[TPM_ENUM_GMAC_1].conn == TPM_GMAC_CON_SWITCH_5)
+ && (tpm_init.eth_cmplx_profile != TPM_G0_WAN_G1_INT_SWITCH)
+ && (tpm_init.eth_cmplx_profile != TPM_PON_G0_WAN_G1_INT_SWITCH))
+ ;/* OK */
+ else {
+ TPM_OS_FATAL(TPM_INIT_MOD, "\n cpu_wan_loopback can not be supported on this profile\n");
+ return (TPM_FAIL);
+ }
+ }
+
return (TPM_OK);
}
@@ -2240,7 +2347,7 @@
{
uint32_t i;
- for (i = 0; i < TPM_MAX_NUM_TX_QUEUE; i++) {
+ for (i = 0; i < TPM_MAX_NUM_RX_QUEUE; i++) {
if (tpm_init.gmac_rx[gmac].rx_queue[i].valid == TPM_TRUE)
tpm_db_gmac_rx_q_conf_set(gmac, i, tpm_init.gmac_rx[gmac].rx_queue[i].queue_size);
}
@@ -2424,6 +2531,9 @@
ret_code = tpm_init_api_rng_init(TPM_PNC_CNM_MAIN, TPM_CNM_MAIN_ACL, TPM_DIR_DS);
IF_ERROR(ret_code);
+ ret_code = tpm_init_api_rng_init(TPM_PNC_DS_LOAD_BALANCE, TPM_DS_LOAD_BALANCE_ACL, TPM_DIR_DS);
+ IF_ERROR(ret_code);
+
return (TPM_OK);
}
@@ -2526,7 +2636,7 @@
IF_ERROR(ret_code);
ret_code = tpm_db_pon_type_set(tpm_init.pon_type);
IF_ERROR(ret_code);
- ret_code = tpm_db_backup_wan_set(tpm_init.backup_wan);
+ ret_code = tpm_db_active_wan_set(tpm_init.active_wan);
IF_ERROR(ret_code);
ret_code = tpm_db_ds_mh_set_conf_set(tpm_init.ds_mh_set_conf);
IF_ERROR(ret_code);
@@ -2558,6 +2668,8 @@
IF_ERROR(ret_code);
ret_code = tpm_db_fc_conf_set(&tpm_init.port_fc_conf);
IF_ERROR(ret_code);
+ ret_code = tpm_db_ds_mac_based_trunk_enable_set(tpm_init.ds_mac_based_trunk_enable);
+ IF_ERROR(ret_code);
/* Set GMAC Logical Functions */
@@ -2586,6 +2698,7 @@
printk(KERN_INFO "TPM_SRC_PORT: %d, value: %d\n", src_port, tpm_init.igmp_pkt_frwd_mod[src_port]);
}
tpm_db_igmp_set_cpu_queue(tpm_init.igmp_cpu_queue);
+ tpm_db_igmp_set_snoop_enable(tpm_init.igmp_snoop);
/*printk("TPM_SRC_PORT_WAN: %d, TPM_SRC_PORT_UNI_0: %d, TPM_SRC_PORT_UNI_1: %d, TPM_SRC_PORT_UNI_2: %d, "
"TPM_SRC_PORT_UNI_3: %d, igmp_cpu_queue: %d\n",
tpm_init.igmp_pkt_frwd_mod[4],tpm_init.igmp_pkt_frwd_mod[0],tpm_init.igmp_pkt_frwd_mod[1],
@@ -2660,7 +2773,9 @@
tpm_init_gmac_rxq_set(TPM_ENUM_GMAC_1);
}
/* PMAC Rx */
- if (tpm_init.pon_type == TPM_GPON || tpm_init.pon_type == TPM_EPON) {
+ if ( tpm_init.pon_type == TPM_GPON
+ || tpm_init.pon_type == TPM_EPON
+ || tpm_init.pon_type == TPM_P2P) {
tpm_db_gmac_rx_val_set(TPM_ENUM_PMAC);
tpm_init_gmac_rxq_set(TPM_ENUM_PMAC);
}
@@ -2754,13 +2869,24 @@
tpm_db_gmac1_lpbk_en_set(false);
/* set CPU WAN loopback en */
- if ( (tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK)
- || (tpm_init.gmac_port_conf[TPM_ENUM_GMAC_0].conn == TPM_GMAC_CON_SWITCH_5))
- tpm_db_cpu_wan_lpbk_en_set(true);
- else
- tpm_db_cpu_wan_lpbk_en_set(false);
+ tpm_db_cpu_wan_lpbk_en_set(tpm_init.cpu_loopback);
tpm_db_switch_init_set(tpm_init.switch_init);
+ if ( (tpm_init.eth_cmplx_profile == TPM_PON_WAN_DUAL_MAC_INT_SWITCH)
+ || (tpm_init.eth_cmplx_profile == TPM_PON_WAN_DUAL_MAC_EXT_SWITCH))
+ tpm_db_ds_load_bal_en_set(true);
+ else
+ tpm_db_ds_load_bal_en_set(false);
+
+
+ /* set switch active WAN en */
+ if ( (tpm_init.eth_cmplx_profile == TPM_PON_G1_WAN_G0_INT_SWITCH)
+ || (tpm_init.eth_cmplx_profile == TPM_PON_G0_WAN_G1_INT_SWITCH)
+ || (tpm_init.eth_cmplx_profile == TPM_PON_G1_WAN_G0_SINGLE_PORT)
+ || (tpm_init.eth_cmplx_profile == TPM_PON_G0_WAN_G1_SINGLE_PORT))
+ tpm_db_switch_active_wan_en_set(true);
+ else
+ tpm_db_switch_active_wan_en_set(false);
return (TPM_OK);
}
@@ -2802,6 +2928,14 @@
"GMAC = %d TCONT = %d Q = %d HWF: owner_rx %d\n",
dest_port, dest_port_txp, q_num, owner_rx_port);
}
+ else
+ {
+ if (mv_eth_ctrl_txq_cpu_own(dest_port, dest_port_txp, q_num, 1)){
+ TPM_OS_ERROR(TPM_INIT_MOD,
+ "mv_eth_ctrl_txq_cpu_own err GMAC = %d TCONT = %d Q = %d SWF: owner_rx %d\n",
+ dest_port, dest_port_txp, q_num, owner_rx_port);
+ }
+ }
} else {
if (mv_eth_ctrl_txq_hwf_own(dest_port, dest_port_txp, q_num, -1)){
TPM_OS_DEBUG(TPM_INIT_MOD,
@@ -2898,7 +3032,7 @@
} /* All GMACs */
}
-int32_t tpm_init_mh_select(void)
+int32_t tpm_init_mh_select(tpm_init_mh_src_t ds_mh_set_conf)
{
tpm_gmacs_enum_t gmac_i;
tpm_db_gmac_func_t gmac_func;
@@ -2911,7 +3045,7 @@
tpm_db_gmac_func_get(gmac_i, &gmac_func);
if ((gmac_func == TPM_GMAC_FUNC_LAN_AND_WAN) || (gmac_func == TPM_GMAC_FUNC_WAN)) {
- switch (tpm_init.ds_mh_set_conf) {
+ switch (ds_mh_set_conf) {
case TPM_MH_SRC_RX_CTRL:
mvNetaHwfMhSrcSet(gmac_i, MV_NETA_HWF_MH_REG);
mvNetaHwfMhSelSet(gmac_i, (uint8_t) NETA_MH_REPLACE_MH_REG(0));
@@ -2922,10 +3056,10 @@
mvNetaHwfMhSelSet(gmac_i, (uint8_t) NETA_MH_DONT_CHANGE);
break;
default:
- TPM_OS_ERROR(TPM_INIT_MOD, " Unknown d/s MH source (%d)\n", tpm_init.ds_mh_set_conf);
+ TPM_OS_ERROR(TPM_INIT_MOD, " Unknown d/s MH source (%d)\n", ds_mh_set_conf);
return (TPM_FAIL);
}
- } else if ((gmac_func == TPM_GMAC_FUNC_LAN_AND_WAN) || (gmac_func == TPM_GMAC_FUNC_LAN)) {
+ } else if ((gmac_func == TPM_GMAC_FUNC_LAN_AND_WAN) || (gmac_func == TPM_GMAC_FUNC_LAN) || (gmac_func == TPM_GMAC_FUNC_LAN_UNI)) {
mvNetaHwfMhSrcSet(gmac_i, MV_NETA_HWF_MH_REG);
mvNetaHwfMhSelSet(gmac_i, (uint8_t) NETA_MH_REPLACE_GPON_HDR);
}
@@ -2984,6 +3118,34 @@
return ret_code;
}
+/*******************************************************************************
+* tpm_init_gmac_PHY_poll()
+*
+* DESCRIPTION: Initialize the GMAC PHY polling state accordint to it connect to PHY or not
+*
+* INPUTS:
+* port -- GMAC port
+* state -- true: enable PHY polling; false: disable PHY polling
+* OUTPUTS:None
+*
+* RETURNS:
+*
+*******************************************************************************/
+int32_t tpm_init_gmac_PHY_poll(int port, bool state)
+{
+ unsigned int regData;
+
+ regData = MV_REG_READ(ETH_UNIT_CONTROL_REG(port));
+ if (state)
+ regData |= ETH_PHY_POLLING_ENABLE_MASK;
+ else
+ regData &= (~ETH_PHY_POLLING_ENABLE_MASK);
+
+ MV_REG_WRITE(ETH_UNIT_CONTROL_REG(port), regData);
+
+ return TPM_OK;
+}
+
int32_t tpm_init_switch(void)
{
uint32_t i;
@@ -3001,6 +3163,7 @@
case TPM_PON_G1_WAN_G0_SINGLE_PORT:
case TPM_PON_G0_WAN_G1_SINGLE_PORT:
case TPM_PON_WAN_G0_G1_LPBK:
+ case TPM_PON_WAN_G0_G1_DUAL_LAN:
return (TPM_OK);
default:
break;
@@ -3159,10 +3322,20 @@
if (mv_switch_mac_addr_set(gq_da, 0, sw_port_bmp, 1))
TPM_OS_WARN(TPM_INIT_MOD, "mv_switch_mac_addr_set err. sw_port_bmp 0X%x\n", sw_port_bmp);
+ /* If Switch port MAC no connected to PHY, disable GMAC PHY polling */
+ for (gmac_i = TPM_ENUM_GMAC_0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
+ if (TPM_FALSE == tpm_init.gmac_port_conf[gmac_i].valid)
+ continue;
+
+ if (TPM_GMAC_CON_SWITCH_4 == tpm_init.gmac_port_conf[gmac_i].conn ||
+ TPM_GMAC_CON_SWITCH_5 == tpm_init.gmac_port_conf[gmac_i].conn)
+ tpm_init_gmac_PHY_poll(gmac_i, false);
+ }
+
return (TPM_OK);
}
-int32_t tpm_init_mh_conf_set(void)
+int32_t tpm_init_mh_conf_set(uint32_t gmac0_mh_en, uint32_t gmac1_mh_en, tpm_init_gmac_conn_conf_t *gmac_port_conf)
{
tpm_gmacs_enum_t gmac_i;
uint32_t amber_port_num, mh_en;
@@ -3180,13 +3353,13 @@
switch (gmac_i) {
case TPM_ENUM_GMAC_0:
- mh_en = tpm_init.gmac0_mh_en;
- if (TPM_GMAC_CON_SWITCH_4 == tpm_init.gmac_port_conf[gmac_i].conn)
+ mh_en = gmac0_mh_en;
+ if (TPM_GMAC_CON_SWITCH_4 == gmac_port_conf[gmac_i].conn)
amber_port_num = TPM_GMAC0_AMBER_PORT_NUM;
break;
case TPM_ENUM_GMAC_1:
- mh_en = tpm_init.gmac1_mh_en;
- if (TPM_GMAC_CON_SWITCH_5 == tpm_init.gmac_port_conf[gmac_i].conn)
+ mh_en = gmac1_mh_en;
+ if (TPM_GMAC_CON_SWITCH_5 == gmac_port_conf[gmac_i].conn)
amber_port_num = TPM_GMAC1_AMBER_PORT_NUM;
break;
case TPM_ENUM_PMAC:
@@ -3222,7 +3395,7 @@
return (TPM_OK);
}
-int32_t tpm_init_mh_reg_set(void)
+int32_t tpm_init_mh_reg_set(tpm_init_mh_src_t ds_mh_set_conf)
{
tpm_gmacs_enum_t gmac_i;
uint32_t pp_port_num;
@@ -3248,7 +3421,7 @@
}
pp_port_num = TPM_GMAC_TO_PP_PORT(gmac_i);
- if (((gmac_func == TPM_GMAC_FUNC_LAN_AND_WAN) || (gmac_func == TPM_GMAC_FUNC_LAN)) &&
+ if (((gmac_func == TPM_GMAC_FUNC_LAN_AND_WAN) || (gmac_func == TPM_GMAC_FUNC_LAN) || (gmac_func == TPM_GMAC_FUNC_LAN_UNI)) &&
gmac_mh_en && (tpm_init.ds_mh_set_conf == TPM_MH_SRC_PNC_RI)) {
/* Set MH Tx registers to full table */
for (tx_reg_i = 0; tx_reg_i < TPM_TX_MAX_MH_REGS; tx_reg_i++) {
@@ -3275,9 +3448,9 @@
/* VLANTable field is (re)set to 'all_other_switch_ports' */
if (gmac_i == TPM_ENUM_GMAC_0)
- regVal = 0x3f & (~(1 << TPM_GMAC0_AMBER_PORT_NUM));
+ regVal = 0x7f & (~(1 << TPM_GMAC0_AMBER_PORT_NUM));
else
- regVal = 0x3f & (~(1 << TPM_GMAC1_AMBER_PORT_NUM));
+ regVal = 0x7f & (~(1 << TPM_GMAC1_AMBER_PORT_NUM));
} else {
if (tpm_db_num_tcont_llid_get(&num_txp) != TPM_OK) {
TPM_OS_ERROR(TPM_INIT_MOD,
@@ -3307,8 +3480,8 @@
{
tpm_db_tx_mod_t tx_mod_i;
tpm_gmacs_enum_t gmac_i;
- uint32_t txp_i = 0;
- uint32_t size = 0, queue = 0, rate = 0;
+ uint32_t txp_i = 0, prio = 0;
+ uint32_t size = 0, queue = 0, rate = 0, wrr = 0;
for (tx_mod_i = 0; tx_mod_i < TPM_MAX_NUM_TX_PORTS; tx_mod_i++) {
if (TPM_FALSE == tpm_db_gmac_tx_val_get(tx_mod_i)) {
@@ -3322,19 +3495,34 @@
gmac_i = TPM_ENUM_PMAC;
txp_i = tx_mod_i - TPM_TX_MOD_PMAC_0;
}
+
/* get Tx queue bucket size */
for (queue = 0; queue < TPM_MAX_NUM_TX_QUEUE; queue++) {
#ifdef MV_ETH_WRR_NEW
size = MV_REG_READ(NETA_TXQ_TOKEN_SIZE_REG(gmac_i, txp_i, queue));
rate = MV_REG_READ(NETA_TXQ_REFILL_REG(gmac_i, txp_i, queue));
+ wrr = MV_REG_READ(NETA_TXQ_WRR_ARBITER_REG(gmac_i, txp_i, queue));
#else /* Old WRR/EJP module */
/* token size and rate are in the same reg */
rate = MV_REG_READ(ETH_TXQ_TOKEN_CFG_REG(gmac_i, txp_i, queue));
#endif /* MV_ETH_WRR_NEW */
TPM_OS_INFO(TPM_INIT_MOD, "gmac_i (%d), txp_i (%d), queue (%d), size (%d), rate (%d)\n",
gmac_i, txp_i, queue, size, rate);
- tpm_db_set_gmac_rate_limit(tx_mod_i, queue, size, rate);
+ tpm_db_set_gmac_q_rate_limit(tx_mod_i, queue, size, rate, wrr);
}
+
+ /* get TX bucket and rate */
+#ifdef MV_ETH_WRR_NEW
+ size = MV_REG_READ(NETA_TXP_TOKEN_SIZE_REG(gmac_i, txp_i));
+ rate = MV_REG_READ(NETA_TXP_REFILL_REG(gmac_i, txp_i));
+ prio = MV_REG_READ(NETA_TX_FIXED_PRIO_CFG_REG(gmac_i, txp_i));
+#else /* Old WRR/EJP module */
+ rate = MV_REG_READ(ETH_TXP_TOKEN_RATE_CFG_REG(gmac_i, txp_i));
+ size = MV_REG_READ(ETH_TXP_TOKEN_SIZE_REG(gmac_i, txp_i));
+#endif /* MV_ETH_WRR_NEW */
+ TPM_OS_INFO(TPM_INIT_MOD, "gmac_i (%d), txp_i (%d), queue (%d), size (%d), rate (%d)\n",
+ gmac_i, txp_i, queue, size, rate);
+ tpm_db_set_gmac_rate_limit(tx_mod_i, size, rate, prio);
}
return (TPM_OK);
}
@@ -3344,6 +3532,10 @@
tpm_gmacs_enum_t gmac_i;
uint32_t txp_i = 0;
uint32_t size = 0, queue = 0, rate = 0;
+ uint32_t wrr = 0, prio = 0, regVal = 0;
+
+ /* keep the compiler quiet */
+ regVal = 0;
for (tx_mod_i = 0; tx_mod_i < TPM_MAX_NUM_TX_PORTS; tx_mod_i++) {
if (TPM_FALSE == tpm_db_gmac_tx_val_get(tx_mod_i))
@@ -3355,18 +3547,39 @@
gmac_i = TPM_ENUM_PMAC;
txp_i = tx_mod_i - TPM_TX_MOD_PMAC_0;
}
- /* get Tx queue bucket size */
+
+ /* set Tx queue bucket size */
for (queue = 0; queue < TPM_MAX_NUM_TX_QUEUE; queue++) {
- tpm_db_get_gmac_rate_limit(tx_mod_i, queue, &size, &rate);
+ tpm_db_get_gmac_q_rate_limit(tx_mod_i, queue, &size, &rate, &wrr);
TPM_OS_INFO(TPM_INIT_MOD, "gmac_i (%d), txp_i (%d), queue (%d), size (%d), rate (%d)\n",
gmac_i, txp_i, queue, size, rate);
#ifdef MV_ETH_WRR_NEW
MV_REG_WRITE(NETA_TXQ_REFILL_REG(gmac_i, txp_i, queue), rate);
MV_REG_WRITE(NETA_TXQ_TOKEN_SIZE_REG(gmac_i, txp_i, queue), size);
+ MV_REG_WRITE(NETA_TXQ_WRR_ARBITER_REG(gmac_i, txp_i, queue), wrr);
#else /* Old WRR/EJP module */
MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(gmac_i, txp_i, queue), rate);
#endif /* MV_ETH_WRR_NEW */
}
+
+ tpm_db_get_gmac_rate_limit(tx_mod_i, &size, &rate, &prio);
+ TPM_OS_INFO(TPM_INIT_MOD, "gmac_i (%d), txp_i (%d), size (%d), rate (%d)\n",
+ gmac_i, txp_i, size, rate);
+ /* set TX bucket and rate */
+#ifdef MV_ETH_WRR_NEW
+ MV_REG_WRITE(NETA_TXP_TOKEN_SIZE_REG(gmac_i, txp_i), size);
+ MV_REG_WRITE(NETA_TXP_REFILL_REG(gmac_i, txp_i), rate);
+ MV_REG_WRITE(NETA_TX_FIXED_PRIO_CFG_REG(gmac_i, txp_i), prio);
+#else /* Old WRR/EJP module */
+ regVal = MV_REG_READ(ETH_TXP_TOKEN_RATE_CFG_REG(gmac_i, txp_i));
+ regVal &= ~ETH_TXP_TOKEN_RATE_ALL_MASK;
+ regVal |= ETH_TXP_TOKEN_RATE_MASK(rate);
+ MV_REG_WRITE(ETH_TXP_TOKEN_RATE_CFG_REG(gmac_i, txp_i), regVal);
+ regVal = MV_REG_READ(ETH_TXP_TOKEN_SIZE_REG(gmac_i, txp_i));
+ regVal &= ~ETH_TXP_TOKEN_SIZE_ALL_MASK;
+ regVal |= ETH_TXP_TOKEN_SIZE_MASK(size);
+ MV_REG_WRITE(ETH_TXP_TOKEN_SIZE_REG(gmac_i, txp_i), regVal);
+#endif /* MV_ETH_WRR_NEW */
}
return (TPM_OK);
}
@@ -3396,17 +3609,20 @@
return (TPM_OK);
}
-int32_t tpm_init_mh(void)
+int32_t tpm_init_mh(tpm_init_mh_src_t ds_mh_set_conf,
+ uint32_t gmac0_mh_en,
+ uint32_t gmac1_mh_en,
+ tpm_init_gmac_conn_conf_t *gmac_port_conf)
{
- if (tpm_init_mh_select() != TPM_OK) {
+ if (tpm_init_mh_select(ds_mh_set_conf) != TPM_OK) {
TPM_OS_ERROR(TPM_INIT_MOD, "tpm_init_mh_select err\n");
return (TPM_FAIL);
}
- if (tpm_init_mh_conf_set() != TPM_OK) {
+ if (tpm_init_mh_conf_set(gmac0_mh_en, gmac1_mh_en, gmac_port_conf) != TPM_OK) {
TPM_OS_ERROR(TPM_INIT_MOD, "tpm_init_mh_conf_set err\n");
return (TPM_FAIL);
}
- if (tpm_init_mh_reg_set() != TPM_OK) {
+ if (tpm_init_mh_reg_set(ds_mh_set_conf) != TPM_OK) {
TPM_OS_ERROR(TPM_INIT_MOD, "tpm_init_mh_reg_set err\n");
return (TPM_FAIL);
}
@@ -3451,7 +3667,7 @@
return (TPM_OK);
}
-int32_t tpm_init_ipg(void)
+int32_t tpm_init_ipg(int32_t mod_value)
{
int status;
tpm_gmacs_enum_t gmac_i;
@@ -3460,7 +3676,14 @@
tpm_db_gmac_func_t gmac_func;
tpm_db_gmac_conn_t gmac_con;
MV_BOOL link_is_up;
+ tpm_db_error_t db_ret_code;
+ uint32_t gmac0_mh_en = 0;
+ uint32_t gmac1_mh_en = 0;
+ db_ret_code = tpm_db_gmac_mh_en_conf_get(TPM_ENUM_GMAC_0, &gmac0_mh_en);
+ IF_ERROR(db_ret_code);
+ db_ret_code = tpm_db_gmac_mh_en_conf_get(TPM_ENUM_GMAC_1, &gmac1_mh_en);
+ IF_ERROR(db_ret_code);
for (gmac_i = 0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
if (!INIT_GMAC_VALID(gmac_i))
@@ -3471,12 +3694,13 @@
if (gmac_func != TPM_GMAC_FUNC_NONE) {
- if ((gmac_i == 0 && tpm_init.gmac0_mh_en != TPM_FALSE && gmac_con == TPM_GMAC_CON_SWITCH_4) ||
- (gmac_i == 1 && tpm_init.gmac1_mh_en != TPM_FALSE && gmac_con == TPM_GMAC_CON_SWITCH_5)) {
+ if ((gmac_i == 0 && gmac0_mh_en != TPM_FALSE && gmac_con == TPM_GMAC_CON_SWITCH_4) ||
+ (gmac_i == 1 && gmac1_mh_en != TPM_FALSE && (gmac_con == TPM_GMAC_CON_SWITCH_5 ||
+ tpm_init.eth_cmplx_profile == TPM_PON_WAN_G0_G1_LPBK))) {
mvNetaPortDisable(gmac_i);
mvNetaHwfEnable(gmac_i, 0);
ipg_val = mvNetaPortIpgGet(gmac_i);
- ipg_val -= TPM_MH_LEN;
+ ipg_val += mod_value;
mvNetaPortIpgSet(gmac_i, ipg_val);
mvNetaHwfEnable(gmac_i, 1);
status = mvNetaPortEnable(gmac_i);
@@ -3487,23 +3711,25 @@
mvNetaPortUp(gmac_i);
}
- if (gmac_i == 0)
- port = TPM_GMAC0_AMBER_PORT_NUM;
- else
- port = TPM_GMAC1_AMBER_PORT_NUM;
+ if ((gmac_con == TPM_GMAC_CON_SWITCH_4) || (gmac_con == TPM_GMAC_CON_SWITCH_5)) {
+ if (gmac_i == 0)
+ port = TPM_GMAC0_AMBER_PORT_NUM;
+ else
+ port = TPM_GMAC1_AMBER_PORT_NUM;
- /* TODO: Need to check if switch is attached to GMAC */
- status = mv_switch_get_port_preamble(port, &preamble);
- if (status) {
- TPM_OS_ERROR(TPM_INIT_MOD, "Fail to get port(%d) preamble_len\n", port);
- return (TPM_FAIL);
- }
- preamble -= TPM_MH_LEN;
- status = mv_switch_set_port_preamble(port, preamble);
- if (status) {
- TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set port(%d) preamble_len(%d)\n"
- , port, preamble);
- return (TPM_FAIL);
+ /* TODO: Need to check if switch is attached to GMAC */
+ status = mv_switch_get_port_preamble(port, &preamble);
+ if (status) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to get port(%d) preamble_len\n", port);
+ return (TPM_FAIL);
+ }
+ preamble += mod_value;
+ status = mv_switch_set_port_preamble(port, preamble);
+ if (status) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set port(%d) preamble_len(%d)\n"
+ , port, preamble);
+ return (TPM_FAIL);
+ }
}
}
}
@@ -3595,20 +3821,57 @@
* RETURNS:
*
*******************************************************************************/
-int32_t tpm_init_gmac_loopback(int port)
+int32_t tpm_init_gmac_loopback(tpm_gmacs_enum_t port, uint8_t enable)
{
uint32_t regVal;
- mvNetaPortDisable(port);
- mvNetaHwfEnable(port, 0);
+ if (port > TPM_MAX_GMAC) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "GMAC port(%d) is invalid\n", port);
+ return TPM_FAIL;
+ }
- mvNetaForceLinkModeSet(port, 1, 0);/*for link up*/
- mvNetaSpeedDuplexSet(port, MV_ETH_SPEED_1000, MV_ETH_DUPLEX_FULL);/*set 1G*/
+ /* Check Port Available or not */
+ if (!tpm_init_check_gmac_init(port)) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "GMAC port(%d) is not available\n", port);
+ return TPM_FAIL;
+ }
- mvNetaHwfEnable(port, 1);
- mvNetaPortEnable(port);
+ if (mvNetaPortDisable(port)) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to disable GMAC port(%d)\n", port);
+ return (TPM_FAIL);
+ }
+ if (mvNetaHwfEnable(port, 0)) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to disable GMAC port(%d) HWF\n", port);
+ return (TPM_FAIL);
+ }
- MV_REG_WRITE(NETA_GMAC_CTRL_1_REG(port), 0x31); /* set gmac to loopback mode */
+ if (mvNetaForceLinkModeSet(port, 1, 0)) {/*for link up*/
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set GMAC port(%d) force link\n", port);
+ return (TPM_FAIL);
+ }
+ if (mvNetaSpeedDuplexSet(port, MV_ETH_SPEED_1000, MV_ETH_DUPLEX_FULL)) {/*set 1G*/
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set GMAC port(%d) speed and duplex\n", port);
+ return (TPM_FAIL);
+ }
+
+ if (mvNetaHwfEnable(port, 1)) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to enable GMAC port(%d) HWF\n", port);
+ return (TPM_FAIL);
+ }
+ if (mvNetaPortEnable(port)) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to enable GMAC port(%d)\n", port);
+ return (TPM_FAIL);
+ }
+
+ /* set GMAC_CTRL_2_REG */
+ regVal = MV_REG_READ(NETA_GMAC_CTRL_2_REG(port));
+ regVal &= ~NETA_GMAC_PSC_ENABLE_MASK;
+ MV_REG_WRITE(NETA_GMAC_CTRL_2_REG(port), regVal);
+
+ if (enable)
+ MV_REG_WRITE(NETA_GMAC_CTRL_1_REG(port), 0x31); /* set gmac to loopback mode */
+ else
+ MV_REG_WRITE(NETA_GMAC_CTRL_1_REG(port), 0x11); /* set gmac to no-loopback mode */
regVal = MV_REG_READ(NETA_GMAC_AN_CTRL_REG(port));
regVal |= NETA_FORCE_LINK_FAIL_MASK; /* enable Force Link Pass */
@@ -3641,12 +3904,15 @@
tpm_pnc_ranges_t cur_range = TPM_INVALID_RANGE, next_range = 0;
tpm_db_pnc_range_t next_range_data;
tpm_db_pnc_range_conf_t range_conf;
+ tpm_db_pnc_range_conf_t range_conf_tcp_flag;
uint32_t switch_init;
- int32_t ret_code;
+ int32_t ret_code, ret_code_tcp_flag;
tpm_db_ttl_illegal_action_t ttl_illegal_action;
tpm_db_tcp_flag_check_t tcp_flag_check;
tpm_gmacs_enum_t gmac_i;
tpm_db_gmac_func_t gfunc;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
+ uint32_t snoop_enable;
TPM_OS_DEBUG(TPM_INIT_MOD, "\n");
@@ -3666,21 +3932,26 @@
ret_code = tpm_mod2_split_mod_init(gmac_i);
IF_ERROR(ret_code);
}
- /* Init Tx queue rate limit */
- ret_code = tpm_init_reset_gmac_queue_rate_limit();
- IF_ERROR(ret_code);
/* Init Amber Switch */
tpm_db_switch_init_get(&switch_init);
if (switch_init)
tpm_init_switch();
- else
- /* Init GMAC1 in loopback mod if no switch*/
- tpm_init_gmac_loopback(TPM_ENUM_GMAC_1);
+ else {
+ if (tpm_db_gmac1_lpbk_en_get()) {
+ /* Init GMAC1 in loopback mod if GMAC loopback is enabled */
+ ret_code = tpm_init_gmac_loopback(TPM_ENUM_GMAC_1, 1);
+ IF_ERROR(ret_code);
+ }
+ }
/*Init TX scheduling */
ret_code = tpm_init_tx_queue_sched();
IF_ERROR(ret_code);
+ /* Init Tx queue rate limit */
+ ret_code = tpm_init_reset_gmac_queue_rate_limit();
+ IF_ERROR(ret_code);
+
/* Initialize (wipe out) the PNC ranges in PnC HW */
tpm_db_pnc_rng_val_get_next(cur_range, &next_range, &next_range_data);
TPM_OS_DEBUG(TPM_INIT_MOD, "next_range(%d)\n", next_range);
@@ -3704,6 +3975,25 @@
} else
TPM_OS_WARN(TPM_INIT_MOD, "PNC range(%d) not initialized\n", TPM_PNC_NUM_VLAN_TAGS);
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_DS_LOAD_BALANCE, &range_conf);
+ if (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable) {
+ if (ret_code != TPM_DB_OK) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "PNC range TPM_PNC_DS_LOAD_BALANCE is not created "
+ "when ds_mac_based_trunk is enabled\n");
+ return ERR_GENERAL;
+ } else if (range_conf.range_size < 3) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "PNC range TPM_PNC_DS_LOAD_BALANCE size should be at least "
+ "3 when ds_mac_based_trunk is enabled\n");
+ return ERR_GENERAL;
+ }
+ } else {
+ if ((ret_code == TPM_DB_OK) && (range_conf.range_size != 0)) {
+ TPM_OS_WARN(TPM_INIT_MOD, "do not perform ds_mac_based_trunk, "
+ "no need to create TPM_PNC_DS_LOAD_BALANCE range\n");
+ }
+ }
+
tpm_db_get_ttl_illegal_action(&ttl_illegal_action);
ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_TTL, &range_conf);
if (TPM_TTL_ZERO_ACTION_NOTHING == ttl_illegal_action) {
@@ -3760,11 +4050,21 @@
}
}
ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_IGMP, &range_conf);
- if (ret_code == TPM_DB_OK) {
- ret_code = tpm_proc_ipv4_igmp_init();
- IF_ERROR(ret_code);
- } else
- TPM_OS_WARN(TPM_INIT_MOD, "PNC range(%d) not initialized\n", TPM_PNC_IGMP);
+ tpm_db_igmp_get_snoop_enable(&snoop_enable);
+ if (TPM_TRUE == snoop_enable) {
+ if (ret_code == TPM_DB_OK) {
+ ret_code = tpm_proc_ipv4_igmp_init();
+ IF_ERROR(ret_code);
+ } else {
+ TPM_OS_ERROR(TPM_INIT_MOD, "PNC range(TPM_PNC_IGMP) not initialized with IGMP snoop enabled\n");
+ return ERR_GENERAL;
+ }
+ } else if (ret_code == TPM_DB_OK) {
+ if (range_conf.range_size != 0) {
+ /* igmp snoop is disabled, no need to create TPM_PNC_IGMP range */
+ TPM_OS_WARN(TPM_INIT_MOD, "igmp snoop is disabled, no need to create TPM_PNC_IGMP range\n");
+ }
+ }
ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_IPV4_PROTO, &range_conf);
if (ret_code == TPM_DB_OK) {
@@ -3788,16 +4088,20 @@
TPM_OS_WARN(TPM_INIT_MOD, "PNC range(%d) not initialized\n", TPM_PNC_CATCH_ALL);
tpm_db_get_tcp_flag_check(&tcp_flag_check);
- ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_TCP_FLAG, &range_conf);
+ ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_IPV4_TCP_FLAG, &range_conf);
+ ret_code_tcp_flag = tpm_db_pnc_rng_conf_get(TPM_PNC_IPV6_TCP_FLAG, &range_conf_tcp_flag);
if (TPM_TCP_FLAG_NOT_CHECK == tcp_flag_check) {
- if (ret_code == TPM_DB_OK) {
+ if (ret_code == TPM_DB_OK || ret_code_tcp_flag == TPM_DB_OK) {
/* do not check tcp flag, no need to create tcp flag range */
- TPM_OS_WARN(TPM_INIT_MOD, "do not check tcp flag, no need to create tcp flag range\n");
+ TPM_OS_WARN(TPM_INIT_MOD, "do not check tcp flag, no need to create IPv4/6 tcp flag range\n");
}
} else {
- if ((ret_code != TPM_DB_OK) || (range_conf.range_size < 4)) {
+ if ((ret_code != TPM_DB_OK) || (range_conf.range_size < 3)) {
/* check tcp flag, need to create tcp flag range */
- TPM_OS_WARN(TPM_INIT_MOD, "check tcp flag, need to create tcp flag range with size of 4\n");
+ TPM_OS_WARN(TPM_INIT_MOD, "check tcp flag, need to create IPv4 tcp flag range with size of 3\n");
+ } else if ((ret_code_tcp_flag != TPM_DB_OK) || (range_conf_tcp_flag.range_size < 2)) {
+ /* check tcp flag, need to create tcp flag range */
+ TPM_OS_WARN(TPM_INIT_MOD, "check tcp flag, need to create IPv6 tcp flag range with size of 2\n");
} else {
ret_code = tpm_proc_tcp_flag_init();
IF_ERROR(ret_code);
@@ -3906,6 +4210,20 @@
TPM_OS_DEBUG(TPM_INIT_MOD, "\n");
+ /* check PON and GMAC state */
+ for (gmac_i = 0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
+ if (!INIT_GMAC_VALID(gmac_i))
+ continue;
+
+ tpm_db_gmac_func_get(gmac_i, &gfunc);
+
+ if (gfunc == TPM_GMAC_FUNC_NONE)
+ continue;
+ if (!tpm_init_check_gmac_init(gmac_i)) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "GMAC port(%d) is not init, system is not fully functional!\n", gmac_i);
+ return TPM_FAIL;
+ }
+ }
/* Init Vlan Ethertype Registers */
ret_code = tpm_init_vlan_etype_set();
IF_ERROR(ret_code);
@@ -3946,14 +4264,17 @@
tpm_init_rxq_size_set();
/* Init marvell header configuration */
- ret_code = tpm_init_mh();
+ ret_code = tpm_init_mh(tpm_init.ds_mh_set_conf,
+ tpm_init.gmac0_mh_en,
+ tpm_init.gmac1_mh_en,
+ tpm_init.gmac_port_conf);
IF_ERROR(ret_code);
/* Init Buffer Mngmt Pool configuration */
tpm_init_bm_pool();
/* Init IPG */
- tpm_init_ipg();
+ tpm_init_ipg((-TPM_MH_LEN));
ret_code = tpm_init_system_mib_reset(reset_type);
IF_ERROR(ret_code);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.h
index 311a5be..009d272 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_init.h
@@ -102,5 +102,12 @@
int32_t tpm_module_init(void);
int32_t tpm_module_start(tpm_init_t *tpm_init);
void tpm_init_params_get(tpm_init_t *tpm_init_params);
+int32_t tpm_init_get_gmac_queue_rate_limit(void);
+int32_t tpm_init_mh(tpm_init_mh_src_t ds_mh_set_conf,
+ uint32_t gmac0_mh_en,
+ uint32_t gmac1_mh_en,
+ tpm_init_gmac_conn_conf_t *gmac_port_conf);
+int32_t tpm_init_ipg(int32_t mod_value);
+int32_t tpm_init_gmac_loopback(tpm_gmacs_enum_t port, uint8_t enable);
#endif /* _TPM_INIT_H_ */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_internal_types.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_internal_types.h
index 947432a..7f8344e 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_internal_types.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_internal_types.h
@@ -95,8 +95,6 @@
#define TPM_CHAIN_NUM_UNLIMITED (0x1000)
-#define FROM_SPEC_UNI(src) (src >= TPM_SRC_PORT_UNI_0 && src <= TPM_SRC_PORT_UNI_VIRT)
-
/* PNC Target TXP, in exact numbering scheme, do not change !! */
typedef enum {
TPM_INVALID_PNC_TRG = -1,
@@ -114,22 +112,13 @@
} tpm_pnc_trg_t;
typedef enum {
- TPM_INVALID_GMAC = -1,
- TPM_ENUM_GMAC_0,
- TPM_ENUM_GMAC_1,
- TPM_ENUM_PMAC,
- TPM_MAX_GMAC = TPM_ENUM_PMAC,
- TPM_MAX_NUM_GMACS
-} tpm_gmacs_enum_t;
-
-typedef enum {
TPM_INT_CALL = 0,
TPM_EXT_CALL
} tpm_caller_t;
#define TPM_MAX_VID (4096) /* legal VLAN ID = 0-4095 */
-#define TPM_MAX_NUM_CTC_PRECEDENCE (8)
+#define TPM_MAX_NUM_CTC_PRECEDENCE (8)
#define PON_PORT (2)
#define SW_GMAC_0 (0)
@@ -165,20 +154,22 @@
#define TPM_INTERNAL_OWNER_ID (0xABBACDDC)
+#define TPM_INVALID_QUEUE (0xFFFF)
typedef enum {
TPM_INVALID_SECTION = -1,
TPM_PNC_MAC_LEARN_ACL,
+ TPM_DS_LOAD_BALANCE_ACL,
TPM_CPU_LOOPBACK_ACL,
TPM_L2_PRIM_ACL,
TPM_L3_TYPE_ACL,
TPM_IPV4_ACL,
TPM_IPV4_MC,
+ TPM_IPV6_NH_ACL,
+ TPM_L4_ACL,
TPM_IPV6_GEN_ACL,
TPM_IPV6_DIP_ACL,
TPM_IPV6_MC_ACL,
- TPM_IPV6_NH_ACL,
- TPM_L4_ACL,
TPM_CNM_MAIN_ACL,
TPM_MAX_NUM_API_SECTIONS /* Equals to number of entries in enum */
} tpm_api_sections_t;
@@ -224,6 +215,9 @@
#define TPM_PARSE_FLAG_CNM_IPV4_MASK (TPM_PARSE_FLAG_CNM_IPV4_TRUE | TPM_PARSE_FLAG_CNM_IPV4_FALSE)
#define TPM_PARSE_FLAG_SPLIT_MOD_MASK (TPM_PARSE_FLGA_SPLIT_MOD_TRUE | TPM_PARSE_FLGA_SPLIT_MOD_FALSE)
+#define TPM_DS_LOAD_BALNC_PARSE_BM_MASK \
+ (TPM_L2_PARSE_MAC_DA | TPM_L2_PARSE_MAC_SA | TPM_L2_PARSE_ONE_VLAN_TAG | TPM_L2_PARSE_TWO_VLAN_TAG |\
+ TPM_L2_PARSE_ETYPE | TPM_L2_PARSE_PPPOE_SES | TPM_L2_PARSE_PPP_PROT | TPM_L2_PARSE_GEMPORT)
#define TPM_L2_PARSE_BM_MASK \
(TPM_L2_PARSE_MAC_DA | TPM_L2_PARSE_MAC_SA | TPM_L2_PARSE_ONE_VLAN_TAG | TPM_L2_PARSE_TWO_VLAN_TAG |\
TPM_L2_PARSE_ETYPE | TPM_L2_PARSE_PPPOE_SES | TPM_L2_PARSE_PPP_PROT | TPM_L2_PARSE_GEMPORT)
@@ -262,6 +256,7 @@
#define TPM_PARSE_FLAG_IPV4_PRE_KEY_PARSE (0x00020000LL)
#define TPM_PARSE_FLAG_CNM_PREC_PARSE (0x00040000LL)
#define TPM_PARSE_FLAG_IPV6_MC_SIP_PARSE (0x00080000LL)
+#define TPM_PARSE_FLAG_DNRT_DS_TRUNK (0x00100000LL) /* Set DNRT_DS_TRUNK bit */
/* Following additional TPM_ACTIONs for internal use, they must co-exist (not overlap)
with existing TPM_ACTIONs in types.h */
@@ -290,6 +285,7 @@
#define TPM_ACTION_UNSET_IPV4_PRE_KEY (0x00400000LL)
#define TPM_ACTION_SET_CNM_PREC (0x00800000LL)
#define TPM_ACTION_UNSET_CNM_PREC (0x01000000LL)
+#define TPM_ACTION_UNSET_DNRT_DS_TRUNK (0x02000000LL) /* Unset DNRT_DS_TRUNK bit */
#define TPM_MAX_WRR_WEIGHT (255)
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mempool.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mempool.c
index 99f1d34..7f8b193 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mempool.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mempool.c
@@ -259,10 +259,10 @@
return NULL;
hdr = (tpm_common_mpool_hdr_t *) ((uint8_t *) ptr - sizeof(tpm_common_mpool_hdr_t));
-
+
if (!hdr)
return NULL;
-
+
ftr = (tpm_common_mpool_ftr_t *) ((uint8_t *) ptr + hdr->pool->data_size);
if (hdr->magic != TPM_COMMON_MPOOL_HDR_MAGIC) {
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mtu.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mtu.c
index 75e6b8c..a911319 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mtu.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_mtu.c
@@ -109,7 +109,7 @@
pnc_range_id = TPM_PNC_IPV4_LEN;
pnc_index_cfg = &(g_tpm_mtu_cfg.ipv4_mtu_cfg.pncIndex_cfg);
} else {
- /*pnc_range_id = TPM_PNC_IPV6_LEN;
+ /*pnc_range_id = TPM_PNC_IPV6_LEN;
pnc_index_cfg = &(g_tpm_mtu_cfg.ipv6_mtu_cfg.pncIndex_cfg);*/
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "there is no length check for IPv6\n");
return ERR_GENERAL;
@@ -169,7 +169,7 @@
} else {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "there is no length check for IPv6\n");
return ERR_GENERAL;
- /*pnc_range_id = TPM_PNC_IPV6_LEN;
+ /*pnc_range_id = TPM_PNC_IPV6_LEN;
pnc_index_cfg = &(g_tpm_mtu_cfg.ipv6_mtu_cfg.pncIndex_cfg);*/
}
@@ -295,7 +295,7 @@
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "\n");
- int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_TCP_FLAG, &nextphase_range_data);
+ int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_IPV4_TCP_FLAG, &nextphase_range_data);
IF_ERROR(int_ret_code);
ipv6_frag_type_lu = nextphase_range_data.pnc_range_conf.base_lu_id;
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c
index ea0a0a0..3098a69 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.c
@@ -85,6 +85,7 @@
#include "tpm_header.h"
/* Local definitions */
+extern MV_STATUS mv_cust_set_tcont_state(uint32_t tcont, bool state);
typedef tpm_error_code_t (*tpm_proc_common_int_del_func_t) (uint32_t, uint32_t);
@@ -143,12 +144,31 @@
/* Bitmap of PNC port_ids */
static uint32_t gmac_pnc_bm[3] = { TPM_BM_GMAC_0, TPM_BM_GMAC_1, TPM_BM_PMAC};
+tpm_hot_swap_acl_recovery_t tpm_hot_swap_acl_recovery[] = {
+ {TPM_API_MAC_LEARN, tpm_acl_rcvr_func_mac_learn},
+ {TPM_API_DS_LOAD_BALANCE, tpm_acl_rcvr_func_ds_load_balance},
+ {TPM_API_CPU_LOOPBACK, tpm_acl_rcvr_func_cpu_loopback},
+ {TPM_API_L2_PRIM, tpm_acl_rcvr_func_l2_prim},
+ {TPM_API_L3_TYPE, tpm_acl_rcvr_func_l3_type},
+ {TPM_API_IPV4, tpm_acl_rcvr_func_ipv4},
+ {TPM_API_IPV4_MC, tpm_acl_rcvr_func_ipv4_mc},
+ {TPM_API_IPV6_GEN, tpm_acl_rcvr_func_ipv6_gen},
+ {TPM_API_IPV6_DIP, tpm_acl_rcvr_func_ipv6_dip},
+ {TPM_API_IPV6_MC, tpm_acl_rcvr_func_ipv6_mc},
+ {TPM_API_IPV6_NH, tpm_acl_rcvr_func_ipv6_nh},
+ {TPM_API_IPV6_L4, tpm_acl_rcvr_func_ipv6_l4},
+ {TPM_API_CNM, tpm_acl_rcvr_func_cnm},
+
+};
static tpm_api_sup_param_val_t api_sup_param_val[] = {
/* tpm_pnc_api_num Supported parse field bits
Supported parse flag bits
Forbidden actions */
+ {TPM_ADD_DS_LOAD_BALANCE_RULE, TPM_DS_LOAD_BALNC_PARSE_BM_MASK,
+ (TPM_PARSE_FLAG_TAG1_MASK | TPM_PARSE_FLAG_TAG2_MASK),
+ (0)},
{TPM_ADD_L2_PRIM_ACL_RULE, TPM_L2_PARSE_BM_MASK,
(TPM_PARSE_FLAG_TAG1_MASK | TPM_PARSE_FLAG_TAG2_MASK),
(0)},
@@ -338,6 +358,7 @@
tpm_gmacs_enum_t gmac_i;
tpm_gmac_bm_t l_gmac_bm = 0;
tpm_db_gmac_func_t gmac_func;
+ tpm_init_gmac_conn_conf_t gmac_port_conf;
for (gmac_i = TPM_ENUM_GMAC_0; gmac_i <= TPM_MAX_GMAC; gmac_i++) {
if (!tpm_db_gmac_valid(gmac_i))
@@ -351,22 +372,27 @@
/* LAN possiblilties (Note: can be from both WAN or LAN) */
- /* From UNI_$, but not Virtual_Port */
- if (src_port == TPM_SRC_PORT_UNI_VIRT) {
- if (GMAC_IS_UNI_LAN(gmac_func)) {
- l_gmac_bm = gmac_pnc_bm[gmac_i];
- break;
- }
-
- if (GMAC_IS_LAN(gmac_func))
- l_gmac_bm = gmac_pnc_bm[gmac_i];
- /* Any other UNI */
- } else if (FROM_SPEC_UNI(src_port) && GMAC_IS_LAN(gmac_func)) {
- l_gmac_bm = gmac_pnc_bm[gmac_i];
- break;
- /* Any remaining LAN option (UNI_ANY or WAN_OR_LAN) */
- } else if (FROM_LAN(src_port) && (GMAC_IS_UNI_LAN(gmac_func) || GMAC_IS_LAN(gmac_func)))
+ /* From UNI_$, include UNI_virt Port */
+ if (FROM_SPEC_UNI(src_port) && GMAC_IS_LAN(gmac_func)) {
l_gmac_bm |= gmac_pnc_bm[gmac_i];
+ //break;
+ /* Any remaining LAN option (UNI_ANY or WAN_OR_LAN) */
+ } else if (FROM_LAN(src_port) && (GMAC_IS_UNI_LAN(gmac_func) || GMAC_IS_LAN(gmac_func))) {
+ if (GMAC_IS_UNI_LAN(gmac_func)) {
+ if (tpm_db_gmac_conn_conf_get(gmac_i, &gmac_port_conf)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "gmac(%d) connection info get fail\n", gmac_i);
+ return(TPM_FAIL);
+ }
+ if (src_port == gmac_port_conf.port_src) {
+ l_gmac_bm |= gmac_pnc_bm[gmac_i];
+ break;
+ } else if (src_port == TPM_SRC_PORT_UNI_ANY) {
+ l_gmac_bm |= gmac_pnc_bm[gmac_i];
+ }
+ } else {
+ l_gmac_bm |= gmac_pnc_bm[gmac_i];
+ }
+ }
}
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "gmac_bm(0x%x)\n", l_gmac_bm);
@@ -520,25 +546,37 @@
{
tpm_gmacs_enum_t gmac_i;
tpm_db_gmac_func_t gmac_func;
- tpm_eth_complex_profile_t profile;
+ tpm_init_gmac_conn_conf_t gmac_port_conf;
if (gmac_port == NULL) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Invalid pointer-NULL \n");
return(ERR_GENERAL);
}
- /* get board profile */
- profile = tpm_db_eth_cmplx_profile_get();
-
(*gmac_port) = -1;
for (gmac_i = TPM_ENUM_GMAC_0; gmac_i <= TPM_MAX_GMAC; gmac_i++) {
if (!tpm_db_gmac_valid(gmac_i))
continue;
tpm_db_gmac_func_get(gmac_i, &gmac_func);
-
- if (((TRG_WAN(trg_port)) && GMAC_IS_WAN(gmac_func))
- || ((TRG_UNI(trg_port)) && ((!tpm_db_gmac1_lpbk_en_get()) ? GMAC_IS_LAN(gmac_func) : GMAC_IS_UNI_LAN(gmac_func)))) {
+ if (tpm_db_gmac_conn_conf_get(gmac_i, &gmac_port_conf)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "gmac(%d) connection info get fail\n", gmac_i);
+ return(TPM_FAIL);
+ }
+ /* TRG WAN */
+ if ((TRG_WAN(trg_port)) && GMAC_IS_WAN(gmac_func)) {
+ (*gmac_port) = gmac_i;
+ break;
+ /* TRG GMAC_UNI, such as MC lpk, dual gmac uni */
+ } else if (TRG_UNI(trg_port) && (GMAC_IS_UNI_LAN(gmac_func) || GMAC_IS_DS_UNI_LAN(gmac_func))) {
+ if ((gmac_port_conf.port_src != TPM_SRC_PORT_ILLEGAL) &&
+ ((trg_port == (1 << (gmac_port_conf.port_src + TPM_TRG_UNI_OFFSET))) ||
+ (trg_port == TPM_TRG_PORT_UNI_ANY))) {
+ (*gmac_port) = gmac_i;
+ break;
+ }
+ /* TRG UNI, such as KW2 */
+ } else if (TRG_UNI(trg_port) && GMAC_IS_LAN(gmac_func)) {
(*gmac_port) = gmac_i;
break;
}
@@ -590,23 +628,78 @@
return(l_gmac_bm);
}
+int32_t tpm_proc_delete_mod(tpm_mod_owner_t owner, tpm_gmacs_enum_t gmac_port, uint32_t mod_entry)
+{
+ tpm_gmacs_enum_t duplicate_gmac;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
+ int32_t ret_code;
+
+ ret_code = tpm_mod2_entry_del(owner, gmac_port, mod_entry);
+ IF_ERROR(ret_code);
+
+ /* when ds load balance on G0 and G1 is enabled, need to duplicate DS PMT on G0/1 */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if ( (TPM_DS_MAC_BASED_TRUNK_DISABLED == ds_mac_based_trunk_enable)
+ || ((gmac_port != TPM_ENUM_GMAC_0) && (gmac_port != TPM_ENUM_GMAC_1))) {
+ /* if this is US or DS_MAC_BASED_TRUNK is DISABLED, do nothing */
+ return(TPM_OK);
+ }
+
+ if (gmac_port == TPM_ENUM_GMAC_0)
+ duplicate_gmac = TPM_ENUM_GMAC_1;
+ else
+ duplicate_gmac = TPM_ENUM_GMAC_0;
+
+ ret_code = tpm_mod2_entry_del(owner, duplicate_gmac, mod_entry);
+ IF_ERROR(ret_code);
+
+ return(TPM_OK);
+}
+
int32_t tpm_proc_create_mod(tpm_pkt_action_t pkt_act, tpm_trg_port_type_t trg_port, tpm_pkt_mod_t *pkt_mod,
tpm_pkt_mod_bm_t pkt_mod_bm, tpm_pkt_mod_int_bm_t int_mod_bm, uint32_t *mod_entry,
uint32_t *trg_gmac)
{
int32_t ret_code;
+ tpm_gmacs_enum_t duplicate_gmac;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
if (SET_MOD(pkt_act)) {
/* Currently supporting Vlan operation only */
/* Get dest. gmac */
- tpm_proc_trg_port_gmac_map(trg_port, trg_gmac);
- if (*trg_gmac == -1) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD, "pkt modification not possible on this target gmac(%d) \n",
- *trg_gmac);
- return(ERR_ACTION_INVALID);
+ if (TPM_TRG_LOAD_BAL & trg_port) {
+ /* DS load balance, set trg port to G1 */
+ *trg_gmac = TPM_ENUM_GMAC_1;
+ } else {
+ tpm_proc_trg_port_gmac_map(trg_port, trg_gmac);
+ if (*trg_gmac == -1) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "pkt modification not possible on this target gmac(%d) \n",
+ *trg_gmac);
+ return(ERR_ACTION_INVALID);
+ }
+ }
+ ret_code = tpm_mod2_entry_set(TPM_MOD_OWNER_TPM, *trg_gmac, pkt_mod_bm, int_mod_bm, pkt_mod, mod_entry);
+ IF_ERROR(ret_code);
+
+ /* when ds load balance on G0 and G1 is enabled, need to duplicate DS PMT on G0/1 */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if ( (TPM_DS_MAC_BASED_TRUNK_DISABLED == ds_mac_based_trunk_enable)
+ || (TRG_WAN(trg_port))) {
+ /* if this is US or DS_MAC_BASED_TRUNK is DISABLED, do nothing */
+ return(TPM_OK);
}
- ret_code = tpm_mod2_entry_set(TPM_MOD_OWNER_TPM, *trg_gmac, pkt_mod_bm, int_mod_bm, pkt_mod, mod_entry);
+ if (*trg_gmac == TPM_ENUM_GMAC_0)
+ duplicate_gmac = TPM_ENUM_GMAC_1;
+ else if (*trg_gmac == TPM_ENUM_GMAC_1)
+ duplicate_gmac = TPM_ENUM_GMAC_0;
+ else {
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "target gmac(%d) invalid\n", *trg_gmac);
+ return(TPM_OK);
+ }
+
+ ret_code = tpm_mod2_entry_set(TPM_MOD_OWNER_TPM, duplicate_gmac,
+ pkt_mod_bm, int_mod_bm, pkt_mod, mod_entry);
IF_ERROR(ret_code);
}
return(TPM_OK);
@@ -660,13 +753,21 @@
int32_t tpm_proc_check_valid_target(tpm_dir_t dir,
tpm_db_pon_type_t pon_type,
+ tpm_src_port_type_t src_port,
tpm_trg_port_type_t trg_port,
uint8_t trg_queue,
- tpm_pkt_action_t pkt_act)
+ tpm_pkt_action_t pkt_act,
+ uint8_t ds_load_bal_valid)
{
tpm_init_virt_uni_t virt_uni_info;
int32_t ret_code;
+ uint32_t rx_queue_valid, rx_queue_size;
+ tpm_gmac_bm_t gmac_bm;
+ tpm_gmacs_enum_t gmac;
+ uint32_t tx_queue_valid, tx_queue_size;
+ tpm_db_txq_owner_t tx_owner;
+ tpm_db_tx_mod_t tx_port;
tpm_gmacs_enum_t act_wan= tpm_db_active_wan_get();
/* Check Valid Target */
@@ -678,6 +779,20 @@
/* check target uni port valid or not */
ret_code = tpm_proc_check_dst_uni_port(trg_port);
IF_ERROR(ret_code);
+
+ /* check ds load balance trg */
+ if (trg_port & TPM_TRG_LOAD_BAL) {
+ if (!ds_load_bal_valid) {
+ /* TPM_TRG_LOAD_BAL should not be set */
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "TPM_TRG_LOAD_BAL should not be set\n");
+ return(ERR_FRWD_INVALID);
+ }
+ if (!tpm_db_ds_load_bal_en_get()) {
+ /* profile dose not support TPM_TRG_LOAD_BAL */
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "profile dose not support TPM_TRG_LOAD_BAL\n");
+ return(ERR_FRWD_INVALID);
+ }
+ }
} else {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "* dir=%d, trg_port=%d, pon_type=%d *\r\n", dir, trg_port,
pon_type);
@@ -704,11 +819,101 @@
}
/* Check Valid Queue */
+ tpm_proc_src_port_gmac_bm_map(src_port, &gmac_bm);
/* TODO - Check Queue depending on actual queues in target or in Rx */
if (SET_TARGET_QUEUE(pkt_act) && (trg_queue >= TPM_MAX_NUM_TX_QUEUE)) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target Queue Out of Range\n");
return(ERR_FRWD_INVALID);
}
+ /* Check Rx queue valid */
+ if (SET_TARGET_PORT(pkt_act) && TO_CPU(trg_port) && SET_TARGET_QUEUE(pkt_act)) {
+ for (gmac = TPM_ENUM_GMAC_0; gmac < TPM_MAX_NUM_GMACS; gmac++) {
+ if (((gmac_bm & TPM_BM_GMAC_0) && (gmac == TPM_ENUM_GMAC_0)) ||
+ ((gmac_bm & TPM_BM_GMAC_1) && (gmac == TPM_ENUM_GMAC_1)) ||
+ ((gmac_bm & TPM_BM_PMAC) && (gmac == TPM_ENUM_PMAC))) {
+ /* Get Rx queue info */
+ ret_code = tpm_db_gmac_rx_q_conf_get(gmac, trg_queue, &rx_queue_valid, &rx_queue_size);
+ if (ret_code != TPM_DB_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, " rx queue recvd ret_code(%d)\n", ret_code);
+ return(ERR_FRWD_INVALID);
+ }
+
+ /* Check queue valid state */
+ if (TPM_FALSE == rx_queue_valid) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target Queue Invalid\n");
+ return(ERR_FRWD_INVALID);
+ }
+
+ /* Check queue size */
+ if (0 == rx_queue_size) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target Queue Size is Zero\n");
+ return(ERR_FRWD_INVALID);
+ }
+ }
+ }
+ }
+
+ /* Check Tx queue valid */
+ if (SET_TARGET_PORT(pkt_act) && (!TO_CPU(trg_port)) && SET_TARGET_QUEUE(pkt_act)) {
+ tpm_proc_trg_port_gmac_map(trg_port, &gmac);
+ for (tx_port = TPM_TX_MOD_GMAC0; tx_port < TPM_MAX_NUM_TX_PORTS; tx_port++) {
+ if (((trg_port & TPM_TRG_TCONT_0) && (act_wan == TPM_ENUM_PMAC) && (tx_port == TPM_TX_MOD_PMAC_0)) ||
+ ((trg_port & TPM_TRG_TCONT_0) && (act_wan == TPM_ENUM_GMAC_0) && (tx_port == TPM_TX_MOD_GMAC0)) ||
+ ((trg_port & TPM_TRG_TCONT_0) && (act_wan == TPM_ENUM_GMAC_1) && (tx_port == TPM_TX_MOD_GMAC1)) ||
+ ((trg_port & TPM_TRG_TCONT_1) && (tx_port == TPM_TX_MOD_PMAC_1)) ||
+ ((trg_port & TPM_TRG_TCONT_2) && (tx_port == TPM_TX_MOD_PMAC_2)) ||
+ ((trg_port & TPM_TRG_TCONT_3) && (tx_port == TPM_TX_MOD_PMAC_3)) ||
+ ((trg_port & TPM_TRG_TCONT_4) && (tx_port == TPM_TX_MOD_PMAC_4)) ||
+ ((trg_port & TPM_TRG_TCONT_5) && (tx_port == TPM_TX_MOD_PMAC_5)) ||
+ ((trg_port & TPM_TRG_TCONT_6) && (tx_port == TPM_TX_MOD_PMAC_6)) ||
+ ((trg_port & TPM_TRG_TCONT_7) && (tx_port == TPM_TX_MOD_PMAC_7)) ||
+ ((trg_port & (TPM_TRG_UNI_0 |
+ TPM_TRG_UNI_1 |
+ TPM_TRG_UNI_2 |
+ TPM_TRG_UNI_3 |
+ TPM_TRG_UNI_4 |
+ TPM_TRG_UNI_5 |
+ TPM_TRG_UNI_6 |
+ TPM_TRG_UNI_7 |
+ TPM_TRG_UNI_VIRT |
+ TPM_TRG_PORT_UNI_ANY)) && (tx_port == (tpm_db_tx_mod_t)gmac))) {
+ /* Get Tx queue info */
+ ret_code = tpm_db_gmac_tx_q_conf_get(tx_port,
+ trg_queue,
+ &tx_queue_valid,
+ NULL,
+ &tx_owner,
+ NULL,
+ &tx_queue_size,
+ NULL);
+ if (ret_code != TPM_DB_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, " tx queue recvd ret_code(%d)\n", ret_code);
+ return(ERR_FRWD_INVALID);
+ }
+
+ /* Check queue valid state */
+ if (TPM_FALSE == tx_queue_valid) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target Queue Invalid\n");
+ return(ERR_FRWD_INVALID);
+ }
+
+ /* Check queue owner */
+ if (((gmac_bm & TPM_BM_GMAC_0) && (tx_owner != TPM_Q_OWNER_GMAC0)) ||
+ ((gmac_bm & TPM_BM_GMAC_1) && (tx_owner != TPM_Q_OWNER_GMAC1)) ||
+ ((gmac_bm & TPM_BM_PMAC) && (tx_owner != TPM_Q_OWNER_PMAC))) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target Queue Owner Invalid, gmac_bm: [%d], tx_owner: [%d]\n",
+ gmac_bm, tx_owner);
+ return(ERR_FRWD_INVALID);
+ }
+
+ /* check queue size */
+ if (0 == tx_queue_size) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target Queue Size is Zero\n");
+ return(ERR_FRWD_INVALID);
+ }
+ }
+ }
+ }
return(TPM_OK);
}
@@ -779,6 +984,47 @@
return(TPM_OK);
}
+/* Get GMAC Lan UNI number and UNI port number */
+/*******************************************************************************
+* tpm_proc_gmaclanuni_uninum_get()
+*
+* DESCRIPTION: The function Get GMAC Lan UNI number and UNI port number.
+*
+* INPUTS:
+* src_port - None
+*
+* OUTPUTS:
+* gmac_is_uni_num - number of GMAC which is LAN UNI
+* max_uni_port_num - number os UNI ports
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_proc_gmaclanuni_uninum_get(uint32_t *gmac_is_uni_num, uint32_t *max_uni_port_num)
+{
+ tpm_db_gmac_func_t gmac_func;
+ tpm_gmacs_enum_t gmac_i;
+ uint32_t temp1 = 0, temp2 = 0;
+
+ /* Cal number of GMAC LAN UNI */
+ for (gmac_i = TPM_ENUM_GMAC_0; gmac_i <= TPM_MAX_GMAC; gmac_i++) {
+ tpm_db_gmac_func_get(gmac_i, &gmac_func);
+ if (GMAC_IS_UNI_LAN(gmac_func))
+ temp1++;
+ }
+ /* Get Max UNI port number */
+ tpm_db_max_uni_port_nr_get(&temp2);
+
+ *gmac_is_uni_num = temp1;
+ *max_uni_port_num = temp2;
+
+ return (TPM_OK);
+}
+
/*******************************************************************************
* tpm_proc_src_port_check()
*
@@ -804,6 +1050,7 @@
tpm_db_int_conn_t dummy_int_conn;
uint32_t dummy_switch_port;
tpm_init_virt_uni_t virt_uni_info;
+ uint32_t gmac_is_uni_num = 0, max_uni_port_num = 0;
/* Check Port exists */
if (src_port == TPM_SRC_PORT_WAN) {
@@ -824,9 +1071,17 @@
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Source UNI Port (%d) is not valid port \n", src_port);
return(TPM_FAIL);
}
- } else if (src_port == TPM_SRC_PORT_UNI_ANY)
+ } else if (src_port == TPM_SRC_PORT_UNI_ANY) {
+ /* Check UNI_ANY is supported or not */
+ /* Get GMAC LAN_UNI and UNI ports number */
+ tpm_proc_gmaclanuni_uninum_get(&gmac_is_uni_num, &max_uni_port_num);
+ if (gmac_is_uni_num > TPM_SRC_PORT_UNI_1 ||
+ (gmac_is_uni_num == TPM_SRC_PORT_UNI_1 && max_uni_port_num > TPM_SRC_PORT_UNI_1)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Src port UNI_ANY is not supported\n");
+ return(ERR_SRC_PORT_INVALID);
+ }
return(TPM_OK);
- else if (src_port == TPM_SRC_PORT_UNI_VIRT) {
+ } else if (src_port == TPM_SRC_PORT_UNI_VIRT) {
tpm_db_virt_info_get(&virt_uni_info);
if (TPM_VIRT_UNI_DISABLED == virt_uni_info.enabled) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "UNI_VIRT is not enabled\n");
@@ -972,6 +1227,7 @@
tpm_pncl_sram_data_t *sram_data)
{
uint32_t i;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
if (SET_TARGET_PORT(rule_action->pkt_act)) {
tpm_gmacs_enum_t act_wan= tpm_db_active_wan_get();
@@ -999,13 +1255,22 @@
return(TPM_FAIL);
}
} else if (TO_LAN(dir, pkt_frwd->trg_port)) {
- tpm_trg_port_type_t pnc_target;
+ tpm_pnc_trg_t pnc_target;
- if (tpm_db_to_lan_gmac_get(pkt_frwd->trg_port, &pnc_target) != TPM_DB_OK){
+ /* when ds load balance on G0 and G1 is enabled, trgt port can only
+ * be set in the first range TPM_DS_MAC_BASED_TRUNKING.
+ */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable) {
+ sram_data->sram_updt_bm &= (~TPM_PNCL_SET_TXP);
+ } else if (TPM_TRG_LOAD_BAL & pkt_frwd->trg_port) {
+ /* DS load balance, set trg port to G1 */
+ pnc_target = TPM_PNC_TRG_GMAC1;
+ } else if (tpm_db_to_lan_gmac_get(pkt_frwd->trg_port, &pnc_target) != TPM_DB_OK){
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "tpm_db_to_lan_gmac_get failed trg_port 0x%x\n",
pkt_frwd->trg_port);
return(TPM_FAIL);
- }
+ }
sram_data->flow_id_sub.pnc_target = pnc_target;
} else if (TO_CPU(pkt_frwd->trg_port)) {
sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_CPU;
@@ -1135,6 +1400,41 @@
return(rc_code);
}
+int32_t tpm_proc_check_all_api_busy(void)
+{
+ uint32_t db_ret_code;
+ int32_t rc_code = TPM_RC_OK;
+ int32_t rule_num;
+ int32_t rule_num_max;
+ tpm_api_sections_t api_section;
+ tpm_pnc_ranges_t range_id;
+ tpm_db_pnc_range_conf_t rangConf;
+ tpm_api_type_t api_type;
+
+ for (api_type = TPM_API_MAC_LEARN; api_type < TPM_MAX_API_TYPES; api_type++) {
+
+ /* Get api_section, range_Id, range configuration, to get range type */
+ db_ret_code = tpm_db_api_section_get_from_api_type(api_type, &api_section);
+ IF_ERROR(db_ret_code);
+ db_ret_code = tpm_db_api_section_main_pnc_get(api_section, &range_id);
+ if (TPM_DB_OK != db_ret_code)
+ continue;
+ db_ret_code = tpm_db_pnc_rng_conf_get(range_id, &rangConf);
+ IF_ERROR(db_ret_code);
+
+ if (rangConf.range_type == TPM_RANGE_TYPE_ACL)
+ rule_num_max = 1;
+ else
+ rule_num_max = TPM_MAX_PARALLEL_API_CALLS;
+
+ for (rule_num = 0; rule_num < rule_num_max; rule_num++) {
+ rc_code = tpm_proc_check_api_busy(api_type, rule_num);
+ IF_ERROR(rc_code);
+ }
+ }
+
+ return(TPM_OK);
+}
int32_t tpm_proc_api_busy_done(tpm_api_type_t api_type, uint32_t rule_num)
{
@@ -1151,6 +1451,42 @@
return(rc_code);
}
+int32_t tpm_proc_all_api_busy_done(void)
+{
+ uint32_t db_ret_code;
+ int32_t rc_code = TPM_RC_OK;
+ int32_t rule_num;
+ int32_t rule_num_max;
+ tpm_api_sections_t api_section;
+ tpm_pnc_ranges_t range_id;
+ tpm_db_pnc_range_conf_t rangConf;
+ tpm_api_type_t api_type;
+
+ for (api_type = TPM_API_MAC_LEARN; api_type < TPM_MAX_API_TYPES; api_type++) {
+
+ /* Get api_section, range_Id, range configuration, to get range type */
+ db_ret_code = tpm_db_api_section_get_from_api_type(api_type, &api_section);
+ IF_ERROR(db_ret_code);
+ db_ret_code = tpm_db_api_section_main_pnc_get(api_section, &range_id);
+ if (TPM_DB_OK != db_ret_code)
+ continue;
+ db_ret_code = tpm_db_pnc_rng_conf_get(range_id, &rangConf);
+ IF_ERROR(db_ret_code);
+
+ if (rangConf.range_type == TPM_RANGE_TYPE_ACL)
+ rule_num_max = 1;
+ else
+ rule_num_max = TPM_MAX_PARALLEL_API_CALLS;
+
+ for (rule_num = 0; rule_num < rule_num_max; rule_num++) {
+ rc_code = tpm_proc_api_busy_done(api_type, rule_num);
+ IF_ERROR(rc_code);
+ }
+ }
+
+ return(TPM_OK);
+}
+
int32_t tpm_proc_parse_flag_ai_tcam_build(tpm_ai_vectors_t *ai_fields,
@@ -1281,6 +1617,11 @@
*ai_mask |= TPM_AI_SPLIT_MOD_MASK;
}
+ if (parse_int_flags & TPM_PARSE_FLAG_DNRT_DS_TRUNK) {
+ *ai_data &= ~(TPM_AI_DNRT_DS_TRUNK_MASK);
+ *ai_mask |= TPM_AI_DNRT_DS_TRUNK_MASK;
+ }
+
/*BIT_4 */
if (parse_int_flags & TPM_PARSE_FLAG_UNI_PORT_PARSE) {
if (ai_fields == NULL) {
@@ -1360,6 +1701,10 @@
*ai_data &= ~(TPM_AI_DNRT_MASK);
*ai_mask |= TPM_AI_DNRT_MASK;
}
+ if (int_pkt_action & TPM_ACTION_UNSET_DNRT_DS_TRUNK) {
+ *ai_data &= ~(TPM_AI_DNRT_DS_TRUNK_MASK);
+ *ai_mask |= TPM_AI_DNRT_DS_TRUNK_MASK;
+ }
if (int_pkt_action & TPM_ACTION_UNSET_UNI_PORT) {
*ai_data &= ~(TPM_AI_UNI_MASK);
@@ -1556,6 +1901,8 @@
*******************************************************************************/
int32_t tpm_proc_virt_uni_trg_port_validation(tpm_trg_port_type_t trg_port)
{
+ /* unset TPM_TRG_LOAD_BAL first, since it can be mixed with UNI port */
+ trg_port &= (~TPM_TRG_LOAD_BAL);
if ((trg_port == TPM_TRG_UNI_0) ||
(trg_port == TPM_TRG_UNI_1) ||
@@ -1779,7 +2126,8 @@
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_bm */
@@ -1927,6 +2275,105 @@
return(TPM_RC_OK);
}
+/*******************************************************************************
+* tpm_proc_add_ds_load_balance_check()
+*
+* DESCRIPTION: The function checks consistency of the tpm_proc_add_ds_load_balance_acl_rule params.
+*
+* INPUTS:
+* owner_id - See tpm_proc_add_ds_load_balance_acl_rule
+* rule_num - See tpm_proc_add_ds_load_balance_acl_rule
+* parse_rule_bm - See tpm_proc_add_ds_load_balance_acl_rule
+* l2_key - See tpm_proc_add_ds_load_balance_acl_rule
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_add_ds_load_balance_check(uint32_t owner_id,
+ uint32_t rule_num,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l2_acl_key_t *l2_key)
+{
+ int32_t ret_code;
+ tpm_pnc_ranges_t range_id = 0;
+ tpm_db_pnc_range_conf_t rangConf;
+
+ /* Check TPM was successfully initialized */
+ if (!tpm_db_init_done_get())
+ IF_ERROR(ERR_SW_NOT_INIT);
+
+ /* Get Range_Id, rang configuration, to get range type */
+ ret_code = tpm_db_api_section_main_pnc_get(TPM_DS_LOAD_BALANCE_ACL, &range_id);
+ IF_ERROR(ret_code);
+ ret_code = tpm_db_pnc_rng_conf_get(range_id, &rangConf);
+ IF_ERROR(ret_code);
+
+ /* Check necessary pointers are valid */
+ if ((l2_key == NULL) && (parse_rule_bm != 0)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Parsing requested with NULL pointer\n");
+ return(ERR_FRWD_INVALID);
+ }
+ IF_ERROR(ret_code);
+
+ /* Check parse_rule_bm */
+ if (parse_rule_bm & (~(api_sup_param_val[TPM_ADD_DS_LOAD_BALANCE_RULE].sup_parse_fields))) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Invalid parse_rule_bm(0x%x) \n", parse_rule_bm);
+ return(ERR_PARSE_MAP_INVALID);
+ }
+
+ /* Check parse_flag_bm */
+ if (parse_flags_bm & (~(api_sup_param_val[TPM_ADD_DS_LOAD_BALANCE_RULE].sup_parse_flags))) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Invalid parse_flags_bm(0x%x) \n", parse_flags_bm);
+ return(ERR_PARSE_MAP_INVALID);
+ }
+
+ /* Check Vlan Tag TPID mask */
+ if (parse_rule_bm & (TPM_L2_PARSE_TWO_VLAN_TAG | TPM_L2_PARSE_ONE_VLAN_TAG)) {
+ if ((l2_key->vlan1.tpid_mask != 0) && (l2_key->vlan1.tpid_mask != 0xffff)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Invalid vlan1 tpid mask(0x%x) \n", l2_key->vlan1.tpid_mask);
+ return(ERR_L2_KEY_INVALID);
+ }
+
+ if (parse_rule_bm & TPM_L2_PARSE_ONE_VLAN_TAG) {
+ if ((l2_key->vlan2.tpid_mask != 0) && (l2_key->vlan2.tpid_mask != 0xffff)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Invalid vlan2 tpid mask(0x%x) \n", l2_key->vlan2.tpid_mask);
+ return(ERR_L2_KEY_INVALID);
+ }
+ }
+ }
+
+ /* Cannot do Double Vlan Tag with looking into PPPoE (up to 24Bytes) with MH */
+ if ((parse_rule_bm & TPM_L2_PARSE_TWO_VLAN_TAG) &&
+ ((parse_rule_bm & TPM_L2_PARSE_PPP_PROT) || (parse_rule_bm & TPM_L2_PARSE_PPPOE_SES))) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Parse map of Double Vlan Tag + PPPoE not supported\n");
+ return(ERR_PARSE_MAP_INVALID);
+ }
+
+ /* Cannot do Single or Double Vlan Tag with checking PPP protocol (up to 24Bytes) with MH */
+ if (((parse_rule_bm & TPM_L2_PARSE_TWO_VLAN_TAG) || (parse_rule_bm & TPM_L2_PARSE_ONE_VLAN_TAG))
+ && (parse_rule_bm & TPM_L2_PARSE_PPP_PROT)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Parse map of Single Vlan Tag + PPPoE proto not supported\n");
+ return(ERR_PARSE_MAP_INVALID);
+ }
+
+ /* Check owner_id */
+ ret_code = tpm_owner_id_check(TPM_API_DS_LOAD_BALANCE, owner_id);
+ if (ret_code != TPM_OK)
+ IF_ERROR(ERR_OWNER_INVALID);
+
+ /* Check rule_num, and api_section is active */
+ ret_code = tpm_proc_add_api_ent_check(TPM_DS_LOAD_BALANCE_ACL, rangConf.range_type, rule_num);
+ if (ret_code != TPM_OK)
+ IF_ERROR(ERR_RULE_NUM_INVALID);
+
+ return(TPM_RC_OK);
+}
+
tpm_error_code_t tpm_proc_add_ipv6_gen_check(uint32_t owner_id,
tpm_src_port_type_t src_port,
@@ -1971,7 +2418,8 @@
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_bm */
@@ -2074,7 +2522,8 @@
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_rule_bm */
@@ -2117,7 +2566,7 @@
}
/* Check forwarding rule, currently only support STAGE_DONE */
- if (rule_action->next_phase != STAGE_IPv6_NH && rule_action->next_phase != STAGE_DONE) {
+ if (rule_action->next_phase != STAGE_DONE) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, " Next Phase (%d) is not supported \n", rule_action->next_phase);
return(ERR_NEXT_PHASE_INVALID);
}
@@ -2176,7 +2625,8 @@
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_rule_bm */
@@ -2254,6 +2704,7 @@
tpm_db_pnc_range_t range_data;
tpm_pkt_mod_t pkt_mod;
tpm_pkt_mod_bm_t pkt_mod_bm = 0;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
/* Check TPM was successfully initialized */
if (!tpm_db_init_done_get())
@@ -2345,6 +2796,15 @@
return(ERR_ACTION_INVALID);
}
+ /* when ds load balance on G0 and G1 is enabled, no 2 NH rule can be added */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if ( (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable)
+ && (NH_ITER_1 == nh_iter)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "when ds load balance on G0 and G1 is enabled, "
+ "no 2 NH rule can be added\n");
+ return(ERR_FEAT_UNSUPPORT);
+ }
+
return(TPM_RC_OK);
}
@@ -2407,7 +2867,8 @@
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_TRUE);
IF_ERROR(ret_code);
/* Check Packet Modification */
@@ -2565,7 +3026,8 @@
*lu_id = range_conf.base_lu_id;
start_offset->range_id = range_id;
- if (range_id == TPM_PNC_L2_MAIN || range_id == TPM_PNC_MAC_LEARN) {
+ if ( range_id == TPM_PNC_L2_MAIN || range_id == TPM_PNC_MAC_LEARN
+ || range_id == TPM_PNC_DS_LOAD_BALANCE) {
start_offset->offset_base = TPM_PNCL_ZERO_OFFSET;
start_offset->offset_sub.subf = TPM_L2_PARSE_MH;
} else if (range_id == TPM_PNC_ETH_TYPE) {
@@ -2683,6 +3145,9 @@
if (rule_action->pkt_act & TPM_ACTION_SPEC_MC_VID)
return false;
+ if (!SET_MOD(rule_action->pkt_act))
+ return false;
+
if (STAGE_DONE == rule_action->next_phase)
return false;
@@ -2842,7 +3307,7 @@
}
/* Unset DNRT bit (Do not Repeat Tags Phase), the bit is leftover from previous hardcoded Vlan_tags phase */
- int_pkt_act |= TPM_ACTION_UNSET_DNRT;
+ int_pkt_act |= (TPM_ACTION_UNSET_DNRT | TPM_ACTION_UNSET_DNRT_DS_TRUNK);
/* Set UNI Port */
if (FROM_SPEC_UNI(src_port)) {
@@ -2917,6 +3382,136 @@
}
/*******************************************************************************
+* tpm_proc_ds_load_balance_tcam_build()
+*
+* DESCRIPTION: Function builds a logical TCAM entry from the API data
+*
+* INPUTS:
+* rule_num - API rule number
+* l2_key - layer2 key data
+* parse_rule_bm - Parse rules bitmap
+*
+* OUTPUTS:
+* tcam_data - Logical TCAM Structure
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_proc_ds_load_balance_tcam_build(uint32_t rule_num,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_pncl_tcam_data_t *tcam_data)
+{
+ tpm_gmac_bm_t gmac_bm;
+ uint32_t lu_id;
+ tpm_pncl_offset_t start_offset;
+ int32_t ret_code;
+ long long parse_int_flags = 0;
+
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " rule_num(%d) parse_rule_bm(%x) \n", rule_num, parse_rule_bm);
+
+ /* L2 Parsing, according to bm in param */
+ tcam_data->l2_parse_bm = parse_rule_bm;
+
+ /* do not repeat this section again */
+ parse_int_flags |= TPM_PARSE_FLAG_DNRT_DS_TRUNK;
+
+ tpm_proc_parse_flag_ai_tcam_build(NULL, parse_flags_bm, parse_int_flags,
+ &(tcam_data->add_info_data), &(tcam_data->add_info_mask));
+
+ /*Parse MH for specific src_port or for gemport_parse request */
+ if (parse_rule_bm & TPM_L2_PARSE_GEMPORT)
+ tcam_data->l2_parse_bm |= TPM_L2_PARSE_MH;
+
+ /* Get GMAC(s) */
+ tpm_proc_src_port_gmac_bm_map(TPM_SRC_PORT_WAN, &gmac_bm);
+ tcam_data->port_ids = gmac_bm;
+
+ /* Copy in logical PnC Key */
+ tcam_data->pkt_key.src_port = TPM_SRC_PORT_WAN;
+ if (l2_key)
+ memcpy(&(tcam_data->pkt_key.l2_key), l2_key, sizeof(tpm_l2_acl_key_t));
+
+ /* Get PNC Range information */
+ ret_code = tpm_proc_common_pncl_info_get(TPM_PNC_DS_LOAD_BALANCE, &lu_id, &start_offset);
+ IF_ERROR(ret_code);
+ tcam_data->lu_id = lu_id;
+ memcpy(&(tcam_data->start_offset), &start_offset, sizeof(tpm_pncl_offset_t));
+
+ return(TPM_OK);
+}
+
+/*******************************************************************************
+* tpm_proc_ds_load_balance_sram_build()
+*
+* DESCRIPTION: Function builds a logical SRAM entry from the API data
+*
+* INPUTS:
+* rule_num - API rule number
+* l2_key - layer2 key data
+* parse_rule_bm - Parse rules bitmap
+*
+* OUTPUTS:
+* sram_data - Logical SRAM Structure
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_proc_ds_load_balance_sram_build(uint32_t rule_num,
+ tpm_pncl_sram_data_t *sram_data,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_ds_load_balance_tgrt_t tgrt_port)
+{
+ int32_t ret_code;
+ tpm_db_pnc_range_conf_t range_conf;
+ uint32_t cpu_rx_queue = 0;
+
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " rule_num(%d) \n", rule_num);
+
+ sram_data->add_info_data |= (1 << TPM_AI_DNRT_DS_TRUNK_BIT_OFF);
+ sram_data->add_info_mask |= TPM_AI_DNRT_DS_TRUNK_MASK;
+
+ /* Update dummy register (offset automatically=zero) */
+ sram_data->shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
+
+ ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_L2_MAIN, &range_conf);
+ IF_ERROR(ret_code);
+
+ sram_data->next_lu_id = range_conf.base_lu_id;
+ sram_data->next_lu_off_reg = TPM_PNC_LU_REG0;
+
+ /* For Target set PNC TXP, GemPort */
+ sram_data->sram_updt_bm = TPM_PNCL_SET_TXP;
+ sram_data->pnc_queue = TPM_PNCL_NO_QUEUE_UPDATE;
+ if (TPM_DS_TGRT_G0 == tgrt_port)
+ sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_GMAC0;
+ else if (TPM_DS_TGRT_G1 == tgrt_port)
+ sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_GMAC1;
+ else {
+ /* Set lookup done and target */
+ sram_data->sram_updt_bm |= TPM_PNCL_SET_LUD;
+ sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_CPU;
+ tpm_db_get_cpu_rx_queue(&cpu_rx_queue);
+ sram_data->pnc_queue = cpu_rx_queue;
+
+ /* Set L3, L4 to OTHER */
+ sram_data->sram_updt_bm |= (TPM_PNCL_SET_L3 | TPM_PNCL_SET_L4);
+ sram_data->l3_type = TPM_PNCL_L3_OTHER;
+ sram_data->l4_type = TPM_PNCL_L4_OTHER;
+ }
+ return(TPM_OK);
+}
+
+/*******************************************************************************
* tpm_proc_ipv4_tcam_build()
*
* DESCRIPTION: Function builds a logical TCAM entry from the API data
@@ -3169,7 +3764,7 @@
l4_parse = ((ipv4_parse_bm & TPM_PARSE_L4_SRC) || (ipv4_parse_bm & TPM_PARSE_L4_DST));
if (l4_parse && (sram_data->l4_type == TPM_PNCL_L4_TCP)) {
sram_data->next_lu_off_reg = TPM_PNC_LU_REG1;
- ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_TCP_FLAG, &range_conf);
+ ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_IPV4_TCP_FLAG, &range_conf);
IF_ERROR(ret_code);
}
/* For any other NAPT/ROUTE, check TTL */
@@ -4313,7 +4908,7 @@
/* Check whether CPU loopback entry number exceed the Max value */
lpbk_num = tpm_proc_get_cpu_lpbk_entry_num();
- if (lpbk_num > TPM_MAX_CPU_LOOPBACK_ENTRY) {
+ if (lpbk_num >= TPM_MAX_CPU_LOOPBACK_ENTRY) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "%s[Line(%d)]:(%d) Exceed MAX entry number\r\n", __func__, __LINE__,
lpbk_num);
return ERR_GENERAL;
@@ -4490,9 +5085,9 @@
{
tpm_error_code_t ret_code;
int32_t int_ret_code;
- uint32_t pnc_entry = 0, mod_entry = 0, api_rng_entries = 0;
+ uint32_t pnc_entry = 0, mod_entry = 0, mod_entry_tmp = 0, api_rng_entries = 0;
uint32_t l_rule_idx = 0, bi_dir = 0, update_sram_only = 0;
- tpm_gmacs_enum_t trg_gmac;
+ tpm_gmacs_enum_t trg_gmac, duplicate_gmac;
tpm_dir_t dir = 0;
tpm_pnc_ranges_t range_id = 0;
tpm_db_pon_type_t pon_type = 0;
@@ -4505,6 +5100,7 @@
tpm_db_pnc_range_t range_data;
tpm_db_pnc_range_conf_t rangConf;
tpm_api_lu_conf_t lu_conf;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
/* Set Structs to zero */
tpm_proc_set_int_structs(&pnc_data, &start_offset, &api_data, &pnc_conn, &range_data);
@@ -4570,15 +5166,15 @@
}
}
- if (!update_sram_only) {
- if (SET_MOD(rule_action->pkt_act)) {
- if (tpm_proc_trg_port_gmac_map(pkt_frwd->trg_port, &trg_gmac)) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD, "tpm_proc_trg_port_gmac_map failed \n");
- return(ERR_MOD_INVALID);
- } else if (trg_gmac == TPM_INVALID_GMAC) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target gmac invalid (%d) \n", trg_gmac);
- return(ERR_MOD_INVALID);
- }
+ if ( (!update_sram_only)
+ && (SET_MOD(rule_action->pkt_act))) {
+
+ if (tpm_proc_trg_port_gmac_map(pkt_frwd->trg_port, &trg_gmac)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "tpm_proc_trg_port_gmac_map failed \n");
+ return(ERR_MOD_INVALID);
+ } else if (trg_gmac == TPM_INVALID_GMAC) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Target gmac invalid (%d) \n", trg_gmac);
+ return(ERR_MOD_INVALID);
}
/* if split mod is enable, add split rule if possible*/
@@ -4592,13 +5188,13 @@
TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "failed to add pmt split mod stage-1\n");
return(TPM_FAIL);
}
- int_ret_code = tpm_db_mod2_split_mod_get_vlan_index(trg_gmac, pkt_mod, &mod_entry);
+ int_ret_code = tpm_db_mod2_split_mod_get_vlan_index(trg_gmac, pkt_mod, &mod_entry_tmp);
if (TPM_DB_OK != int_ret_code) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "split mod stage-1, failed to get pmt entry\n");
return ERR_MOD_INVALID;
}
- mod_entry *= 16;
+ mod_entry = mod_entry_tmp * 16;
/* VLANOP_EXT_TAG_MOD_INS mod insert VLAN p_bit*/
if (VLANOP_EXT_TAG_MOD_INS == pkt_mod->vlan_mod.vlan_op) {
@@ -4610,6 +5206,28 @@
}
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "Set Modification mod_cmd(%d)\n", mod_entry);
+
+ /* when ds load balance on G0 and G1 is enabled, need to duplicate DS PMT on G0/1 */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if ( (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable)
+ && (TPM_ENUM_GMAC_0 == trg_gmac || TPM_ENUM_GMAC_1 == trg_gmac)) {
+
+ /* if this is DS and DS_MAC_BASED_TRUNK is ENABLED */
+ if (trg_gmac == TPM_ENUM_GMAC_0)
+ duplicate_gmac = TPM_ENUM_GMAC_1;
+ else
+ duplicate_gmac = TPM_ENUM_GMAC_0;
+
+ ret_code = tpm_mod2_split_mod_create_l2_pmts(duplicate_gmac, pkt_mod, false);
+ if (TPM_RC_OK != ret_code)
+ {
+ TPM_OS_ERROR(TPM_MODZ2_HM_MOD,
+ "failed to add pmt split mod stage-1 for duplicate GMAC\n");
+ tpm_mod2_split_mod_try_pmt_entry_del(TPM_L2_PRIM_ACL, trg_gmac, mod_entry_tmp);
+ return(TPM_FAIL);
+ }
+
+ }
} else if((TPM_SPLIT_MOD_ENABLED == tpm_db_split_mod_get_enable()) &&
(TPM_VLAN_MOD == pkt_mod_bm) &&
(VLANOP_NOOP == pkt_mod->vlan_mod.vlan_op) &&
@@ -4729,6 +5347,171 @@
return(TPM_RC_OK);
}
+
+/*******************************************************************************
+* tpm_proc_add_ds_load_balance_acl_rule()
+*
+* DESCRIPTION: Main function for adding DS load balance API rule.
+*
+* INPUTS:
+* All inputs/outputs are same as API call
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_add_ds_load_balance_acl_rule(uint32_t owner_id,
+ uint32_t rule_num,
+ uint32_t *rule_idx,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_ds_load_balance_tgrt_t tgrt_port)
+{
+ tpm_error_code_t ret_code;
+ int32_t int_ret_code;
+ uint32_t pnc_entry = 0, api_rng_entries = 0;
+ uint32_t l_rule_idx = 0;
+ uint32_t bi_dir;
+ tpm_pnc_ranges_t range_id = 0;
+ tpm_db_mod_conn_t mod_con = { 0, 0};
+
+ tpm_pncl_pnc_full_t pnc_data;
+ tpm_pncl_offset_t start_offset;
+ tpm_rule_entry_t api_data;
+ tpm_db_pnc_conn_t pnc_conn;
+ tpm_db_pnc_range_t range_data;
+ tpm_db_pnc_range_conf_t rangConf;
+ tpm_api_lu_conf_t lu_conf;
+
+ /* Set Structs to zero */
+ tpm_proc_set_int_structs(&pnc_data, &start_offset, &api_data, &pnc_conn, &range_data);
+
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " owner(%d), rule_num(%d)\n", owner_id, rule_num);
+
+ /* Check parameters */
+ ret_code = tpm_proc_add_ds_load_balance_check(owner_id, rule_num, parse_rule_bm, parse_flags_bm, l2_key);
+ IF_ERROR(ret_code);
+
+ /* Get Range_Id */
+ tpm_db_api_section_main_pnc_get(TPM_DS_LOAD_BALANCE_ACL, &range_id);
+
+ /* Get Range Conf */
+ ret_code = tpm_db_pnc_rng_conf_get(range_id, &rangConf);
+ IF_ERROR(ret_code);
+
+ /* Only do it in table mode */
+ if (TPM_RANGE_TYPE_TABLE == rangConf.range_type) {
+ /* Try to getting the current entry */
+ ret_code = tpm_db_api_entry_get(TPM_DS_LOAD_BALANCE_ACL, rule_num, &l_rule_idx, &bi_dir,
+ &api_data, &mod_con, &pnc_conn);
+ /* if current entry with this rule num is valid */
+ if (TPM_DB_OK == ret_code) {
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " owner(%d) , rule_num(%d) already exists\n", owner_id, rule_num);
+
+ ret_code = tpm_proc_del_ds_load_balance_acl_rule(owner_id, rule_num, TPM_INT_CALL);
+ IF_ERROR(ret_code);
+ } else {
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " owner(%d) , rule_num(%d) is a new entry\n", owner_id, rule_num);
+ }
+ }
+ /*********** Create PNC Entries **********/
+ /* Build PnC Entry */
+ int_ret_code = tpm_proc_ds_load_balance_tcam_build(rule_num, l2_key,
+ parse_rule_bm, parse_flags_bm, &(pnc_data.pncl_tcam));
+ IF_ERROR(int_ret_code);
+
+ /* Build SRAM Entry */
+ int_ret_code = tpm_proc_ds_load_balance_sram_build(rule_num, &(pnc_data.pncl_sram), l2_key, tgrt_port);
+ IF_ERROR(int_ret_code);
+
+ if (TPM_RANGE_TYPE_ACL == rangConf.range_type) {
+ /*** Insert the PNC Entry ***/
+ int_ret_code =
+ tpm_proc_create_acl_pnc_entry(TPM_DS_LOAD_BALANCE_ACL, rule_num, &pnc_data,
+ &pnc_entry, &api_rng_entries);
+ IF_ERROR(int_ret_code);
+ } else {
+ /*** Set the PNC Entry ***/
+ int_ret_code =
+ tpm_proc_create_table_pnc_entry(TPM_DS_LOAD_BALANCE_ACL, rule_num, 0,
+ &pnc_data, &pnc_entry, &api_rng_entries);
+ IF_ERROR(int_ret_code);
+ }
+
+ /*********** Update API Range in DB **********/
+ /* Set PNC API data */
+ api_data.l2_prim_key.parse_rule_bm = parse_rule_bm;
+ if (l2_key)
+ memcpy(&(api_data.l2_prim_key.l2_key), l2_key, sizeof(tpm_l2_acl_key_t));
+
+ /* Set Pnc Connection data */
+ pnc_conn.num_pnc_ranges = 1;
+ pnc_conn.pnc_conn_tbl[0].pnc_range = range_id;
+ pnc_conn.pnc_conn_tbl[0].pnc_index = pnc_entry;
+
+ if (TPM_RANGE_TYPE_ACL == rangConf.range_type) {
+ /* Increase rule_numbers and PnC entries of the existing API entries that were "moved down" */
+ if (rule_num < api_rng_entries) {
+ int_ret_code =
+ tpm_proc_api_entry_rulenum_inc(TPM_DS_LOAD_BALANCE_ACL, rule_num, (api_rng_entries - 1));
+ IF_ERROR(int_ret_code);
+ }
+ }
+
+ /* Set new API Entry */
+ int_ret_code = tpm_db_api_entry_set(TPM_DS_LOAD_BALANCE_ACL, rule_num, 0 /*bi_dir */ ,
+ &api_data, &mod_con, &pnc_conn, &l_rule_idx);
+ IF_ERROR(int_ret_code);
+
+ /* Return Output */
+ *rule_idx = l_rule_idx;
+
+ /* Set aging counter group nunmber and msk */
+ int_ret_code = tpm_db_pnc_get_lu_conf(TPM_PNC_DS_LOAD_BALANCE, &lu_conf);
+ IF_ERROR(int_ret_code);
+ tpm_tcam_set_lu_mask(pnc_entry, (int32_t) lu_conf.lu_mask);
+ tpm_tcam_set_cntr_group(pnc_entry, (int32_t) lu_conf.cntr_grp);
+
+ return(TPM_RC_OK);
+}
+
+
+/*******************************************************************************
+* tpm_proc_del_ds_load_balance_acl_rule()
+*
+* DESCRIPTION: Main function for deleting DS load balance API rule.
+*
+* INPUTS:
+* All inputs/outputs are same as API call
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_del_ds_load_balance_acl_rule(uint32_t owner_id, uint32_t rule_idx, uint32_t ext_call)
+{
+
+ int32_t ret_code;
+
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " owner(%d) rule_idx(%d)", owner_id, rule_idx);
+
+ ret_code = tpm_proc_del_acl_rule(TPM_DS_LOAD_BALANCE_ACL, owner_id, rule_idx, ext_call);
+ IF_ERROR(ret_code);
+
+ return(TPM_RC_OK);
+}
+
tpm_error_code_t tpm_proc_pnc_create(tpm_pnc_ranges_t range_id, uint32_t pnc_entry, tpm_pncl_pnc_full_t *pnc_data)
{
@@ -4900,7 +5683,7 @@
pnc_data.pncl_sram.add_info_data = 1 << TPM_AI_DNRT_BIT_OFF;
pnc_data.pncl_sram.add_info_mask = TPM_AI_DNRT_MASK;
/* Set SINGLE_TAG AI filter */
- pnc_data.pncl_sram.add_info_data |= 0 << TPM_AI_TAG2_BIT_OFF;
+ pnc_data.pncl_sram.add_info_data &= (~TPM_AI_TAG2_MASK);
pnc_data.pncl_sram.add_info_mask |= TPM_AI_TAG2_MASK;
pnc_data.pncl_sram.add_info_data |= 1 << TPM_AI_TAG1_BIT_OFF;
pnc_data.pncl_sram.add_info_mask |= TPM_AI_TAG1_MASK;
@@ -4938,9 +5721,9 @@
pnc_data.pncl_sram.add_info_data = 1 << TPM_AI_DNRT_BIT_OFF;
pnc_data.pncl_sram.add_info_mask = TPM_AI_DNRT_MASK;
/* Set ZERO_TAG AI filter */
- pnc_data.pncl_sram.add_info_data |= 0 << TPM_AI_TAG2_BIT_OFF;
+ pnc_data.pncl_sram.add_info_data &= (~TPM_AI_TAG2_MASK);
pnc_data.pncl_sram.add_info_mask |= TPM_AI_TAG2_MASK;
- pnc_data.pncl_sram.add_info_data |= 0 << TPM_AI_TAG1_BIT_OFF;
+ pnc_data.pncl_sram.add_info_data &= (~TPM_AI_TAG1_MASK);
pnc_data.pncl_sram.add_info_mask |= TPM_AI_TAG1_MASK;
/* Do NOT set VLAN Result_Info bit */
@@ -5249,11 +6032,12 @@
}
/*******************************************************************************
-* tpm_proc_tcp_flag_init()
+* tpm_proc_tcp_flag_pnc_entry_create()
*
* DESCRIPTION:
*
* INPUTS:
+* ip_ver - IP version, IPV4 or IPV6
*
* RETURNS:
* On success, the function returns TPM_RC_OK. On error different types are returned
@@ -5263,15 +6047,16 @@
* It is APIs caller responsibility to maintain the correct number of each rule.
*
*******************************************************************************/
-tpm_error_code_t tpm_proc_tcp_flag_init(void)
+tpm_error_code_t tpm_proc_tcp_flag_pnc_entry_create(tpm_ip_ver_t ip_ver)
{
int32_t int_ret_code;
- uint32_t free_entries, tcp_flag_lu, ttl_lu, pnc_entry;
+ uint32_t free_entries, tcp_flag_lu, ttl_lu = 0, pnc_entry;
int32_t cpu_rx_queue;
tpm_pncl_pnc_full_t pnc_data;
tpm_pncl_offset_t start_offset;
tpm_db_pnc_range_t range_data;
+ tpm_pnc_ranges_t range_id;
/* Set Structs to zero */
memset(&pnc_data, 0, sizeof(tpm_pncl_pnc_full_t));
@@ -5283,16 +6068,21 @@
/* Get default CPU Rx queue */
tpm_db_get_cpu_rx_queue(&cpu_rx_queue);
- /* Get Next Range TTL Info */
- int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_TTL, &range_data);
- if (int_ret_code != TPM_OK) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD, " To create TCP Flag range, TPM_PNC_TTL range must exist \n");
- return(int_ret_code);
- }
- ttl_lu = range_data.pnc_range_conf.base_lu_id;
+ if (TPM_IP_VER_4 == ip_ver) {
+ range_id = TPM_PNC_IPV4_TCP_FLAG;
+
+ /* Get Next Range TTL Info, only for IPv4 */
+ int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_TTL, &range_data);
+ if (int_ret_code != TPM_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, " To create TCP Flag range, TPM_PNC_TTL range must exist \n");
+ return(int_ret_code);
+ }
+ ttl_lu = range_data.pnc_range_conf.base_lu_id;
+ } else
+ range_id = TPM_PNC_IPV6_TCP_FLAG;
/* Get TCP_FLAG Range Info */
- int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_TCP_FLAG, &range_data);
+ int_ret_code = tpm_db_pnc_rng_get(range_id, &range_data);
IF_ERROR(int_ret_code);
tcp_flag_lu = range_data.pnc_range_conf.base_lu_id;
@@ -5303,11 +6093,16 @@
pnc_data.pncl_tcam.start_offset.offset_sub.tcp_subf = TPM_PARSE_L4_SRC;
/* Set common SRAM params */
- pnc_data.pncl_sram.next_offset.offset_base = TPM_PNCL_TCP_OFFSET;
- pnc_data.pncl_sram.next_offset.offset_sub.tcp_subf = TPM_PARSE_TCPFLAGS;
+ if (TPM_IP_VER_4 == ip_ver) {
+ pnc_data.pncl_sram.next_offset.offset_base = TPM_PNCL_TCP_OFFSET;
+ pnc_data.pncl_sram.next_offset.offset_sub.tcp_subf = TPM_PARSE_TCPFLAGS;
+ pnc_data.pncl_sram.next_lu_id = ttl_lu;
+ pnc_data.pncl_sram.next_lu_off_reg = TPM_PNC_LU_REG0;
+ } else {
+ pnc_data.pncl_sram.sram_updt_bm = TPM_PNCL_SET_LUD;
+ }
+
pnc_data.pncl_sram.pnc_queue = cpu_rx_queue;
- pnc_data.pncl_sram.next_lu_id = ttl_lu;
- pnc_data.pncl_sram.next_lu_off_reg = TPM_PNC_LU_REG0;
pnc_data.pncl_sram.shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
/* Get pnc_range tcam_start_entry, and number of free entries */
@@ -5318,25 +6113,32 @@
/* Create FIN FLAG=1 */
/*******************/
NO_FREE_ENTRIES();
+
/* Build PnC Entry */
/* Double check - only check packets that are MTM */
pnc_data.pncl_tcam.add_info_data |= (1 << TPM_AI_MTM_BIT_OFF);
pnc_data.pncl_tcam.add_info_mask |= TPM_AI_MTM_MASK;
+ if (TPM_IP_VER_6 == ip_ver) {
+ pnc_data.pncl_tcam.add_info_data &= ~(TPM_AI_L4P_MASK);
+ pnc_data.pncl_tcam.add_info_mask |= TPM_AI_L4P_MASK;
+ }
pnc_data.pncl_tcam.tcp_parse_bm = TPM_PARSE_TCPFLAGS;
pnc_data.pncl_tcam.pkt_key.tcp_key.tcp_flags = TPM_TCP_FIN;
pnc_data.pncl_tcam.pkt_key.tcp_key.tcp_flags_mask = TPM_TCP_FIN;
/* Build SRAM Entry */
- pnc_data.pncl_sram.sram_updt_bm = TPM_PNCL_SET_TXP;
+ pnc_data.pncl_sram.sram_updt_bm |= TPM_PNCL_SET_TXP;
pnc_data.pncl_sram.flow_id_sub.pnc_target = TPM_PNC_TRG_CPU;
- /* Signal the packet is going to CPU */
- pnc_data.pncl_sram.add_info_data |= (1 << TPM_AI_TO_CPU_BIT_OFF);
- pnc_data.pncl_sram.add_info_mask |= TPM_AI_TO_CPU_MASK;
+ if (TPM_IP_VER_4 == ip_ver) {
+ /* Signal the packet is going to CPU */
+ pnc_data.pncl_sram.add_info_data |= (1 << TPM_AI_TO_CPU_BIT_OFF);
+ pnc_data.pncl_sram.add_info_mask |= TPM_AI_TO_CPU_MASK;
+ }
/* Create Entry in PnC */
- int_ret_code = tpm_proc_pnc_create(TPM_PNC_TCP_FLAG, pnc_entry, &pnc_data);
+ int_ret_code = tpm_proc_pnc_create(range_id, pnc_entry, &pnc_data);
IF_ERROR(int_ret_code);
free_entries--;
pnc_entry++;
@@ -5350,11 +6152,15 @@
pnc_data.pncl_tcam.pkt_key.tcp_key.tcp_flags_mask = TPM_TCP_RES;
/* Create Entry in PnC */
- int_ret_code = tpm_proc_pnc_create(TPM_PNC_TCP_FLAG, pnc_entry, &pnc_data);
+ int_ret_code = tpm_proc_pnc_create(range_id, pnc_entry, &pnc_data);
IF_ERROR(int_ret_code);
free_entries--;
pnc_entry++;
+ if (TPM_IP_VER_6 == ip_ver) {
+ /* no default rule for IPv6 */
+ return(TPM_RC_OK);
+ }
/***************/
/* All Others */
/***************/
@@ -5372,7 +6178,7 @@
pnc_data.pncl_sram.pnc_queue = TPM_PNCL_NO_QUEUE_UPDATE;
/* Create Entry in PnC */
- int_ret_code = tpm_proc_pnc_create(TPM_PNC_TCP_FLAG, pnc_entry, &pnc_data);
+ int_ret_code = tpm_proc_pnc_create(range_id, pnc_entry, &pnc_data);
IF_ERROR(int_ret_code);
free_entries--;
pnc_entry++;
@@ -5380,6 +6186,36 @@
}
/*******************************************************************************
+* tpm_proc_tcp_flag_init()
+*
+* DESCRIPTION:
+*
+* INPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* It is APIs caller responsibility to maintain the correct number of each rule.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_tcp_flag_init(void)
+{
+ int32_t int_ret_code;
+
+ /* Create Entry in PnC */
+ int_ret_code = tpm_proc_tcp_flag_pnc_entry_create(TPM_IP_VER_4);
+ IF_ERROR(int_ret_code);
+
+ int_ret_code = tpm_proc_tcp_flag_pnc_entry_create(TPM_IP_VER_6);
+ IF_ERROR(int_ret_code);
+
+ return(TPM_RC_OK);
+}
+
+
+/*******************************************************************************
* tpm_proc_virt_uni_init()
*
* DESCRIPTION:
@@ -5530,6 +6366,80 @@
return(TPM_RC_OK);
}
+/*******************************************************************************
+* tpm_proc_ds_load_balance_init()
+*
+* DESCRIPTION:
+*
+* INPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* It is APIs caller responsibility to maintain the correct number of each rule.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_ds_load_balance_init(void)
+{
+ int32_t ret_code;
+ tpm_pnc_all_t pnc_data;
+ tpm_pncl_offset_t start_offset;
+ tpm_db_pnc_range_t range_data, nextphase_range_data;
+ uint32_t pnc_entry;
+
+ /* Set Structs to zero */
+ memset(&pnc_data, 0, sizeof(tpm_pnc_all_t));
+ memset(&start_offset, 0, sizeof(tpm_pncl_offset_t));
+ memset(&range_data, 0, sizeof(tpm_db_pnc_range_t));
+ memset(&nextphase_range_data, 0, sizeof(tpm_db_pnc_range_t));
+
+ /* Get Range data */
+ ret_code = tpm_db_pnc_rng_get(TPM_PNC_DS_LOAD_BALANCE, &range_data);
+ IF_ERROR(ret_code);
+
+ /* Get Next Range data */
+ ret_code = tpm_db_pnc_rng_get(TPM_PNC_L2_MAIN, &nextphase_range_data);
+ IF_ERROR(ret_code);
+
+ /* Get pnc_range tcam_start_entry, and number of free entries */
+ pnc_entry = range_data.pnc_range_conf.range_end;
+
+ /* Set common TCAM params */
+ pnc_data.tcam_entry.lu_id = range_data.pnc_range_conf.base_lu_id;
+ pnc_data.tcam_entry.port_ids = TPM_BM_PMAC;
+
+ /* Set common SRAM params */
+ pnc_data.sram_entry.shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
+ pnc_data.sram_entry.next_lu_id = nextphase_range_data.pnc_range_conf.base_lu_id;
+
+ /* do not repeat this section again */
+ pnc_data.tcam_entry.add_info_data = 0;
+ pnc_data.tcam_entry.add_info_mask = TPM_AI_DNRT_DS_TRUNK_MASK;
+
+ /* Packet forwarded to GMAC0 */
+ pnc_data.sram_entry.flowid_updt_mask = TPM_TXP_FL_UPDT_MASK;
+ pnc_data.sram_entry.pnc_queue = TPM_PNCL_NO_QUEUE_UPDATE;
+ pnc_data.sram_entry.flowid_val = (TPM_PNC_TRG_GMAC0 << TPM_TXP_FL_SHIFT);
+
+ pnc_data.sram_entry.add_info_data |= (1 << TPM_AI_DNRT_DS_TRUNK_BIT_OFF);
+ pnc_data.sram_entry.add_info_mask |= TPM_AI_DNRT_DS_TRUNK_MASK;
+
+ /* create default rule to frwd all DS packets to GMAC0 */
+ ret_code = tpm_pnc_set(pnc_entry, 0, &pnc_data);
+ IF_ERROR(ret_code);
+
+ /* Write to Shadow */
+ ret_code = tpm_db_pnc_shdw_ent_set(pnc_entry, &pnc_data);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_db_pnc_rng_api_end_dec(TPM_PNC_DS_LOAD_BALANCE);
+ IF_ERROR(ret_code);
+
+ return(TPM_RC_OK);
+}
+
/*******************************************************************************
* tpm_proc_ipv4_ttl_init()
@@ -5810,7 +6720,7 @@
ret_code = tpm_mod2_split_mod_try_pmt_entry_del(api_section, mod_con.mod_cmd_mac, mod_con.mod_cmd_ind);
if (TPM_OK != ret_code) {
/* this is not split mod entry, remove it */
- ret_code = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, mod_con.mod_cmd_mac, mod_con.mod_cmd_ind);
+ ret_code = tpm_proc_delete_mod(TPM_MOD_OWNER_TPM, mod_con.mod_cmd_mac, mod_con.mod_cmd_ind);
}
}
IF_ERROR(ret_code);
@@ -5967,7 +6877,8 @@
}
}
- if (!update_sram_only) {
+ if ( (!update_sram_only)
+ && (SET_MOD(rule_action->pkt_act))) {
/* if split mod stage-2 */
if ((TPM_SPLIT_MOD_ENABLED == tpm_db_split_mod_get_enable()) &&
VLANOP_SPLIT_MOD_PBIT == pkt_mod->vlan_mod.vlan_op &&
@@ -6170,6 +7081,7 @@
uint32_t dst_port;
tpm_src_port_type_t src_port;
tpm_init_virt_uni_t virt_uni_info;
+ uint32_t gmac_is_uni_num, max_uni_port_num;
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "dest_port_bm(0x%x)\n", dest_port_bm);
@@ -6194,6 +7106,26 @@
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "TPM_TRG_UNI_VIRT is not enabled\n");
return ERR_MC_DST_PORT_INVALID;
}
+ /* Get GMAC LAN_UNI and UNI ports number */
+ tpm_proc_gmaclanuni_uninum_get(&gmac_is_uni_num, &max_uni_port_num);
+
+ /* check UNI_ANY */
+ if (dest_port_bm & TPM_TRG_PORT_UNI_ANY) {
+ /* Check UNI_ANY is supported or not */
+ if (gmac_is_uni_num > 1 ||
+ (gmac_is_uni_num == 1 && max_uni_port_num > 1)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "dest_port UNI_ANY is not supported\n");
+ return ERR_MC_DST_PORT_INVALID;
+ }
+ }
+
+ /* Check multi des port in bm */
+ if (dest_port_bm > TPM_TRG_UNI_1) {
+ if (gmac_is_uni_num > 1) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "dest_port bit map combine is not supported\n");
+ return ERR_MC_DST_PORT_INVALID;
+ }
+ }
return TPM_RC_OK;
}
@@ -6219,16 +7151,18 @@
* COMMENTS:
*
*******************************************************************************/
-tpm_error_code_t tpm_proc_add_ipv4_mc_check(uint32_t owner_id,
+tpm_error_code_t tpm_proc_add_ipvx_mc_check(uint32_t owner_id,
uint32_t stream_num,
tpm_mc_igmp_mode_t igmp_mode,
uint8_t mc_stream_pppoe,
uint16_t vid,
- uint8_t ipv4_src_add[4],
- uint8_t ipv4_dst_add[4],
- uint8_t ignore_ipv4_src,
+ uint8_t src_add[16],
+ uint8_t dst_add[16],
+ uint8_t ignore_ipvx_src,
+ uint16_t dest_queue,
tpm_trg_port_type_t dest_port_bm,
- tpm_mc_filter_mode_t filter_mode)
+ tpm_mc_filter_mode_t filter_mode,
+ tpm_ip_ver_t ip_version)
{
tpm_error_code_t ret_code;
int32_t int_ret_code, index;
@@ -6236,16 +7170,30 @@
uint32_t ai_bit;
tpm_init_virt_uni_t virt_uni;
uint32_t pnc_rng_free_size;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
+ tpm_pnc_ranges_t range;
+ tpm_api_sections_t api_section;
+ tpm_api_type_t api_type;
+
+ if (TPM_IP_VER_4 == ip_version) {
+ range = TPM_PNC_IPV4_MC_DS;
+ api_section = TPM_IPV4_MC;
+ api_type = TPM_API_IPV4_MC;
+ } else {
+ range = TPM_PNC_IPV6_MC_DS;
+ api_section = TPM_IPV6_MC_ACL;
+ api_type = TPM_API_IPV6_MC;
+ }
/* Check TPM was successfully initialized */
if (!tpm_db_init_done_get())
IF_ERROR(ERR_SW_NOT_INIT);
- ret_code = tpm_owner_id_check(TPM_API_IPV4_MC, owner_id);
+ ret_code = tpm_owner_id_check(api_type, owner_id);
IF_ERROR(ret_code);
/* Get PNC Range Start */
- int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_IPV4_MC_DS, &range_data);
+ int_ret_code = tpm_db_pnc_rng_get(range, &range_data);
IF_ERROR(int_ret_code);
if (stream_num >= range_data.pnc_range_conf.range_size)
@@ -6268,7 +7216,7 @@
if ((stream_num < range_data.pnc_range_conf.api_start) || (stream_num > range_data.pnc_range_conf.api_end))
IF_ERROR(ERR_MC_STREAM_INVALID);
- tpm_db_api_entry_ind_get(TPM_IPV4_MC, stream_num, &index);
+ tpm_db_api_entry_ind_get(api_section, stream_num, &index);
if (-1 != index)
IF_ERROR(ERR_MC_STREAM_EXISTS);
@@ -6304,8 +7252,25 @@
IF_ERROR(ERR_FEAT_UNSUPPORT);
}
- if ((ipv4_dst_add[0] < 224) || (ipv4_dst_add[0] > 239))
- IF_ERROR(ERR_IPV4_MC_DST_IP_INVALID);
+ if (TPM_IP_VER_4 == ip_version) {
+ if ((dst_add[0] < 224) || (dst_add[0] > 239))
+ IF_ERROR(ERR_IPV4_MC_DST_IP_INVALID);
+ } else {
+ if (dst_add[0] != 0xff)
+ IF_ERROR(ERR_IPV6_MC_DST_IP_INVALID);
+
+ /* check if there is MC SIP slot */
+ if(0 == ignore_ipvx_src) {
+ if(!tpm_db_ipv6_mc_sip_index_get(src_add)) {
+ /* this is a new MC SIP */
+ if(!tpm_db_ipv6_mc_sip_free_slot_num_get())
+ IF_ERROR(ERR_OUT_OF_RESOURCES);
+ }
+ }
+ }
+
+ if ((dest_queue != TPM_INVALID_QUEUE) && (dest_queue >= TPM_MAX_NUM_RX_QUEUE))
+ IF_ERROR(ERR_MC_DST_QUEUE_INVALID);
if (dest_port_bm & TPM_TRG_UNI_VIRT) {
if (virt_uni.enabled == 0)
@@ -6317,6 +7282,21 @@
IF_ERROR(ERR_MC_DST_PORT_INVALID);
}
+ /* when ds load balance on G0 and G1 is enabled, no Proxy stream is allowed */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable) {
+ if ( (TPM_IP_VER_4 == ip_version)
+ && (TPM_MC_IGMP_PROXY == igmp_mode)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "when ds load balance on G0 and G1 is enabled, "
+ "no Proxy stream is allowed\n");
+ return(ERR_FEAT_UNSUPPORT);
+ }
+ if (TPM_IP_VER_6 == ip_version) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "when ds load balance on G0 and G1 is enabled, "
+ "there is no IPv6 MC feature\n");
+ return(ERR_FEAT_UNSUPPORT);
+ }
+ }
return(TPM_RC_OK);
}
@@ -6411,7 +7391,7 @@
}
/*******************************************************************************
-* tpm_proc_l2_sram_build()
+* tpm_proc_ipvx_mc_sram_build()
*
* DESCRIPTION: Function builds a logical TCAM entry from the API data
*
@@ -6435,34 +7415,41 @@
* COMMENTS:
*
*******************************************************************************/
-int32_t tpm_proc_ipv4_mc_sram_build(tpm_mc_filter_mode_t filter_mode,
+int32_t tpm_proc_ipvx_mc_sram_build(tpm_mc_filter_mode_t filter_mode,
tpm_mc_igmp_mode_t igmp_mode,
+ uint16_t dest_queue,
tpm_trg_port_type_t target_port,
uint32_t mod_entry,
- tpm_pncl_sram_data_t *sram_data)
+ tpm_pncl_sram_data_t *sram_data,
+ tpm_ip_ver_t ip_version)
{
tpm_db_mh_src_t ds_mh_src;
tpm_init_virt_uni_t virt_uni;
tpm_db_pnc_range_conf_t range_conf;
int32_t ret_code;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " target_port(%d)\n", target_port);
/* Update dummy register (offset automatically=zero) */
sram_data->shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
- sram_data->sram_updt_bm = 0;
-
- /*Set next lookup */
- sram_data->next_lu_off_reg = 0;
- /* For igmp_proxy, check TTL, for igmp_snooping do not */
- if (igmp_mode == TPM_MC_IGMP_PROXY) {
- ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_TTL, &range_conf);
- IF_ERROR(ret_code);
+ if (TPM_IP_VER_4 == ip_version) {
+ sram_data->sram_updt_bm = 0;
+ /*Set next lookup */
+ sram_data->next_lu_off_reg = 0;
+ /* For igmp_proxy, check TTL, for igmp_snooping do not */
+ if (igmp_mode == TPM_MC_IGMP_PROXY) {
+ ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_TTL, &range_conf);
+ IF_ERROR(ret_code);
+ } else {
+ ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_IPV4_PROTO, &range_conf);
+ IF_ERROR(ret_code);
+ }
+ sram_data->next_lu_id = range_conf.base_lu_id;
} else {
- ret_code = tpm_db_pnc_rng_conf_get(TPM_PNC_IPV4_PROTO, &range_conf);
- IF_ERROR(ret_code);
+ sram_data->sram_updt_bm = TPM_PNCL_SET_LUD;
}
- sram_data->next_lu_id = range_conf.base_lu_id;
+
/* Set MH */
if (tpm_db_get_mc_per_uni_vlan_xlate() == 0) {
@@ -6496,42 +7483,48 @@
sram_data->flow_id_sub.mod_cmd = mod_entry;
}
- /* Reset AI bits for following LU */
- sram_data->add_info_data = 0;
- sram_data->add_info_mask = (TPM_AI_MC_VID_MASK | TPM_AI_MC_VID_VALID_MASK);
- if (TPM_MC_IGMP_PROXY == igmp_mode) {
- /* set MTM AI since in proxy mode */
- sram_data->add_info_data |= (1 << TPM_AI_MTM_BIT_OFF);
- sram_data->add_info_mask |= TPM_AI_MTM_MASK;
+ if (TPM_IP_VER_4 == ip_version) {
+ /* Reset AI bits for following LU */
+ sram_data->add_info_data = 0;
+ sram_data->add_info_mask = (TPM_AI_MC_VID_MASK | TPM_AI_MC_VID_VALID_MASK);
+ if (TPM_MC_IGMP_PROXY == igmp_mode) {
+ /* set MTM AI since in proxy mode */
+ sram_data->add_info_data |= (1 << TPM_AI_MTM_BIT_OFF);
+ sram_data->add_info_mask |= TPM_AI_MTM_MASK;
+ }
+
+ /* Final Fragment and L4 is detremined in separate stage */
+ sram_data->l3_type = TPM_PNCL_L3_IPV4_NFRAG;
+ sram_data->l4_type = TPM_PNCL_L4_OTHER;
}
- /* Final Fragment and L4 is detremined in separate stage */
- sram_data->l3_type = TPM_PNCL_L3_IPV4_NFRAG;
- sram_data->l4_type = TPM_PNCL_L4_OTHER;
-
/* Set Target Port */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+
sram_data->sram_updt_bm |= TPM_PNCL_SET_TXP;
+ sram_data->pnc_queue = dest_queue;
if (target_port == TPM_TRG_PORT_CPU) {
sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_CPU;
- sram_data->pnc_queue = tpm_db_get_mc_cpu_queue();
+ } else if (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable){
+ sram_data->sram_updt_bm &= (~TPM_PNCL_SET_TXP);
} else {
tpm_pnc_trg_t pnc_target;
ret_code = tpm_db_to_lan_gmac_get(target_port, &pnc_target);
IF_ERROR(ret_code);
sram_data->flow_id_sub.pnc_target = pnc_target;
- sram_data->pnc_queue = tpm_db_get_mc_hwf_queue();
}
return(TPM_OK);
}
-int32_t tpm_proc_create_ipv4_mc_mod(tpm_mc_filter_mode_t filter_mode,
+int32_t tpm_proc_create_ipvx_mc_mod(tpm_mc_filter_mode_t filter_mode,
tpm_mc_igmp_mode_t igmp_mode,
uint8_t mc_stream_pppoe,
uint16_t vid,
uint8_t *group_addr,
uint32_t dest_port_bm,
- uint32_t *mod_entry)
+ uint32_t *mod_entry,
+ tpm_ip_ver_t ip_version)
{
int32_t ret_code;
tpm_pkt_mod_bm_t pkt_mod_bm = 0;
@@ -6541,13 +7534,25 @@
tpm_mc_vid_port_cfg_t *mc_vid_cfg = NULL;
uint8_t valid;
uint32_t mh_en;
- uint32_t switch_init;
+ uint32_t switch_init, trgt_gmac;
+ tpm_pnc_trg_t pnc_target;
+ tpm_gmacs_enum_t gmac;
/*struct net_device *dev = NULL;*/
memset(&pkt_mod, 0, sizeof(tpm_pkt_mod_t));
+ if (TPM_TRG_PORT_CPU == dest_port_bm) {
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "target to CPU, no pkt mod is needed\n");
+ *mod_entry = 0;
+ return TPM_OK;
+ }
+
/*get MH EN */
- ret_code = tpm_db_gmac_mh_en_conf_get(TPM_ENUM_GMAC_0, &mh_en);
+ ret_code = tpm_db_to_lan_gmac_get(dest_port_bm, &pnc_target);
+ IF_ERROR(ret_code);
+ ret_code = tpm_db_target_to_gmac(pnc_target, &gmac);
+ IF_ERROR(ret_code);
+ ret_code = tpm_db_gmac_mh_en_conf_get(gmac, &mh_en);
IF_ERROR(ret_code);
/*get switch init*/
@@ -6635,7 +7640,11 @@
pkt_mod.mac_mod.mac_sa_mask[5] = 0xff;
#endif
- pkt_mod_bm |= (TPM_MAC_SA_SET | TPM_TTL_DEC | TPM_IPV4_UPDATE);
+ if (TPM_IP_VER_4 == ip_version)
+ pkt_mod_bm |= (TPM_MAC_SA_SET | TPM_TTL_DEC | TPM_IPV4_UPDATE);
+ else
+ pkt_mod_bm |= (TPM_MAC_SA_SET | TPM_HOPLIM_DEC | TPM_IPV6_UPDATE);
+
tpm_db_get_mc_igmp_proxy_sa_mac(mc_mac, &valid);
if (valid) {
@@ -6646,14 +7655,20 @@
if (mc_stream_pppoe) {
pkt_mod_bm |= (TPM_MAC_DA_SET | TPM_PPPOE_DEL);
- MULTI_IP_2_MAC(mc_mac, group_addr);
+
+ if (TPM_IP_VER_4 == ip_version) {
+ MULTI_IP_2_MAC(mc_mac, group_addr);
+ } else {
+ MULTI_IPV6_2_MAC(mc_mac, group_addr);
+ }
memcpy(pkt_mod.mac_mod.mac_da, mc_mac, 6 * sizeof(uint8_t));
memset(pkt_mod.mac_mod.mac_da_mask, 0xff, 6 * sizeof(uint8_t));
}
}
if (pkt_mod_bm != 0) {
- ret_code = tpm_mod2_entry_set(TPM_MOD_OWNER_TPM, TPM_ENUM_GMAC_0, pkt_mod_bm, TPM_INT_MC_MOD, &pkt_mod, mod_entry);
+ ret_code = tpm_proc_create_mod(TPM_ACTION_SET_PKT_MOD, dest_port_bm, &pkt_mod, pkt_mod_bm,
+ TPM_INT_MC_MOD, mod_entry, &trgt_gmac);
IF_ERROR(ret_code);
}
@@ -7067,6 +8082,7 @@
uint8_t ipv4_src_add[4],
uint8_t ipv4_dst_add[4],
uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
uint32_t dest_port_bm)
{
tpm_pncl_pnc_full_t pnc_data;
@@ -7077,6 +8093,7 @@
tpm_db_pnc_range_t range_data;
tpm_db_mc_stream_entry_t mc_stream;
tpm_mc_vid_port_cfg_t *mc_vid_cfg = NULL;
+ tpm_gmacs_enum_t gmac;
int32_t ret_code;
uint32_t pnc_entry = 0, mod_entry = 0, rule_num = 0xffff;
@@ -7093,8 +8110,8 @@
/*********** Create Modification Entries **********/
ret_code =
- tpm_proc_create_ipv4_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe, vid, ipv4_dst_add,
- dest_port_bm, &mod_entry);
+ tpm_proc_create_ipvx_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe, vid, ipv4_dst_add,
+ dest_port_bm, &mod_entry, TPM_IP_VER_4);
IF_ERROR(ret_code);
/*********** Create PNC Entries **********/
@@ -7106,7 +8123,9 @@
/* Build SRAM Entry */
ret_code =
- tpm_proc_ipv4_mc_sram_build(filter_mode, igmp_mode, dest_port_bm, mod_entry, &(pnc_data.pncl_sram));
+ tpm_proc_ipvx_mc_sram_build(filter_mode, igmp_mode, dest_queue,
+ dest_port_bm, mod_entry,
+ &(pnc_data.pncl_sram), TPM_IP_VER_4);
IF_ERROR(ret_code);
/*** Calculate PNC Entry ***/
@@ -7136,7 +8155,11 @@
memcpy(api_data.ipv4_mc_key.ipv4_dest_add, ipv4_dst_add, sizeof(ipv4_dst_add));
api_data.ipv4_mc_key.ignore_ipv4_src = ignore_ipv4_src;
api_data.ipv4_mc_key.dest_port_bm = dest_port_bm;
+ api_data.ipv4_mc_key.dest_queue = dest_queue;
api_data.ipv4_mc_key.vid = vid;
+ api_data.ipv4_mc_key.igmp_mode = igmp_mode;
+ api_data.ipv4_mc_key.mc_stream_pppoe = mc_stream_pppoe;
+ api_data.ipv4_mc_key.stream_num = stream_num;
/* Set Pnc Connection data */
pnc_conn.num_pnc_ranges = 1;
@@ -7145,8 +8168,11 @@
/* Set Modification Connection data */
mod_con.mod_cmd_ind = mod_entry;
- mod_con.mod_cmd_mac = TPM_PNC_TRG_GMAC0;
-
+ if (mod_entry) {
+ ret_code = tpm_db_target_to_gmac(pnc_data.pncl_sram.flow_id_sub.pnc_target, &gmac);
+ IF_ERROR(ret_code);
+ mod_con.mod_cmd_mac = gmac;
+ }
/* Set new API Entry */
ret_code = tpm_db_api_entry_set(TPM_IPV4_MC, stream_num, 0 /*bi_dir */ ,
&api_data, &mod_con, &pnc_conn, &rule_idx);
@@ -7189,10 +8215,11 @@
mc_stream.mc_stream_pppoe = mc_stream_pppoe;
mc_stream.src_valid = ignore_ipv4_src;
mc_stream.vid = vid;
+ mc_stream.dest_queue = dest_queue;
mc_stream.dest_port_bm = dest_port_bm;
mc_stream.u4_entry = rule_num;
memcpy(mc_stream.group_addr, ipv4_dst_add, 4 * sizeof(uint8_t));
- if (ignore_ipv4_src)
+ if (!ignore_ipv4_src)
memcpy(mc_stream.src_addr, ipv4_src_add, 4 * sizeof(uint8_t));
ret_code = tpm_db_set_mc_stream_entry(stream_num, &mc_stream);
@@ -7209,6 +8236,7 @@
uint8_t ipv4_src_add[4],
uint8_t ipv4_dst_add[4],
uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
uint32_t dest_port_bm)
{
tpm_db_pnc_range_t range_data;
@@ -7226,6 +8254,11 @@
memset(&mc_stream, 0, sizeof(tpm_db_mc_stream_entry_t));
+ /* Get old API Entry */
+ ret_code = tpm_db_api_entry_get(TPM_IPV4_MC, stream_num, &rule_idx, &bi_dir,
+ &api_data, &mod_con, &pnc_conn);
+ IF_ERROR(ret_code);
+
/* Only MC_IP_ONLY_FILTER mode, update the multicast group member ports by mh_mod. */
if (filter_mode == TPM_MC_IP_ONLY_FILTER) {
/* Get PNC Range Start */
@@ -7235,16 +8268,11 @@
if (stream_num >= range_data.pnc_range_conf.range_size)
IF_ERROR(ERR_MC_STREAM_INVALID);
- /* Get old API Entry */
- ret_code = tpm_db_api_entry_get(TPM_IPV4_MC, stream_num, &rule_idx, &bi_dir,
- &api_data, &mod_con, &pnc_conn);
- IF_ERROR(ret_code);
-
pnc_entry = pnc_conn.pnc_conn_tbl[0].pnc_index;
/* Create new Modification Entry */
- ret_code = tpm_proc_create_ipv4_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe,
- vid, ipv4_dst_add, dest_port_bm, &mod_entry);
+ ret_code = tpm_proc_create_ipvx_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe,
+ vid, ipv4_dst_add, dest_port_bm, &mod_entry, TPM_IP_VER_4);
IF_ERROR(ret_code);
/* Rebuild PnC Entry */
@@ -7254,7 +8282,9 @@
/* Rebuild SRAM Entry */
ret_code =
- tpm_proc_ipv4_mc_sram_build(filter_mode, igmp_mode, dest_port_bm, mod_entry, &(pnc_data.pncl_sram));
+ tpm_proc_ipvx_mc_sram_build(filter_mode, igmp_mode, dest_queue,
+ dest_port_bm, mod_entry,
+ &(pnc_data.pncl_sram), TPM_IP_VER_4);
IF_ERROR(ret_code);
/* Update only Sram of PNC Entry */
@@ -7263,21 +8293,11 @@
/* Delete old Modification Entry */
if (mod_con.mod_cmd_ind != 0) {
- ret_code = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, TPM_ENUM_GMAC_0, mod_con.mod_cmd_ind);
+ ret_code = tpm_proc_delete_mod(TPM_MOD_OWNER_TPM, mod_con.mod_cmd_mac, mod_con.mod_cmd_ind);
IF_ERROR(ret_code);
}
/* Update new Modification Entry */
mod_con.mod_cmd_ind = mod_entry;
-
- /* Invalidate old API Entry */
- ret_code = tpm_db_api_entry_invalidate(TPM_IPV4_MC, stream_num);
- IF_ERROR(ret_code);
-
- /* Set new API Entry */
- mod_con.mod_cmd_ind = mod_entry;
- ret_code = tpm_db_api_entry_set(TPM_IPV4_MC, stream_num, 0 /*bi_dir */ ,
- &api_data, &mod_con, &pnc_conn, &rule_idx);
- IF_ERROR(ret_code);
}
if (filter_mode == TPM_MC_COMBINED_IP_MAC_FILTER) {
@@ -7340,79 +8360,16 @@
ret_code = tpm_db_set_mc_stream_entry(stream_num, &mc_stream);
IF_ERROR(ret_code);
- return(TPM_RC_OK);
-}
+ /* Update API entry */
+ /* Invalidate old API Entry */
+ ret_code = tpm_db_api_entry_invalidate(TPM_IPV4_MC, stream_num);
+ IF_ERROR(ret_code);
-tpm_error_code_t tpm_proc_delete_ipv4_mc_pnc_entry(tpm_mc_filter_mode_t filter_mode,
- uint32_t stream_num,
- uint32_t dest_port_bm,
- uint32_t u4_entry)
-{
- tpm_db_pnc_range_t range_data;
- tpm_rule_entry_t api_data;
- tpm_db_mod_conn_t mod_con;
- tpm_db_pnc_conn_t pnc_conn;
-
- int32_t ret_code;
- uint32_t bi_dir = 0, rule_idx = 0;
- uint32_t pnc_range_start = 0, api_start = 0, pnc_entry = 0;
-
- if (filter_mode != TPM_MC_MAC_ONLY_FILTER) {
- /* Get PNC Range Start */
- ret_code = tpm_db_pnc_rng_get(TPM_PNC_IPV4_MC_DS, &range_data);
- IF_ERROR(ret_code);
-
- if (stream_num >= range_data.pnc_range_conf.range_size)
- IF_ERROR(ERR_MC_STREAM_INVALID);
-
- /* Check parameters */
- ret_code = tpm_db_api_entry_get(TPM_IPV4_MC, stream_num, &rule_idx, &bi_dir,
- &api_data, &mod_con, &pnc_conn);
- IF_ERROR(ret_code);
-
- /* Delete PNC Entry */
-#if 0
- ret_code = tpm_proc_pnc_con_del(&pnc_conn);
- IF_ERROR(ret_code);
-#endif
- pnc_range_start = range_data.pnc_range_conf.range_start;
- api_start = range_data.pnc_range_conf.api_start;
-
- /* Pull range from this index untill last used entry in Pnc range */
- pnc_entry = (pnc_range_start + api_start) + stream_num;
-
- /* Delete PNC entry */
- ret_code = tpm_pncl_entry_delete(pnc_entry, pnc_entry);
- IF_ERROR(ret_code);
-
- /* Increase number of free entries in pnc_range */
- ret_code = tpm_db_pnc_rng_free_ent_inc(TPM_PNC_IPV4_MC_DS);
- IF_ERROR(ret_code);
-
- if (mod_con.mod_cmd_ind != 0) {
- ret_code = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, TPM_ENUM_GMAC_0, mod_con.mod_cmd_ind);
- IF_ERROR(ret_code);
- }
-
- /* Delete API Rule Entry */
- ret_code = tpm_db_api_entry_invalidate(TPM_IPV4_MC, stream_num);
- IF_ERROR(ret_code);
- }
-
- if (filter_mode == TPM_MC_COMBINED_IP_MAC_FILTER) {
- if (tpm_db_get_mc_per_uni_vlan_xlate() != 0) {
- if (u4_entry != 0xffff) {
- ret_code = tpm_proc_mc_delete_virt_uni_pnc_entry(u4_entry);
- IF_ERROR(ret_code);
-
- ret_code = tpm_db_mc_free_virt_uni_entry(u4_entry);
- IF_ERROR(ret_code);
- }
- }
- }
-
- /* Remove stream entry */
- tpm_db_reset_mc_stream_entry(stream_num);
+ /* Set new API Entry */
+ api_data.ipv4_mc_key.dest_port_bm = dest_port_bm;
+ ret_code = tpm_db_api_entry_set(TPM_IPV4_MC, stream_num, 0 /*bi_dir */ ,
+ &api_data, &mod_con, &pnc_conn, &rule_idx);
+ IF_ERROR(ret_code);
return(TPM_RC_OK);
}
@@ -7511,6 +8468,7 @@
uint8_t ipv4_src_add[4],
uint8_t ipv4_dst_add[4],
uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
tpm_trg_port_type_t dest_port_bm)
{
tpm_error_code_t ret_code;
@@ -7533,13 +8491,21 @@
dest_port_bm = tpm_db_trg_port_uni_any_bmp_get(true);
/* Check parameters */
- ret_code = tpm_proc_add_ipv4_mc_check(owner_id, stream_num, igmp_mode, mc_stream_pppoe, vid,
- ipv4_src_add, ipv4_dst_add, ignore_ipv4_src, dest_port_bm, filter_mode);
+ ret_code = tpm_proc_add_ipvx_mc_check(owner_id, stream_num, igmp_mode, mc_stream_pppoe, vid,
+ ipv4_src_add, ipv4_dst_add, ignore_ipv4_src, dest_queue,
+ dest_port_bm, filter_mode, TPM_IP_VER_4);
IF_ERROR(ret_code);
+ /* get queue number */
+ if (dest_queue == TPM_INVALID_QUEUE) {
+ if (dest_port_bm & TPM_TRG_PORT_CPU)
+ dest_queue = tpm_db_get_mc_cpu_queue();
+ else
+ dest_queue = tpm_db_get_mc_hwf_queue();
+ }
/* Create PNC entry */
ret_code = tpm_proc_add_ipv4_mc_pnc_entry(filter_mode, stream_num, igmp_mode, mc_stream_pppoe, vid,
- ipv4_src_add, ipv4_dst_add, ignore_ipv4_src, dest_port_bm);
+ ipv4_src_add, ipv4_dst_add, ignore_ipv4_src, dest_queue, dest_port_bm);
IF_ERROR(ret_code);
/* Set switch port_map for multicast MAC, but don't overwrite 224.0.0.1 (IGMP General Query) MAC */
@@ -7610,21 +8576,30 @@
ret_code = tpm_db_get_mc_stream_entry(stream_num, &mc_stream);
IF_ERROR(ret_code);
+ if (dest_port_bm == mc_stream.dest_port_bm) {
+ /* nothing changed, return directly */
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "dest_port_bm does not change, return directly\n");
+ return (TPM_OK);
+ }
+
if (((dest_port_bm & TPM_TRG_PORT_CPU) != 0 && (mc_stream.dest_port_bm & TPM_TRG_PORT_CPU) == 0) ||
((dest_port_bm & TPM_TRG_PORT_CPU) == 0 && (mc_stream.dest_port_bm & TPM_TRG_PORT_CPU) != 0)) {
- ret_code = tpm_proc_delete_ipv4_mc_pnc_entry(filter_mode, stream_num,
- mc_stream.dest_port_bm, mc_stream.u4_entry);
+ ret_code = tpm_proc_delete_ipvx_mc_pnc_entry(filter_mode, stream_num,
+ mc_stream.dest_port_bm, mc_stream.u4_entry,
+ TPM_IP_VER_4);
IF_ERROR(ret_code);
ret_code = tpm_proc_add_ipv4_mc_pnc_entry(filter_mode, stream_num, mc_stream.igmp_mode,
- mc_stream.mc_stream_pppoe, mc_stream.vid,
- mc_stream.src_addr, mc_stream.group_addr,
- mc_stream.src_valid, dest_port_bm);
+ mc_stream.mc_stream_pppoe, mc_stream.vid,
+ mc_stream.src_addr, mc_stream.group_addr,
+ mc_stream.src_valid, mc_stream.dest_queue,
+ dest_port_bm);
} else {
ret_code = tpm_proc_update_ipv4_mc_pnc_entry(filter_mode, stream_num, mc_stream.igmp_mode,
- mc_stream.mc_stream_pppoe, mc_stream.vid,
- mc_stream.src_addr, mc_stream.group_addr,
- mc_stream.src_valid, dest_port_bm);
+ mc_stream.mc_stream_pppoe, mc_stream.vid,
+ mc_stream.src_addr, mc_stream.group_addr,
+ mc_stream.src_valid, mc_stream.dest_queue,
+ dest_port_bm);
}
IF_ERROR(ret_code);
@@ -7679,7 +8654,10 @@
IF_ERROR(ret_code);
ret_code =
- tpm_proc_delete_ipv4_mc_pnc_entry(filter_mode, stream_num, mc_stream.dest_port_bm, mc_stream.u4_entry);
+ tpm_proc_delete_ipvx_mc_pnc_entry(filter_mode, stream_num,
+ mc_stream.dest_port_bm,
+ mc_stream.u4_entry,
+ TPM_IP_VER_4);
IF_ERROR(ret_code);
/* Set switch VID and multicast MAC */
@@ -8210,6 +9188,7 @@
stream_data.vid, stream_data.src_addr,
stream_data.group_addr,
stream_data.src_valid,
+ stream_data.dest_queue,
stream_data.dest_port_bm);
IF_ERROR(ret_code);
} else {
@@ -9117,13 +10096,10 @@
return(TPM_RC_OK);
}
-
/*******************************************************************************
-* tpm_proc_loop_detect_add_channel()
+* tpm_proc_loop_detect_del_channel()
*
-* DESCRIPTION: Establishes a communication channel for the loop detection management protocol.
-* The API sets the Rx input queue in the CPU, and the
-* Tx T-CONT and queue parameters, which are configured in the driver.
+* DESCRIPTION: remove the communication channel for the loop detection management protocol.
*
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
@@ -9138,7 +10114,73 @@
* COMMENTS:
*
*******************************************************************************/
-tpm_error_code_t tpm_proc_loop_detect_add_channel(uint32_t owner_id)
+tpm_error_code_t tpm_proc_loop_detect_del_channel(uint32_t owner_id)
+{
+ uint32_t pnc_entry;
+ tpm_db_pnc_range_t range_data;
+ tpm_error_code_t ret_code;
+
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "owner(%d)\n", owner_id);
+
+ ret_code = tpm_owner_id_check(TPM_API_MGMT, owner_id);
+ IF_ERROR(ret_code);
+
+ memset(&range_data, 0, sizeof(range_data));
+ /* Get PNC Range data */
+ ret_code = tpm_db_pnc_rng_get(TPM_PNC_LOOP_DET_US, &range_data);
+ IF_ERROR(ret_code);
+
+ if (!range_data.valid) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "range TPM_PNC_LOOP_DET_US is not valid\n");
+ return ERR_GENERAL;
+ }
+
+ if (range_data.pnc_range_conf.range_size == range_data.pnc_range_oper.free_entries) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "there is no loopback detect channel yet\n");
+ return ERR_GENERAL;
+ }
+
+ pnc_entry = range_data.pnc_range_conf.range_start;
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "remove pnc_entry(%d)\n", pnc_entry);
+
+ ret_code = tpm_pnc_entry_inv(pnc_entry);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_db_pnc_rng_free_ent_inc(TPM_PNC_LOOP_DET_US);
+ IF_ERROR(ret_code);
+
+ /* remove tag PNC rule */
+ pnc_entry++;
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "remove pnc_entry(%d)\n", pnc_entry);
+
+ ret_code = tpm_pnc_entry_inv(pnc_entry);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_db_pnc_rng_free_ent_inc(TPM_PNC_LOOP_DET_US);
+ IF_ERROR(ret_code);
+
+ return(TPM_RC_OK);
+}
+/*******************************************************************************
+* tpm_proc_loop_detect_add_channel()
+*
+* DESCRIPTION: Establishes a communication channel for the loop detection management protocol.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* ety - EtherType of the loop detection Pkt.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_loop_detect_add_channel(uint32_t owner_id, tpm_ether_type_key_t ety)
{
tpm_pncl_pnc_full_t pnc_data;
tpm_gmac_bm_t gmac_bm;
@@ -9155,51 +10197,62 @@
memset(&pnc_data, 0, sizeof(tpm_pncl_pnc_full_t));
/* build TCAM */
- pnc_data.pncl_tcam.l2_parse_bm = TPM_L2_PARSE_ONE_VLAN_TAG | TPM_L2_PARSE_ETYPE;
- pnc_data.pncl_tcam.l3_parse_bm = 0;
- pnc_data.pncl_tcam.ipv6_parse_bm = 0;
- pnc_data.pncl_tcam.ipv4_parse_bm = 0;
- pnc_data.pncl_tcam.add_info_mask = 0;
+ pnc_data.pncl_tcam.l2_parse_bm = TPM_L2_PARSE_ETYPE;
+ pnc_data.pncl_tcam.add_info_mask = TPM_AI_TAG1_MASK;
pnc_data.pncl_tcam.add_info_data = 0;
/* src port */
tpm_proc_src_port_gmac_bm_map(TPM_SRC_PORT_UNI_ANY, &gmac_bm);
pnc_data.pncl_tcam.port_ids = gmac_bm;
- pnc_data.pncl_tcam.pkt_key.l2_key.vlan1.tpid = 0x8100;
- pnc_data.pncl_tcam.pkt_key.l2_key.vlan1.tpid_mask = 0xffff;
- pnc_data.pncl_tcam.pkt_key.l2_key.ether_type = 0xA0A0;
+ pnc_data.pncl_tcam.pkt_key.l2_key.ether_type = ety;
pnc_data.pncl_tcam.lu_id = 0;
pnc_data.pncl_tcam.start_offset.offset_base = TPM_PNCL_ZERO_OFFSET;
pnc_data.pncl_tcam.start_offset.offset_sub.l2_subf = TPM_L2_PARSE_MH;
/* Build SRAM */
- pnc_data.pncl_sram.next_lu_id = 0;
- pnc_data.pncl_sram.next_lu_off_reg = 0;
- pnc_data.pncl_sram.next_offset.offset_base = 0;
- pnc_data.pncl_sram.next_offset.offset_sub.l2_subf = 0;
pnc_data.pncl_sram.shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
pnc_data.pncl_sram.pnc_queue = 0; /*send to queue 0 by default */
pnc_data.pncl_sram.sram_updt_bm = TPM_PNCL_SET_LUD | TPM_PNCL_SET_TXP | TPM_PNCL_SET_RX_SPECIAL;
- pnc_data.pncl_sram.mh_reg.mh_set = TPM_FALSE;
- pnc_data.pncl_sram.mh_reg.mh_reg = 0;
- pnc_data.pncl_sram.add_info_data = 0;
- pnc_data.pncl_sram.add_info_mask = 0;
pnc_data.pncl_sram.l3_type = TPM_PNCL_L3_OTHER;
pnc_data.pncl_sram.l4_type = TPM_PNCL_L4_OTHER;
pnc_data.pncl_sram.flow_id_sub.pnc_target = TPM_PNC_TRG_CPU;
- pnc_data.pncl_sram.flow_id_sub.mod_cmd = 0;
- pnc_data.pncl_sram.flow_id_sub.gem_port = 0;
- /* Get PNC Range Start */
+ /* Get PNC Range data */
int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_LOOP_DET_US, &range_data);
IF_ERROR(int_ret_code);
+
+ if ((!range_data.valid) || (range_data.pnc_range_conf.range_size < 2)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "range TPM_PNC_LOOP_DET_US is not big enough!\n");
+ return ERR_OUT_OF_RESOURCES;
+ }
+
+ if (range_data.pnc_range_conf.range_size != range_data.pnc_range_oper.free_entries) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "loopback detect channel has already been added\n");
+ return ERR_GENERAL;
+ }
+
pnc_entry = range_data.pnc_range_conf.range_start;
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " pnc_entry(%d)\n", pnc_entry);
+
+ int_ret_code = tpm_pncl_entry_set(pnc_entry, &pnc_data);
+ IF_ERROR(int_ret_code);
+
int_ret_code = tpm_db_pnc_rng_free_ent_dec(TPM_PNC_LOOP_DET_US);
IF_ERROR(int_ret_code);
+
+ /* add tag PNC rule */
+ pnc_data.pncl_tcam.l2_parse_bm = TPM_L2_PARSE_ONE_VLAN_TAG | TPM_L2_PARSE_ETYPE;
+ pnc_data.pncl_tcam.add_info_data = TPM_AI_TAG1_MASK;
+
+ pnc_entry++;
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " pnc_entry(%d)\n", pnc_entry);
+
int_ret_code = tpm_pncl_entry_set(pnc_entry, &pnc_data);
IF_ERROR(int_ret_code);
+ int_ret_code = tpm_db_pnc_rng_free_ent_dec(TPM_PNC_LOOP_DET_US);
+ IF_ERROR(int_ret_code);
+
return(TPM_RC_OK);
}
@@ -9491,7 +10544,8 @@
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check owner_id */
@@ -10852,16 +11906,16 @@
}
tpm_error_code_t tpm_proc_add_ipv6_gen_5t_check(uint32_t owner_id,
- tpm_dir_t dir,
- uint32_t rule_num,
- tpm_parse_fields_t parse_rule_bm,
- tpm_parse_flags_t parse_flags_bm,
- tpm_l4_ports_key_t *l4_key,
- tpm_ipv6_gen_acl_key_t *ipv6_gen_key,
- tpm_pkt_frwd_t *pkt_frwd,
- tpm_pkt_mod_bm_t pkt_mod_bm,
- tpm_pkt_mod_t *pkt_mod,
- tpm_rule_action_t *rule_action)
+ tpm_dir_t dir,
+ uint32_t rule_num,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l4_ports_key_t *l4_key,
+ tpm_ipv6_gen_acl_key_t *ipv6_gen_key,
+ tpm_pkt_frwd_t *pkt_frwd,
+ tpm_pkt_mod_bm_t pkt_mod_bm,
+ tpm_pkt_mod_t *pkt_mod,
+ tpm_rule_action_t *rule_action)
{
int32_t ret_code;
tpm_db_pon_type_t pon_type;
@@ -10871,6 +11925,7 @@
tpm_ipv6_gen_acl_key_t _gen_key;
tpm_ipv6_addr_key_t _dip_key, dip_key;
tpm_init_ipv6_5t_enable_t ipv6_5t_enable;
+ tpm_src_port_type_t src_port;
memset(&dip_key, 0, sizeof(tpm_ipv6_addr_key_t));
memset(&range_data, 0, sizeof(tpm_db_pnc_range_t));
@@ -10909,9 +11964,16 @@
return(ERR_FRWD_INVALID);
}
+ /* Get GMAC(s) */
+ if (dir == TPM_DIR_DS)
+ src_port = TPM_SRC_PORT_WAN;
+ else
+ src_port = TPM_SRC_PORT_UNI_ANY;
+
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_bm */
@@ -11003,17 +12065,17 @@
}
tpm_error_code_t tpm_proc_add_ipv6_dip_5t_check(uint32_t owner_id,
- tpm_dir_t dir,
- uint32_t rule_num,
- tpm_parse_fields_t parse_rule_bm,
- tpm_parse_flags_t parse_flags_bm,
- tpm_l4_ports_key_t *l4_key,
- tpm_ipv6_gen_acl_key_t *ipv6_gen_key,
- tpm_ipv6_addr_key_t *ipv6_dip_key,
- tpm_pkt_frwd_t *pkt_frwd,
- tpm_pkt_mod_bm_t pkt_mod_bm,
- tpm_pkt_mod_t *pkt_mod,
- tpm_rule_action_t *rule_action)
+ tpm_dir_t dir,
+ uint32_t rule_num,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l4_ports_key_t *l4_key,
+ tpm_ipv6_gen_acl_key_t *ipv6_gen_key,
+ tpm_ipv6_addr_key_t *ipv6_dip_key,
+ tpm_pkt_frwd_t *pkt_frwd,
+ tpm_pkt_mod_bm_t pkt_mod_bm,
+ tpm_pkt_mod_t *pkt_mod,
+ tpm_rule_action_t *rule_action)
{
int32_t ret_code;
tpm_db_pon_type_t pon_type;
@@ -11023,6 +12085,7 @@
tpm_ipv6_gen_acl_key_t _gen_key;
tpm_ipv6_addr_key_t _dip_key;
tpm_init_ipv6_5t_enable_t ipv6_5t_enable;
+ tpm_src_port_type_t src_port;
memset(&range_data, 0, sizeof(tpm_db_pnc_range_t));
@@ -11060,9 +12123,16 @@
return(ERR_FRWD_INVALID);
}
+ /* Get GMAC(s) */
+ if (dir == TPM_DIR_DS)
+ src_port = TPM_SRC_PORT_WAN;
+ else
+ src_port = TPM_SRC_PORT_UNI_ANY;
+
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port,
+ pkt_frwd->trg_queue, rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_bm */
@@ -11175,6 +12245,7 @@
tpm_ipv6_gen_acl_key_t _gen_key, gen_key;
tpm_ipv6_addr_key_t _dip_key, dip_key;
tpm_init_ipv6_5t_enable_t ipv6_5t_enable;
+ tpm_src_port_type_t src_port;
memset(&gen_key, 0, sizeof(tpm_ipv6_gen_acl_key_t));
memset(&dip_key, 0, sizeof(tpm_ipv6_addr_key_t));
@@ -11215,9 +12286,16 @@
return(ERR_FRWD_INVALID);
}
+ /* Get GMAC(s) */
+ if (dir == TPM_DIR_DS)
+ src_port = TPM_SRC_PORT_WAN;
+ else
+ src_port = TPM_SRC_PORT_UNI_ANY;
+
/* Check Target_port and Queue are valid */
ret_code =
- tpm_proc_check_valid_target(dir, pon_type, pkt_frwd->trg_port, pkt_frwd->trg_queue, rule_action->pkt_act);
+ tpm_proc_check_valid_target(dir, pon_type, src_port, pkt_frwd->trg_port, pkt_frwd->trg_queue,
+ rule_action->pkt_act, TPM_FALSE);
IF_ERROR(ret_code);
/* Check parse_bm */
@@ -12778,66 +13856,6 @@
return(TPM_OK);
}
-int32_t tpm_proc_ipv6_mc_sram_build(tpm_mc_filter_mode_t filter_mode,
- tpm_mc_igmp_mode_t igmp_mode,
- tpm_trg_port_type_t target_port,
- uint32_t mod_entry,
- tpm_pncl_sram_data_t *sram_data)
-{
- tpm_db_mh_src_t ds_mh_src;
- tpm_init_virt_uni_t virt_uni;
-
- TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " target_port(%d)\n", target_port);
-
- /* Update dummy register (offset automatically=zero) */
- sram_data->shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
- sram_data->sram_updt_bm = TPM_PNCL_SET_LUD;
-
- /* Set MH */
- if (tpm_db_get_mc_per_uni_vlan_xlate() == 0) {
- tpm_db_ds_mh_get_conf_set(&ds_mh_src);
-
- if (filter_mode == TPM_MC_COMBINED_IP_MAC_FILTER) {
- if (TPM_MH_SRC_PNC_RI == ds_mh_src) {
- sram_data->sram_updt_bm |= TPM_PNCL_SET_MH_RI;
- sram_data->mh_reg.mh_set = TPM_TRUE;
-
- tpm_db_virt_info_get(&virt_uni);
- if (virt_uni.enabled)
- sram_data->mh_reg.mh_reg = (TPM_MH_RI_BIT16 | TPM_MH_RI_BIT15);
- else
- sram_data->mh_reg.mh_reg = (TPM_MH_RI_BIT17 | TPM_MH_RI_BIT16 |
- TPM_MH_RI_BIT15 | TPM_MH_RI_BIT14);
- } else {
- sram_data->mh_reg.mh_set = TPM_FALSE;
- sram_data->mh_reg.mh_reg = 0;
- }
- } else if (filter_mode == TPM_MC_IP_ONLY_FILTER) {
- /* Target UNI is set by Modification Entry */
- }
- } else {
- /* Target UNI is set by Modification Entry */
- }
-
- /* Set modification command */
- if (mod_entry != 0) {
- sram_data->sram_updt_bm |= TPM_PNCL_SET_MOD;
- sram_data->flow_id_sub.mod_cmd = mod_entry;
- }
-
- /* Set Target Port */
- sram_data->sram_updt_bm |= TPM_PNCL_SET_TXP;
- if (target_port == TPM_TRG_PORT_CPU) {
- sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_CPU;
- sram_data->pnc_queue = tpm_db_get_mc_cpu_queue();
- } else {
- sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_GMAC0;
- sram_data->pnc_queue = tpm_db_get_mc_hwf_queue();
- }
-
- return(TPM_OK);
-}
-
int32_t tpm_proc_ipv6_mc_sip_entry_create(uint32_t sip_index, uint8_t *ipv6_src_add)
{
int32_t int_ret_code;
@@ -12932,250 +13950,6 @@
return TPM_RC_OK;
}
-int32_t tpm_proc_create_ipv6_mc_mod(tpm_mc_filter_mode_t filter_mode,
- tpm_mc_igmp_mode_t igmp_mode,
- uint8_t mc_stream_pppoe,
- uint16_t vid,
- uint8_t *group_addr,
- uint32_t dest_port_bm,
- uint32_t *mod_entry)
-{
- int32_t ret_code;
- tpm_pkt_mod_bm_t pkt_mod_bm = 0;
- tpm_pkt_mod_t pkt_mod;
- uint8_t mc_mac[6];
- uint32_t lpbk_port_bm = 0, entry_id;
- tpm_mc_vid_port_cfg_t *mc_vid_cfg = NULL;
- uint8_t valid;
- uint32_t switch_init;
- uint32_t mh_en;
- /*struct net_device *dev = NULL;*/
-
- memset(&pkt_mod, 0, sizeof(tpm_pkt_mod_t));
-
- /*get switch init*/
- ret_code = tpm_db_switch_init_get(&switch_init);
- IF_ERROR(ret_code);
-
- /*get MH EN */
- ret_code = tpm_db_gmac_mh_en_conf_get(TPM_ENUM_GMAC_0, &mh_en);
- IF_ERROR(ret_code);
-
- if (filter_mode == TPM_MC_IP_ONLY_FILTER && mh_en) {
- /* TODO: Check virt_port status. If it is not enabled, set target_port via MH_Tx_reg in RI. */
- pkt_mod_bm |= TPM_MH_SET;
- pkt_mod.mh_mod = tpm_db_trg_port_switch_port_get(dest_port_bm);
- }
-
- if (tpm_db_get_mc_per_uni_vlan_xlate() == 0) {
- if (vid != 0xffff) {
- if (tpm_db_get_mc_vid_cfg(vid, &mc_vid_cfg) == TPM_OK) {
- for (entry_id = 0; entry_id < TPM_MAX_NUM_UNI_PORTS; entry_id++) {
- if (mc_vid_cfg[entry_id].mc_uni_port_mode == TPM_MC_UNI_MODE_TRANSLATE) {
- pkt_mod_bm |= TPM_VLAN_MOD;
-
- pkt_mod.vlan_mod.vlan_op = VLANOP_EXT_TAG_MOD;
- pkt_mod.vlan_mod.vlan1_out.tpid = 0x8100;
- pkt_mod.vlan_mod.vlan1_out.pbit = 0;
- pkt_mod.vlan_mod.vlan1_out.pbit_mask = 0x0;
- pkt_mod.vlan_mod.vlan1_out.cfi = 0;
- pkt_mod.vlan_mod.vlan1_out.cfi_mask = 0x0;
- pkt_mod.vlan_mod.vlan1_out.vid = mc_vid_cfg[entry_id].uni_port_vid;
- pkt_mod.vlan_mod.vlan1_out.vid_mask = 0xffff;
- break;
- } else if (mc_vid_cfg[entry_id].mc_uni_port_mode == TPM_MC_UNI_MODE_STRIP) {
- /* Just for MC, no switch */
- if (switch_init == 0) {
- pkt_mod_bm |= TPM_VLAN_MOD;
-
- pkt_mod.vlan_mod.vlan_op = VLANOP_EXT_TAG_DEL;
- break;
- }
- }
- }
- } else
- TPM_OS_DEBUG(TPM_TPM_LOG_MOD, " not found mv_vlan_cfg %d, assume as transparent! \n", vid);
- }
- } else if (filter_mode == TPM_MC_COMBINED_IP_MAC_FILTER) {
- pkt_mod_bm |= TPM_MH_SET;
-
- ret_code = tpm_db_get_mc_vid_cfg(vid, &mc_vid_cfg);
- IF_ERROR(ret_code);
-
- for (entry_id = 0; entry_id < TPM_MAX_NUM_UNI_PORTS; entry_id++) {
- if (mc_vid_cfg[entry_id].tpm_src_port != TPM_SRC_PORT_UNI_VIRT) {
- if (mc_vid_cfg[entry_id].mc_uni_port_mode == TPM_MC_UNI_MODE_TRANSPARENT ||
- mc_vid_cfg[entry_id].mc_uni_port_mode == TPM_MC_UNI_MODE_STRIP) {
- lpbk_port_bm |=
- TPM_TRG_UNI_0 << (mc_vid_cfg[entry_id].tpm_src_port - TPM_SRC_PORT_UNI_0);
- }
- }
- }
- lpbk_port_bm |= TPM_TRG_UNI_VIRT;
-
- pkt_mod.mh_mod = tpm_db_trg_port_switch_port_get(lpbk_port_bm);
- }
-
- if (igmp_mode == TPM_MC_IGMP_PROXY) {
-#if 0
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
- dev = dev_get_by_name("eth0");
-#else
- dev = dev_get_by_name(&init_net, "eth0");
-#endif
- if (dev == NULL)
- IF_ERROR(ERR_GENERAL);
-
- pkt_mod_bm |= (TPM_MAC_SA_SET | TPM_TTL_DEC | TPM_IPV4_UPDATE);
- pkt_mod.mac_mod.mac_sa[0] = ((uint8_t *) dev->dev_addr)[0];
- pkt_mod.mac_mod.mac_sa[1] = ((uint8_t *) dev->dev_addr)[1];
- pkt_mod.mac_mod.mac_sa[2] = ((uint8_t *) dev->dev_addr)[2];
- pkt_mod.mac_mod.mac_sa[3] = ((uint8_t *) dev->dev_addr)[3];
- pkt_mod.mac_mod.mac_sa[4] = ((uint8_t *) dev->dev_addr)[4];
- pkt_mod.mac_mod.mac_sa[5] = ((uint8_t *) dev->dev_addr)[5];
-
- pkt_mod.mac_mod.mac_sa_mask[0] = 0xff;
- pkt_mod.mac_mod.mac_sa_mask[1] = 0xff;
- pkt_mod.mac_mod.mac_sa_mask[2] = 0xff;
- pkt_mod.mac_mod.mac_sa_mask[3] = 0xff;
- pkt_mod.mac_mod.mac_sa_mask[4] = 0xff;
- pkt_mod.mac_mod.mac_sa_mask[5] = 0xff;
-#endif
-
- pkt_mod_bm |= (TPM_MAC_SA_SET | TPM_HOPLIM_DEC | TPM_IPV6_UPDATE);
- tpm_db_get_mc_igmp_proxy_sa_mac(mc_mac, &valid);
-
- if (valid) {
- memcpy(pkt_mod.mac_mod.mac_sa, mc_mac, 6 * sizeof(uint8_t));
- memset(pkt_mod.mac_mod.mac_sa_mask, 0xff, 6 * sizeof(uint8_t));
- } else
- IF_ERROR(ERR_GENERAL);
-
- if (mc_stream_pppoe) {
- pkt_mod_bm |= (TPM_MAC_DA_SET | TPM_PPPOE_DEL);
- MULTI_IPV6_2_MAC(mc_mac, group_addr);
- memcpy(pkt_mod.mac_mod.mac_da, mc_mac, 6 * sizeof(uint8_t));
- memset(pkt_mod.mac_mod.mac_da_mask, 0xff, 6 * sizeof(uint8_t));
- }
- }
-
- if (pkt_mod_bm != 0) {
- ret_code = tpm_mod2_entry_set(TPM_MOD_OWNER_TPM, TPM_ENUM_GMAC_0,
- pkt_mod_bm, TPM_INT_MC_MOD, &pkt_mod, mod_entry);
- IF_ERROR(ret_code);
- }
-
- return(TPM_OK);
-}
-tpm_error_code_t tpm_proc_add_ipv6_mc_check(uint32_t owner_id,
- uint32_t stream_num,
- tpm_mc_igmp_mode_t igmp_mode,
- uint8_t mc_stream_pppoe,
- uint16_t vid,
- uint8_t ipv6_src_add[16],
- uint8_t ipv6_dst_add[16],
- uint8_t ignore_ipv6_src,
- tpm_trg_port_type_t dest_port_bm,
- tpm_mc_filter_mode_t filter_mode)
-{
- tpm_error_code_t ret_code;
- int32_t int_ret_code, index;
- tpm_db_pnc_range_t range_data;
- uint32_t ai_bit;
- tpm_init_virt_uni_t virt_uni;
- uint32_t pnc_rng_free_size;
-
- /* Check TPM was successfully initialized */
- if (!tpm_db_init_done_get())
- IF_ERROR(ERR_SW_NOT_INIT);
-
- ret_code = tpm_owner_id_check(TPM_API_IPV6_MC, owner_id);
- IF_ERROR(ret_code);
-
- /* Get PNC Range Start */
- int_ret_code = tpm_db_pnc_rng_get(TPM_PNC_IPV6_MC_DS, &range_data);
- IF_ERROR(int_ret_code);
-
- if (stream_num >= range_data.pnc_range_conf.range_size)
- IF_ERROR(ERR_MC_STREAM_INVALID);
-
- ret_code = tpm_proc_check_dst_uni_port(dest_port_bm);
- IF_ERROR(ret_code);
-
- /*check virt range size if necessary*/
- if(filter_mode == TPM_MC_COMBINED_IP_MAC_FILTER) {
- if ((tpm_db_get_mc_per_uni_vlan_xlate() != 0) && ((dest_port_bm & TPM_TRG_UNI_VIRT) != 0)) {
- int_ret_code = tpm_db_pnc_rng_free_ent_get(TPM_PNC_VIRT_UNI, &pnc_rng_free_size);
- IF_ERROR(int_ret_code);
- if(pnc_rng_free_size == 0)
- IF_ERROR(ERR_OUT_OF_RESOURCES);
- }
- }
-
- /* fix bug of adding 1-2-3 instead of 0-1-2 => when 3 is over-writing the hardcoded entry */
- if ((stream_num < range_data.pnc_range_conf.api_start) || (stream_num > range_data.pnc_range_conf.api_end))
- IF_ERROR(ERR_MC_STREAM_INVALID);
-
- tpm_db_api_entry_ind_get(TPM_IPV6_MC_ACL, stream_num, &index);
- if (-1 != index)
- IF_ERROR(ERR_MC_STREAM_EXISTS);
-
- tpm_db_virt_info_get(&virt_uni);
-
- if (vid == 0xffff) {
- if (tpm_db_get_mc_filter_mode() == TPM_MC_IP_ONLY_FILTER) {
- if (virt_uni.enabled) {
- TPM_OS_WARN(TPM_TPM_LOG_MOD,
- " filter mode fall back to MC_COMBINED_MAC_IP_FILTER \r\n");
- }
- }
-
- if (tpm_db_get_mc_per_uni_vlan_xlate() != 0) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD,
- "when mc_per_uni_vlan_xlate is enabled, untagged mcast stream is not supported, "
- "and MC VID must be specified \r\n");
- IF_ERROR(ERR_SW_VID_INVALID);
- }
- } else {
- if (tpm_db_mc_vlan_get_ai_bit(vid, &ai_bit) != TPM_OK) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD,
- "MC VID must be configured first \r\n");
- IF_ERROR(ERR_SW_VID_INVALID);
- }
- }
-
- if (mc_stream_pppoe) {
- if (tpm_db_get_mc_pppoe_enable() == 0)
- IF_ERROR(ERR_FEAT_UNSUPPORT);
-
- if (igmp_mode == TPM_MC_IGMP_SNOOPING && tpm_db_get_mc_per_uni_vlan_xlate())
- IF_ERROR(ERR_FEAT_UNSUPPORT);
- }
-
- if (ipv6_dst_add[0] != 0xff)
- IF_ERROR(ERR_IPV6_MC_DST_IP_INVALID);
-
- if (dest_port_bm & TPM_TRG_UNI_VIRT) {
- if (virt_uni.enabled == 0)
- IF_ERROR(ERR_MC_DST_PORT_INVALID);
- }
-
- if (dest_port_bm & TPM_TRG_PORT_CPU) {
- if (dest_port_bm & (~TPM_TRG_PORT_CPU))
- IF_ERROR(ERR_MC_DST_PORT_INVALID);
- }
-
- /* check if there is MC SIP slot */
- if(0 == ignore_ipv6_src) {
- if(!tpm_db_ipv6_mc_sip_index_get(ipv6_src_add)) {
- /* this is a new MC SIP */
- if(!tpm_db_ipv6_mc_sip_free_slot_num_get())
- IF_ERROR(ERR_OUT_OF_RESOURCES);
- }
- }
-
- return(TPM_RC_OK);
-}
tpm_error_code_t tpm_proc_add_ipv6_mc_pnc_entry(tpm_mc_filter_mode_t filter_mode,
uint32_t stream_num,
tpm_mc_igmp_mode_t igmp_mode,
@@ -13184,6 +13958,7 @@
uint8_t ipv6_src_add[16],
uint8_t ipv6_dst_add[16],
uint8_t ignore_ipv6_src,
+ uint16_t dest_queue,
uint32_t dest_port_bm)
{
tpm_pncl_pnc_full_t pnc_data;
@@ -13201,6 +13976,7 @@
uint32_t entry_id;
uint16_t u4_vid;
int32_t sip_index = 0;
+ tpm_gmacs_enum_t gmac;
memset(&mc_stream, 0, sizeof(tpm_db_mc_stream_entry_t));
@@ -13209,8 +13985,8 @@
/*********** Create Modification Entries **********/
ret_code =
- tpm_proc_create_ipv6_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe, vid, ipv6_dst_add,
- dest_port_bm, &mod_entry);
+ tpm_proc_create_ipvx_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe, vid, ipv6_dst_add,
+ dest_port_bm, &mod_entry, TPM_IP_VER_6);
IF_ERROR(ret_code);
/* Handle IPv6 SSM */
@@ -13240,7 +14016,10 @@
/* Build SRAM Entry */
ret_code =
- tpm_proc_ipv6_mc_sram_build(filter_mode, igmp_mode, dest_port_bm, mod_entry, &(pnc_data.pncl_sram));
+ tpm_proc_ipvx_mc_sram_build(filter_mode, igmp_mode,
+ dest_queue, dest_port_bm,
+ mod_entry, &(pnc_data.pncl_sram),
+ TPM_IP_VER_6);
IF_ERROR(ret_code);
/*** Calculate PNC Entry ***/
@@ -13267,8 +14046,14 @@
/* Set API data */
memcpy(api_data.ipv6_mc_key.ipv6_dest_add, ipv6_dst_add, 16 * sizeof(uint8_t));
+ memcpy(api_data.ipv6_mc_key.ipv6_src_add, ipv6_src_add, 16 * sizeof(uint8_t));
api_data.ipv6_mc_key.dest_port_bm = dest_port_bm;
+ api_data.ipv6_mc_key.dest_queue = dest_queue;
api_data.ipv6_mc_key.vid = vid;
+ api_data.ipv6_mc_key.igmp_mode = igmp_mode;
+ api_data.ipv6_mc_key.mc_stream_pppoe = mc_stream_pppoe;
+ api_data.ipv6_mc_key.stream_num = stream_num;
+ api_data.ipv6_mc_key.ignore_ipv6_src = ignore_ipv6_src;
/* Set Pnc Connection data */
pnc_conn.num_pnc_ranges = 1;
@@ -13277,7 +14062,11 @@
/* Set Modification Connection data */
mod_con.mod_cmd_ind = mod_entry;
- mod_con.mod_cmd_mac = TPM_PNC_TRG_GMAC0;
+ if (mod_entry) {
+ ret_code = tpm_db_target_to_gmac(pnc_data.pncl_sram.flow_id_sub.pnc_target, &gmac);
+ IF_ERROR(ret_code);
+ mod_con.mod_cmd_mac = gmac;
+ }
/* Set new API Entry */
ret_code = tpm_db_api_entry_set(TPM_IPV6_MC_ACL, stream_num, 0 /*bi_dir */ ,
@@ -13319,6 +14108,7 @@
mc_stream.igmp_mode = igmp_mode;
mc_stream.mc_stream_pppoe = mc_stream_pppoe;
mc_stream.vid = vid;
+ mc_stream.dest_queue = dest_queue;
mc_stream.dest_port_bm = dest_port_bm;
mc_stream.u4_entry = rule_num;
mc_stream.ignore_src_addr = ignore_ipv6_src;
@@ -13339,6 +14129,7 @@
uint8_t ipv6_src_add[16],
uint8_t ipv6_dst_add[16],
uint8_t ignore_ipv6_src,
+ uint16_t dest_queue,
tpm_trg_port_type_t dest_port_bm)
{
tpm_error_code_t ret_code;
@@ -13362,14 +14153,22 @@
dest_port_bm = tpm_db_trg_port_uni_any_bmp_get(true);
/* Check parameters */
- ret_code = tpm_proc_add_ipv6_mc_check(owner_id, stream_num, igmp_mode, mc_stream_pppoe, vid,
+ ret_code = tpm_proc_add_ipvx_mc_check(owner_id, stream_num, igmp_mode, mc_stream_pppoe, vid,
ipv6_src_add, ipv6_dst_add, ignore_ipv6_src,
- dest_port_bm, filter_mode);
+ dest_queue, dest_port_bm, filter_mode, TPM_IP_VER_6);
IF_ERROR(ret_code);
+ /* get queue number */
+ if (dest_queue == TPM_INVALID_QUEUE) {
+ if (dest_port_bm & TPM_TRG_PORT_CPU)
+ dest_queue = tpm_db_get_mc_cpu_queue();
+ else
+ dest_queue = tpm_db_get_mc_hwf_queue();
+ }
/* Create PNC entry */
ret_code = tpm_proc_add_ipv6_mc_pnc_entry(filter_mode, stream_num, igmp_mode, mc_stream_pppoe, vid,
- ipv6_src_add, ipv6_dst_add, ignore_ipv6_src, dest_port_bm);
+ ipv6_src_add, ipv6_dst_add, ignore_ipv6_src,
+ dest_queue, dest_port_bm);
IF_ERROR(ret_code);
/* Set switch port_map for multicast MAC, but don't overwrite FF02::1 (MLD General Query) MAC */
@@ -13382,10 +14181,11 @@
return(TPM_RC_OK);
}
-tpm_error_code_t tpm_proc_delete_ipv6_mc_pnc_entry(tpm_mc_filter_mode_t filter_mode,
+tpm_error_code_t tpm_proc_delete_ipvx_mc_pnc_entry(tpm_mc_filter_mode_t filter_mode,
uint32_t stream_num,
uint32_t dest_port_bm,
- uint32_t u4_entry)
+ uint32_t u4_entry,
+ tpm_ip_ver_t ip_version)
{
tpm_db_pnc_range_t range_data;
tpm_rule_entry_t api_data;
@@ -13398,17 +14198,27 @@
uint32_t pnc_range_start = 0, api_start = 0, pnc_entry = 0;
uint32_t sip_index = 0;
uint8_t new_ref_num = 0;
+ tpm_pnc_ranges_t range;
+ tpm_api_sections_t api_section;
+
+ if (TPM_IP_VER_4 == ip_version) {
+ range = TPM_PNC_IPV4_MC_DS;
+ api_section = TPM_IPV4_MC;
+ } else {
+ range = TPM_PNC_IPV6_MC_DS;
+ api_section = TPM_IPV6_MC_ACL;
+ }
if (filter_mode != TPM_MC_MAC_ONLY_FILTER) {
/* Get PNC Range Start */
- ret_code = tpm_db_pnc_rng_get(TPM_PNC_IPV6_MC_DS, &range_data);
+ ret_code = tpm_db_pnc_rng_get(range, &range_data);
IF_ERROR(ret_code);
if (stream_num >= range_data.pnc_range_conf.range_size)
IF_ERROR(ERR_MC_STREAM_INVALID);
/* Check parameters */
- ret_code = tpm_db_api_entry_get(TPM_IPV6_MC_ACL, stream_num, &rule_idx, &bi_dir,
+ ret_code = tpm_db_api_entry_get(api_section, stream_num, &rule_idx, &bi_dir,
&api_data, &mod_con, &pnc_conn);
IF_ERROR(ret_code);
@@ -13428,38 +14238,41 @@
IF_ERROR(ret_code);
/* Increase number of free entries in pnc_range */
- ret_code = tpm_db_pnc_rng_free_ent_inc(TPM_PNC_IPV6_MC_DS);
+ ret_code = tpm_db_pnc_rng_free_ent_inc(range);
IF_ERROR(ret_code);
if (mod_con.mod_cmd_ind != 0) {
- ret_code = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, TPM_ENUM_GMAC_0, mod_con.mod_cmd_ind);
+ ret_code = tpm_proc_delete_mod(TPM_MOD_OWNER_TPM, mod_con.mod_cmd_mac, mod_con.mod_cmd_ind);
IF_ERROR(ret_code);
}
/* Delete API Rule Entry */
- ret_code = tpm_db_api_entry_invalidate(TPM_IPV6_MC_ACL, stream_num);
+ ret_code = tpm_db_api_entry_invalidate(api_section, stream_num);
IF_ERROR(ret_code);
- /* remove SIP PNC entry */
- ret_code = tpm_db_get_ipv6_mc_stream_entry(stream_num, &mc_stream);
- IF_ERROR(ret_code);
- if (0 == mc_stream.ignore_src_addr) {
- /* get index of this IPv6 MC SIP */
- sip_index = tpm_db_ipv6_mc_sip_index_get(mc_stream.src_addr);
- if (0 == sip_index) {
- /* SIP is not in DB, error */
- TPM_OS_ERROR(TPM_TPM_LOG_MOD, "get index of IPv6 MC SIP failed!\n");
- return(ERR_IPV6_MC_SRC_IP_INVALID);
- }
-
- /* dec reference number in DB */
- ret_code = tpm_db_ipv6_mc_sip_ref_num_dec(sip_index, &new_ref_num);
+
+ if (TPM_IP_VER_6 == ip_version) {
+ /* remove SIP PNC entry */
+ ret_code = tpm_db_get_ipv6_mc_stream_entry(stream_num, &mc_stream);
IF_ERROR(ret_code);
+ if (0 == mc_stream.ignore_src_addr) {
+ /* get index of this IPv6 MC SIP */
+ sip_index = tpm_db_ipv6_mc_sip_index_get(mc_stream.src_addr);
+ if (0 == sip_index) {
+ /* SIP is not in DB, error */
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "get index of IPv6 MC SIP failed!\n");
+ return(ERR_IPV6_MC_SRC_IP_INVALID);
+ }
- /* if new ref num is 0, remove this SIP in PNC */
- if (new_ref_num == 0) {
- ret_code = tpm_proc_ipv6_mc_sip_entry_del(sip_index);
+ /* dec reference number in DB */
+ ret_code = tpm_db_ipv6_mc_sip_ref_num_dec(sip_index, &new_ref_num);
IF_ERROR(ret_code);
+
+ /* if new ref num is 0, remove this SIP in PNC */
+ if (new_ref_num == 0) {
+ ret_code = tpm_proc_ipv6_mc_sip_entry_del(sip_index);
+ IF_ERROR(ret_code);
+ }
}
}
@@ -13478,7 +14291,10 @@
}
/* Remove stream entry */
- tpm_db_reset_ipv6_mc_stream_entry(stream_num);
+ if (TPM_IP_VER_4 == ip_version)
+ tpm_db_reset_mc_stream_entry(stream_num);
+ else
+ tpm_db_reset_ipv6_mc_stream_entry(stream_num);
return(TPM_RC_OK);
}
@@ -13491,6 +14307,7 @@
uint8_t ipv6_dst_add[16],
uint8_t sip_index,
uint8_t ignore_sip,
+ uint16_t dest_queue,
uint32_t dest_port_bm)
{
tpm_db_pnc_range_t range_data;
@@ -13508,6 +14325,11 @@
memset(&mc_stream, 0, sizeof(tpm_db_ipv6_mc_stream_entry_t));
+ /* Get old API Entry */
+ ret_code = tpm_db_api_entry_get(TPM_IPV6_MC_ACL, stream_num, &rule_idx, &bi_dir,
+ &api_data, &mod_con, &pnc_conn);
+ IF_ERROR(ret_code);
+
/* Only MC_IP_ONLY_FILTER mode, update the multicast group member ports by mh_mod. */
if (filter_mode == TPM_MC_IP_ONLY_FILTER) {
/* Get PNC Range Start */
@@ -13517,16 +14339,11 @@
if (stream_num >= range_data.pnc_range_conf.range_size)
IF_ERROR(ERR_MC_STREAM_INVALID);
- /* Get old API Entry */
- ret_code = tpm_db_api_entry_get(TPM_IPV6_MC_ACL, stream_num, &rule_idx, &bi_dir,
- &api_data, &mod_con, &pnc_conn);
- IF_ERROR(ret_code);
-
pnc_entry = pnc_conn.pnc_conn_tbl[0].pnc_index;
/* Create new Modification Entry */
- ret_code = tpm_proc_create_ipv6_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe,
- vid, ipv6_dst_add, dest_port_bm, &mod_entry);
+ ret_code = tpm_proc_create_ipvx_mc_mod(filter_mode, igmp_mode, mc_stream_pppoe,
+ vid, ipv6_dst_add, dest_port_bm, &mod_entry, TPM_IP_VER_6);
IF_ERROR(ret_code);
/* Rebuild PnC Entry */
@@ -13536,7 +14353,9 @@
/* Rebuild SRAM Entry */
ret_code =
- tpm_proc_ipv6_mc_sram_build(filter_mode, igmp_mode, dest_port_bm, mod_entry, &(pnc_data.pncl_sram));
+ tpm_proc_ipvx_mc_sram_build(filter_mode, igmp_mode, dest_queue,
+ dest_port_bm, mod_entry, &(pnc_data.pncl_sram),
+ TPM_IP_VER_6);
IF_ERROR(ret_code);
/* Update only Sram of PNC Entry */
@@ -13545,22 +14364,12 @@
/* Delete old Modification Entry */
if (mod_con.mod_cmd_ind != 0) {
- ret_code = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, TPM_ENUM_GMAC_0, mod_con.mod_cmd_ind);
+ ret_code = tpm_proc_delete_mod(TPM_MOD_OWNER_TPM, mod_con.mod_cmd_mac, mod_con.mod_cmd_ind);
IF_ERROR(ret_code);
}
/* Update new Modification Entry */
mod_con.mod_cmd_ind = mod_entry;
-
- /* Invalidate old API Entry */
- ret_code = tpm_db_api_entry_invalidate(TPM_IPV6_MC_ACL, stream_num);
- IF_ERROR(ret_code);
-
- /* Set new API Entry */
- mod_con.mod_cmd_ind = mod_entry;
- ret_code = tpm_db_api_entry_set(TPM_IPV6_MC_ACL, stream_num, 0 /*bi_dir */ ,
- &api_data, &mod_con, &pnc_conn, &rule_idx);
- IF_ERROR(ret_code);
}
if (filter_mode == TPM_MC_COMBINED_IP_MAC_FILTER) {
@@ -13620,6 +14429,17 @@
ret_code = tpm_db_set_ipv6_mc_stream_entry(stream_num, &mc_stream);
IF_ERROR(ret_code);
+ /* Update API entry */
+ /* Invalidate old API Entry */
+ ret_code = tpm_db_api_entry_invalidate(TPM_IPV6_MC_ACL, stream_num);
+ IF_ERROR(ret_code);
+
+ /* Set new API Entry */
+ api_data.ipv6_mc_key.dest_port_bm = dest_port_bm;
+ ret_code = tpm_db_api_entry_set(TPM_IPV6_MC_ACL, stream_num, 0 /*bi_dir */ ,
+ &api_data, &mod_con, &pnc_conn, &rule_idx);
+ IF_ERROR(ret_code);
+
return(TPM_RC_OK);
}
@@ -13669,6 +14489,12 @@
ret_code = tpm_db_get_ipv6_mc_stream_entry(stream_num, &mc_stream);
IF_ERROR(ret_code);
+ if (dest_port_bm == mc_stream.dest_port_bm) {
+ /* nothing changed, return directly */
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "dest_port_bm does not change, return directly\n");
+ return (TPM_OK);
+ }
+
/* get sip_index */
if (0 == mc_stream.ignore_src_addr) {
/* get index of this IPv6 MC SIP */
@@ -13682,19 +14508,22 @@
if (((dest_port_bm & TPM_TRG_PORT_CPU) != 0 && (mc_stream.dest_port_bm & TPM_TRG_PORT_CPU) == 0) ||
((dest_port_bm & TPM_TRG_PORT_CPU) == 0 && (mc_stream.dest_port_bm & TPM_TRG_PORT_CPU) != 0)) {
- ret_code = tpm_proc_delete_ipv6_mc_pnc_entry(filter_mode, stream_num,
- mc_stream.dest_port_bm, mc_stream.u4_entry);
+ ret_code = tpm_proc_delete_ipvx_mc_pnc_entry(filter_mode, stream_num,
+ mc_stream.dest_port_bm,
+ mc_stream.u4_entry,
+ TPM_IP_VER_6);
IF_ERROR(ret_code);
ret_code = tpm_proc_add_ipv6_mc_pnc_entry(filter_mode, stream_num, mc_stream.igmp_mode,
mc_stream.mc_stream_pppoe, mc_stream.vid,
- mc_stream.group_addr, mc_stream.src_addr,
- mc_stream.ignore_src_addr, dest_port_bm);
+ mc_stream.src_addr, mc_stream.group_addr,
+ mc_stream.ignore_src_addr, mc_stream.dest_queue,
+ dest_port_bm);
} else {
ret_code = tpm_proc_update_ipv6_mc_pnc_entry(filter_mode, stream_num, mc_stream.igmp_mode,
mc_stream.mc_stream_pppoe, mc_stream.vid,
mc_stream.group_addr, sip_index, mc_stream.ignore_src_addr,
- dest_port_bm);
+ mc_stream.dest_queue, dest_port_bm);
}
IF_ERROR(ret_code);
@@ -13734,7 +14563,10 @@
IF_ERROR(ret_code);
ret_code =
- tpm_proc_delete_ipv6_mc_pnc_entry(filter_mode, stream_num, mc_stream.dest_port_bm, mc_stream.u4_entry);
+ tpm_proc_delete_ipvx_mc_pnc_entry(filter_mode, stream_num,
+ mc_stream.dest_port_bm,
+ mc_stream.u4_entry,
+ TPM_IP_VER_6);
IF_ERROR(ret_code);
/* Set switch VID and multicast MAC */
@@ -13838,6 +14670,59 @@
return(TPM_RC_OK);
}
+tpm_error_code_t tpm_proc_set_active_wan_check(tpm_gmacs_enum_t active_wan)
+{
+ tpm_gmacs_enum_t active_wan_current;
+ tpm_eth_complex_profile_t profile_id;
+
+ if(!tpm_db_switch_active_wan_en_get()) {
+ TPM_OS_ERROR(TPM_DB_MOD, "current profile does not support switching active wan\n");
+ return ERR_FEAT_UNSUPPORT;
+ }
+
+ active_wan_current = tpm_db_active_wan_get();
+ profile_id = tpm_db_eth_cmplx_profile_get();
+
+ if (active_wan == active_wan_current) {
+ TPM_OS_ERROR(TPM_DB_MOD, "new active wan port should not be the same with current one\n");
+ return ERR_FEAT_UNSUPPORT;
+ }
+
+ if ( ((profile_id == TPM_PON_G1_WAN_G0_INT_SWITCH) || (profile_id == TPM_PON_G1_WAN_G0_SINGLE_PORT))
+ && ((active_wan == TPM_ENUM_GMAC_1) || (active_wan == TPM_ENUM_PMAC)))
+ ;/* OK */
+ else if ( ((profile_id == TPM_PON_G0_WAN_G1_INT_SWITCH) || (profile_id == TPM_PON_G0_WAN_G1_SINGLE_PORT))
+ && ((active_wan == TPM_ENUM_GMAC_0) || (active_wan == TPM_ENUM_PMAC)))
+ ;/* OK */
+ else {
+ TPM_OS_ERROR(TPM_DB_MOD, "new active wan port is invalid according to current profile id\n");
+ return ERR_FEAT_UNSUPPORT;
+ }
+
+ return TPM_OK;
+}
+tpm_error_code_t tpm_proc_set_active_wan(tpm_gmacs_enum_t active_wan)
+{
+ int32_t db_ret;
+ tpm_error_code_t tpm_ret;
+
+ tpm_ret = tpm_proc_set_active_wan_check(active_wan);
+ if(TPM_OK != tpm_ret) {
+ TPM_OS_ERROR(TPM_DB_MOD, "input active wan is invalid, error code (%d)\n", tpm_ret);
+ return ERR_GENERAL;
+ }
+
+ db_ret = tpm_db_active_wan_set(active_wan);
+ if(TPM_DB_OK != db_ret) {
+ TPM_OS_ERROR(TPM_DB_MOD, "set current active wan failed(%d)\n", db_ret);
+ return ERR_GENERAL;
+ }
+ /* reset gmac fun */
+ tpm_db_mac_func_set();
+
+ return (TPM_OK);
+}
+
tpm_error_code_t tpm_proc_ipv6_mc_sip_init(void)
{
@@ -14236,6 +15121,7 @@
/* Set next offset and update register */
sram_data->shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
+ sram_data->pnc_queue = TPM_PNCL_NO_QUEUE_UPDATE;
/*** Set next lookup configuration ***/
@@ -14719,7 +15605,6 @@
long long int_pkt_act = 0;
tpm_ai_vectors_t key_field;
tpm_db_pon_type_t pon_type;
- uint32_t i;
int32_t ret_code;
memset(&key_field, 0, sizeof(tpm_ai_vectors_t));
@@ -14763,11 +15648,7 @@
sram_data->sram_updt_bm |= TPM_PNCL_SET_TXP;
/* Set PNC FlowId Target */
- for (i = 0; i < 8; i++) {
- if (pkt_frwd->trg_port == (uint32_t)(TPM_TRG_TCONT_0 << i))
- break;
- }
- sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_PMAC0 + i;
+ sram_data->flow_id_sub.pnc_target = tpm_proc_cnm_pnc_trg_get(pkt_frwd->trg_port);
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "Set Target(%d)\n", sram_data->flow_id_sub.pnc_target);
@@ -14877,7 +15758,6 @@
{
tpm_ai_vectors_t key_field;
tpm_db_pon_type_t pon_type;
- uint32_t i;
memset(&key_field, 0, sizeof(tpm_ai_vectors_t));
@@ -14902,11 +15782,7 @@
sram_data->sram_updt_bm |= TPM_PNCL_SET_TXP;
/* Set PNC FlowId Target */
- for (i = 0; i < 8; i++) {
- if (pkt_frwd->trg_port == (uint32_t)(TPM_TRG_TCONT_0 << i))
- break;
- }
- sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_PMAC0 + i;
+ sram_data->flow_id_sub.pnc_target = tpm_proc_cnm_pnc_trg_get(pkt_frwd->trg_port);
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "Set Target(%d)\n", sram_data->flow_id_sub.pnc_target);
@@ -14933,7 +15809,29 @@
return(TPM_OK);
}
+tpm_pnc_trg_t tpm_proc_cnm_pnc_trg_get(tpm_trg_port_type_t trg_port)
+{
+ uint32_t i;
+ tpm_pnc_trg_t pnc_trgt = 0;
+ tpm_gmacs_enum_t active_wan;
+ active_wan = tpm_db_active_wan_get();
+
+ /* Set PNC FlowId Target */
+ if (TPM_ENUM_PMAC == active_wan) {
+ for (i = 0; i < 8; i++) {
+ if (trg_port == (uint32_t)(TPM_TRG_TCONT_0 << i))
+ break;
+ }
+ pnc_trgt = TPM_PNC_TRG_PMAC0 + i;
+ } else if (TPM_ENUM_GMAC_0 == active_wan)
+ pnc_trgt = TPM_PNC_TRG_GMAC0;
+ else if (TPM_ENUM_GMAC_1 == active_wan)
+ pnc_trgt = TPM_PNC_TRG_GMAC1;
+
+ TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "Set Target(%d)\n", pnc_trgt);
+ return pnc_trgt;
+}
int32_t tpm_proc_cnm_ipv4_tcam_build(tpm_src_port_type_t src_port,
uint32_t precedence,
tpm_parse_fields_t ipv4_parse_rule_bm,
@@ -14992,7 +15890,6 @@
{
tpm_ai_vectors_t key_field;
tpm_db_pon_type_t pon_type;
- uint32_t i;
memset(&key_field, 0, sizeof(tpm_ai_vectors_t));
@@ -15016,12 +15913,7 @@
/* Add Target Txp to update BM */
sram_data->sram_updt_bm |= TPM_PNCL_SET_TXP;
- /* Set PNC FlowId Target */
- for (i = 0; i < 8; i++) {
- if (pkt_frwd->trg_port == (uint32_t)(TPM_TRG_TCONT_0 << i))
- break;
- }
- sram_data->flow_id_sub.pnc_target = TPM_PNC_TRG_PMAC0 + i;
+ sram_data->flow_id_sub.pnc_target = tpm_proc_cnm_pnc_trg_get(pkt_frwd->trg_port);
TPM_OS_DEBUG(TPM_TPM_LOG_MOD, "Set Target(%d)\n", sram_data->flow_id_sub.pnc_target);
@@ -15098,6 +15990,8 @@
uint32_t precedence,
tpm_parse_fields_t l2_parse_rule_bm,
tpm_l2_acl_key_t *l2_key,
+ tpm_parse_fields_t ipv4_parse_rule_bm,
+ tpm_ipv4_acl_key_t *ipv4_key,
uint32_t ipv4_key_idx,
tpm_pkt_frwd_t *pkt_frwd,
tpm_pkt_action_t pkt_act,
@@ -15190,10 +16084,13 @@
/* Set PNC API data */
api_data.cnm_key.src_port = src_port;
api_data.cnm_key.l2_parse_rule_bm = l2_parse_rule_bm;
+ api_data.cnm_key.ipv4_parse_rule_bm = ipv4_parse_rule_bm;
api_data.cnm_key.pkt_act = pkt_act;
api_data.cnm_key.pbits = pbits;
if (l2_key)
memcpy(&(api_data.cnm_key.l2_key), l2_key, sizeof(tpm_l2_acl_key_t));
+ if (ipv4_key)
+ memcpy(&(api_data.cnm_key.ipv4_key), ipv4_key, sizeof(tpm_ipv4_acl_key_t));
if (pkt_frwd != NULL)
memcpy(&(api_data.cnm_key.pkt_frwd), pkt_frwd, sizeof(tpm_pkt_frwd_t));
else
@@ -15564,6 +16461,49 @@
}
/*******************************************************************************
+* tpm_proc_mac_learn_port_gmac_bm_map()
+*
+* DESCRIPTION: The function get the MAC learn port by means of the GMAC Functionality
+* for Media convert with loopback mode.
+*
+* INPUTS:
+* None
+*
+* OUTPUTS:
+* gmac_bm - Bitmap of the GMACs relevant to set in TCAM
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+int32_t tpm_proc_mac_learn_port_gmac_bm_map(tpm_gmac_bm_t *gmac_bm)
+{
+ int32_t ret_code = TPM_DB_OK;
+ uint32_t gmac_id;
+ tpm_db_gmac_func_t gfunc;
+ tpm_gmac_bm_t l_gmac_bm = 0;
+
+ /* Find the GMAC used to do MAC learn on MC */
+ for (gmac_id = TPM_ENUM_GMAC_0; gmac_id < TPM_MAX_NUM_GMACS; gmac_id ++) {
+ ret_code = tpm_db_gmac_func_get(gmac_id, &gfunc);
+ if (TPM_DB_OK == ret_code) {
+ if (TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI == gfunc)
+ l_gmac_bm |= gmac_pnc_bm[gmac_id];
+ } else {
+ TPM_OS_ERROR(TPM_DB_MOD, "GMAC%d Func get failed \n", gmac_id);
+ return ret_code;
+ }
+ }
+
+ *gmac_bm = l_gmac_bm;
+
+ return (TPM_OK);
+}
+
+/*******************************************************************************
* tpm_proc_mac_learn_tcam_build()
*
* DESCRIPTION: Function builds a logical TCAM entry from the API data
@@ -15588,10 +16528,15 @@
int32_t ret_code;
uint32_t lu_id;
tpm_pncl_offset_t start_offset;
+ tpm_gmac_bm_t gmac_bm;
/* L2 Parsing, according to bm in param */
tcam_data->l2_parse_bm = TPM_L2_PARSE_MAC_SA;
- tcam_data->port_ids = TPM_BM_GMAC_0;
+
+ /* Get GMAC(s) */
+ ret_code = tpm_proc_mac_learn_port_gmac_bm_map(&gmac_bm);
+ IF_ERROR(ret_code);
+ tcam_data->port_ids = gmac_bm;
/* Copy in logical PnC Key */
if (src_mac_addr)
@@ -15959,7 +16904,7 @@
if (addr_exist)
return TPM_OK;
/* Get Tx queue */
- if (tpm_db_gmac_lpk_queue_get(&gmac_num, &queue_idx)) {
+ if (tpm_db_gmac_lpk_queue_get(&gmac_num, &queue_idx, TPM_GMAC1_QUEUE_DATA_TRAFFIC)) {
printk("Loopback Tx queue index get failed\n");
return TPM_FAIL;
}
@@ -16045,10 +16990,11 @@
tpm_db_pnc_range_t range_data;
tpm_pnc_all_t pnc_entry;
uint32_t entry_id;
- int32_t cpu_rx_queue;
uint32_t queue_id;
tpm_gmacs_enum_t lpk_gmac;
uint32_t switch_init;
+ uint32_t mod_idx = 0;
+ tpm_pkt_mod_t mod_data;
/* check switch init */
ret_code = tpm_db_switch_init_get(&switch_init);
@@ -16072,6 +17018,12 @@
IF_ERROR(ret_code);
entry_id = range_data.pnc_range_conf.range_end;
+ /* Get mod_idx */
+ if (TPM_DB_OK != tpm_db_mac_learn_mod_idx_get(&mod_idx)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "MAC learn mod index get failed \n");
+ return TPM_FAIL;
+ }
+
/* construct default rule */
/* Set Lookup Id */
pnc_entry.tcam_entry.lu_id = range_data.pnc_range_conf.base_lu_id;
@@ -16086,28 +17038,77 @@
pnc_entry.sram_entry.flowid_updt_mask = TPM_TXP_FL_UPDT_MASK;
switch (mac_conf) {
case TPM_UNK_MAC_TRAP:
- /* Get default CPU queue */
- tpm_db_get_cpu_rx_queue(&cpu_rx_queue);
- /* Trap to CPU */
- pnc_entry.sram_entry.flowid_val = (TPM_PNC_TRG_CPU << TPM_TXP_FL_SHIFT);
- pnc_entry.sram_entry.pnc_queue = cpu_rx_queue;
- /* Set result info */
- pnc_entry.sram_entry.res_info_15_0_data |= (1 << TPM_PNC_RI_MAC_LEARN_BIT);
- pnc_entry.sram_entry.res_info_15_0_mask |= (1 << TPM_PNC_RI_MAC_LEARN_BIT);
+ if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac,
+ &queue_id,
+ TPM_GMAC1_QUEUE_MAC_LEARN_TRAFFIC)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "loopback gmac queue get failed \n");
+ return TPM_FAIL;
+ }
+ /* Alloc PMT for MAC learn if needed */
+ if (mod_idx == 0) {
+ memset((uint8_t *) &mod_data, 0, sizeof(tpm_pkt_mod_t));
+ mod_data.mh_mod = TPM_MOD2_MAC_LEARN_MH;
+ if (tpm_mod2_entry_set(owner_id,
+ lpk_gmac,
+ TPM_MH_SET,
+ 0,
+ &mod_data,
+ &mod_idx)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "PMT entry for MAC leanrn get failed\n");
+ return TPM_FAIL;
+ }
+ /* store mod_idx in TPM_DB */
+ if (TPM_DB_OK != tpm_db_mac_learn_mod_idx_set(mod_idx)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "Mod index set to tpm db failed \n");
+ return TPM_FAIL;
+ }
+ }
+ /* Frwd to loopback GMAC1 */
+ pnc_entry.sram_entry.flowid_val = (TPM_PNC_TRG_GMAC1 << TPM_TXP_FL_SHIFT);
+ pnc_entry.sram_entry.pnc_queue = queue_id;
+ /* Set MH */
+ pnc_entry.sram_entry.flowid_val |= mod_idx;
+ pnc_entry.sram_entry.flowid_updt_mask |= TPM_MOD_FL_UPDT_MASK;
break;
case TPM_UNK_MAC_DROP:
/* Drop the packet */
pnc_entry.sram_entry.res_info_15_0_data |= (1 << TPM_PNC_RI_DISC_BIT);
pnc_entry.sram_entry.res_info_15_0_mask |= (1 << TPM_PNC_RI_DISC_BIT);
+ /* delete MAC learn PMT entry if there is */
+ if (mod_idx) {
+ if (tpm_mod2_entry_del(owner_id, TPM_ENUM_GMAC_1, mod_idx)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "PMT entry del failed\n");
+ return TPM_FAIL;
+ }
+ /* clearn mod index in TPM_DB */
+ if (TPM_DB_OK != tpm_db_mac_learn_mod_idx_set(0)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "MAC learn mod index clear failed \n");
+ return TPM_FAIL;
+ }
+ }
break;
case TPM_UNK_MAC_CONTINUE:
- if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac, &queue_id)) {
+ if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac,
+ &queue_id,
+ TPM_GMAC1_QUEUE_DATA_TRAFFIC)) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "loopback gmac queue get failed \n");
return TPM_FAIL;
}
/* Frwd to loopback GMAC1 */
pnc_entry.sram_entry.flowid_val = (TPM_PNC_TRG_GMAC1 << TPM_TXP_FL_SHIFT);
pnc_entry.sram_entry.pnc_queue = queue_id;
+ /* delete MAC learn PMT entry if there is */
+ if (mod_idx) {
+ if (tpm_mod2_entry_del(owner_id, TPM_ENUM_GMAC_1, mod_idx)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "PMT entry del failed\n");
+ return TPM_FAIL;
+ }
+ /* clearn mod index in TPM_DB */
+ if (TPM_DB_OK != tpm_db_mac_learn_mod_idx_set(0)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "MAC learn mod index clear failed \n");
+ return TPM_FAIL;
+ }
+ }
break;
default:
break;
@@ -16123,6 +17124,626 @@
return TPM_OK;
}
+tpm_error_code_t tpm_acl_rcvr_func_mac_learn(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ ret_code = tpm_proc_add_static_mac_rule(owner_id, &(api_data->api_rule_data.l2_prim_key.l2_key));
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ds_load_balance(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ ret_code = tpm_proc_add_ds_load_balance_acl_rule(owner_id, api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.l2_prim_key.parse_rule_bm,
+ api_data->api_rule_data.l2_prim_key.parse_flags_bm,
+ &(api_data->api_rule_data.l2_prim_key.l2_key),
+ api_data->api_rule_data.l2_prim_key.pkt_frwd.trg_port);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_DS_LOAD_BALANCE_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_cpu_loopback(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ ret_code = tpm_proc_add_cpu_loopback_rule(owner_id, api_data->rule_num, &rule_index_tmp,
+ &(api_data->api_rule_data.l2_prim_key.pkt_frwd));
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_CPU_LOOPBACK_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_l2_prim(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ ret_code = tpm_proc_add_l2_prim_acl_rule(owner_id, api_data->api_rule_data.l2_prim_key.src_port,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.l2_prim_key.parse_rule_bm,
+ api_data->api_rule_data.l2_prim_key.parse_flags_bm,
+ &(api_data->api_rule_data.l2_prim_key.l2_key),
+ &(api_data->api_rule_data.l2_prim_key.pkt_frwd),
+ &(api_data->api_rule_data.l2_prim_key.pkt_mod),
+ api_data->api_rule_data.l2_prim_key.pkt_mod_bm,
+ &(api_data->api_rule_data.l2_prim_key.rule_action));
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_L2_PRIM_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_l3_type(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ ret_code = tpm_proc_add_l3_type_acl_rule(owner_id, api_data->api_rule_data.l3_type_key.src_port,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.l3_type_key.parse_rule_bm,
+ api_data->api_rule_data.l3_type_key.parse_flags_bm,
+ &(api_data->api_rule_data.l3_type_key.l3_key),
+ &(api_data->api_rule_data.l3_type_key.pkt_frwd),
+ &(api_data->api_rule_data.l3_type_key.rule_action));
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_L3_TYPE_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv4(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ ret_code = tpm_proc_add_ipv4_acl_rule(owner_id, api_data->api_rule_data.ipv4_key.src_port,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv4_key.parse_rule_bm,
+ api_data->api_rule_data.ipv4_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv4_key.ipv4_key),
+ &(api_data->api_rule_data.ipv4_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv4_key.pkt_mod),
+ api_data->api_rule_data.ipv4_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv4_key.rule_action));
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_IPV4_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv4_mc(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+
+ ret_code = tpm_proc_add_ipv4_mc_stream(owner_id,
+ api_data->api_rule_data.ipv4_mc_key.stream_num,
+ api_data->api_rule_data.ipv4_mc_key.igmp_mode,
+ api_data->api_rule_data.ipv4_mc_key.mc_stream_pppoe,
+ api_data->api_rule_data.ipv4_mc_key.vid,
+ api_data->api_rule_data.ipv4_mc_key.ipv4_src_add,
+ api_data->api_rule_data.ipv4_mc_key.ipv4_dest_add,
+ api_data->api_rule_data.ipv4_mc_key.ignore_ipv4_src,
+ api_data->api_rule_data.ipv4_mc_key.dest_queue,
+ api_data->api_rule_data.ipv4_mc_key.dest_port_bm);
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_gen(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+ tpm_init_ipv6_5t_enable_t ipv6_5t_enable;
+ tpm_dir_t src_dir;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+
+ /* Check 5_tuple feature is enable/disabled */
+ tpm_db_ipv6_5t_enable_get(&ipv6_5t_enable);
+ if (ipv6_5t_enable == TPM_IPV6_5T_DISABLED)
+ ret_code = tpm_proc_add_ipv6_gen_acl_rule(owner_id, api_data->api_rule_data.ipv6_gen_key.src_port,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_gen_key.parse_rule_bm,
+ api_data->api_rule_data.ipv6_gen_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv6_gen_key.ipv6_gen_key),
+ &(api_data->api_rule_data.ipv6_gen_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_gen_key.pkt_mod),
+ api_data->api_rule_data.ipv6_gen_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv6_gen_key.rule_action));
+ else {
+ /* get direction */
+ if (FROM_LAN(api_data->api_rule_data.ipv6_gen_key.src_port))
+ src_dir = TPM_DIR_US;
+ else
+ src_dir = TPM_DIR_DS;
+ ret_code = tpm_proc_add_ipv6_gen_5t_rule(owner_id, src_dir,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_gen_key.parse_rule_bm,
+ api_data->api_rule_data.ipv6_gen_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv6_gen_key.l4_key),
+ &(api_data->api_rule_data.ipv6_gen_key.ipv6_gen_key),
+ &(api_data->api_rule_data.ipv6_gen_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_gen_key.pkt_mod),
+ api_data->api_rule_data.ipv6_gen_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv6_gen_key.rule_action));
+ }
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_IPV6_GEN_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_dip(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+ tpm_init_ipv6_5t_enable_t ipv6_5t_enable;
+ tpm_dir_t src_dir;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+
+ /* Check 5_tuple feature is enable/disabled */
+ tpm_db_ipv6_5t_enable_get(&ipv6_5t_enable);
+ if (ipv6_5t_enable == TPM_IPV6_5T_DISABLED)
+ ret_code = tpm_proc_add_ipv6_dip_acl_rule(owner_id, api_data->api_rule_data.ipv6_dip_key.src_port,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_dip_key.parse_rule_bm,
+ api_data->api_rule_data.ipv6_dip_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv6_dip_key.ipv6_dipkey),
+ &(api_data->api_rule_data.ipv6_dip_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_dip_key.pkt_mod),
+ api_data->api_rule_data.ipv6_dip_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv6_dip_key.rule_action));
+ else {
+ /* get direction */
+ if (FROM_LAN(api_data->api_rule_data.ipv6_dip_key.src_port))
+ src_dir = TPM_DIR_US;
+ else
+ src_dir = TPM_DIR_DS;
+ ret_code = tpm_proc_add_ipv6_dip_5t_rule(owner_id, src_dir,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_dip_key.parse_rule_bm,
+ api_data->api_rule_data.ipv6_dip_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv6_dip_key.l4_key),
+ &(api_data->api_rule_data.ipv6_dip_key.ipv6_gen_key),
+ &(api_data->api_rule_data.ipv6_dip_key.ipv6_dipkey),
+ &(api_data->api_rule_data.ipv6_dip_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_dip_key.pkt_mod),
+ api_data->api_rule_data.ipv6_dip_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv6_dip_key.rule_action));
+ }
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_IPV6_DIP_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_mc(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+
+ ret_code = tpm_proc_add_ipv6_mc_stream(owner_id,
+ api_data->api_rule_data.ipv6_mc_key.stream_num,
+ api_data->api_rule_data.ipv6_mc_key.igmp_mode,
+ api_data->api_rule_data.ipv6_mc_key.mc_stream_pppoe,
+ api_data->api_rule_data.ipv6_mc_key.vid,
+ api_data->api_rule_data.ipv6_mc_key.ipv6_src_add,
+ api_data->api_rule_data.ipv6_mc_key.ipv6_dest_add,
+ api_data->api_rule_data.ipv6_mc_key.ignore_ipv6_src,
+ api_data->api_rule_data.ipv6_mc_key.dest_queue,
+ api_data->api_rule_data.ipv6_mc_key.dest_port_bm);
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_nh(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+
+ ret_code = tpm_proc_add_ipv6_nh_acl_rule(owner_id,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_nh_key.parse_flags_bm,
+ api_data->api_rule_data.ipv6_nh_key.nh_iter,
+ api_data->api_rule_data.ipv6_nh_key.nh,
+ &(api_data->api_rule_data.ipv6_nh_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_nh_key.rule_action));
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_IPV6_NH_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_l4(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ uint32_t rule_index_tmp;
+ tpm_init_ipv6_5t_enable_t ipv6_5t_enable;
+ tpm_dir_t src_dir;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+
+ /* Check 5_tuple feature is enable/disabled */
+ tpm_db_ipv6_5t_enable_get(&ipv6_5t_enable);
+ if (ipv6_5t_enable == TPM_IPV6_5T_DISABLED)
+ ret_code = tpm_proc_add_ipv6_l4_ports_acl_rule(owner_id, api_data->api_rule_data.ipv6_l4_key.src_port,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_l4_key.parse_rule_bm,
+ api_data->api_rule_data.ipv6_l4_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv6_l4_key.l4_key),
+ &(api_data->api_rule_data.ipv6_l4_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_l4_key.pkt_mod),
+ api_data->api_rule_data.ipv6_l4_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv6_l4_key.rule_action));
+ else {
+ /* get direction */
+ if (FROM_LAN(api_data->api_rule_data.ipv6_l4_key.src_port))
+ src_dir = TPM_DIR_US;
+ else
+ src_dir = TPM_DIR_DS;
+ ret_code = tpm_proc_add_ipv6_l4_ports_5t_rule(owner_id, src_dir,
+ api_data->rule_num, &rule_index_tmp,
+ api_data->api_rule_data.ipv6_l4_key.parse_rule_bm,
+ api_data->api_rule_data.ipv6_l4_key.parse_flags_bm,
+ &(api_data->api_rule_data.ipv6_l4_key.l4_key),
+ &(api_data->api_rule_data.ipv6_l4_key.pkt_frwd),
+ &(api_data->api_rule_data.ipv6_l4_key.pkt_mod),
+ api_data->api_rule_data.ipv6_l4_key.pkt_mod_bm,
+ &(api_data->api_rule_data.ipv6_l4_key.rule_action));
+ }
+ IF_ERROR(ret_code);
+
+ if (rule_idx_updt_en) {
+ ret_code = tpm_db_api_entry_update_rule_idx(TPM_L4_ACL, rule_index_tmp, api_data->rule_idx);
+ IF_ERROR(ret_code);
+ }
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_acl_rcvr_func_cnm(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en)
+{
+ tpm_error_code_t ret_code;
+ static tpm_src_port_type_t src_port = TPM_SRC_PORT_UNI_0;
+ static uint32_t precedence_base = 0;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "rule_index:[%d]\n", api_data->rule_idx);
+ if (src_port < api_data->api_rule_data.cnm_key.src_port) {
+ src_port = api_data->api_rule_data.cnm_key.src_port;
+ precedence_base = api_data->rule_num;
+ } else if (src_port > api_data->api_rule_data.cnm_key.src_port) {
+ src_port = api_data->api_rule_data.cnm_key.src_port;
+ precedence_base = 0;
+ }
+ ret_code = tpm_ctc_cm_acl_rule_add(owner_id, api_data->api_rule_data.cnm_key.src_port,
+ api_data->rule_num - precedence_base,
+ api_data->api_rule_data.cnm_key.l2_parse_rule_bm,
+ api_data->api_rule_data.cnm_key.ipv4_parse_rule_bm,
+ api_data->api_rule_data.cnm_key.ipv6_parse_rule_bm,
+ &(api_data->api_rule_data.cnm_key.l2_key),
+ &(api_data->api_rule_data.cnm_key.ipv4_key),
+ &(api_data->api_rule_data.cnm_key.ipv6_key),
+ &(api_data->api_rule_data.cnm_key.pkt_frwd),
+ api_data->api_rule_data.cnm_key.pkt_act,
+ api_data->api_rule_data.cnm_key.pbits);
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+
+tpm_error_code_t tpm_acl_rcvr_func_get(tpm_api_type_t api_type, tpm_acl_recovery_func *func)
+{
+ uint32_t api_loop;
+ uint32_t api_max;
+
+ api_max = sizeof(tpm_hot_swap_acl_recovery)/sizeof(tpm_hot_swap_acl_recovery_t);
+
+ for (api_loop = 0; api_loop < api_max; api_loop++) {
+
+ if (tpm_hot_swap_acl_recovery[api_loop].api_type == api_type) {
+ *func = tpm_hot_swap_acl_recovery[api_loop].func;
+ return TPM_OK;
+ }
+ }
+ return (TPM_OK);
+}
+#ifdef CONFIG_MV_ETH_WAN_SWAP
+
+tpm_error_code_t tpm_proc_check_hot_swap_profile(uint32_t owner_id,
+ tpm_eth_complex_profile_t profile_id)
+{
+ tpm_error_code_t ret_code;
+ tpm_api_type_t api_type;
+ tpm_eth_complex_profile_t profile_current;
+
+ /* Check owner_id */
+ for (api_type = TPM_API_MAC_LEARN; api_type < TPM_MAX_API_TYPES; api_type++) {
+ ret_code = tpm_owner_id_check(api_type, owner_id);
+ IF_ERROR(ret_code);
+ }
+
+ /* check profile id */
+ profile_current = tpm_db_eth_cmplx_profile_get();
+ if ( TPM_G0_WAN_G1_INT_SWITCH == profile_current
+ && TPM_G1_WAN_G0_INT_SWITCH == profile_id)
+ /* allowed */
+ ;
+ else if ( TPM_G1_WAN_G0_INT_SWITCH == profile_current
+ && TPM_G0_WAN_G1_INT_SWITCH == profile_id)
+ /* allowed */
+ ;
+ else {
+ /* not support */
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "So far only swapping from TPM_PON_G1_WAN_G0_INT_SWITCH "
+ "to TPM_PON_G0_WAN_G1_INT_SWITCH or vice versa are supported,"
+ "current profile: [%d], new profile: [%d]\n", profile_current, profile_id);
+ return ERR_FEAT_UNSUPPORT;
+ }
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_proc_hot_swap_update_acl_rules(uint32_t owner_id)
+{
+ tpm_db_api_entry_t api_data;
+ tpm_api_type_t api_type;
+ tpm_acl_recovery_func func = NULL;
+ tpm_api_sections_t api_section;
+ int32_t db_ret = 0;
+ int32_t next_rule = 0;
+ uint32_t current_rule = 0;
+ uint32_t rule_index = 0;
+ uint32_t rule_index_max = 0;
+ tpm_error_code_t ret_code;
+ uint32_t rule_idx_updt_en = 0;
+ tpm_pnc_ranges_t range_id;
+ tpm_db_pnc_range_conf_t range_conf;
+
+ //tpm_glob_trace = ~0;
+
+ rule_index_max = 1000;
+
+ /* add ACL rules again */
+ for (api_type = TPM_API_MAC_LEARN; api_type < TPM_MAX_API_TYPES; api_type++) {
+
+ /* Get acl recovery func */
+ ret_code = tpm_acl_rcvr_func_get(api_type, &func);
+ IF_ERROR(ret_code);
+
+ /* Get the api_section */
+ ret_code = tpm_db_api_section_get_from_api_type(api_type, &api_section);
+ IF_ERROR(ret_code);
+
+ current_rule = -1;
+
+ TPM_OS_INFO(TPM_DB_MOD, "api_type(%d)\n\n", api_type);
+
+ ret_code = tpm_db_api_entry_bak_get_next(api_section, current_rule, &next_rule);
+ IF_ERROR(ret_code);
+
+ if (-1 == next_rule) {
+ continue;
+ }
+
+ /* Get Range_Id */
+ tpm_db_api_section_main_pnc_get(api_section, &range_id);
+
+ /* Get Range Conf */
+ ret_code = tpm_db_pnc_rng_conf_get(range_id, &range_conf);
+ IF_ERROR(ret_code);
+
+ if (range_conf.range_type == TPM_RANGE_TYPE_ACL)
+ rule_idx_updt_en = TPM_TRUE;
+ else
+ rule_idx_updt_en = TPM_FALSE;
+
+ while (-1 != next_rule) {
+ /*get api section table entry*/
+ if (tpm_db_api_section_bak_ent_tbl_get(api_section, &api_data, next_rule)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "get API data failed, api_section:[%d], rule_index:[%d] \n",
+ api_section, rule_index);
+ return TPM_FAIL;
+ }
+
+ if (api_data.valid != TPM_DB_VALID) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "API data is not valid, api_section:[%d], rule_index:[%d] \n",
+ api_section, rule_index);
+ return TPM_FAIL;
+ }
+ TPM_OS_INFO(TPM_DB_MOD, "rule_num(%d), rule_idx(%d) \n", api_data.rule_num, api_data.rule_idx);
+
+ ret_code = (*func)(owner_id, &api_data, rule_idx_updt_en);
+ IF_ERROR(ret_code);
+
+ if (rule_index_max < api_data.rule_idx)
+ rule_index_max = api_data.rule_idx;
+
+ ret_code = tpm_db_api_entry_bak_get_next(api_section, api_data.rule_num, &next_rule);
+ IF_ERROR(ret_code);
+ }
+
+ IF_ERROR(ret_code);
+ }
+
+ /* update the max rule index */
+ db_ret = tpm_db_rule_index_set(rule_index_max + 1);
+ if (TPM_DB_OK != db_ret) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "update rule_index failed, before hot swap, max rule_index:[%d]\n", rule_index_max);
+ return TPM_FAIL;
+ }
+ return (TPM_OK);
+}
+tpm_error_code_t tpm_proc_hot_swap_misc_cfg(tpm_eth_complex_profile_t profile_id)
+{
+ tpm_error_code_t ret_code;
+ tpm_init_gmac_conn_conf_t gmac_port_conf[TPM_NUM_GMACS];
+ tpm_gmacs_enum_t gmac_i;
+ uint32_t gmac0_mh_en = 0;
+ uint32_t gmac1_mh_en = 0;
+ tpm_db_mh_src_t ds_mh_set_conf;
+
+ /* keep current API data */
+ tpm_db_api_data_backup();
+
+ /* do not update switch */
+ tpm_db_switch_init_set(false);
+
+ /* restore normal IPG of GMAC and switch */
+ ret_code = tpm_init_ipg(TPM_MH_LEN);
+ IF_ERROR(ret_code);
+
+ /* set new profile_id */
+ tpm_db_eth_cmplx_profile_set(profile_id);
+
+ /* update active wan and GMAC conf */
+ for (gmac_i = 0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++)
+ tpm_db_gmac_conn_conf_get(gmac_i, &(gmac_port_conf[gmac_i]));
+
+ if (TPM_G0_WAN_G1_INT_SWITCH == profile_id) {
+ tpm_db_active_wan_set(TPM_ENUM_GMAC_0);
+ gmac_port_conf[TPM_ENUM_GMAC_0].conn = TPM_GMAC_CON_RGMII2;
+ gmac_port_conf[TPM_ENUM_GMAC_0].port_src = TPM_SRC_PORT_WAN;
+ gmac_port_conf[TPM_ENUM_GMAC_1].conn = TPM_GMAC_CON_SWITCH_5;
+ gmac_port_conf[TPM_ENUM_GMAC_1].port_src = TPM_SRC_PORT_ILLEGAL;
+ gmac0_mh_en = TPM_FALSE;
+ gmac1_mh_en = TPM_TRUE;
+ } else if (TPM_G1_WAN_G0_INT_SWITCH == profile_id){
+ tpm_db_active_wan_set(TPM_ENUM_GMAC_1);
+ gmac_port_conf[TPM_ENUM_GMAC_0].conn = TPM_GMAC_CON_SWITCH_4;
+ gmac_port_conf[TPM_ENUM_GMAC_0].port_src = TPM_SRC_PORT_ILLEGAL;
+ gmac_port_conf[TPM_ENUM_GMAC_1].conn = TPM_GMAC_CON_GE_PHY;
+ gmac_port_conf[TPM_ENUM_GMAC_1].port_src = TPM_SRC_PORT_WAN;
+ gmac0_mh_en = TPM_TRUE;
+ gmac1_mh_en = TPM_FALSE;
+ }
+
+ /* Set GMAC Port Config */
+ ret_code = tpm_db_gmac_conn_conf_set(gmac_port_conf, TPM_NUM_GMACS);
+ IF_ERROR(ret_code);
+
+ /* update GMAC func */
+ tpm_db_mac_func_set();
+
+ tpm_db_ds_mh_get_conf_set(&ds_mh_set_conf);
+
+ /* update MH conf */
+ ret_code = tpm_init_mh(ds_mh_set_conf, gmac0_mh_en, gmac1_mh_en, gmac_port_conf);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_db_gmac_mh_en_conf_set(TPM_ENUM_GMAC_0, gmac0_mh_en);
+ IF_ERROR(ret_code);
+ ret_code = tpm_db_gmac_mh_en_conf_set(TPM_ENUM_GMAC_1, gmac1_mh_en);
+ IF_ERROR(ret_code);
+
+ /* update rate limitation */
+ ret_code = tpm_init_get_gmac_queue_rate_limit();
+ IF_ERROR(ret_code);
+
+ /* exchange rate limitation between G0/G1 */
+ tpm_init_get_gmac_queue_rate_limit();
+ tpm_db_wan_lan_rate_limit_exchange();
+
+ /* set new IPG of GMAC and switch */
+ ret_code = tpm_init_ipg((-TPM_MH_LEN));
+ IF_ERROR(ret_code);
+
+ /* switch pppoe length reg's value */
+ tpm_mod2_registers_init(TPM_ENUM_GMAC_0, 0);
+ tpm_mod2_registers_init(TPM_ENUM_GMAC_1, 0);
+
+#if 0
+ /* Set GMAC mh_enable */
+ if (mv_eth_ctrl_flag(TPM_ENUM_GMAC_0, MV_ETH_F_MH, gmac0_mh_en)){
+ TPM_OS_ERROR(TPM_INIT_MOD, " set GMAC0 MH en (%d) failed\n", gmac0_mh_en);
+ return (TPM_FAIL);
+ }
+ if (mv_eth_ctrl_flag(TPM_ENUM_GMAC_1, MV_ETH_F_MH, gmac1_mh_en)){
+ TPM_OS_ERROR(TPM_INIT_MOD, " set GMAC1 MH en (%d) failed\n", gmac1_mh_en);
+ return (TPM_FAIL);
+ }
+#endif
+
+ return (TPM_OK);
+}
+
+extern int mv_eth_wan_swap(int wan_mode);
+tpm_error_code_t tpm_proc_hot_swap_lsp(tpm_eth_complex_profile_t profile_id)
+{
+ int lsp_ret = 0;
+
+ if (TPM_G0_WAN_G1_INT_SWITCH == profile_id)
+ lsp_ret = mv_eth_wan_swap(0);
+ else if (TPM_G1_WAN_G0_INT_SWITCH == profile_id)
+ lsp_ret = mv_eth_wan_swap(1);
+
+ if (lsp_ret) {
+ TPM_OS_ERROR(TPM_HWM_MOD, "LSP hot swap failed, return value (%d)\n", lsp_ret);
+ return (TPM_FAIL);
+ }
+ return (TPM_OK);
+}
+
+tpm_error_code_t tpm_proc_hot_swap_profile(uint32_t owner_id,
+ tpm_eth_complex_profile_t profile_id)
+{
+ tpm_error_code_t ret_code = TPM_OK;
+
+ ret_code = tpm_proc_check_hot_swap_profile(owner_id, profile_id);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_proc_hot_swap_lsp(profile_id);
+ IF_ERROR(ret_code);
+
+ ret_code = tpm_proc_hot_swap_misc_cfg(profile_id);
+ IF_ERROR(ret_code);
+
+ /* perform mib-reset */
+ tpm_proc_mib_reset(owner_id, TPM_ENUM_RESET_LEVEL0);
+
+ /* tpm_db recovery */
+ tpm_db_api_data_rcvr();
+
+ ret_code = tpm_proc_hot_swap_update_acl_rules(owner_id);
+ IF_ERROR(ret_code);
+
+ return (TPM_OK);
+}
+#endif /* CONFIG_MV_ETH_WAN_SWAP */
+
/*******************************************************************************
* tpm_proc_mac_learn_entry_num_get()
*
@@ -16171,3 +17792,100 @@
return TPM_OK;
}
+/*******************************************************************************
+* tpm_proc_hwf_admin_set()
+*
+* DESCRIPTION: Function used to enable/disable hwf to certain port.
+*
+* INPUTS:
+*
+* port
+* txp
+*
+* OUTPUTS:
+*
+* RETURNS:
+* On success, the function returns TPM_OK. On error different types are returned
+* according to the case - see tpm_db_err_t.
+*
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_proc_hwf_admin_set(tpm_gmacs_enum_t port, uint8_t txp, uint8_t enable)
+{
+ uint32_t valid, q_num;
+ tpm_db_sched_t sched_method;
+ tpm_db_txq_owner_t queue_owner;
+ uint32_t owner_queue_num;
+ uint32_t queue_size;
+ uint32_t queue_weight;
+ int32_t db_ret;
+ tpm_db_tx_mod_t tx_mod;
+ uint32_t curr_state = 0;
+
+ //TPM_OS_INFO(TPM_PNCL_MOD, "port = %d txp = %d enable = %d\n", port, txp, enable);
+
+ printk("TPM T-Cont API, port(%d), txp(%d) enable(%d)\n", port, txp, enable);
+
+ tx_mod = port + txp;
+
+ if (tx_mod >= TPM_MAX_NUM_TX_PORTS) {
+ TPM_OS_ERROR(TPM_PNCL_MOD, "input invalid, port = %d txp = %d\n", port, txp);
+ return ERR_OMCI_TCONT_INVALID;
+ }
+
+ for (q_num = 0; q_num < TPM_MAX_NUM_TX_QUEUE; q_num++) {
+ db_ret = tpm_db_gmac_tx_q_conf_get(tx_mod, q_num, &valid, &sched_method,
+ &queue_owner, &owner_queue_num, &queue_size,
+ &queue_weight);
+ if (!valid)
+ {
+ //TPM_OS_INFO(TPM_PNCL_MOD, "Q-num = %d not valid, continue\n", q_num);
+ continue;
+ }
+
+ /* HWF Traffic */
+ /* =========== */
+ if (queue_owner != TPM_Q_OWNER_CPU)
+ {
+ /* get the hwf en first */
+ curr_state = NETA_HWF_TX_PORT_MASK(port + txp) | NETA_HWF_TXQ_MASK(q_num);
+ MV_REG_WRITE(NETA_HWF_TX_PTR_REG((queue_owner - 1)), curr_state);
+ curr_state = MV_REG_READ(NETA_HWF_TXQ_ENABLE_REG((queue_owner - 1)));
+
+ /* enable/disable hwf */
+ if (enable == true)
+ printk("HWF T-Cont active, port(%d), txp(%d), que(%d)\n", port, txp, q_num);
+
+ mvNetaHwfTxqEnable((queue_owner - 1), port, txp, q_num, enable);
+
+ //TPM_OS_INFO(TPM_PNCL_MOD,"GMAC = %d TCONT = %d Q = %d HWF: owner_rx %d\n", port, txp, q_num, (queue_owner - 1));
+
+ if ((!enable) && (curr_state))
+ {
+ //TPM_OS_INFO(TPM_PNCL_MOD, "Call mv_eth_txq_clean - current state: %d, enable %d\n", curr_state, enable);
+ printk("HWF T-Cont stop/clean, port(%d), txp(%d), que(%d)\n", port, txp, q_num);
+ mv_eth_txq_clean(port, txp, q_num);
+ }
+ }
+ /* SWF Traffic */
+ /* =========== */
+ else
+ {
+ if (!enable)
+ {
+ printk("SWF T-Cont stop/clean, port(%d), txp(%d), que(%d)\n", port, txp, q_num);
+ mv_cust_set_tcont_state(txp, false);
+ mv_eth_txq_clean(port, txp, q_num);
+ }
+ else
+ {
+ printk("SWF T-Cont active, port(%d), txp(%d), que(%d)\n", port, txp, q_num);
+ mv_cust_set_tcont_state(txp, true);
+ }
+ }
+ }
+
+ return TPM_OK;
+}
+
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.h
index 2899e15..9f47c12 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pkt_proc_logic.h
@@ -141,6 +141,10 @@
#define TPM_AI_DNRT_BIT_SIZE (1)
#define TPM_AI_DNRT_MASK (AI_TO_MASK(TPM_AI_DNRT_BIT_OFF, TPM_AI_DNRT_BIT_SIZE))
+#define TPM_AI_DNRT_DS_TRUNK_BIT_OFF (3)
+#define TPM_AI_DNRT_DS_TRUNK_BIT_SIZE (1)
+#define TPM_AI_DNRT_DS_TRUNK_MASK (AI_TO_MASK(TPM_AI_DNRT_DS_TRUNK_BIT_OFF, TPM_AI_DNRT_DS_TRUNK_BIT_SIZE))
+
#define TPM_AI_MTM_BIT_OFF (2)
#define TPM_AI_MTM_BIT_SIZE (1)
#define TPM_AI_MTM_MASK (AI_TO_MASK(TPM_AI_MTM_BIT_OFF, TPM_AI_MTM_BIT_SIZE))
@@ -232,6 +236,7 @@
#define GMAC_IS_WAN(gmac_func) ((gmac_func == TPM_GMAC_FUNC_LAN_AND_WAN) || (gmac_func == TPM_GMAC_FUNC_WAN))
#define GMAC_IS_UNI_LAN(gmac_func) (gmac_func == TPM_GMAC_FUNC_LAN_UNI)
#define GMAC_IS_UNI_VIRT(gmac_func) (gmac_func == TPM_GMAC_FUNC_VIRT_UNI)
+#define GMAC_IS_DS_UNI_LAN(gmac_func) (gmac_func == TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI)
#define TPM_CNM_L2_MAIN_LUID_OFFSET (0)
@@ -249,6 +254,7 @@
} ttl_illegal_action_t;
typedef enum {
+ TPM_ADD_DS_LOAD_BALANCE_RULE,
TPM_ADD_L2_PRIM_ACL_RULE,
TPM_ADD_L3_TYPE_ACL_RULE,
TPM_ADD_IPV4_ACL_RULE,
@@ -306,6 +312,13 @@
del_cnm_ipv4_pre_filter_key_fn_t del_cnm_ipv4_pre_filter;
} tpm_cnm_ipv4_pre_filter_rule_oper_t;
+typedef tpm_error_code_t (*tpm_acl_recovery_func)(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+
+typedef struct {
+ tpm_api_type_t api_type;
+ tpm_acl_recovery_func func;
+} tpm_hot_swap_acl_recovery_t;
+
/* API's */
@@ -335,6 +348,14 @@
uint32_t *mod_idx);
tpm_error_code_t tpm_proc_del_cpu_wan_loopback(uint32_t owner_id, tpm_pkt_frwd_t *pkt_frwd);
+tpm_error_code_t tpm_proc_add_ds_load_balance_acl_rule(uint32_t owner_id,
+ uint32_t rule_num,
+ uint32_t *rule_idx,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_ds_load_balance_tgrt_t tgrt_port);
+tpm_error_code_t tpm_proc_del_ds_load_balance_acl_rule(uint32_t owner_id, uint32_t rule_idx, uint32_t ext_call);
int32_t tpm_proc_l2_tcam_build(tpm_src_port_type_t src_port,
tpm_dir_t dir,
@@ -409,7 +430,9 @@
uint32_t cpu_rx_queue,
tpm_trg_port_type_t llid_num);
-tpm_error_code_t tpm_proc_loop_detect_add_channel(uint32_t owner_id);
+tpm_error_code_t tpm_proc_loop_detect_add_channel(uint32_t owner_id, tpm_ether_type_key_t ety);
+
+tpm_error_code_t tpm_proc_loop_detect_del_channel(uint32_t owner_id);
tpm_error_code_t tpm_proc_oam_loopback_add_channel(uint32_t owner_id);
@@ -450,6 +473,7 @@
uint8_t ipv4_src_add[4],
uint8_t ipv4_dst_add[4],
uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
tpm_trg_port_type_t dest_port_bm);
int32_t tpm_proc_ipv4_sram_build(tpm_src_port_type_t src_port,
@@ -486,11 +510,13 @@
uint8_t ignore_ipv4_src,
tpm_pncl_tcam_data_t *tcam_data);
-int32_t tpm_proc_ipv4_mc_sram_build(tpm_mc_filter_mode_t filter_mode,
+int32_t tpm_proc_ipvx_mc_sram_build(tpm_mc_filter_mode_t filter_mode,
tpm_mc_igmp_mode_t igmp_mode,
+ uint16_t dest_queue,
tpm_trg_port_type_t target_port,
uint32_t mod_entry,
- tpm_pncl_sram_data_t *sram_data);
+ tpm_pncl_sram_data_t *sram_data,
+ tpm_ip_ver_t ip_version);
tpm_error_code_t tpm_proc_updt_ipv4_mc_stream(uint32_t owner_id,
uint32_t stream_num, tpm_trg_port_type_t dest_port_bm);
@@ -506,12 +532,6 @@
uint8_t ignore_sip,
tpm_pncl_tcam_data_t *tcam_data);
-int32_t tpm_proc_ipv6_mc_sram_build(tpm_mc_filter_mode_t filter_mode,
- tpm_mc_igmp_mode_t igmp_mode,
- tpm_trg_port_type_t target_port,
- uint32_t mod_entry,
- tpm_pncl_sram_data_t *sram_data);
-
tpm_error_code_t tpm_proc_add_ipv6_mc_stream(uint32_t owner_id,
uint32_t stream_num,
tpm_mc_igmp_mode_t igmp_mode,
@@ -520,6 +540,7 @@
uint8_t ipv6_src_add[16],
uint8_t ipv6_dst_add[16],
uint8_t ignore_ipv6_src,
+ uint16_t dest_queue,
tpm_trg_port_type_t dest_port_bm);
tpm_error_code_t tpm_proc_updt_ipv6_mc_stream(uint32_t owner_id,
@@ -532,6 +553,8 @@
tpm_error_code_t tpm_proc_l2_num_vlan_tags_init(void);
tpm_error_code_t tpm_proc_ipv4_ttl_init(uint32_t ttl_illegal_action);
+tpm_error_code_t tpm_proc_ds_load_balance_init(void);
+
tpm_error_code_t tpm_proc_tcp_flag_init(void);
tpm_error_code_t tpm_proc_ipv4_len_init(void);
tpm_error_code_t tpm_proc_ipv4_igmp_init(void);
@@ -691,6 +714,11 @@
tpm_error_code_t tpm_proc_set_mc_vid_port_vids(uint32_t owner_id,
uint32_t mc_vid,
tpm_mc_vid_port_vid_set_t *mc_vid_uniports_config);
+tpm_error_code_t tpm_proc_delete_ipvx_mc_pnc_entry(tpm_mc_filter_mode_t filter_mode,
+ uint32_t stream_num,
+ uint32_t dest_port_bm,
+ uint32_t u4_entry,
+ tpm_ip_ver_t ip_version);
tpm_error_code_t tpm_proc_catch_all_init(void);
@@ -828,12 +856,24 @@
tpm_pkt_action_t pkt_act,
uint32_t mod_cmd,
tpm_pncl_sram_data_t *sram_data);
+tpm_pnc_trg_t tpm_proc_cnm_pnc_trg_get(tpm_trg_port_type_t trg_port);
uint8_t tpm_proc_if_ipv4_pre_range_is_full(tpm_src_port_type_t src_port, tpm_parse_fields_t ipv4_parse_rule_bm, tpm_ipv4_acl_key_t *ipv4_key);
uint8_t tpm_proc_if_cnm_main_range_is_full(tpm_src_port_type_t src_port, uint32_t precedence);
int32_t tpm_proc_add_cnm_ipv4_pre_filter_key(uint32_t owner_id, tpm_src_port_type_t src_port, tpm_parse_fields_t ipv4_parse_rule_bm, tpm_ipv4_acl_key_t *ipv4_key, uint32_t *key_idx);
int32_t tpm_proc_del_cnm_ipv4_pre_filter_key(uint32_t owner_id, tpm_src_port_type_t src_port, uint32_t key_idx);
-int32_t tpm_proc_add_l2_cnm_rule(uint32_t owner_id, tpm_src_port_type_t src_port, uint32_t precedence, tpm_parse_fields_t l2_parse_rule_bm, tpm_l2_acl_key_t *l2_key, uint32_t ipv4_key_idx, tpm_pkt_frwd_t *pkt_frwd, tpm_pkt_action_t pkt_act, uint32_t pbits, uint32_t *rule_idx);
+int32_t tpm_proc_add_l2_cnm_rule(uint32_t owner_id,
+ tpm_src_port_type_t src_port,
+ uint32_t precedence,
+ tpm_parse_fields_t l2_parse_rule_bm,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_parse_fields_t ipv4_parse_rule_bm,
+ tpm_ipv4_acl_key_t *ipv4_key,
+ uint32_t ipv4_key_idx,
+ tpm_pkt_frwd_t *pkt_frwd,
+ tpm_pkt_action_t pkt_act,
+ uint32_t pbits,
+ uint32_t *rule_idx);
int32_t tpm_proc_del_l2_cnm_rule(uint32_t owner_id, uint32_t rule_idx);
int32_t tpm_proc_add_ipv4_cnm_rule(uint32_t owner_id, tpm_src_port_type_t src_port, uint32_t precedence, tpm_parse_fields_t ipv4_parse_rule_bm, tpm_ipv4_acl_key_t *ipv4_key, tpm_pkt_frwd_t *pkt_frwd, tpm_pkt_action_t pkt_act, uint32_t pbits, uint32_t *rule_idx);
int32_t tpm_proc_add_ipv6_cnm_rule(uint32_t owner_id,
@@ -853,20 +893,42 @@
tpm_error_code_t tpm_proc_del_static_mac_rule(uint32_t owner_id, tpm_l2_acl_key_t *src_mac_addr);
tpm_error_code_t tpm_proc_mac_learn_default_rule_act_set(uint32_t owner_id, tpm_unknown_mac_conf_t mac_conf);
tpm_error_code_t tpm_proc_mac_learn_entry_num_get(uint32_t *entry_num);
+#ifdef CONFIG_MV_ETH_WAN_SWAP
+tpm_error_code_t tpm_proc_hot_swap_profile(uint32_t owner_id,
+ tpm_eth_complex_profile_t profile_id);
+#endif /* CONFIG_MV_ETH_WAN_SWAP */
int32_t tpm_proc_check_api_busy(tpm_api_type_t api_type, uint32_t rule_num);
int32_t tpm_proc_api_busy_done(tpm_api_type_t api_type, uint32_t rule_num);
int32_t tpm_proc_src_port_dir_map(tpm_src_port_type_t src_port, tpm_dir_t *dir);
+int32_t tpm_proc_check_all_api_busy(void);
+int32_t tpm_proc_all_api_busy_done(void);
bool tpm_split_mod_stage1_check(tpm_pkt_mod_bm_t pkt_mod_bm,
tpm_pkt_mod_t *pkt_mod,
tpm_rule_action_t *rule_action,
bool check_vlan_noop);
int32_t tpm_proc_calc_cnm_precedence(tpm_src_port_type_t src_port, uint32_t rule_num, uint32_t *precedence);
+tpm_error_code_t tpm_proc_hwf_admin_set(tpm_gmacs_enum_t port, uint8_t txp, uint8_t enable);
tpm_error_code_t tpm_proc_check_dst_uni_port(tpm_trg_port_type_t dest_port_bm);
+tpm_error_code_t tpm_proc_set_active_wan(tpm_gmacs_enum_t active_wan);
+/* hot swap profile acl recovery func api section */
+tpm_error_code_t tpm_acl_rcvr_func_mac_learn(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ds_load_balance(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_cpu_loopback(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_l2_prim(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_l3_type(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv4(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv4_mc(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_gen(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_dip(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_mc(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_nh(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_ipv6_l4(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
+tpm_error_code_t tpm_acl_rcvr_func_cnm(uint32_t owner_id, tpm_db_api_entry_t *api_data, uint32_t rule_idx_updt_en);
#ifdef __cplusplus
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pnc_logic.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pnc_logic.c
index 733e952..447de4e 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pnc_logic.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_pnc_logic.c
@@ -439,6 +439,7 @@
int32_t ret_code;
uint16_t mh = 0;
tpm_db_pon_type_t pon_type;
+ uint32_t switch_init;
/* Parse MH, depending on field parse request */
@@ -483,8 +484,20 @@
TPM_OS_DEBUG(TPM_PNCL_MOD, "MH from GemPort\n");
} else {
if (tcam_in->pkt_key.src_port == TPM_SRC_PORT_WAN) {
- /* DS, from WAN, no MH need to be parsed */
- mh = 0;
+ /* it is for multicast per uni vlan feature
+ in the first loop, pkt goes to G1 from G0 through Switch.
+ */
+ ret_code = tpm_db_switch_init_get(&switch_init);
+ IF_ERROR(ret_code);
+ if (switch_init) {
+ mh = tpm_db_eth_port_switch_port_get(TPM_SRC_PORT_WAN);
+ if (TPM_DB_ERR_PORT_NUM == mh) {
+ TPM_OS_ERROR(TPM_PNCL_MOD, "tpm_db_eth_port_switch_port_get returned %d\n", mh);
+ return(TPM_FAIL);
+ }
+ } else
+ mh = 0;
+
/* Update TCAM Data and Mask */
*(uint16_t *) (&(pkt_data->pkt_byte[offset])) = htons(mh);
*(uint16_t *) (&(pkt_mask->pkt_byte[offset])) = htons(MH_UNI_PORT_MASK);
@@ -3425,6 +3438,7 @@
uint32_t free_entry = 0, entry_id;
uint32_t queue_id;
tpm_gmacs_enum_t lpk_gmac;
+ int32_t cpu_rx_queue;
/* Set Structs to zero */
memset(&range_data, 0, sizeof(tpm_db_pnc_range_t));
@@ -3439,14 +3453,15 @@
IF_ERROR(ret_code);
free_entry = range_data.pnc_range_oper.free_entries;
- entry_id = range_data.pnc_range_conf.range_end;
/* check the free size in the range for default rule*/
- if (free_entry == 0) {
- TPM_OS_ERROR(TPM_TPM_LOG_MOD, "No free entries\n");
+ if (free_entry < 2) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "No enough entries(%d) for MAC learn default rules\n",
+ free_entry);
return(TPM_FAIL);
}
- /* construct default rule */
+ /* construct default rule on GMAC0 forward packet to GMAC1*/
+ entry_id = range_data.pnc_range_conf.range_end;
/* Set Lookup Id */
pnc_entry.tcam_entry.lu_id = range_data.pnc_range_conf.base_lu_id;
/* Set port_id */
@@ -3460,11 +3475,13 @@
pnc_entry.sram_entry.flowid_updt_mask = TPM_TXP_FL_UPDT_MASK;
/*forward packet to GMAC1 as default*/
- if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac, &queue_id)) {
+ if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac,
+ &queue_id,
+ TPM_GMAC1_QUEUE_DATA_TRAFFIC)) {
TPM_OS_ERROR(TPM_TPM_LOG_MOD, "loopback gmac queue get failed \n");
return TPM_FAIL;
}
- /* Set target GMAC1 */
+ /* Set target GMAC1, queue id changed to cpu_rate_limit queue*/
pnc_entry.sram_entry.flowid_val = (TPM_PNC_TRG_GMAC1 << TPM_TXP_FL_SHIFT);
pnc_entry.sram_entry.pnc_queue = queue_id;
@@ -3478,6 +3495,45 @@
ret_code = tpm_db_pnc_shdw_ent_set(entry_id, &pnc_entry);
IF_ERROR(ret_code);
+ /*CPU rate limit*/
+ memset(&pnc_entry, 0, sizeof(tpm_pnc_all_t));
+ entry_id = range_data.pnc_range_conf.range_end - 1;
+ /* Set Lookup Id */
+ pnc_entry.tcam_entry.lu_id = range_data.pnc_range_conf.base_lu_id;
+ /* Set port_id */
+ pnc_entry.tcam_entry.port_ids = TPM_BM_GMAC_1;
+ /* check MH, 0xAACC indicates MAC learning packets */
+ pnc_entry.tcam_entry.pkt_data.pkt_byte[0] = TPM_MOD2_MAC_LEARN_MH >> 8;
+ pnc_entry.tcam_entry.pkt_data.pkt_byte[1] = TPM_MOD2_MAC_LEARN_MH & 0xFF;
+ pnc_entry.tcam_entry.pkt_mask.pkt_byte[0] = 0xFF;
+ pnc_entry.tcam_entry.pkt_mask.pkt_byte[1] = 0xFF;
+ /* Set LU Done */
+ pnc_entry.sram_entry.lookup_done = TPM_TRUE;
+
+ pnc_entry.sram_entry.pnc_queue = TPM_PNCL_NO_QUEUE_UPDATE;
+ pnc_entry.sram_entry.shift_updt_reg = TPM_PNC_NOSHIFT_UPDATE_REG;
+
+ pnc_entry.sram_entry.flowid_updt_mask = TPM_TXP_FL_UPDT_MASK;
+
+ /* Get default CPU queue */
+ tpm_db_get_cpu_rx_queue(&cpu_rx_queue);
+ /* Trap to CPU */
+ pnc_entry.sram_entry.flowid_val = (TPM_PNC_TRG_CPU << TPM_TXP_FL_SHIFT);
+ pnc_entry.sram_entry.pnc_queue = cpu_rx_queue;
+ /* Set result info */
+ pnc_entry.sram_entry.res_info_15_0_data |= (1 << TPM_PNC_RI_MAC_LEARN_BIT);
+ pnc_entry.sram_entry.res_info_15_0_mask |= (1 << TPM_PNC_RI_MAC_LEARN_BIT);
+
+ /* Write to PNC */
+ tpm_pnc_set(entry_id, 0, &pnc_entry);
+
+ ret_code = tpm_db_pnc_rng_api_end_dec(TPM_PNC_MAC_LEARN);
+ IF_ERROR(ret_code);
+
+ /* Write to Shadow */
+ ret_code = tpm_db_pnc_shdw_ent_set(entry_id, &pnc_entry);
+ IF_ERROR(ret_code);
+
return(TPM_OK);
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.c
index caa9ea0..7fc477a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.c
@@ -83,6 +83,7 @@
#include "tpm_common.h"
#include "tpm_header.h"
#include "tpm_sysfs_utils.h"
+#include "dbg-trace.h"
/*TODO - currently some printing funtions are directly accessing DB */
extern tpm_db_t tpm_db;
@@ -152,6 +153,7 @@
BuildEnumString(TPM_GMAC_FUNC_LAN_AND_WAN),
BuildEnumString(TPM_GMAC_FUNC_VIRT_UNI),
BuildEnumString(TPM_GMAC_FUNC_LAN_UNI),
+ BuildEnumString(TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI),
};
db_enum_string_t tpm_pnc_ranges_str[] = {
@@ -159,6 +161,7 @@
BuildEnumString(TPM_PNC_MAC_LEARN),
BuildEnumString(TPM_PNC_CPU_WAN_LPBK_US),
BuildEnumString(TPM_PNC_NUM_VLAN_TAGS),
+ BuildEnumString(TPM_PNC_DS_LOAD_BALANCE),
BuildEnumString(TPM_PNC_VIRT_UNI),
BuildEnumString(TPM_PNC_MULTI_LPBK),
BuildEnumString(TPM_PNC_LOOP_DET_US),
@@ -167,7 +170,7 @@
BuildEnumString(TPM_PNC_IGMP),
BuildEnumString(TPM_PNC_IPV4_MC_DS),
BuildEnumString(TPM_PNC_IPV4_MAIN),
- BuildEnumString(TPM_PNC_TCP_FLAG),
+ BuildEnumString(TPM_PNC_IPV4_TCP_FLAG),
BuildEnumString(TPM_PNC_TTL),
BuildEnumString(TPM_PNC_IPV4_PROTO),
BuildEnumString(TPM_PNC_IPV4_FRAG),
@@ -179,6 +182,7 @@
BuildEnumString(TPM_PNC_IPV6_MC_DS),
BuildEnumString(TPM_PNC_IPV6_NH),
BuildEnumString(TPM_PNC_IPV6_L4_MC_DS),
+ BuildEnumString(TPM_PNC_IPV6_TCP_FLAG),
BuildEnumString(TPM_PNC_IPV6_L4),
BuildEnumString(TPM_PNC_CNM_IPV4_PRE),
BuildEnumString(TPM_PNC_CNM_MAIN),
@@ -209,16 +213,22 @@
static tpm_str_map_t api_type_str[] = {
{TPM_API_MGMT, "MNGMT"},
- {TPM_API_CPU_LOOPBACK, "CPU_LOOPBACK"},
+ {TPM_API_MAC_LEARN, "MAC_LEARN "},
+ {TPM_API_DS_LOAD_BALANCE, "DS_LOAD_BAL "},
+ {TPM_API_CPU_LOOPBACK, "CPU_LOOPBACK"},
{TPM_API_L2_PRIM, "L2 "},
{TPM_API_L3_TYPE, "L3 "},
- {TPM_API_IPV4, "IPV4 "},
+ {TPM_API_IPV4, "IPV4 "},
{TPM_API_IPV4_MC, "IPV4_MC "},
{TPM_API_IPV6_GEN, "IPV6_GEN"},
{TPM_API_IPV6_DIP, "IPV6_DIP"},
+ {TPM_API_IPV6_MC, "IPV6_MC"},
{TPM_API_IPV6_NH, "IPV6_NH "},
{TPM_API_IPV6_L4, "L4 "},
+ {TPM_API_CNM, "CNM "},
};
+char *tpm_db_params_illegal_str = "??";
+
/********************************************************************************/
@@ -306,7 +316,7 @@
* COMMENTS:
*
*******************************************************************************/
-static uint8_t *api_type_to_str(tpm_api_type_t api_type)
+uint8_t *api_type_to_str(tpm_api_type_t api_type)
{
uint32_t i;
@@ -314,7 +324,7 @@
if (api_type_str[i].enum_in == api_type)
return (&(api_type_str[i].str_out[0]));
}
- return (NULL);
+ return (tpm_db_params_illegal_str);
}
/*******************************************************************************
@@ -824,10 +834,10 @@
printk("Debug port %4d\n", tpm_db.init_misc.pnc_init_debug_port);
printk("PON type %s\n", pon_type[tpm_db.init_misc.pon_type]);
- if ((tpm_db.init_misc.backup_wan < TPM_MAX_GMAC) && (tpm_db.init_misc.backup_wan >= TPM_ENUM_GMAC_0))
- printk("Backup WAN %s\n", gmac_name[tpm_db.init_misc.backup_wan]);
+ if ((tpm_db.init_misc.active_wan <= TPM_MAX_GMAC) && (tpm_db.init_misc.active_wan >= TPM_ENUM_GMAC_0))
+ printk("Active WAN %s\n", gmac_name[tpm_db.init_misc.active_wan]);
else
- printk("Backup WAN N/A");
+ printk("Active WAN N/A");
printk("DS MH select source %4d\n", tpm_db.init_misc.ds_mh_set_conf);
printk("CFG PNC parse %4d\n", tpm_db.init_misc.cfg_pnc_parse);
printk("CPU loopback %4d\n", tpm_db.init_misc.cpu_loopback);
@@ -1067,24 +1077,6 @@
printk("==========================================================================================================================================================\n");
}
-char *tpm_db_params_illegal_str = "??";
-
-char *tpm_db_api_type_str[TPM_MAX_API_TYPES] = {
- "MGNT",
- "MAC_LEARN",
- "CPU_LPBK",
- "L2",
- "L3",
- "IPV4",
- "IPV4_MC",
- "IPV6_GEN",
- "IPV6_DIP",
- "IPV6_MC",
- "IPV6_NH",
- "IPV6_L4",
- "CTC_CNM"
-};
-
char *tpm_db_src_port_str[] = {
"UNI_0",
"UNI_1",
@@ -1225,6 +1217,8 @@
tpm_db_none_parse_type_str,
/* TPM_API_MAC_LEARN */
tpm_db_none_parse_type_str,
+ /* TPM_API_DS_LOAD_BALANCE */
+ tpm_db_l2_parse_type,
/* TPM_API_CPU_LOOPBACK */
tpm_db_none_parse_type_str,
/* TPM_API_L2_PRIM */
@@ -1235,16 +1229,16 @@
tpm_db_ipv4_parse_type,
/* TPM_API_IPV4_MC */
tpm_db_ipv4_mc_parse_type,
+ /* TPM_API_IPV6_NH */
+ tpm_db_ipv6_nh_parse_type,
+ /* TPM_API_IPV6_L4 */
+ tpm_db_ipv6_l4_parse_type,
/* TPM_API_IPV6_GEN */
tpm_db_ipv6_gen_parse_type,
/* TPM_API_IPV6_DIP */
tpm_db_ipv6_dip_parse_type,
/* TPM_API_IPV6_MC */
tpm_db_ipv6_mc_parse_type,
- /* TPM_API_IPV6_NH */
- tpm_db_ipv6_nh_parse_type,
- /* TPM_API_IPV6_L4 */
- tpm_db_ipv6_l4_parse_type,
/* TPM_API_CTC_CM */
tpm_db_ctc_cm_parse_type,
};
@@ -1485,7 +1479,7 @@
if (first_rule) {
if (api_type < TPM_MAX_API_TYPES)
- api_type_str = tpm_db_api_type_str[api_type];
+ api_type_str = api_type_to_str(api_type);
else
api_type_str = tpm_db_params_illegal_str;
}
@@ -1743,7 +1737,7 @@
if (-1 == next_rule) {
if (api_type < TPM_MAX_API_TYPES)
- api_type_str = tpm_db_api_type_str[api_type];
+ api_type_str = api_type_to_str(api_type);
else
api_type_str = tpm_db_params_illegal_str;
@@ -2475,6 +2469,8 @@
return;
}
+ //TRC_OUTPUT(0,1);
+
printk(KERN_INFO "---------------------------------------------------------------------------------\n");
printk(KERN_INFO "FC is %s\n", (tpm_fc_is_running() == MV_TRUE) ? "ENABLED" : "DISABLED");
printk(KERN_INFO "The Flow Control engine settings:\n");
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.h
index d1909fb..9e7deca 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_print.h
@@ -146,6 +146,7 @@
void tpm_print_fc(unsigned int print_only);
void tpm_init_eth_cmplx_setup_error_print(uint32_t hwEthCmplx, bool sysfs_call);
void tpm_print_mac_learn_entry_count(void);
+uint8_t *api_type_to_str(tpm_api_type_t api_type);
#endif /* _TPM_PRINT_H_ */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_setup.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_setup.c
index 1438a48..6e2b416 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_setup.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_setup.c
@@ -284,7 +284,7 @@
tpm_setup.mc_setting.mc_hwf_queue = MV_TPM_UN_INITIALIZED_INIT_PARAM;
tpm_setup.mc_setting.mc_cpu_queue = MV_TPM_UN_INITIALIZED_INIT_PARAM;
}
-
+
app_rc = get_ipv4_mc_support(&tpm_setup.mc_setting.ipv4_mc_support);
if (app_rc == TPM_FAIL)
rc = TPM_FAIL;
@@ -365,16 +365,29 @@
return rc;
}
-int32_t tpm_init_backup_wan_get_para(void)
+int32_t tpm_init_active_wan_get_para(void)
{
int32_t rc = TPM_OK;
int app_rc;
- app_rc = get_backup_wan_params(&(tpm_setup.backup_wan));
+ app_rc = get_active_wan_params(&(tpm_setup.active_wan));
if (app_rc == TPM_FAIL)
rc = TPM_FAIL;
else if (app_rc == TPM_NOT_FOUND)
- tpm_setup.backup_wan = MV_TPM_UN_INITIALIZED_INIT_PARAM;
+ tpm_setup.active_wan = MV_TPM_UN_INITIALIZED_INIT_PARAM;
+
+ return rc;
+}
+int32_t tpm_init_ds_mac_based_trunking_get_para(void)
+{
+ int32_t rc = TPM_OK;
+ int app_rc;
+
+ app_rc = get_ds_mac_based_trunking_enable(&(tpm_setup.ds_mac_based_trunk_enable));
+ if (app_rc == TPM_FAIL)
+ rc = TPM_FAIL;
+ else if (app_rc == TPM_NOT_FOUND)
+ tpm_setup.ds_mac_based_trunk_enable = MV_TPM_UN_INITIALIZED_INIT_PARAM;
return rc;
}
@@ -808,7 +821,7 @@
tpm_init_eth_cmplx_profile_get_para();
tpm_init_eth_port_conf_get_para();
tpm_init_gmac_port_conf_get_para();
- tpm_init_backup_wan_get_para();
+ tpm_init_active_wan_get_para();
tpm_init_gmac_conn_get_para();
tpm_init_gmac_rx_get_para();
tpm_init_gmac_tx_get_para();
@@ -824,6 +837,7 @@
tpm_init_ctc_cm_ipv6_parse_window_get_para();
tpm_init_pnc_mac_learn_enable_get_para();
tpm_init_switch_init_get_para();
+ tpm_init_ds_mac_based_trunking_get_para();
free_xml_head_ptr();
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.c
index 3c88ca6..d9af0f8 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.c
@@ -79,6 +79,51 @@
#include "tpm_common.h"
#include "tpm_header.h"
+uint32_t tpm_tm_lan_gmac_get(uint32_t *lan_gmac)
+{
+ int32_t db_ret;
+ tpm_pnc_trg_t pnc_target;
+
+ db_ret = tpm_db_to_lan_gmac_get(TPM_TRG_PORT_UNI_ANY, &pnc_target);
+ if (db_ret != TPM_DB_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
+ "can not get GMAC that works as LAN\n\r");
+ return ERR_GENERAL;
+ }
+ if (pnc_target == TPM_PNC_TRG_GMAC0)
+ *lan_gmac = SW_GMAC_0;
+ else if (pnc_target == TPM_PNC_TRG_GMAC1)
+ *lan_gmac = SW_GMAC_1;
+ else {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
+ "GMAC works as LAN is not valid: (%d)\n\r", pnc_target);
+ return ERR_GENERAL;
+ }
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "GMAC works as LAN is: (%d)\n\r", *lan_gmac);
+
+ return TPM_OK;
+}
+uint32_t tpm_tm_wan_gmac_get(uint32_t *wan_gmac)
+{
+ tpm_gmacs_enum_t wan_gmac_tmp;
+
+ wan_gmac_tmp = tpm_db_active_wan_get();
+
+ if (wan_gmac_tmp == TPM_ENUM_GMAC_0)
+ *wan_gmac = SW_GMAC_0;
+ else if (wan_gmac_tmp == TPM_ENUM_GMAC_1)
+ *wan_gmac = SW_GMAC_1;
+ else if (wan_gmac_tmp == TPM_ENUM_PMAC)
+ *wan_gmac = PON_PORT;
+ else {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
+ "GMAC works as WAN is not valid: (%d)\n\r", wan_gmac_tmp);
+ return ERR_GENERAL;
+ }
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "GMAC works as WAN is: (%d)\n\r", *wan_gmac);
+
+ return TPM_OK;
+}
/*******************************************************************************
* tpm_tm_set_wan_egr_queue_sched()
*
@@ -108,13 +153,14 @@
tpm_error_code_t retVal = TPM_RC_OK;
uint32_t i = 0;
uint32_t num_tcont_llid = 0;
+ uint32_t wan_gmac = 0;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d],sched_ent[%d],sched_mode[%d],"
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d],sched_ent[%d],sched_mode[%d],"
" queue_id[%d], wrr_weight[%d]\n\r",
__func__, owner_id, sched_ent, sched_mode, queue_id, wrr_weight);
if (queue_id >= TPM_MAX_NUM_TX_QUEUE) {
- printk(KERN_INFO "==ERROE==%s: Invalid queue number: owner_id[%d],sched_ent[%d],sched_mode[%d],"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: Invalid queue number: owner_id[%d],sched_ent[%d],sched_mode[%d],"
" queue_id[%d], wrr_weight[%d]\n\r",
__func__, owner_id, sched_ent, sched_mode, queue_id, wrr_weight);
return ERR_SW_TM_QUEUE_INVALID;
@@ -122,22 +168,26 @@
if ((sched_mode == TPM_PP_SCHED_WRR) && (wrr_weight > TPM_MAX_WRR_WEIGHT)) {
- printk(KERN_INFO "==ERROE==%s: WRR weight is out of rage: owner_id[%d],sched_mode[%d],"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: WRR weight is out of rage: owner_id[%d],sched_mode[%d],"
" queue_id[%d], wrr_weight[%d]\n\r",
__func__, owner_id, sched_mode, queue_id, wrr_weight);
return ERR_SW_TM_QUEUE_INVALID;
}
+ retVal = tpm_tm_wan_gmac_get(&wan_gmac);
+ if (retVal != TPM_OK) {
+ return ERR_SRC_PORT_INVALID;
+ }
tpm_db_num_tcont_llid_get(&num_tcont_llid);
for (i = 0; i < num_tcont_llid; i++) {
if (sched_ent & 0x1) {
switch (sched_mode) {
case TPM_PP_SCHED_STRICT:
- mvNetaTxqFixPrioSet(PON_PORT, i, queue_id);
+ mvNetaTxqFixPrioSet(wan_gmac, i, queue_id);
break;
case TPM_PP_SCHED_WRR:
- mvNetaTxqWrrPrioSet(PON_PORT, i, queue_id, wrr_weight);
+ mvNetaTxqWrrPrioSet(wan_gmac, i, queue_id, wrr_weight);
break;
default:
@@ -150,9 +200,9 @@
break;
}
if ((sched_ent != 0) && (i == num_tcont_llid - 1))
- printk(KERN_INFO "TCONT doesn't not exist\n");
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "TCONT doesn't not exist\n");
- printk(KERN_INFO "==EXIT== %s:\n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s:\n\r", __func__);
return retVal;
}
@@ -184,31 +234,38 @@
{
uint32_t i = 0;
uint32_t num_tcont_llid = 0;
+ uint32_t wan_gmac = 0;
+ uint32_t tpm_ret = 0;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d],sched_ent[%d],rate_limit_val[%d], bucket_size[%d]\n\r",
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d],sched_ent[%d],rate_limit_val[%d], bucket_size[%d]\n\r",
__func__, owner_id, sched_ent, rate_limit_val, bucket_size);
+ tpm_ret = tpm_tm_wan_gmac_get(&wan_gmac);
+ if (tpm_ret != TPM_OK) {
+ return ERR_SRC_PORT_INVALID;
+ }
+
tpm_db_num_tcont_llid_get(&num_tcont_llid);
for (i = 0; i < num_tcont_llid; i++) {
if (sched_ent & 0x1) {
- if (mvNetaTxpBurstSet(PON_PORT, i, bucket_size) != MV_OK) {
- printk(KERN_INFO
+ if (mvNetaTxpBurstSet(wan_gmac, i, bucket_size) != MV_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
"==ERROE==%s: Invalid bucket size value: "
"owner_id[%d],sched_ent[%d] bucket_size[%d]\n\r",
__func__, owner_id, i, bucket_size);
return ERR_SW_TM_BUCKET_SIZE_INVALID;
}
- mvNetaTxpRateSet(PON_PORT, i, rate_limit_val);
+ mvNetaTxpRateSet(wan_gmac, i, rate_limit_val);
}
sched_ent = sched_ent >> 1;
if (sched_ent == 0)
break;
}
if ((sched_ent != 0) && (i == num_tcont_llid - 1))
- printk(KERN_INFO "TCONT doesn't not exist\n");
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "TCONT doesn't not exist\n");
- printk(KERN_INFO "==EXIT== %s: \n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s: \n\r", __func__);
return TPM_RC_OK;
@@ -244,8 +301,10 @@
{
uint32_t i = 0;
uint32_t num_tcont_llid = 0;
+ uint32_t wan_gmac = 0;
+ uint32_t tpm_ret = 0;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d],sched_ent[%d],queue_id[%d]"
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d],sched_ent[%d],queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, sched_ent, queue_id, rate_limit_val, bucket_size);
@@ -253,32 +312,37 @@
if (queue_id >= TPM_MAX_NUM_TX_QUEUE) {
- printk(KERN_INFO "==ERROE==%s: Invalid queue number: owner_id[%d],sched_ent[%d],queue_id[%d]"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: Invalid queue number: owner_id[%d],sched_ent[%d],queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, sched_ent, queue_id, rate_limit_val, bucket_size);
return ERR_SW_TM_QUEUE_INVALID;
}
+ tpm_ret = tpm_tm_wan_gmac_get(&wan_gmac);
+ if (tpm_ret != TPM_OK) {
+ return ERR_SRC_PORT_INVALID;
+ }
+
for (i = 0; i < num_tcont_llid; i++) {
if (sched_ent & 0x1) {
- if (mvNetaTxqBurstSet(PON_PORT, i, queue_id, bucket_size) != MV_OK) {
- printk(KERN_INFO
+ if (mvNetaTxqBurstSet(wan_gmac, i, queue_id, bucket_size) != MV_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
"==ERROE==%s: Invalid bucket size value: owner_id[%d], sched_ent[%d], queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r", __func__, owner_id,
i, queue_id, rate_limit_val, bucket_size);
return ERR_SW_TM_BUCKET_SIZE_INVALID;
}
- mvNetaTxqRateSet(PON_PORT, i, queue_id, rate_limit_val);
+ mvNetaTxqRateSet(wan_gmac, i, queue_id, rate_limit_val);
}
sched_ent = sched_ent >> 1;
if (sched_ent == 0)
break;
}
if ((sched_ent != 0) && (i == num_tcont_llid - 1))
- printk(KERN_INFO "TCONT doesn't not exist\n");
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "TCONT doesn't not exist\n");
- printk(KERN_INFO "==EXIT== %s: \n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s: \n\r", __func__);
return TPM_RC_OK;
}
@@ -309,14 +373,21 @@
IN uint16_t wrr_weight)
{
uint32_t tmp_tcont = 0;
+ uint32_t lan_gmac = 0;
+ uint32_t tpm_ret = 0;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d],sched_mode[%d],"
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d],sched_mode[%d],"
" queue_id[%d], wrr_weight[%d]\n\r",
__func__, owner_id, sched_mode, queue_id, wrr_weight);
+ tpm_ret = tpm_tm_lan_gmac_get(&lan_gmac);
+ if (tpm_ret != TPM_OK) {
+ return ERR_SRC_PORT_INVALID;
+ }
+
if (queue_id >= TPM_MAX_NUM_TX_QUEUE) {
- printk(KERN_INFO "==ERROE==%s: Invalid queue number: owner_id[%d],sched_mode[%d],"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: Invalid queue number: owner_id[%d],sched_mode[%d],"
" queue_id[%d], wrr_weight[%d]\n\r",
__func__, owner_id, sched_mode, queue_id, wrr_weight);
return ERR_SW_TM_QUEUE_INVALID;
@@ -324,7 +395,7 @@
if ((sched_mode == TPM_PP_SCHED_WRR) && (wrr_weight > TPM_MAX_WRR_WEIGHT)) {
- printk(KERN_INFO "==ERROE==%s: WRR weight is out of rage: owner_id[%d],sched_mode[%d],"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: WRR weight is out of rage: owner_id[%d],sched_mode[%d],"
" queue_id[%d], wrr_weight[%d]\n\r",
__func__, owner_id, sched_mode, queue_id, wrr_weight);
return ERR_SW_TM_QUEUE_INVALID;
@@ -332,20 +403,20 @@
switch (sched_mode) {
case TPM_PP_SCHED_STRICT:
- mvNetaTxqFixPrioSet(SW_GMAC_0, tmp_tcont, queue_id);
+ mvNetaTxqFixPrioSet(lan_gmac, tmp_tcont, queue_id);
break;
case TPM_PP_SCHED_WRR:
- mvNetaTxqWrrPrioSet(SW_GMAC_0, tmp_tcont, queue_id, wrr_weight);
+ mvNetaTxqWrrPrioSet(lan_gmac, tmp_tcont, queue_id, wrr_weight);
break;
default:
- printk(KERN_ERR " Unknown TXQ command \n");
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD," Unknown TXQ command \n");
return ERR_GENERAL;
}
- printk(KERN_INFO "==EXIT== %s:\n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s:\n\r", __func__);
return TPM_RC_OK;
@@ -375,20 +446,27 @@
IN uint32_t bucket_size)
{
uint32_t tmp_tcont = 0;
+ uint32_t lan_gmac = 0;
+ uint32_t tpm_ret = 0;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d],rate_limit_val[%d] bucket_size[%d]\n\r",
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d],rate_limit_val[%d] bucket_size[%d]\n\r",
__func__, owner_id, rate_limit_val, bucket_size);
- if (mvNetaTxpBurstSet(SW_GMAC_0, tmp_tcont, bucket_size) != MV_OK) {
- printk(KERN_INFO
+ tpm_ret = tpm_tm_lan_gmac_get(&lan_gmac);
+ if (tpm_ret != TPM_OK) {
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ if (mvNetaTxpBurstSet(lan_gmac, tmp_tcont, bucket_size) != MV_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
"==ERROE==%s: Invalid bucket size value: owner_id[%d],rate_limit_val[%d] bucket_size[%d]\n\r",
__func__, owner_id, rate_limit_val, bucket_size);
return ERR_SW_TM_BUCKET_SIZE_INVALID;
}
- mvNetaTxpRateSet(SW_GMAC_0, tmp_tcont, rate_limit_val);
+ mvNetaTxpRateSet(lan_gmac, tmp_tcont, rate_limit_val);
- printk(KERN_INFO "==EXIT== %s: \n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s: \n\r", __func__);
return TPM_RC_OK;
}
@@ -420,28 +498,35 @@
IN uint32_t bucket_size)
{
uint32_t tmp_tcont = 0;
+ uint32_t lan_gmac = 0;
+ uint32_t tpm_ret = 0;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d], queue_id[%d]"
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d], queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, queue_id, rate_limit_val, bucket_size);
if (queue_id >= TPM_MAX_NUM_TX_QUEUE) {
- printk(KERN_INFO "==ERROE==%s: Invalid queue number: owner_id[%d], queue_id[%d]"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: Invalid queue number: owner_id[%d], queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, queue_id, rate_limit_val, bucket_size);
return ERR_SW_TM_QUEUE_INVALID;
}
- if (mvNetaTxqBurstSet(SW_GMAC_0, tmp_tcont, queue_id, bucket_size) != MV_OK) {
- printk(KERN_INFO "==ERROE==%s: Invalid bucket size value: owner_id[%d], queue_id[%d]"
+ tpm_ret = tpm_tm_lan_gmac_get(&lan_gmac);
+ if (tpm_ret != TPM_OK) {
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ if (mvNetaTxqBurstSet(lan_gmac, tmp_tcont, queue_id, bucket_size) != MV_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROE==%s: Invalid bucket size value: owner_id[%d], queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, queue_id, rate_limit_val, bucket_size);
return ERR_SW_TM_BUCKET_SIZE_INVALID;
}
- mvNetaTxqRateSet(SW_GMAC_0, tmp_tcont, queue_id, rate_limit_val);
+ mvNetaTxqRateSet(lan_gmac, tmp_tcont, queue_id, rate_limit_val);
- printk(KERN_INFO "==EXIT== %s: \n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s: \n\r", __func__);
return TPM_RC_OK;
}
@@ -473,17 +558,19 @@
uint32_t queue_id;
tpm_gmacs_enum_t lpk_gmac;
- printk(KERN_INFO "==ENTER==%s: owner_id[%d], rate_limit_val[%d], bucket_size[%d] \n\r",
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d], rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, rate_limit_val, bucket_size);
/*Get Tx queue on loopback gmac*/
- if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac, &queue_id)) {
- printk(KERN_INFO "==ERROR==%s: loopback gmac queue get failed \n\r", __func__);
+ if (TPM_DB_OK != tpm_db_gmac_lpk_queue_get(&lpk_gmac,
+ &queue_id,
+ TPM_GMAC1_QUEUE_DATA_TRAFFIC)) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROR==%s: loopback gmac queue get failed \n\r", __func__);
return ERR_GENERAL;
}
if (mvNetaTxqBurstSet((int)lpk_gmac, tmp_tcont, queue_id, bucket_size) != MV_OK) {
- printk(KERN_INFO "==ERROR==%s: Invalid bucket size value: owner_id[%d], queue_id[%d]"
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD, "==ERROR==%s: Invalid bucket size value: owner_id[%d], queue_id[%d]"
" rate_limit_val[%d], bucket_size[%d] \n\r",
__func__, owner_id, queue_id, rate_limit_val, bucket_size);
return ERR_SW_TM_BUCKET_SIZE_INVALID;
@@ -491,9 +578,56 @@
mvNetaTxqRateSet(SW_GMAC_1, tmp_tcont, queue_id, rate_limit_val);
- printk(KERN_INFO "==EXIT== %s: \n\r", __func__);
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s: \n\r", __func__);
return TPM_RC_OK;
}
EXPORT_SYMBOL(tpm_tm_set_gmac0_ingr_rate_lim);
+
+/*******************************************************************************
+* tpm_tm_set_tx_port_rate_lim()
+*
+* DESCRIPTION: Configures the rate limit of tx port wanted.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* port - port want to do rate limit
+* rate_limit_val - ingress rate limit value
+* bucket_size - bucket size value, if set 0, use the current bucket size
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_tm_set_tx_port_rate_lim(IN uint32_t owner_id,
+ IN uint32_t port,
+ IN uint32_t rate_limit_val,
+ IN uint32_t bucket_size)
+{
+ uint32_t tmp_tcont = 0;
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==ENTER==%s: owner_id[%d],port[%d],rate_limit_val[%d] bucket_size[%d]\n\r",
+ __func__, owner_id, port, rate_limit_val, bucket_size);
+
+ if (bucket_size) {
+ if (mvNetaTxpBurstSet(port, tmp_tcont, bucket_size) != MV_OK) {
+ TPM_OS_ERROR(TPM_TPM_LOG_MOD,
+ "==ERROE==%s: Invalid bucket size value: owner_id[%d],rate_limit_val[%d] bucket_size[%d]\n\r",
+ __func__, owner_id, rate_limit_val, bucket_size);
+ return ERR_SW_TM_BUCKET_SIZE_INVALID;
+ }
+ }
+
+ mvNetaTxpRateSet(port, tmp_tcont, rate_limit_val);
+
+ TPM_OS_INFO(TPM_TPM_LOG_MOD, "==EXIT== %s: \n\r", __func__);
+
+ return TPM_RC_OK;
+}
+EXPORT_SYMBOL(tpm_tm_set_tx_port_rate_lim);
+
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.h
index dabec88..6aae62d 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_tm.h
@@ -250,4 +250,29 @@
tpm_error_code_t tpm_tm_set_gmac0_ingr_rate_lim(IN uint32_t owner_id,
IN uint32_t rate_limit_val,
IN uint32_t bucket_size);
+
+/*******************************************************************************
+* tpm_tm_set_tx_port_rate_lim()
+*
+* DESCRIPTION: Configures the rate limit of tx port wanted.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* port - port want to do rate limit
+* rate_limit_val - ingress rate limit value
+* bucket_size - bucket size value
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success, the function returns TPM_RC_OK. On error different types are returned
+* according to the case - see tpm_error_code_t.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_tm_set_tx_port_rate_lim(IN uint32_t owner_id,
+ IN uint32_t port,
+ IN uint32_t rate_limit_val,
+ IN uint32_t bucket_size);
+
#endif /* _TPM_TM_H_ */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_types.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_types.h
index 8053dd7..4f85779 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_types.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_types.h
@@ -114,16 +114,17 @@
typedef enum {
TPM_API_MGMT,
TPM_API_MAC_LEARN,
+ TPM_API_DS_LOAD_BALANCE,
TPM_API_CPU_LOOPBACK,
TPM_API_L2_PRIM,
TPM_API_L3_TYPE,
TPM_API_IPV4,
TPM_API_IPV4_MC,
+ TPM_API_IPV6_NH,
+ TPM_API_IPV6_L4,
TPM_API_IPV6_GEN,
TPM_API_IPV6_DIP,
TPM_API_IPV6_MC,
- TPM_API_IPV6_NH,
- TPM_API_IPV6_L4,
TPM_API_CNM,
TPM_API_TYPE_ILLEGAL,
TPM_MAX_API_TYPES = TPM_API_TYPE_ILLEGAL
@@ -247,10 +248,19 @@
#define TPM_TRG_PORT_CPU (0x00020000) /* upstream / downstream - CPU port */
#define TPM_TRG_PORT_UNI_ANY (0x00040000) /* downstream - all UNI ports */
#define TPM_TRG_PORT_UNI_CPU_LOOP (0x00080000) /* downstream - loop to the CPU port */
+
+#define TPM_TRG_LOAD_BAL (0x80000000) /* for 2G DS Load-Balancing,
+ set target_gmac to GMAC1 */
+
#define TPM_TRG_PORT_ILLEGAL (0xFFFFFFFF) /* illegal port number value */
#define TPM_TRG_UNI_OFFSET 8
#define TPM_TRG_UNI_MASK 0x1FF
+typedef enum {
+ TPM_DS_TGRT_G0,
+ TPM_DS_TGRT_G1,
+ TPM_DS_TGRT_CPU,
+} tpm_ds_load_balance_tgrt_t;
/* target port type - bitmap */
typedef uint32_t tpm_trg_port_type_t; /*ex: TPM_TRG_PORT_WAN or TPM_TRG_TCONT_0 */
@@ -448,6 +458,20 @@
/****************************************************************/
/* IPV4 Multicast definitions */
/****************************************************************/
+typedef enum {
+ TPM_MC_ALL_CPU_FRWD,
+ TPM_MC_MAC_ONLY_FILTER,
+ TPM_MC_COMBINED_IP_MAC_FILTER,
+ TPM_MC_IP_ONLY_FILTER,
+ TPM_MC_FILTER_MODE_MAX,
+} tpm_mc_filter_mode_t;
+
+typedef enum {
+ TPM_MC_IGMP_SNOOPING,
+ TPM_MC_IGMP_PROXY,
+ TPM_MC_IGMP_MODE_MAX,
+} tpm_mc_igmp_mode_t;
+
typedef enum tpm_mc_port_mode {
TPM_MC_UNI_MODE_EXCLUDE,
TPM_MC_UNI_MODE_TRANSPARENT,
@@ -586,16 +610,26 @@
} tpm_rule_ipv4_key_t;
typedef struct tpm_rule_ipv4_mc_key {
+ uint32_t stream_num;
+ tpm_mc_igmp_mode_t igmp_mode;
+ uint8_t mc_stream_pppoe;
uint16_t vid;
uint8_t ipv4_src_add[4];
uint8_t ipv4_dest_add[4];
uint8_t ignore_ipv4_src;
+ uint16_t dest_queue;
tpm_trg_port_type_t dest_port_bm;
} tpm_rule_ipv4_mc_key_t;
typedef struct tpm_rule_ipv6_mc_key {
+ uint32_t stream_num;
+ tpm_mc_igmp_mode_t igmp_mode;
+ uint8_t mc_stream_pppoe;
uint16_t vid;
+ uint8_t ipv6_src_add[16];
uint8_t ipv6_dest_add[16];
+ uint8_t ignore_ipv6_src;
+ uint16_t dest_queue;
tpm_trg_port_type_t dest_port_bm;
} tpm_rule_ipv6_mc_key_t;
@@ -836,6 +870,14 @@
uint16_t dummy2;
} tpm_sw_mirror_t;
+/* Switch trunk type */
+typedef struct {
+ uint32_t trunk_id;
+ uint32_t port_mask;
+ uint32_t mask_num;
+ uint32_t trunk_mask;
+} tpm_sw_trunk_t;
+
/* typedef: struct tpm_sw_pirl_customer_t*/
typedef struct {
uint32_t ebsLimit;
@@ -891,6 +933,46 @@
uint32_t packets_1024_1518Octets;
} tpm_swport_pm_3_t;
+/*
+ All counter set 3 is used by 88E6093 and 88E6065
+*/
+typedef struct {
+ uint32_t dropEvents;
+ uint32_t InGoodOctetsLo;
+ uint32_t InGoodOctetsHi;
+ uint32_t InBadOctets;
+ uint32_t OutFCSErr;
+ uint32_t InUnicasts;
+ uint32_t Deferred;
+ uint32_t InBroadcasts;
+ uint32_t InMulticasts;
+ uint32_t Octets64;
+ uint32_t Octets127;
+ uint32_t Octets255;
+ uint32_t Octets511;
+ uint32_t Octets1023;
+ uint32_t OctetsMax;
+ uint32_t OutOctetsLo;
+ uint32_t OutOctetsHi;
+ uint32_t OutUnicasts;
+ uint32_t Excessive;
+ uint32_t OutMulticasts;
+ uint32_t OutBroadcasts;
+ uint32_t Single;
+ uint32_t OutPause;
+ uint32_t InPause;
+ uint32_t Multiple;
+ uint32_t Undersize;
+ uint32_t Fragments;
+ uint32_t Oversize;
+ uint32_t Jabber;
+ uint32_t InMACRcvErr;
+ uint32_t InFCSErr;
+ uint32_t Collisions;
+ uint32_t Late;
+
+} tpm_swport_pm_3_all_t;
+
/******************************************************************************/
/********************************** Initialisation defs ***********************/
/******************************************************************************/
@@ -930,7 +1012,8 @@
TPM_PON_WAN_G1_SINGLE_PORT,
TPM_PON_G1_WAN_G0_SINGLE_PORT,
TPM_PON_G0_WAN_G1_SINGLE_PORT,
- TPM_PON_WAN_G0_G1_LPBK
+ TPM_PON_WAN_G0_G1_LPBK,
+ TPM_PON_WAN_G0_G1_DUAL_LAN
} tpm_eth_complex_profile_t;
typedef enum {
@@ -1023,26 +1106,6 @@
TPM_MAX_NUM_TX_PORTS
} tpm_init_tx_mod_t;
-typedef struct {
- uint32_t omci_etype;
-
- uint32_t oam_channel_configured; /* omci or oam channel configured */
- uint16_t omci_gemport;
- uint32_t oam_cpu_rx_q; /* omci cpu rx q or oam cpu rx q */
- uint32_t oam_cpu_tx_q; /* omci cpu tx q or oam cpu tx q */
- uint32_t oam_cpu_tx_port; /* omci tcount or oam llid */
- uint32_t pnc_init_debug_port;
- tpm_init_pon_type_t pon_type;
-
-} tpm_init_misc_t;
-
-/* Structure holds the IGMP/MLD settings */
-typedef struct {
- uint32_t valid;
- uint32_t igmp_snoop;
- uint32_t igmp_cpu_queue;
-} tpm_init_igmp_t;
-
/* Structure holds the physical connections of all external Ethernet ports */
typedef struct {
uint32_t valid;
@@ -1099,6 +1162,7 @@
TPM_PNC_MAC_LEARN,
TPM_PNC_CPU_WAN_LPBK_US,
TPM_PNC_NUM_VLAN_TAGS,
+ TPM_PNC_DS_LOAD_BALANCE,
TPM_PNC_MULTI_LPBK,
TPM_PNC_VIRT_UNI,
TPM_PNC_LOOP_DET_US,
@@ -1107,13 +1171,14 @@
TPM_PNC_IGMP,
TPM_PNC_IPV4_MC_DS,
TPM_PNC_IPV4_MAIN,
- TPM_PNC_TCP_FLAG,
+ TPM_PNC_IPV4_TCP_FLAG,
TPM_PNC_TTL,
TPM_PNC_IPV4_PROTO,
TPM_PNC_IPV4_FRAG,
TPM_PNC_IPV4_LEN,
TPM_PNC_IPV6_NH,
TPM_PNC_IPV6_L4_MC_DS,
+ TPM_PNC_IPV6_TCP_FLAG,
TPM_PNC_IPV6_L4,
TPM_PNC_IPV6_HOPL,
TPM_PNC_IPV6_MC_SIP,
@@ -1152,6 +1217,10 @@
TPM_IPV6_5T_DISABLED = 0,
TPM_IPV6_5T_ENABLED,
} tpm_init_ipv6_5t_enable_t;
+typedef enum {
+ TPM_DS_MAC_BASED_TRUNK_DISABLED = 0,
+ TPM_DS_MAC_BASED_TRUNK_ENABLED,
+} tpm_init_ds_mac_based_trunk_enable_t;
typedef enum {
TPM_CTC_CM_DISABLED = 0,
@@ -1277,20 +1346,6 @@
} tpm_init_split_mod_enable_t;
typedef enum {
- TPM_MC_ALL_CPU_FRWD,
- TPM_MC_MAC_ONLY_FILTER,
- TPM_MC_COMBINED_IP_MAC_FILTER,
- TPM_MC_IP_ONLY_FILTER,
- TPM_MC_FILTER_MODE_MAX,
-} tpm_mc_filter_mode_t;
-
-typedef enum {
- TPM_MC_IGMP_SNOOPING,
- TPM_MC_IGMP_PROXY,
- TPM_MC_IGMP_MODE_MAX,
-} tpm_mc_igmp_mode_t;
-
-typedef enum {
TPM_MTU_IPV4, /* IPV4 */
TPM_MTU_IPV6, /* IPV6 */
} tpm_mtu_ethertype_t;
@@ -1337,6 +1392,16 @@
uint32_t ipv6_mc_support;
} tpm_init_mc_setting_t;
+typedef enum {
+ TPM_INVALID_GMAC = -1,
+ TPM_ENUM_GMAC_0,
+ TPM_ENUM_GMAC_1,
+ TPM_ENUM_PMAC,
+ TPM_MAX_GMAC = TPM_ENUM_PMAC,
+ TPM_MAX_NUM_GMACS
+} tpm_gmacs_enum_t;
+
+
typedef struct {
tpm_init_split_mod_enable_t split_mod_enable;
uint8_t p_bit[8];
@@ -1370,7 +1435,8 @@
tpm_eth_complex_profile_t eth_cmplx_profile;
tpm_init_eth_port_conf_t eth_port_conf[TPM_MAX_NUM_ETH_PORTS];
tpm_init_gmac_conn_conf_t gmac_port_conf[TPM_NUM_GMACS];
- uint32_t backup_wan;
+ uint32_t active_wan;
+ tpm_init_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
tpm_init_gmac_tx_t gmac_tx[TPM_MAX_NUM_TX_PORTS];
tpm_init_gmac_rx_t gmac_rx[TPM_NUM_GMACS];
@@ -1436,6 +1502,7 @@
ERR_MC_STREAM_INVALID, /*Illegal stream number. */
ERR_MC_STREAM_EXISTS, /*Stream number already exists. */
ERR_MC_DST_PORT_INVALID, /*Destination port bitmap does not match the UNI ports. */
+ ERR_MC_DST_QUEUE_INVALID, /*Destination queue number invalid. */
ERR_IPV4_MC_DST_IP_INVALID, /*Destination IP address is not in the MC range. */
ERR_IPV6_MC_DST_IP_INVALID, /*Destination IPv6 address is not in the MC range. */
ERR_IPV6_MC_SRC_IP_INVALID, /*SRC IPv6 address is not in the MC_SIP range. */
@@ -1489,6 +1556,8 @@
ERR_TPMCHECK_PMT_DB_MISMATCH,/*DB PMT check FAIL */
ERR_TPMCHECK_PMT_HW_MISMATCH,/*HW PMT check FAIL */
ERR_UNKNOWN_MAC_CONF_INVALID,/*Illegal MAC learn default conf*/
+ ERR_PHY_SRC_PORT_CONN_INVALID,/*PHY and source port connection invalid*/
+ ERR_PHY_STATUS_UNKNOWN,/*PHY status info is unknown*/
} tpm_error_code_t;
#ifdef __cplusplus
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.c
index 49f9876..97373e2 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.c
@@ -634,6 +634,56 @@
}
/*******************************************************************************
+* get_ds_mac_based_trunking_enable()
+*
+* DESCRIPTION: Get DS load balance parameters from XML configuration file
+*
+* INPUTS:
+*
+* OUTPUTS: enable - whether DS load balance is enabled
+*
+* RETURNS: US_RC_OK, US_RC_FAIL or US_RC_NOT_FOUND
+*
+*******************************************************************************/
+int get_ds_mac_based_trunking_enable(uint32_t *enable)
+{
+ ezxml_t xmlHead;
+ ezxml_t xmlElement;
+ int rc = US_RC_OK;
+
+ if (enable == NULL) {
+#ifdef US_DEBUG_PRINT
+ printk(KERN_ERR "%s: NULL pointer\n", __func__);
+#endif
+ return US_RC_FAIL;
+ }
+
+ *enable = 0;
+
+ xmlHead = get_xml_head_ptr(g_pstr_xml_cfg_file);
+
+ if (xmlHead == NULL)
+ return US_RC_FAIL;
+
+ xmlElement = ezxml_child(xmlHead, US_XML_TPM_E);
+ if (xmlElement == NULL) {
+#ifdef US_DEBUG_PRINT
+ printk(KERN_ERR "Failed to find %s in XML config. file %s\n", US_XML_TPM_E, g_pstr_xml_cfg_file);
+#endif
+ rc = US_RC_NOT_FOUND;
+ } else {
+ rc = get_int_param(xmlElement, US_XML_DS_MAC_BASED_TRUNKING_E, enable);
+
+#ifdef US_DEBUG_PRINT
+ printk("ds_mac_based_trunking enable %d \n", *enable);
+#endif
+ }
+
+ /*ezxml_free(xmlHead); */
+ return rc;
+}
+
+/*******************************************************************************
* get_igmp_snoop_params_cpu_queue()
*
* DESCRIPTION: Get IGMP snooping parameters from XML configuration file
@@ -1191,7 +1241,7 @@
rc = US_RC_FAIL;
break;
}
-
+
/* mandatory field */
xmlStr = ezxml_attr(xmlPort, US_XML_ETH_PORT_SRC_ATTR);
if (xmlStr == NULL) {
@@ -1213,7 +1263,7 @@
if (eth_port_bufs[port_nr].valid) {
printk("%d) src_port %d switch_port %d\n",
port_nr,
- eth_port_bufs[port_nr].port_src,
+ eth_port_bufs[port_nr].port_src,
eth_port_bufs[port_nr].switch_port);
}
}
@@ -1224,7 +1274,7 @@
}
/*******************************************************************************
-* get_backup_wan_params()
+* get_active_wan_params()
*
* DESCRIPTION: Get GMAC connection parameters from XML configuration file
*
@@ -1237,20 +1287,20 @@
* RETURNS: US_RC_OK, US_RC_FAIL or US_RC_NOT_FOUND
*
*******************************************************************************/
-int get_backup_wan_params(uint32_t *backup_wan)
+int get_active_wan_params(uint32_t *active_wan)
{
ezxml_t xmlHead;
ezxml_t xmlElement;
int rc = US_RC_OK;
- if (backup_wan == NULL) {
+ if (active_wan == NULL) {
#ifdef US_DEBUG_PRINT
printk(KERN_ERR "%s: NULL pointer\n", __func__);
#endif
return US_RC_FAIL;
}
- *backup_wan = 0;
+ *active_wan = 0;
xmlHead = get_xml_head_ptr(g_pstr_xml_cfg_file);
@@ -1264,12 +1314,12 @@
#endif
rc = US_RC_NOT_FOUND;
} else {
- rc = get_int_param(xmlElement, US_XML_BACKUP_WAN_E, backup_wan);
+ rc = get_int_param(xmlElement, US_XML_ACTIVE_WAN_E, active_wan);
#ifdef US_DEBUG_PRINT
printk("======================================\n");
printk(" ETH COMPLEX \n");
printk("======================================\n");
- printk("backup_wan %d \n", *backup_wan);
+ printk("active_wan %d \n", *active_wan);
#endif
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.h
index ac14460..88d65ae 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/core/tpm_xml_params.h
@@ -147,6 +147,7 @@
#define US_XML_OMCI_E "OMCI"
#define US_XML_OMCI_ETY_E "OMCI_ETY"
+#define US_XML_DS_MAC_BASED_TRUNKING_E "ds_mac_based_trunking"
#define US_XML_IGMP_SNOOP_E "igmp_snoop"
#define US_XML_IGMP_SNOOP_ALL_E "snoop_all"
#define US_XML_ENABLED_E "enabled"
@@ -181,7 +182,7 @@
#define US_XML_ETH_PORT_INTCON_ATTR "intr_conn"
#define US_XML_ETH_CMPLX_CONFIG_E "eth_complex_config"
#define US_XML_WAN_E "WAN"
-#define US_XML_BACKUP_WAN_E "backup_wan"
+#define US_XML_ACTIVE_WAN_E "active_wan"
#define US_XML_VIRTUAL_UNI_E "virtual_uni"
#define US_XML_ETH_PROFILE_E "profile"
@@ -309,6 +310,7 @@
int get_omci_etype_param(uint32_t *ety);
int get_debug_port_params(uint32_t *valid, uint32_t *num);
int get_igmp_snoop_params_enable(uint32_t *enable);
+int get_ds_mac_based_trunking_enable(uint32_t *enable);
int get_igmp_snoop_params_cpu_queue(uint32_t *que);
int get_igmp_snoop_params_port_frwd_mode(uint32_t *mode, tpm_src_port_type_t port);
int get_gmac_conn_params(uint32_t *num_tcont_llid);
@@ -316,7 +318,7 @@
int get_eth_cmplx_profile_params(tpm_eth_complex_profile_t *eth_cmplx_profile);
int get_gmac_port_conf_params(tpm_init_gmac_conn_conf_t *gmac_port_conf_bufs, int max_gmac_port_num);
int get_eth_port_conf_params(tpm_init_eth_port_conf_t *eth_port_bufs, int max_eth_port_num);
-int get_backup_wan_params(uint32_t *backup_wan);
+int get_active_wan_params(uint32_t *active_wan);
int get_gmac_pool_bufs_params(tpm_init_gmac_bufs_t *gmac_bufs, int max_gmacs_num);
int get_trace_debug_info_param(uint32_t *trace_debug_info);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_bring_up.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_bring_up.c
index b87da74..2b1c4f6 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_bring_up.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_bring_up.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Copyright (C) Marvell International Ltd. and its affiliates
-This software file (the "File") is owned and distributed by Marvell
+This software file (the "File") is owned and distributed by Marvell
International Ltd. and/or its affiliates ("Marvell") under the following
alternative licensing terms. Once you have made an election to distribute the
File under one of the following license alternatives, please (i) delete this
@@ -19,45 +19,45 @@
********************************************************************************
Marvell GPL License Option
-If you received this File from Marvell, you may opt to use, redistribute and/or
-modify this File in accordance with the terms and conditions of the General
-Public License Version 2, June 1991 (the "GPL License"), a copy of which is
-available along with the File in the license.txt file or by writing to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
-on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File in accordance with the terms and conditions of the General
+Public License Version 2, June 1991 (the "GPL License"), a copy of which is
+available along with the File in the license.txt file or by writing to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
+on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
-DISCLAIMED. The GPL License provides additional details about this warranty
+THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
+DISCLAIMED. The GPL License provides additional details about this warranty
disclaimer.
********************************************************************************
Marvell BSD License Option
-If you received this File from Marvell, you may opt to use, redistribute and/or
-modify this File under the following licensing terms.
-Redistribution and use in source and binary forms, with or without modification,
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+ this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+ documentation and/or other materials provided with the distribution.
- * Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * Neither the name of Marvell nor the names of its contributors may be
+ used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
@@ -67,11 +67,11 @@
** **
** DESCRIPTION : This file implements TPM BringUp handling **
*******************************************************************************
-* *
+* *
* MODIFICATION HISTORY: *
* *
-* 11Aug10 Yuval Caduri created *
-* =========================================================================== *
+* 11Aug10 Yuval Caduri created *
+* =========================================================================== *
******************************************************************************/
/* Include Files
@@ -80,7 +80,7 @@
#include "tpm_header.h"
/* Local Constant
-------------------------------------------------------------------------------*/
+------------------------------------------------------------------------------*/
/* Global Variables
------------------------------------------------------------------------------*/
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.c
index e6ad713..6a467be 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.c
@@ -117,6 +117,7 @@
tpm_ioctl_tm_tm_t tpm_ioctl_tm_tm;
tpm_ioctl_igmp_t tpm_ioctl_igmp;
tpm_ioctl_mib_reset_t tpm_ioctl_mib_reset;
+ tpm_ioctl_set_active_wan_t tpm_ioctl_set_active_wan;
tpm_ioctl_swport_pm_3_t apm_ioctl_pm_ethernet_3;
tpm_ioctl_rx_igmp_t tpm_ioctl_rx_igmp;
tpm_ioctl_tx_igmp_t tpm_ioctl_tx_igmp;
@@ -654,7 +655,7 @@
ret = 0;
break;
-
+
/* ====== MV_TPM_IOCTL_ADD_CTC_CM_ACL_RULE ========= */
case MV_TPM_IOCTL_ADD_CTC_CM_ACL_RULE:
rcode = tpm_add_ctc_cm_acl_rule(tpm_add_acl_rule->owner_id,
@@ -695,6 +696,24 @@
}
ret = 0;
break;
+ /* ====== MV_TPM_IOCTL_ADD_DS_LOAD_BALANCE_RULE ========= */
+ case MV_TPM_IOCTL_ADD_DS_LOAD_BALANCE_RULE:
+ rcode = tpm_add_ds_load_balance_rule(tpm_add_acl_rule->owner_id,
+ tpm_add_acl_rule->rule_num,
+ &tpm_add_acl_rule->rule_idx,
+ tpm_add_acl_rule->parse_rule_bm,
+ tpm_add_acl_rule->ds_load_balance_acl_rule.parse_flags_bm,
+ &tpm_add_acl_rule->ds_load_balance_acl_rule.l2_key,
+ tpm_add_acl_rule->ds_load_balance_acl_rule.tgrt);
+ if (rcode != TPM_OK)
+ goto ioctlErr;
+
+ if (copy_to_user((tpm_ioctl_add_acl_rule_t*)arg, tpm_add_acl_rule, sizeof(tpm_ioctl_add_acl_rule_t))) {
+ printk(KERN_ERR "ERROR: (%s:%d) copy_to_user failed\n", __FUNCTION__, __LINE__);
+ goto ioctlErr;
+ }
+ ret = 0;
+ break;
/* ====== MV_TPM_IOCTL_SET_MOD_RULE ========= */
case MV_TPM_IOCTL_SET_MOD_RULE:
@@ -762,6 +781,24 @@
ret = 0;
break;
+ /* ====== MV_TPM_IOCTL_DEL_DS_LOAD_BALANCE_RULE ========= */
+ case MV_TPM_IOCTL_DEL_DS_LOAD_BALANCE_RULE:
+
+ rcode = tpm_del_ds_load_balance_rule( tpm_del_acl_rule->owner_id,
+ tpm_del_acl_rule->rule_idx);
+
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ if(copy_to_user((tpm_ioctl_del_acl_rule_t*)arg, tpm_del_acl_rule, sizeof(tpm_ioctl_del_acl_rule_t)))
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) copy_to_user failed\n", __FUNCTION__, __LINE__);
+ goto ioctlErr;
+ }
+
+ ret = 0;
+ break;
+
/* ====== MV_TPM_IOCTL_DEL_MAC_LEARN_ACL_RULE ========= */
case MV_TPM_IOCTL_DEL_MAC_LEARN_ACL_RULE:
rcode = tpm_del_mac_learn_rule(tpm_del_acl_rule->owner_id,
@@ -936,19 +973,19 @@
break;
/* ====== MV_TPM_IOCTL_DEL_CTC_CM_ACL_RULE ========= */
case MV_TPM_IOCTL_DEL_CTC_CM_ACL_RULE:
-
+
rcode = tpm_del_ctc_cm_acl_rule(tpm_del_acl_rule->owner_id,
tpm_del_acl_rule->src_port,
tpm_del_acl_rule->precedence);
-
+
if (rcode != TPM_OK)
goto ioctlErr;
-
+
if (copy_to_user((tpm_ioctl_del_acl_rule_t*)arg, tpm_del_acl_rule, sizeof(tpm_ioctl_del_acl_rule_t))) {
printk(KERN_ERR "ERROR: (%s:%d) copy_to_user failed\n", __FUNCTION__, __LINE__);
goto ioctlErr;
}
-
+
ret = 0;
break;
@@ -1142,6 +1179,25 @@
ret = 0;
break;
+ /* ====== MV_TPM_IOCTL_ADD_IPv4_MC_STREAM_SET_QUEUE ========= */
+ case MV_TPM_IOCTL_ADD_IPv4_MC_STREAM_SET_QUEUE:
+
+
+ rcode = tpm_add_ipv4_mc_stream_set_queue( tpm_mc_rule->owner_id,
+ tpm_mc_rule->stream_num,
+ tpm_mc_rule->igmp_mode,
+ tpm_mc_rule->mc_stream_pppoe,
+ tpm_mc_rule->vid,
+ &(tpm_mc_rule->ipv4_mc.ipv4_src_add[0]),
+ &(tpm_mc_rule->ipv4_mc.ipv4_dst_add[0]),
+ tpm_mc_rule->ipv4_mc.ignore_ipv4_src,
+ tpm_mc_rule->dest_queue,
+ tpm_mc_rule->dest_port_bm);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret = 0;
+ break;
/* ====== MV_TPM_IOCTL_MOD_IPv4_MC_STREAM ========= */
case MV_TPM_IOCTL_MOD_IPv4_MC_STREAM:
@@ -1166,46 +1222,65 @@
ret = 0;
break;
- /* ====== MV_TPM_IOCTL_ADD_IPv6_MC_STREAM ========= */
- case MV_TPM_IOCTL_ADD_IPv6_MC_STREAM:
+ /* ====== MV_TPM_IOCTL_ADD_IPv6_MC_STREAM ========= */
+ case MV_TPM_IOCTL_ADD_IPv6_MC_STREAM:
- rcode = tpm_add_ipv6_mc_stream( tpm_mc_rule->owner_id,
- tpm_mc_rule->stream_num,
- tpm_mc_rule->igmp_mode,
- tpm_mc_rule->mc_stream_pppoe,
- tpm_mc_rule->vid,
- &(tpm_mc_rule->ipv6_mc.ipv6_src_add[0]),
- &(tpm_mc_rule->ipv6_mc.ipv6_dst_add[0]),
- tpm_mc_rule->ipv6_mc.ignore_ipv6_src,
- tpm_mc_rule->dest_port_bm);
- if(rcode != TPM_OK)
- goto ioctlErr;
+ rcode = tpm_add_ipv6_mc_stream( tpm_mc_rule->owner_id,
+ tpm_mc_rule->stream_num,
+ tpm_mc_rule->igmp_mode,
+ tpm_mc_rule->mc_stream_pppoe,
+ tpm_mc_rule->vid,
+ &(tpm_mc_rule->ipv6_mc.ipv6_src_add[0]),
+ &(tpm_mc_rule->ipv6_mc.ipv6_dst_add[0]),
+ tpm_mc_rule->ipv6_mc.ignore_ipv6_src,
+ tpm_mc_rule->dest_port_bm);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
- ret = 0;
- break;
+ ret = 0;
+ break;
- /* ====== MV_TPM_IOCTL_MOD_IPv6_MC_STREAM ========= */
- case MV_TPM_IOCTL_MOD_IPv6_MC_STREAM:
+ /* ====== MV_TPM_IOCTL_ADD_IPv6_MC_STREAM_SET_QUEUE ========= */
+ case MV_TPM_IOCTL_ADD_IPv6_MC_STREAM_SET_QUEUE:
- rcode = tpm_updt_ipv6_mc_stream(tpm_mc_rule->owner_id,
- tpm_mc_rule->stream_num,
- tpm_mc_rule->dest_port_bm);
- if(rcode != TPM_OK)
- goto ioctlErr;
+ rcode = tpm_add_ipv6_mc_stream_set_queue(tpm_mc_rule->owner_id,
+ tpm_mc_rule->stream_num,
+ tpm_mc_rule->igmp_mode,
+ tpm_mc_rule->mc_stream_pppoe,
+ tpm_mc_rule->vid,
+ &(tpm_mc_rule->ipv6_mc.ipv6_src_add[0]),
+ &(tpm_mc_rule->ipv6_mc.ipv6_dst_add[0]),
+ tpm_mc_rule->ipv6_mc.ignore_ipv6_src,
+ tpm_mc_rule->dest_queue,
+ tpm_mc_rule->dest_port_bm);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
- ret = 0;
- break;
+ ret = 0;
+ break;
- /* ====== MV_TPM_IOCTL_DEL_IPv6_MC_STREAM ========= */
- case MV_TPM_IOCTL_DEL_IPv6_MC_STREAM:
+ /* ====== MV_TPM_IOCTL_MOD_IPv6_MC_STREAM ========= */
+ case MV_TPM_IOCTL_MOD_IPv6_MC_STREAM:
- rcode = tpm_del_ipv6_mc_stream(tpm_mc_rule->owner_id,
- tpm_mc_rule->stream_num);
- if(rcode != TPM_OK)
- goto ioctlErr;
+ rcode = tpm_updt_ipv6_mc_stream(tpm_mc_rule->owner_id,
+ tpm_mc_rule->stream_num,
+ tpm_mc_rule->dest_port_bm);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
- ret = 0;
- break;
+ ret = 0;
+ break;
+
+ /* ====== MV_TPM_IOCTL_DEL_IPv6_MC_STREAM ========= */
+ case MV_TPM_IOCTL_DEL_IPv6_MC_STREAM:
+
+ rcode = tpm_del_ipv6_mc_stream(tpm_mc_rule->owner_id,
+ tpm_mc_rule->stream_num);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret = 0;
+ break;
default:
ret = -EINVAL;
@@ -1294,7 +1369,18 @@
/* ====== MV_TPM_IOCTL_ADD_LOOP_DETECT_CHNL ========= */
case MV_TPM_IOCTL_ADD_LOOP_DETECT_CHNL:
- rcode = tpm_loop_detect_add_channel(tpm_mng_ch->tpm_ioctl_oam_ch.owner_id);
+ rcode = tpm_loop_detect_add_channel(tpm_mng_ch->tpm_ioctl_oam_ch.owner_id,
+ tpm_mng_ch->loopback_detect_ety);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret = 0;
+ break;
+
+ /* ====== MV_TPM_IOCTL_ADD_LOOP_DETECT_CHNL ========= */
+ case MV_TPM_IOCTL_DEL_LOOP_DETECT_CHNL:
+
+ rcode = tpm_loop_detect_del_channel(tpm_mng_ch->tpm_ioctl_oam_ch.owner_id);
if(rcode != TPM_OK)
goto ioctlErr;
@@ -1540,6 +1626,26 @@
goto ioctlErr;
ret = 0;
break;
+ /* ====== MV_TPM_IOCTL_SW_SET_TRUNK_PORT ========= */
+ case MV_TPM_IOCTL_SW_SET_TRUNK_PORT:
+ rcode = tpm_sw_set_trunk_ports(tpm_sw_mac_security->owner_id,
+ tpm_sw_mac_security->trunk.trunk_id,
+ tpm_sw_mac_security->trunk.trunk_mask);
+
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+ ret = 0;
+ break;
+ /* ====== MV_TPM_IOCTL_SW_SET_TRUNK_MASK ========= */
+ case MV_TPM_IOCTL_SW_SET_TRUNK_MASK:
+ rcode = tpm_sw_set_trunk_mask(tpm_sw_mac_security->owner_id,
+ tpm_sw_mac_security->trunk.mask_num,
+ tpm_sw_mac_security->trunk.trunk_mask);
+
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+ ret = 0;
+ break;
/* ====== MV_TPM_IOCTL_SW_GET_MIRROR ========= */
case MV_TPM_IOCTL_SW_GET_MIRROR:
@@ -1770,6 +1876,18 @@
}
ret = 0;
break;
+
+ /* ====== MV_TPM_IOCTL_SW_PORT_ADD_VID_SET_EGRESS_MODE ========= */
+ case MV_TPM_IOCTL_SW_PORT_ADD_VID_SET_EGRESS_MODE:
+ rcode = tpm_sw_port_add_vid_set_egrs_mode(tpm_sw_vlan_filter->owner_id,
+ tpm_sw_vlan_filter->port,
+ tpm_sw_vlan_filter->vid,
+ tpm_sw_vlan_filter->egress_mode);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+ ret = 0;
+ break;
+
default:
ret = -EINVAL;
}
@@ -2106,6 +2224,18 @@
ret = 0;
break;
+
+ /* ====== MV_TPM_IOCTL_UNI_2_SW_PORT ========= */
+ case MV_TPM_IOCTL_UNI_2_SW_PORT:
+ rcode = tpm_xlate_uni_2_switch_port( tpm_sw_phy->owner_id,
+ tpm_sw_phy->extern_port_id,
+ &(tpm_sw_phy->switch_port_id));
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret = 0;
+ break;
+
default:
ret = -EINVAL;
}
@@ -2120,7 +2250,8 @@
tpm_sw_phy->sw_phy_cmd == MV_TPM_IOCTL_SW_PHY_GET_SPEED_MODE ||
tpm_sw_phy->sw_phy_cmd == MV_TPM_IOCTL_SW_PHY_GET_PORT_STATE||
tpm_sw_phy->sw_phy_cmd == MV_TPM_IOCTL_SW_PHY_GET_PORT_FC_STATE ||
- tpm_sw_phy->sw_phy_cmd == MV_TPM_IOCTL_SW_PHY_CONVERT_PORT_INDEX))
+ tpm_sw_phy->sw_phy_cmd == MV_TPM_IOCTL_SW_PHY_CONVERT_PORT_INDEX ||
+ tpm_sw_phy->sw_phy_cmd == MV_TPM_IOCTL_UNI_2_SW_PORT))
{
if(copy_to_user((tpm_ioctl_sw_phy_t*)arg, tpm_sw_phy, sizeof(tpm_ioctl_sw_phy_t)))
{
@@ -2556,6 +2687,79 @@
break;
/* ================================ */
+ /* ====== SET active wan Section == */
+ /* ================================ */
+ case MV_TPM_IOCTL_SET_ACTIVE_WAN_SECTION:
+ {
+ tpm_ioctl_set_active_wan_t set_active_wan;
+ if(copy_from_user(&set_active_wan, (tpm_ioctl_set_active_wan_t*)arg, sizeof(tpm_ioctl_set_active_wan_t)))
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) copy_from_user failed\n", __FUNCTION__, __LINE__);
+ goto ioctlErr;
+ }
+ rcode = tpm_set_active_wan(set_active_wan.owner_id, set_active_wan.active_wan);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret=0;
+ break;
+ }
+ /* ================================ */
+ /* ====== SET GMAC LPBK Section == */
+ /* ================================ */
+ case MV_TPM_IOCTL_SET_GMAC_LPBK_SECTION:
+ {
+ tpm_ioctl_set_gmac_loopback_t set_gmac_lpbk;
+ if(copy_from_user(&set_gmac_lpbk, (tpm_ioctl_set_gmac_loopback_t*)arg, sizeof(tpm_ioctl_set_gmac_loopback_t)))
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) copy_from_user failed\n", __FUNCTION__, __LINE__);
+ goto ioctlErr;
+ }
+ rcode = tpm_set_gmac_loopback(set_gmac_lpbk.owner_id, set_gmac_lpbk.gmac, set_gmac_lpbk.enable);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret=0;
+ break;
+ }
+ /* ================================ */
+ /* ====== hot swap profile Section == */
+ /* ================================ */
+ case MV_TPM_IOCTL_HOT_SWAP_PROFILE_SECTION:
+ {
+ tpm_ioctl_hot_swap_profile_t swap_profile;
+ if(copy_from_user(&swap_profile, (tpm_ioctl_hot_swap_profile_t*)arg, sizeof(tpm_ioctl_hot_swap_profile_t)))
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) copy_from_user failed\n", __FUNCTION__, __LINE__);
+ goto ioctlErr;
+ }
+ rcode = tpm_hot_swap_profile(swap_profile.owner_id, swap_profile.profile_id);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret=0;
+ break;
+ }
+ /* ================================ */
+ /* ====== set hwf admin Section == */
+ /* ================================ */
+ case MV_TPM_IOCTL_SET_PORT_HWF_ADMIN_SECTION:
+ {
+ tpm_ioctl_set_port_hwf_admin_t set_port_hwf_admin;
+ if(copy_from_user(&set_port_hwf_admin, (tpm_ioctl_set_port_hwf_admin_t*)arg, sizeof(tpm_ioctl_set_port_hwf_admin_t)))
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) copy_from_user failed\n", __FUNCTION__, __LINE__);
+ goto ioctlErr;
+ }
+
+ rcode = tpm_proc_hwf_admin_set(set_port_hwf_admin.port, set_port_hwf_admin.txp, set_port_hwf_admin.enable);
+ if(rcode != TPM_OK)
+ goto ioctlErr;
+
+ ret=0;
+ break;
+ }
+ /* ================================ */
/* ====== ALARM Section ======= */
/* ================================ */
case MV_TPM_IOCTL_ALARM_SECTION:
@@ -2847,7 +3051,7 @@
(tpm_ioctl_pnc_hit_cnt_t *) tpm_common_mempool_alloc(tpm_ioctl_mpools.mpool_h);
if (tpm_ioctl_pnc_hit_cnt == NULL)
{
- printk(KERN_ERR "ERROR: (%s:%d) tpm_common_mempool_alloc(%p) failed\n",
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_common_mempool_alloc(%p) failed\n",
__FUNCTION__, __LINE__, tpm_ioctl_mpools.mpool_h);
ret = -ENOMEM;
goto ioctlErr;
@@ -2882,7 +3086,7 @@
} /* MV_TPM_IOCTL_GET_ALL_HIT_COUNTERS */
else
{
- tpm_ioctl_age_count_t *tpm_ioctl_age_count =
+ tpm_ioctl_age_count_t *tpm_ioctl_age_count =
(tpm_ioctl_age_count_t *) tpm_common_mempool_alloc(tpm_ioctl_mpools.mpool_m);
if (tpm_ioctl_age_count == NULL)
{
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.h
index ce4787c..9ceffc6 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_mng_if.h
@@ -107,6 +107,10 @@
#define MV_TPM_IOCTL_FLUSH_ATU_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 28, unsigned int)
#define MV_TPM_IOCTL_FLUSH_VTU_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 29, unsigned int)
#define MV_TPM_IOCTL_SET_IPV6_CM_PARSE_WIN_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 30, unsigned int)
+#define MV_TPM_IOCTL_SET_ACTIVE_WAN_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 31, unsigned int)
+#define MV_TPM_IOCTL_HOT_SWAP_PROFILE_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 32, unsigned int)
+#define MV_TPM_IOCTL_SET_GMAC_LPBK_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 33, unsigned int)
+#define MV_TPM_IOCTL_SET_PORT_HWF_ADMIN_SECTION _IOWR(MV_TPM_IOCTL_MAGIC, 34, unsigned int)
#define MV_APM_IOCTL_MAGIC ('A')
@@ -218,6 +222,7 @@
MV_TPM_IOCTL_ALARM_GET_ETH_PORT,
MV_TPM_IOCTL_SW_PHY_CONVERT_PORT_INDEX,
MV_TPM_IOCTL_ADD_LOOP_DETECT_CHNL,
+ MV_TPM_IOCTL_DEL_LOOP_DETECT_CHNL,
MV_TPM_IOCTL_ADD_OAM_LOOPBACK_CHNL,
MV_TPM_IOCTL_DEL_OAM_LOOPBACK_CHNL,
MV_TPM_IOCTL_SW_PHY_SET_PORT_DUPLEX_MODE,
@@ -225,6 +230,7 @@
MV_TPM_IOCTL_SW_GET_MAC_AGE_TIME,
MV_TPM_IOCTL_SW_SET_MAC_LEARN,
MV_TPM_IOCTL_SW_GET_PORT_FLOOD,
+ MV_TPM_IOCTL_UNI_2_SW_PORT,
MV_TPM_IOCTL_RESERVED_3,
MV_TPM_IOCTL_RESERVED_4,
@@ -237,6 +243,8 @@
MV_TPM_IOCTL_SW_SET_MIRROR,
MV_TPM_IOCTL_SW_GET_MIRROR,
MV_TPM_IOCTL_SW_GET_MAC_LEARN,
+ MV_TPM_IOCTL_SW_SET_TRUNK_PORT,
+ MV_TPM_IOCTL_SW_SET_TRUNK_MASK,
MV_TPM_IOCTL_SW_PHY_GET_PORT_DUPLEX_MODE,
MV_TPM_IOCTL_SET_MTU_SIZE,
MV_TPM_IOCTL_GET_MTU_SIZE,
@@ -286,9 +294,9 @@
MV_TPM_IOCTL_SET_IGMP_PROXY_SA_MAC,
MV_TPM_IOCTL_GET_IGMP_PROXY_SA_MAC,
- MV_TPM_IOCTL_ADD_IPv6_MC_STREAM,
- MV_TPM_IOCTL_MOD_IPv6_MC_STREAM,
- MV_TPM_IOCTL_DEL_IPv6_MC_STREAM,
+ MV_TPM_IOCTL_ADD_IPv6_MC_STREAM,
+ MV_TPM_IOCTL_MOD_IPv6_MC_STREAM,
+ MV_TPM_IOCTL_DEL_IPv6_MC_STREAM,
MV_TPM_IOCTL_ADD_IPV6_GEN_5T_RULE,
MV_TPM_IOCTL_DEL_IPV6_GEN_5T_RULE,
@@ -306,6 +314,11 @@
MV_TPM_IOCTL_SET_MAC_LEARN_DEFAULT_ACTION,
MV_TPM_IOCTL_TM_SET_GMAC0_INGR_RATE_LIMIT,
MV_TPM_IOCTL_GET_MAC_LEARN_ENTRY_NUM,
+ MV_TPM_IOCTL_ADD_DS_LOAD_BALANCE_RULE,
+ MV_TPM_IOCTL_DEL_DS_LOAD_BALANCE_RULE,
+ MV_TPM_IOCTL_ADD_IPv4_MC_STREAM_SET_QUEUE,
+ MV_TPM_IOCTL_ADD_IPv6_MC_STREAM_SET_QUEUE,
+ MV_TPM_IOCTL_SW_PORT_ADD_VID_SET_EGRESS_MODE,
} tpm_ioctl_cmd_type_t;
@@ -526,6 +539,14 @@
tpm_pkt_action_t pkt_act;
} ctc_cm_acl_rule_t;
+/* DS load balance */
+typedef struct
+{
+ tpm_l2_acl_key_t l2_key;
+ tpm_parse_flags_t parse_flags_bm;
+ tpm_ds_load_balance_tgrt_t tgrt;
+} ds_load_balance_acl_rule_t;
+
/* Pkt modification */
typedef struct
{
@@ -559,6 +580,7 @@
ipv6_l4_ports_5t_rule_t ipv6_l4_ports_5t_rule;
ctc_cm_acl_rule_t ctc_cm_acl_rule;
pkt_mod_rule_t mod_rule;
+ ds_load_balance_acl_rule_t ds_load_balance_acl_rule;
};
} tpm_ioctl_add_acl_rule_t;
@@ -668,6 +690,7 @@
tpm_mc_igmp_mode_t igmp_mode;
uint8_t mc_stream_pppoe;
uint16_t vid;
+ uint16_t dest_queue;
tpm_trg_port_type_t dest_port_bm;
union
@@ -712,6 +735,7 @@
uint32_t mng_cmd;
tpm_ioctl_omci_ch_t tpm_ioctl_omci_ch;
tpm_ioctl_oam_ch_t tpm_ioctl_oam_ch;
+ uint32_t loopback_detect_ety;
} tpm_ioctl_mng_ch_t;
/* Switch Section
@@ -751,6 +775,7 @@
tpm_mru_type_t mtu_type;
uint32_t mtu_size;
uint32_t port_vector;
+ tpm_sw_trunk_t trunk;
} tpm_ioctl_sw_mac_security_t;
/* Switch Vlan filtering */
@@ -864,6 +889,37 @@
tpm_reset_level_enum_t reset_level;
} tpm_ioctl_mib_reset_t;
+/* set active wan port */
+typedef struct
+{
+ uint32_t owner_id;
+ tpm_gmacs_enum_t active_wan;
+} tpm_ioctl_set_active_wan_t;
+
+/* set gmac loopback */
+typedef struct
+{
+ uint32_t owner_id;
+ tpm_gmacs_enum_t gmac;
+ uint8_t enable;
+} tpm_ioctl_set_gmac_loopback_t;
+
+/* hot swap profile */
+typedef struct
+{
+ uint32_t owner_id;
+ tpm_eth_complex_profile_t profile_id;
+} tpm_ioctl_hot_swap_profile_t;
+
+/* set port hwf admin */
+typedef struct
+{
+ uint32_t owner_id;
+ tpm_gmacs_enum_t port;
+ uint8_t txp;
+ uint8_t enable;
+} tpm_ioctl_set_port_hwf_admin_t;
+
/* ALARM Section */
typedef struct
{
@@ -889,7 +945,7 @@
{
tpm_src_port_type_t port;
uint32_t owner_id;
- tpm_swport_pm_3_t tpm_swport_pm_3;
+ tpm_swport_pm_3_all_t tpm_swport_pm_3;
} tpm_ioctl_swport_pm_3_t;
@@ -1017,6 +1073,9 @@
tpm_ioctl_flush_vtu_t tpm_ioctl_flush_vtu;
tpm_ioctl_flush_atu_t tpm_ioctl_flush_atu;
tpm_ioctl_ipv6_parse_window_t tpm_ipv6_parse_window;
+ tpm_ioctl_set_active_wan_t tpm_set_active_wan_param;
+ tpm_ioctl_hot_swap_profile_t tpm_hot_swap_profile_param;
+ tpm_ioctl_set_port_hwf_admin_t tpm_set_port_hwf_admin_param;
} tpm_cmd_data_t;
/* this structure is used for passing sysfs request from kernel to userspace
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_self_check.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_self_check.c
index 2f33320..097d2b6 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_self_check.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_self_check.c
@@ -85,7 +85,6 @@
#define TPM_CHECK_DIV_BY_32(x) ((x) >> 5)
#define TPM_CHECK_MOD_32(x) ((x) & 0x1f)
-extern char *tpm_db_api_type_str[TPM_MAX_API_TYPES];
extern char *opCodeOperationStr[30];
/*******************************************************************************
@@ -872,6 +871,7 @@
tpm_mc_filter_mode_t filter_mode;
uint8_t mc_stream_pppoe, ignore_ipv4_src, ipv4_src_add[4], ipv4_dst_add[4];
uint16_t mc_vid;
+ uint16_t dest_queue;
uint32_t stream_num, igmp_mode, dest_port_bm;
int32_t tpm_ret = 0;
@@ -893,6 +893,7 @@
mc_vid = tpm_rule->ipv4_mc_key.vid;
ignore_ipv4_src = tpm_rule->ipv4_mc_key.ignore_ipv4_src;
*mod_entry = mod_con->mod_cmd_ind;
+ dest_queue = tpm_rule->ipv4_mc_key.dest_queue;
/*******************generate PnC Rule Start********************/
/*generate tcam entry*/
@@ -906,11 +907,13 @@
&(pnc_data->pncl_tcam));
IF_ERROR(tpm_ret);
/* Build SRAM Entry */
- tpm_ret = tpm_proc_ipv4_mc_sram_build(filter_mode,
+ tpm_ret = tpm_proc_ipvx_mc_sram_build(filter_mode,
igmp_mode,
+ dest_queue,
dest_port_bm,
mod_con->mod_cmd_ind,
- &(pnc_data->pncl_sram));
+ &(pnc_data->pncl_sram),
+ TPM_IP_VER_4 );
IF_ERROR(tpm_ret);
return TPM_OK;
@@ -1206,6 +1209,7 @@
uint8_t ipv6_dst_add[16];
int32_t tpm_ret = 0;
uint8_t sip_index = 0;
+ uint16_t dest_queue;
/*params check*/
tpm_ret = tpm_check_param_check(pon_type, tpm_rule, mod_con, api_ent_mem_area, pnc_data, mod_entry,
@@ -1223,6 +1227,7 @@
rule_action->pkt_act = 0;
mc_vid = tpm_rule->ipv6_mc_key.vid;
*mod_entry = mod_con->mod_cmd_ind;
+ dest_queue = tpm_rule->ipv6_mc_key.dest_queue;
/* get sip_index */
if (0 == ipv6_mc_stream_entry.ignore_src_addr) {
@@ -1246,11 +1251,13 @@
&(pnc_data->pncl_tcam));
IF_ERROR(tpm_ret);
/*generate sram*/
- tpm_ret = tpm_proc_ipv6_mc_sram_build(filter_mode,
+ tpm_ret = tpm_proc_ipvx_mc_sram_build(filter_mode,
igmp_mode,
+ dest_queue,
dest_port_bm,
mod_con->mod_cmd_ind,
- &(pnc_data->pncl_sram));
+ &(pnc_data->pncl_sram),
+ TPM_IP_VER_6);
IF_ERROR(tpm_ret);
return TPM_OK;
@@ -1659,10 +1666,10 @@
if (tpm_check_main_chain_type(trg_gmac, pkt_mod_bm, int_mod_bm, *mod_entry,
&main_chain_check)) {
printk("(Warn) main chain type check failed, API: %s, PnC index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
} else if (main_chain_check) {
printk("main chain type mismatch, API: %s, PnC index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
}
/*clear structure*/
@@ -1681,11 +1688,11 @@
if (tpm_pmt_check(trg_gmac, &pattern_data, &pmt_check_result,
TPM_CHECK_WITH_DB)) {
printk("SW PMT check error, API type: %s, PnC rule index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
} else if (pmt_check_result) {
*pmt_sw_error_count = *pmt_sw_error_count + 1;
printk("SW PMT mismatch, API type: %s, PnC rule index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
}
/*clear structure*/
memset(&pattern_data, 0, sizeof(tpm_mod_pattern_data_t));
@@ -1703,11 +1710,11 @@
if (tpm_pmt_check(trg_gmac, &pattern_data, &pmt_check_result,
TPM_CHECK_WITH_HW)) {
printk("HW PMT check error, API type: %s, PnC rule index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
} else if (pmt_check_result) {
*pmt_hw_error_count = *pmt_hw_error_count + 1;
printk("HW PMT mismatch, API type: %s, PnC rule index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
}
return TPM_OK;
@@ -1785,7 +1792,7 @@
/* Get the api_section */
tpm_ret = tpm_db_api_section_get_from_api_type(api_type, &api_section);
if (tpm_ret != TPM_RC_OK) {
- printk("Get API_SECTION Failed-%s\n", tpm_db_api_type_str[api_type]);
+ printk("Get API_SECTION Failed-%s\n", api_type_to_str(api_type));
continue;
}
@@ -1842,7 +1849,7 @@
&rule_action);
if (tpm_ret) {
printk("API type: %s, the %d th PnC Rule Rebuild Failed\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
unnormal_end_count++;
break;
}
@@ -1873,7 +1880,7 @@
tpm_check_update_sram(&shadow_pnc.sram_entry, &rule_action);
if (memcmp(&pnc_out, &read_pnc, sizeof(tpm_pnc_all_t))) {
printk("HW PNC mismatch, API type: %s, PnC rule index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
pnc_mismatch_info_show(&pnc_out, &read_pnc);
pnc_hw_error_count++;
/*correct the bad tpm rule, TODO done in future*/
@@ -1881,7 +1888,7 @@
}
if (memcmp(&pnc_out, &shadow_pnc, sizeof(tpm_pnc_all_t))) {
printk("SW PNC mismatch, API type: %s, PnC rule index %d\n",
- tpm_db_api_type_str[api_type], rule_index);
+ api_type_to_str(api_type), rule_index);
pnc_mismatch_info_show(&pnc_out, &shadow_pnc);
pnc_sw_error_count++;
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.c
index 5a0ea1e..6771c68 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.c
@@ -116,6 +116,7 @@
off += sprintf(buf+off, "cat help_l3_rule_add - show add L3 rule help\n");
off += sprintf(buf+off, "cat help_mc_ipvx_stream_add - show add multicast IPV4 stream help\n");
off += sprintf(buf+off, "cat help_mib_reset - show MIB reset help\n");
+ off += sprintf(buf+off, "cat help_set_active_wan - show set active wan help\n");
off += sprintf(buf+off, "cat help_mod_rule_cfg - show mod rule help\n");
off += sprintf(buf+off, "cat help_no_mc_stream_add - show delete multicast stream help\n");
off += sprintf(buf+off, "cat help_no_oam_omci_channel - show delete OAM/OMCI channel help\n");
@@ -161,7 +162,7 @@
off += sprintf(buf+off, "\t\tTPM_TRG_UNI_5 %#.5X TPM_TRG_UNI_6 %#.5X\n",TPM_TRG_UNI_5, TPM_TRG_UNI_6);
off += sprintf(buf+off, "\t\tTPM_TRG_UNI_7 %#.5X TPM_TRG_UNI_VIRT %#.5X\n",TPM_TRG_UNI_7, TPM_TRG_UNI_VIRT);
off += sprintf(buf+off, "\t\tTPM_TRG_PORT_CPU %#.5X TPM_TRG_PORT_UNI_ANY %#.5X\n",TPM_TRG_PORT_CPU, TPM_TRG_PORT_UNI_ANY);
- off += sprintf(buf+off, "\t\tTPM_TRG_PORT_UNI_CPU_LOOP %#.5X\n", TPM_TRG_PORT_UNI_CPU_LOOP);
+ off += sprintf(buf+off, "\t\tTPM_TRG_PORT_UNI_CPU_LOOP %#.5X TPM_TRG_LOAD_BAL %#.5X\n",TPM_TRG_PORT_UNI_CPU_LOOP, TPM_TRG_LOAD_BAL);
off += sprintf(buf+off, "\tqueue (dec)Queue number\n");
off += sprintf(buf+off, "\tgem_port (dec)GEM port\n");
@@ -459,6 +460,44 @@
/*******************************************************************************
**
+** sfs_help_ds_load_balance_rule - see header of sfs_tpm_cfg_index
+**
+*******************************************************************************/
+int sfs_help_ds_load_balance_rule(char* buf)
+{
+ int off = 0;
+
+ off += sprintf(buf+off, "echo [owner_id] [rule_num] [parse_rule_bm] [parse_flags_bm] [key_name] [target] > add_ds_load_balance\n");
+ off += sprintf(buf+off, "Creates a new ds load balance ACL\n");
+
+ off += sprintf(buf+off, "\towner_id (dec)Application owner ID\n");
+ off += sprintf(buf+off, "\trule_num (dec)Entry number to be added to the current ACL\n");
+ off += sprintf(buf+off, "\tparse_rule_bm (hex)Bitmap containing the significant flags for parsing fields of the packet:\n");
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_MAC_DA %#.4X\n", TPM_L2_PARSE_MAC_DA);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_MAC_SA %#.4X\n", TPM_L2_PARSE_MAC_SA);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_ONE_VLAN_TAG %#.4X\n", TPM_L2_PARSE_ONE_VLAN_TAG);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_TWO_VLAN_TAG %#.4X\n", TPM_L2_PARSE_TWO_VLAN_TAG);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_ETYPE %#.4X\n", TPM_L2_PARSE_ETYPE);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_PPPOE_SES %#.4X\n", TPM_L2_PARSE_PPPOE_SES);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_PPP_PROT %#.4X\n", TPM_L2_PARSE_PPP_PROT);
+ off += sprintf(buf+off, "\t\tTPM_L2_PARSE_GEMPORT %#.4X\n", TPM_L2_PARSE_GEMPORT);
+ off += sprintf(buf+off, "\tparse_flags_bm (hex)Bitmap containing the significant flags result of the primary ACL filtering\n");
+ off += sprintf(buf+off, "\t\tTPM_PARSE_FLAG_TAG1_TRUE %#.4X\n", TPM_PARSE_FLAG_TAG1_TRUE);
+ off += sprintf(buf+off, "\t\tTPM_PARSE_FLAG_TAG1_FALSE %#.4X\n", TPM_PARSE_FLAG_TAG1_FALSE);
+ off += sprintf(buf+off, "\t\tTPM_PARSE_FLAG_TAG2_TRUE %#.4X\n", TPM_PARSE_FLAG_TAG2_TRUE);
+ off += sprintf(buf+off, "\t\tTPM_PARSE_FLAG_TAG2_FALSE %#.4X\n", TPM_PARSE_FLAG_TAG2_FALSE);
+ off += sprintf(buf+off, "\tkey_name (str)Name of L2 key data which has been defined by user [or l2_key_empty]\n");
+ off += sprintf(buf+off, "\ttarget (dec)0 for GMAC0, 1 for GMAC1, 2 for CPU\n");
+
+ off += sprintf(buf+off, "\n\necho [owner_id] [rule_idx] > del_ds_load_balance - delete a DS load balance ACL\n");
+ off += sprintf(buf+off, "\towner_id (dec)Application owner ID\n");
+ off += sprintf(buf+off, "\trule_idx (dec)Rule Id returned from the create call\n");
+
+ return(off);
+}
+
+/*******************************************************************************
+**
** sfs_help_l2_rule_add - see header of sfs_tpm_cfg_index
**
*******************************************************************************/
@@ -499,7 +538,7 @@
off += sprintf(buf+off, "\t\tTPM_ACTION_MTM %#.4X\n", TPM_ACTION_MTM);
off += sprintf(buf+off, "\t\tTPM_ACTION_CUST_CPU_PKT_PARSE %#.4X\n", TPM_ACTION_CUST_CPU_PKT_PARSE);
off += sprintf(buf+off, "\t\tTPM_ACTION_SPEC_MC_VID %#.4X\n", TPM_ACTION_SPEC_MC_VID);
- off += sprintf(buf+off, "\tnext_phase (str)Parse stage (l2/l3/ipv4/ipv6_gen/ipv6_dip/ipv6_nh/ipv6_l4/done)\n");
+ off += sprintf(buf+off, "\tnext_phase (str)Parse stage (l3/done)\n");
off += sprintf(buf+off, "\tkey_name (str)Name of L2 key data which has been defined by user [or l2_key_empty]\n");
off += sprintf(buf+off, "\tfrwd_name (str)Name of pkt forwarding data which has been defined by user [or frwd_empty]\n");
off += sprintf(buf+off, "\tmod_name (str)Name of pkt modification data which has been defined by user [or mod_empty]\n");
@@ -560,7 +599,7 @@
off += sprintf(buf+off, "\t\tTPM_ACTION_SET_PKT_MOD %#.2X\n", TPM_ACTION_SET_PKT_MOD);
off += sprintf(buf+off, "\t\tTPM_ACTION_TO_CPU %#.2X\n", TPM_ACTION_TO_CPU);
off += sprintf(buf+off, "\t\tTPM_ACTION_CUST_CPU_PKT_PARSE %#.2X\n", TPM_ACTION_CUST_CPU_PKT_PARSE);
- off += sprintf(buf+off, "\tnext_phase (str)Parse stage (l2/l3/ipv4/ipv6_gen/ipv6_dip/ipv6_nh/ipv6_l4/ctc_cm/done)\n");
+ off += sprintf(buf+off, "\tnext_phase (str)Parse stage (ipv4/ipv6_gen/ipv6_nh/ctc_cm/done)\n");
off += sprintf(buf+off, "\tfrwd_name (str)Name of pkt forwarding data which has been defined by user [or frwd_empty]\n");
off += sprintf(buf+off, "\tkey_name (str)Name of L3 key data which has been defined by user [or l3_key_empty]\n");
@@ -604,7 +643,7 @@
off += sprintf(buf+off, "\t\tTPM_ACTION_TO_CPU %#.4X\n", TPM_ACTION_TO_CPU);
off += sprintf(buf+off, "\t\tTPM_ACTION_CUST_CPU_PKT_PARSE %#.4X\n", TPM_ACTION_CUST_CPU_PKT_PARSE);
off += sprintf(buf+off, "\t\tTPM_ACTION_UDP_CHKSUM_CALC %#.4X\n", TPM_ACTION_UDP_CHKSUM_CALC);
- off += sprintf(buf+off, "\tnext_phase (str)Parse stage (l2/l3/ipv4/ipv6_gen/ipv6_dip/ipv6_nh/ipv6_l4/ctc_cm/done)\n");
+ off += sprintf(buf+off, "\tnext_phase (str)Parse stage (ctc_cm/done)\n");
off += sprintf(buf+off, "\tmod_bm (hex)Packet fields modification command bitmap:\n");
off += sprintf(buf+off, "\t\tTPM_VLAN_MOD %#.4X\n", TPM_VLAN_MOD);
off += sprintf(buf+off, "\t\tThis is the only packet modification supported in this version. \n");
@@ -652,7 +691,7 @@
off += sprintf(buf+off, "\t\tTPM_ACTION_TO_CPU %#.2X\n", TPM_ACTION_TO_CPU);
off += sprintf(buf+off, "\t\tTPM_ACTION_CUST_CPU_PKT_PARSE %#.2X\n", TPM_ACTION_CUST_CPU_PKT_PARSE);
- off += sprintf(buf+off, "\tnext_phase (str)Parse stage (l2/l3/ipv4/ipv6_gen/ipv6_dip/ipv6_nh/ipv6_l4/done)\n");
+ off += sprintf(buf+off, "\tnext_phase (str)Parse stage (ipv6_dip/done)\n");
off += sprintf(buf+off, "\tmod_bm (hex)Packet fields modification command bitmap:\n");
off += sprintf(buf+off, "\t\tTPM_VLAN_MOD %#.4X\n", TPM_VLAN_MOD);
@@ -726,23 +765,6 @@
off += sprintf(buf+off, "\tdst_ip Destination IP address\n");
off += sprintf(buf+off, "\tignore (str)true/false. When true, the source IP address is not part of the key\n");
off += sprintf(buf+off, "\ttarget_ports (hex)Bitmap of port targets \n");
- off += sprintf(buf+off, "\t\tTPM_TRG_PORT_WAN %#.4X\n", TPM_TRG_PORT_WAN);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_0 %#.4X\n", TPM_TRG_TCONT_0);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_1 %#.4X\n", TPM_TRG_TCONT_1);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_2 %#.4X\n", TPM_TRG_TCONT_2);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_3 %#.4X\n", TPM_TRG_TCONT_3);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_4 %#.4X\n", TPM_TRG_TCONT_4);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_5 %#.4X\n", TPM_TRG_TCONT_5);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_6 %#.4X\n", TPM_TRG_TCONT_6);
- off += sprintf(buf+off, "\t\tTPM_TRG_TCONT_7 %#.4X\n", TPM_TRG_TCONT_7);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_0 %#.4X\n", TPM_TRG_LLID_0);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_1 %#.4X\n", TPM_TRG_LLID_1);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_2 %#.4X\n", TPM_TRG_LLID_2);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_3 %#.4X\n", TPM_TRG_LLID_3);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_4 %#.4X\n", TPM_TRG_LLID_4);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_5 %#.4X\n", TPM_TRG_LLID_5);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_6 %#.4X\n", TPM_TRG_LLID_6);
- off += sprintf(buf+off, "\t\tTPM_TRG_LLID_7 %#.4X\n", TPM_TRG_LLID_7);
off += sprintf(buf+off, "\t\tTPM_TRG_UNI_0 %#.5X\n", TPM_TRG_UNI_0);
off += sprintf(buf+off, "\t\tTPM_TRG_UNI_1 %#.5X\n", TPM_TRG_UNI_1);
off += sprintf(buf+off, "\t\tTPM_TRG_UNI_2 %#.5X\n", TPM_TRG_UNI_2);
@@ -754,7 +776,6 @@
off += sprintf(buf+off, "\t\tTPM_TRG_UNI_VIRT %#.5X\n", TPM_TRG_UNI_VIRT);
off += sprintf(buf+off, "\t\tTPM_TRG_PORT_CPU %#.5X\n", TPM_TRG_PORT_CPU);
off += sprintf(buf+off, "\t\tTPM_TRG_PORT_UNI_ANY %#.5X\n", TPM_TRG_PORT_UNI_ANY);
- off += sprintf(buf+off, "\t\tTPM_TRG_PORT_UNI_CPU_LOOP %#.5X\n", TPM_TRG_PORT_UNI_CPU_LOOP);
off += sprintf(buf+off, "\n\tIPV4 address: dst_ip 224.x.y.z - 239.x.y.z. Source address w.x.y.z. Each part is decimal value in range 0..255.\n");
off += sprintf(buf+off, "\n\n");
@@ -763,9 +784,20 @@
off += sprintf(buf+off, "\tstream (dec)Stream number\n");
off += sprintf(buf+off, "\ttarget_ports (hex)Bitmap of port targets - SEE ABOVE\n");
+ off += sprintf(buf+off, "\n\n");
+ off += sprintf(buf+off, "echo [owner_id] [stream] [igmp_mode] [mc_stream_pppoe] [vid] [src_ip] [dst_ip] [ignore] [target_queue] [target_ports] > mc_ipv4_stream_set_queue_add\n");
+ off += sprintf(buf+off, "\tdest_queue (dec)destination queue number\n");
+ off += sprintf(buf+off, "Creates a new multicast stream with specified dest queue number\n");
+
off += sprintf(buf+off, "\nIPV6: echo [owner_id] [stream] [igmp_mode] [mc_stream_pppoe] [vid] [src_ip] [dst_ip] [ignore] [target_ports] > mc_ipv6_stream_add\n");
off += sprintf(buf+off, "Creates a new multicast stream, params refer to IPv4 MC stream add interface, except dst_ip.\n");
off += sprintf(buf+off, "\tIPV6 address: ff00:aabb:bbcc:ccdd:ddee:eeff:1111:2222. Each part is Hex value in range 0..ffff.\n");
+
+ off += sprintf(buf+off, "\n\n");
+ off += sprintf(buf+off, "echo [owner_id] [stream] [igmp_mode] [mc_stream_pppoe] [vid] [src_ip] [dst_ip] [ignore] [target_queue] [target_ports] > mc_ipv6_stream_set_queue_add\n");
+ off += sprintf(buf+off, "\tdest_queue (dec)destination queue number\n");
+ off += sprintf(buf+off, "Creates a new multicast stream with specified dest queue number\n");
+
off += sprintf(buf+off, "\n\n");
off += sprintf(buf+off, "echo [owner_id] [stream] [target_ports] > mc_ipv6_stream_update\n");
off += sprintf(buf+off, "\towner_id (dec)Application owner ID\n");
@@ -951,6 +983,56 @@
return(off);
}
+/*******************************************************************************
+**
+** sfs_help_set_active_wan - see header of sfs_tpm_cfg_index
+**
+*******************************************************************************/
+int sfs_help_set_active_wan(char* buf)
+{
+ int off = 0;
+
+ off += sprintf(buf+off, "echo [owner_id] [active_wan] > set_active_wan\n");
+ off += sprintf(buf+off, "\t[owner_id] (dec)Application owner ID\n");
+ off += sprintf(buf+off, "\t[active_wan] (dec)GMAC0: 0; GMAC1: 1; PON: 2\n");
+
+ return(off);
+}
+/*******************************************************************************
+**
+** sfs_help_hot_swap_profile - see header of sfs_tpm_cfg_index
+**
+*******************************************************************************/
+int sfs_help_hot_swap_profile(char* buf)
+{
+ int off = 0;
+
+ off += sprintf(buf+off, "echo [owner_id] [profile_id] > hot_swap_profile\n");
+ off += sprintf(buf+off, "before hot swap profile, eth0, eth1 and pon0 must be taken down by ifconfig command; and be bring up after\n");
+ off += sprintf(buf+off, "\t[owner_id] (dec)Application owner ID\n");
+ off += sprintf(buf+off, "\t[profile_id] (dec)TPM_G0_WAN_G1_INT_SWITCH: %d; TPM_G1_WAN_G0_INT_SWITCH: %d\n",
+ TPM_G0_WAN_G1_INT_SWITCH, TPM_G1_WAN_G0_INT_SWITCH);
+
+ return(off);
+}
+/*******************************************************************************
+**
+** sfs_help_set_port_hwf_admin - see header of sfs_tpm_cfg_index
+**
+*******************************************************************************/
+int sfs_help_set_port_hwf_admin(char* buf)
+{
+ int off = 0;
+
+ off += sprintf(buf+off, "echo [owner_id] [port] [txp] [enable] > set_port_hwf_admin\n");
+ off += sprintf(buf+off, "disable/enable HWF to port\n");
+ off += sprintf(buf+off, "\t[owner_id] (dec)Application owner ID\n");
+ off += sprintf(buf+off, "\t[port] (dec)GMAC0: 0; GMAC1: 1; PON: 2\n");
+ off += sprintf(buf+off, "\t[txp] (dec)T-CONT or LLID, for GMAC0/1 it should be 0\n");
+ off += sprintf(buf+off, "\t[enable] (dec)disable: 0; enable: 1\n");
+
+ return(off);
+}
/*******************************************************************************
**
@@ -1268,7 +1350,7 @@
off += sprintf(buf+off, "\t\tTPM_ACTION_TO_CPU %#.2X\n", TPM_ACTION_TO_CPU);
off += sprintf(buf+off, "\t\tTPM_ACTION_CUST_CPU_PKT_PARSE %#.2X\n", TPM_ACTION_CUST_CPU_PKT_PARSE);
- off += sprintf(buf+off, "\tnext_phase (str)Parse stage (l2/l3/ipv4/ipv6_gen/ipv6_dip/ipv6_nh/ipv6_l4/done)\n");
+ off += sprintf(buf+off, "\tnext_phase (str)Parse stage (done)\n");
off += sprintf(buf+off, "\tmod_bm (hex)Packet fields modification command bitmap:\n");
off += sprintf(buf+off, "\t\tTPM_VLAN_MOD %#.4X\n", TPM_VLAN_MOD);
@@ -1360,7 +1442,7 @@
off += sprintf(buf+off, "\t\tTPM_ACTION_SET_PKT_MOD %#.2X\n", TPM_ACTION_SET_PKT_MOD);
off += sprintf(buf+off, "\t\tTPM_ACTION_TO_CPU %#.2X\n", TPM_ACTION_TO_CPU);
off += sprintf(buf+off, "\t\tTPM_ACTION_CUST_CPU_PKT_PARSE %#.2X\n", TPM_ACTION_CUST_CPU_PKT_PARSE);
- off += sprintf(buf+off, "\tnext_phase (str)Parse stage (ipv6_gen/ipv6_dip/ctc_cm/done)\n");
+ off += sprintf(buf+off, "\tnext_phase (str)Parse stage (ipv6_gen/ctc_cm/done)\n");
off += sprintf(buf+off, "\tl4_src_port (dec)L4 source port\n");
off += sprintf(buf+off, "\tl4_dst_port (dec)L4 destination port\n");
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.h
index 6bac650..15de3bb 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_help.h
@@ -97,6 +97,7 @@
extern int sfs_help_ipv6_dip_key_cfg (char *buf);
extern int sfs_help_ipv6_l4_key_cfg (char *buf);
extern int sfs_help_ipv6_ctc_cm_key_cfg (char *buf);
+extern int sfs_help_ds_load_balance_rule (char* buf);
extern int sfs_help_key_rule_delete (char *buf);
extern int sfs_help_l2_rule_add (char *buf);
extern int sfs_help_l3_rule_add (char *buf);
@@ -111,6 +112,9 @@
extern int sfs_help_no_oam_omci_channel (char *buf);
extern int sfs_help_setup (char *buf);
extern int sfs_help_mib_reset (char *buf);
+extern int sfs_help_set_active_wan (char *buf);
+extern int sfs_help_hot_swap_profile (char* buf);
+extern int sfs_help_set_port_hwf_admin(char* buf);
extern int sfs_help_cfg_cpu_lpbk (char *buf);
extern int sfs_help_cfg_age_count (char *buf);
extern int sfs_help_rate_limit (char *buf);
@@ -170,6 +174,9 @@
#define sfs_help_no_oam_omci_channel NULL
#define sfs_help_setup NULL
#define sfs_help_mib_reset NULL
+#define sfs_help_set_active_wan NULL
+#define sfs_help_hot_swap_profile NULL
+#define sfs_help_set_port_hwf_admin NULL
#define sfs_help_erase_section NULL
#define sfs_help_cfg_cpu_lpbk NULL
#define sfs_help_cfg_age_count NULL
@@ -193,6 +200,7 @@
#define sfs_help_flush_atu NULL
#define sfs_help_mac_learn_rule_add NULL
#define sfs_help_mac_learn_def_act_set NULL
+#define sfs_help_ds_load_balance_rule NULL
#endif /* CONFIG_MV_TPM_SYSFS_HELP */
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.c
index 702bba6..0fa55b6 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.c
@@ -708,6 +708,287 @@
}
}
+
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_add_ipv4_mc_stream_set_queue_bounce(
+ uint32_t owner_id,
+ uint32_t stream_num,
+ tpm_mc_igmp_mode_t igmp_mode,
+ uint8_t mc_stream_pppoe,
+ uint16_t vid,
+ uint8_t ipv4_src_add[4],
+ uint8_t ipv4_dst_add[4],
+ uint8_t ignore_ipv4_src,
+ uint16_t dest_queue,
+ tpm_trg_port_type_t dest_port_bm)
+{
+ tpm_ioctl_mc_rule_t *tpm_mc_rule = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_mc_rule;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_MC_STREAM_SECTION;
+ tpm_mc_rule->mc_cmd = MV_TPM_IOCTL_ADD_IPv4_MC_STREAM_SET_QUEUE;
+ tpm_mc_rule->stream_num = stream_num;
+ tpm_mc_rule->igmp_mode = igmp_mode;
+ tpm_mc_rule->mc_stream_pppoe = mc_stream_pppoe;
+ tpm_mc_rule->vid = vid;
+ tpm_mc_rule->ipv4_mc.ignore_ipv4_src = ignore_ipv4_src;
+ tpm_mc_rule->dest_queue = dest_queue;
+ tpm_mc_rule->dest_port_bm = dest_port_bm;
+ memcpy(&(tpm_mc_rule->ipv4_mc.ipv4_src_add[0]), ipv4_src_add, sizeof(uint8_t)*4);
+ memcpy(&(tpm_mc_rule->ipv4_mc.ipv4_dst_add[0]), ipv4_dst_add, sizeof(uint8_t)*4);
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_add_ipv4_mc_stream_set_queue tpm_add_ipv4_mc_stream_set_queue_bounce
+#else
+ #define _tpm_add_ipv4_mc_stream_set_queue tpm_add_ipv4_mc_stream_set_queue
+#endif
+
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_mc_ipv4_stream_set_queue_add
+*
+* DESCRIPTION:
+* This function creates a multicast IPV4 rule
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_set_mc_ipv4_stream_set_queue_add (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ mcipv4add_owner=0, mcipv4add_stream, mcipv4add_mode, mcipv4add_pppoe, mcipv4add_vid,
+ mcipv4add_src_ip, mcipv4add_dst_ip, mcipv4add_ignore, mcipv4add_target_ports, mcipv4add_target_queue,
+ mcipv4add_max
+ } mcipv4add_parm_indx_t;
+ // shell line parsing
+ unsigned int ownerid;
+ uint32_t stream;
+ uint32_t mode;
+ char mc_pppoe_str[20];
+ uint32_t mc_stream_pppoe;
+ uint32_t vid;
+ char srcip_str[30];
+ char dstip_str[30];
+ uint32_t temp_srcip[4];
+ uint32_t temp_dstip[4];
+ uint8_t srcip[4];
+ uint8_t dstip[4];
+ char ignore_str[20];
+ uint32_t ignore;
+ uint32_t target_queue;
+ uint32_t target_ports;
+ int parsedargs;
+ int numparms;
+ // Used in API call
+ tpm_error_code_t rc;
+
+ numparms = count_parameters(buf);
+ if (numparms != mcipv4add_max)
+ {
+ parm_error_completion(numparms, mcipv4add_max, buf, sfs_help_mc_ipvx_stream_add);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d %d %s %d %s %s %s %d 0x%x",
+ &ownerid, &stream, &mode, mc_pppoe_str, &vid, srcip_str, dstip_str, ignore_str, &target_queue, &target_ports);
+// printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], stream[%d], vid[%d], srcip_str[%s], dstip_str[%s], ignore_str[%s], target_ports[0x%x]\n",
+// len, parsedargs, ownerid, stream, vid, srcip_str, dstip_str, ignore_str, target_ports);
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else if (get_bool_value(mc_pppoe_str, &mc_stream_pppoe) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid ignore[%s]\n", ignore_str);
+ }
+ else if (parse_ipv4_address(srcip_str, temp_srcip) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid src_ip [%s]\n", srcip_str);
+ }
+ else if (parse_ipv4_address(dstip_str, temp_dstip) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid dst_ip [%s]\n", dstip_str);
+ }
+ else if (get_bool_value(ignore_str, &ignore) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid ignore[%s]\n", ignore_str);
+ }
+ else
+ {
+ int indx;
+
+ for (indx = 0; indx < sizeof(srcip); indx++)
+ {
+ srcip[indx] = (uint8_t)temp_srcip[indx];
+ dstip[indx] = (uint8_t)temp_dstip[indx];
+ }
+
+ if ((rc = _tpm_add_ipv4_mc_stream_set_queue(ownerid,
+ stream,
+ mode,
+ (uint8_t)mc_stream_pppoe,
+ vid,
+ srcip,
+ dstip,
+ (uint8_t)ignore,
+ target_queue,
+ target_ports)) == TPM_RC_OK)
+ {
+ printk(KERN_INFO "OK\n");
+ }
+ else
+ {
+ printk(KERN_INFO "%s: tpm_add_ipv4_mc_stream_set_queue failed, rc[%d] - %s\n", __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_add_ipv6_mc_stream_set_queue_bounce(uint32_t owner_id,
+ uint32_t stream_num,
+ tpm_mc_igmp_mode_t igmp_mode,
+ uint8_t mc_stream_pppoe,
+ uint16_t vid,
+ uint8_t ipv6_src_add[16],
+ uint8_t ipv6_dst_add[16],
+ uint8_t ignore_ipv6_src,
+ uint16_t dest_queue,
+ tpm_trg_port_type_t dest_port_bm)
+{
+ tpm_ioctl_mc_rule_t *tpm_mc_rule = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_mc_rule;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_MC_STREAM_SECTION;
+ tpm_mc_rule->mc_cmd = MV_TPM_IOCTL_ADD_IPv6_MC_STREAM_SET_QUEUE;
+ tpm_mc_rule->stream_num = stream_num;
+ tpm_mc_rule->igmp_mode = igmp_mode;
+ tpm_mc_rule->mc_stream_pppoe = mc_stream_pppoe;
+ tpm_mc_rule->vid = vid;
+ tpm_mc_rule->dest_port_bm = dest_port_bm;
+ tpm_mc_rule->dest_queue = dest_queue;
+ memcpy(&(tpm_mc_rule->ipv6_mc.ipv6_dst_add[0]), ipv6_dst_add, sizeof(uint8_t) * 16);
+ memcpy(&(tpm_mc_rule->ipv6_mc.ipv6_src_add[0]), ipv6_src_add, sizeof(uint8_t) * 16);
+ tpm_mc_rule->ipv6_mc.ignore_ipv6_src = ignore_ipv6_src;
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_add_ipv6_mc_stream_set_queue tpm_add_ipv6_mc_stream_set_queue_bounce
+#else
+ #define _tpm_add_ipv6_mc_stream_set_queue tpm_add_ipv6_mc_stream_set_queue
+#endif
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_mc_ipv6_stream_add_set_queue
+*
+* DESCRIPTION:
+* This function creates a multicast ipv6 rule with destination queue
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_set_mc_ipv6_stream_set_queue_add (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ mcipv6add_owner=0, mcipv6add_stream, mcipv6add_mode, mcipv6add_pppoe, mcipv6add_vid,
+ mcipv6add_src_ip, mcipv6add_dst_ip, mcipv6add_ignor_src_ip, mcipv6add_target_queue, mcipv6add_target_ports, mcipv6add_max
+ } mcipv6add_parm_indx_t;
+ // shell line parsing
+ unsigned int ownerid;
+ uint32_t stream;
+ uint32_t mode;
+ char mc_pppoe_str[20];
+ uint32_t mc_stream_pppoe;
+ uint32_t vid;
+ char dstip_str[60];
+ uint32_t temp_dstip[16];
+ char srcip_str[60];
+ uint32_t temp_srcip[16];
+ uint8_t dstip[16];
+ uint8_t srcip[16];
+ uint32_t ignor_srcip;
+ char ignore_str[20];
+ uint32_t target_ports;
+ uint32_t target_queue;
+ int parsedargs;
+ int numparms;
+ // Used in API call
+ tpm_error_code_t rc;
+
+ numparms = count_parameters(buf);
+ if (numparms != mcipv6add_max)
+ {
+ parm_error_completion(numparms, mcipv6add_max, buf, sfs_help_mc_ipvx_stream_add);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d %d %s %d %s %s %s %d 0x%x",
+ &ownerid, &stream, &mode, mc_pppoe_str, &vid, srcip_str, dstip_str, ignore_str, &target_queue, &target_ports);
+ printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], stream[%d], vid[%d], srcip_str[%s], "
+ "dstip_str[%s], ignor_srcip[%s], target_queue[%d], target_ports[0x%x]\n",
+ len, parsedargs, ownerid, stream, vid, srcip_str, dstip_str, ignore_str, target_queue, target_ports);
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else if (get_bool_value(mc_pppoe_str, &mc_stream_pppoe) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid mc_pppoe_str[%s]\n", mc_pppoe_str);
+ }
+ else if (parse_ipv6_address(dstip_str, temp_dstip) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid dst_ip [%s]\n", dstip_str);
+ }
+ else if (parse_ipv6_address(srcip_str, temp_srcip) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid srcip_str [%s]\n", srcip_str);
+ }
+ else if (get_bool_value(ignore_str, &ignor_srcip) == GT_FALSE)
+ {
+ printk(KERN_INFO "Invalid ignore[%s]\n", ignore_str);
+ }
+ else
+ {
+ int indx;
+
+ for (indx = 0; indx < sizeof(dstip); indx++)
+ {
+ dstip[indx] = (uint8_t)temp_dstip[indx];
+ srcip[indx] = (uint8_t)temp_srcip[indx];
+ }
+
+ if ((rc = _tpm_add_ipv6_mc_stream_set_queue(ownerid,
+ stream,
+ mode,
+ (uint8_t)mc_stream_pppoe,
+ vid,
+ srcip,
+ dstip,
+ ignor_srcip,
+ target_queue,
+ target_ports)) == TPM_RC_OK)
+ {
+ printk(KERN_INFO "OK\n");
+ }
+ else
+ {
+ printk(KERN_INFO "%s: tpm_add_ipv6_mc_stream_set_queue failed, rc[%d] - %s\n", __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
tpm_error_code_t tpm_add_ipv6_mc_stream_bounce(uint32_t owner_id,
uint32_t stream_num,
@@ -2411,6 +2692,242 @@
}
}
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_set_active_wan_bounce(uint32_t owner_id,
+ tpm_gmacs_enum_t active_wan)
+{
+ tpm_ioctl_set_active_wan_t *tpm_set_active_wan_param = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_set_active_wan_param;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_SET_ACTIVE_WAN_SECTION;
+ tpm_set_active_wan_param->owner_id = owner_id;
+ tpm_set_active_wan_param->active_wan = active_wan;
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_set_active_wan tpm_set_active_wan_bounce
+#else
+ #define _tpm_set_active_wan tpm_set_active_wan
+#endif
+
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_set_active_wan
+*
+* DESCRIPTION:
+* This function sets active wan port
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_set_active_wan (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ activewan_owner=0, activewan_active_wan, activewan_max
+ } activewan_parm_indx_t;
+ // shell line parsing
+ uint32_t ownerid;
+ int parsedargs;
+ int numparms;
+ //Used in API call
+ tpm_error_code_t rc;
+ tpm_gmacs_enum_t active_wan;
+
+ numparms = count_parameters(buf);
+ if (numparms != activewan_max)
+ {
+ parm_error_completion(numparms, activewan_max, buf, sfs_help_set_active_wan);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d", &ownerid, &active_wan);
+// printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], active_wan_int[%d]\n",
+// len, parsedargs, ownerid, active_wan);
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else if (active_wan >= TPM_MAX_NUM_GMACS)
+ {
+ printk(KERN_INFO "Invalid active_wan[%d]\n", active_wan);
+ }
+ else
+ {
+ if ((rc = _tpm_set_active_wan(ownerid,
+ active_wan)) == TPM_RC_OK)
+ {
+ printk(KERN_INFO "OK\n");
+ }
+ else
+ {
+ printk(KERN_INFO "%s: tpm_set_active_wan failed, rc[%d] - %s\n", __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
+
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_hot_swap_profile_bounce(uint32_t owner_id,
+ tpm_eth_complex_profile_t profile_id)
+{
+ tpm_ioctl_hot_swap_profile_t *tpm_hot_swap_profile_param = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_hot_swap_profile_param;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_HOT_SWAP_PROFILE_SECTION;
+ tpm_hot_swap_profile_param->owner_id = owner_id;
+ tpm_hot_swap_profile_param->profile_id = profile_id;
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_hot_swap_profile tpm_hot_swap_profile_bounce
+#else
+ #define _tpm_hot_swap_profile tpm_hot_swap_profile
+#endif
+
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_hot_swap_profile
+*
+* DESCRIPTION:
+* This function swap profile in run time
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_hot_swap_profile (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ hotswap_owner=0, hotswap_profile_id, hotswap_max
+ } hotswap_parm_indx_t;
+ // shell line parsing
+ uint32_t ownerid;
+ int parsedargs;
+ int numparms;
+ //Used in API call
+ tpm_error_code_t rc;
+ uint32_t profile_id;
+
+ numparms = count_parameters(buf);
+ if (numparms != hotswap_max)
+ {
+ parm_error_completion(numparms, hotswap_max, buf, sfs_help_hot_swap_profile);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d", &ownerid, &profile_id);
+// printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], profile_id_int[%d]\n",
+// len, parsedargs, ownerid, profile_id);
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else
+ {
+ if ((rc = _tpm_hot_swap_profile(ownerid,
+ profile_id)) == TPM_RC_OK)
+ {
+ printk(KERN_INFO "OK\n");
+ }
+ else
+ {
+ printk(KERN_INFO "%s: tpm_hot_swap_profile failed, rc[%d] - %s\n", __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_set_port_hwf_admin_bounce(uint32_t owner_id,
+ tpm_gmacs_enum_t port,
+ uint8_t txp,
+ uint8_t enable)
+{
+ tpm_ioctl_set_port_hwf_admin_t *tpm_set_port_hwf_admin_param = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_set_port_hwf_admin_param;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_SET_PORT_HWF_ADMIN_SECTION;
+ tpm_set_port_hwf_admin_param->owner_id = owner_id;
+ tpm_set_port_hwf_admin_param->port = port;
+ tpm_set_port_hwf_admin_param->txp = txp;
+ tpm_set_port_hwf_admin_param->enable = enable;
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_set_port_hwf_admin tpm_set_port_hwf_admin_bounce
+#else
+ #define _tpm_set_port_hwf_admin tpm_proc_hwf_admin_set
+#endif
+
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_set_port_hwf_admin
+*
+* DESCRIPTION:
+* This function set port hwf enable/disable
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_set_port_hwf_admin (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ setporthwfadmin_owner=0, setporthwfadmin_port, setporthwfadmin_txp,
+ setporthwfadmin_enable, setporthwfadmin_max
+ } setporthwfadmin_parm_indx_t;
+ // shell line parsing
+ int parsedargs;
+ int numparms;
+ //Used in API call
+ tpm_error_code_t rc;
+ uint32_t ownerid;
+ tpm_gmacs_enum_t port;
+ uint32_t txp;
+ uint32_t enable;
+
+ numparms = count_parameters(buf);
+ if (numparms != setporthwfadmin_max)
+ {
+ parm_error_completion(numparms, setporthwfadmin_max, buf, sfs_help_set_port_hwf_admin);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d %d %d", &ownerid, &port, &txp, &enable);
+// printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], port[%d], txp[%d], enable[%d]\n",
+// len, parsedargs, ownerid, port, txp, enable);
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else
+ {
+ if ((rc = _tpm_set_port_hwf_admin(port, txp, enable)) == TPM_RC_OK)
+ {
+ printk(KERN_INFO "OK\n");
+ }
+ else
+ {
+ printk(KERN_INFO "%s: tpm_set_port_hwf_admin failed, rc[%d] - %s\n", __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
/*******************************************************************************
* sfs_tpm_cfg_set_erase_section
*
@@ -6376,3 +6893,192 @@
}
}
+
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_add_ds_load_balance_rule_bounce(uint32_t owner_id,
+ uint32_t rule_num,
+ uint32_t *rule_idx,
+ tpm_parse_fields_t parse_rule_bm,
+ tpm_parse_flags_t parse_flags_bm,
+ tpm_l2_acl_key_t *l2_key,
+ tpm_ds_load_balance_tgrt_t tgrt_port)
+{
+ tpm_ioctl_add_acl_rule_t *tpm_add_acl_rule = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_add_acl_rule;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_ADD_ACL_SECTION;
+ tpm_add_acl_rule->add_acl_cmd = MV_TPM_IOCTL_ADD_DS_LOAD_BALANCE_RULE;
+ tpm_add_acl_rule->owner_id = owner_id;
+ tpm_add_acl_rule->rule_num = rule_num;
+ tpm_add_acl_rule->parse_rule_bm = parse_rule_bm;
+ tpm_add_acl_rule->ds_load_balance_acl_rule.parse_flags_bm = parse_flags_bm;
+ tpm_add_acl_rule->ds_load_balance_acl_rule.tgrt = tgrt_port;
+ memcpy(&(tpm_add_acl_rule->ds_load_balance_acl_rule.l2_key), (void*)l2_key, sizeof(tpm_l2_acl_key_t));
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_add_ds_load_balance_rule tpm_add_ds_load_balance_rule_bounce
+#else
+ #define _tpm_add_ds_load_balance_rule tpm_add_ds_load_balance_rule
+#endif
+
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_ds_load_balance_rule_add
+*
+* DESCRIPTION:
+* This function creates a ds_load_balance rule
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_set_ds_load_balance_rule_add (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ ds_load_blnc_ruleadd_owner=0, ds_load_blnc_ruleadd_rulenum,
+ ds_load_blnc_ruleadd_parserulebm, ds_load_blnc_ruleadd_parseflagsbm,
+ ds_load_blnc_ruleadd_l2keyname,
+ ds_load_blnc_ruleadd_trgt, ds_load_blnc_ruleadd_max
+ } ds_load_blnc_ruleadd_parm_indx_t;
+ // shell line parsing
+ uint32_t ownerid;
+ uint32_t rulenum;
+ uint32_t parserulebm;
+ uint32_t parseflagsbm;
+ uint32_t trgt;
+ char l2keyname[20];
+ int parsedargs;
+ int numparms;
+ // DB
+ tpmcfg_l2_key_entry_t *pdbl2keyentry = 0;
+ //Used in API call
+ tpm_l2_acl_key_t l2_acl;
+ uint32_t rule_idx;
+ tpm_error_code_t rc;
+
+ numparms = count_parameters(buf);
+ if (numparms != ds_load_blnc_ruleadd_max)
+ {
+ parm_error_completion(numparms, ds_load_blnc_ruleadd_max, buf, sfs_help_ds_load_balance_rule);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d 0x%x 0x%x %s %d", &ownerid, &rulenum, &parserulebm,
+ &parseflagsbm, l2keyname, &trgt);
+ printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], rulenum[%d], parserulebm[0x%x], parseflagsbm[0x%x], "
+ "l2keyname[%s], trgt[%d]\n",
+ len, parsedargs, ownerid, rulenum, parserulebm, parseflagsbm, l2keyname, trgt);
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else if (((pdbl2keyentry = find_tpm_l2_key_entry_by_name(l2keyname)) == 0) && strcmp(l2keyname, l2_key_empty_name) != 0)
+ {
+ printk(KERN_INFO "L2 key entry [%s] not found\n", l2keyname);
+ }
+ else
+ {
+
+ if (pdbl2keyentry != 0) memcpy(&l2_acl, &pdbl2keyentry->l2_acl, sizeof(tpm_l2_acl_key_t));
+ else memset(&l2_acl, 0, sizeof(tpm_l2_acl_key_t));
+
+ if ((rc = _tpm_add_ds_load_balance_rule(ownerid,
+ rulenum,
+ &rule_idx,
+ parserulebm,
+ parseflagsbm,
+ &l2_acl,
+ trgt)) == TPM_RC_OK)
+ PR_RULE_IDX(rule_idx)
+ else
+ {
+ printk(KERN_INFO "%s: tpm_add_ds_load_balance_rule failed, rc[%d] - %s\n",
+ __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
+#ifdef CONFIG_MV_TPM_SFS_2_IOCTL
+tpm_error_code_t tpm_del_ds_load_balance_rule_bounce(uint32_t owner_id,
+ uint32_t rule_idx)
+{
+ tpm_ioctl_del_acl_rule_t *tpm_del_acl_rule = &tpm_sfs_2_ioctl_command.tpm_cmd_data.tpm_del_acl_rule;
+
+ tpm_sfs_2_ioctl_command.cmd = MV_TPM_IOCTL_DEL_ACL_SECTION;
+ tpm_del_acl_rule->del_acl_cmd = MV_TPM_IOCTL_DEL_DS_LOAD_BALANCE_RULE;
+ tpm_del_acl_rule->owner_id = owner_id;
+ tpm_del_acl_rule->rule_idx = rule_idx;
+
+ up(&tpm_sfs_2_ioctl_sem);
+
+ return TPM_RC_OK;
+}
+ #define _tpm_del_ds_load_balance_rule tpm_del_ds_load_balance_rule_bounce
+#else
+ #define _tpm_del_ds_load_balance_rule tpm_del_ds_load_balance_rule
+#endif
+
+
+/*******************************************************************************
+* sfs_tpm_cfg_set_no_rule_add_ds_load_balance
+*
+* DESCRIPTION:
+* This function deletes a ds_load_balance HW rule (PNC)
+* INPUTS:
+* buf - Shell parameters as char buffer
+* len - Number of characters in buffer
+*
+*******************************************************************************/
+void sfs_tpm_cfg_set_no_rule_add_ds_load_balance (const char *buf, size_t len)
+{
+ typedef enum
+ {
+ noruleadd_owner=0, noruleadd_ruleidx, noruleadd_max
+ } noruleadd_parm_indx_t;
+ // shell line parsing
+ uint32_t ownerid;
+ uint32_t rule_idx;
+ int parsedargs;
+ int numparms;
+ //Used in API call
+ tpm_error_code_t rc;
+
+ numparms = count_parameters(buf);
+ if (numparms != noruleadd_max)
+ {
+ parm_error_completion(numparms, noruleadd_max, buf, sfs_help_no_rule_add);
+ }
+ else
+ {
+ // Get parameters
+ parsedargs = sscanf(buf, "%d %d", &ownerid, &rule_idx);
+ //printk(KERN_INFO "len=%d, parsedargs=%d. ownerid[%d], rule_idx[%d]\n",
+ // len, parsedargs, ownerid, rule_idx);
+
+
+ if (parsedargs != numparms)
+ {
+ printk(KERN_INFO "Parse failure - %d/%d parameters were parsed\n", parsedargs, numparms);
+ }
+ else
+ {
+ if ((rc = _tpm_del_ds_load_balance_rule(ownerid, rule_idx)) == TPM_RC_OK)
+ {
+ printk(KERN_INFO "OK\n");
+ }
+ else
+ {
+ printk(KERN_INFO "%s: tpm_del_ds_load_balance_rule failed, rc[%d] - %s\n",
+ __FUNCTION__, rc, get_tpm_err_str(rc));
+ }
+ }
+ }
+}
+
+
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.h
index 62d755b..74037d7 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_hwcall.h
@@ -88,8 +88,10 @@
extern void sfs_tpm_cfg_set_ipv4_rule_add (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_ipv6_gen_rule_add (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_mc_ipv4_stream_add (const char *buf, size_t len);
+extern void sfs_tpm_cfg_set_mc_ipv4_stream_set_queue_add (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_mc_ipv4_stream_update (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_mc_ipv6_stream_add (const char *buf, size_t len);
+extern void sfs_tpm_cfg_set_mc_ipv6_stream_set_queue_add (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_mc_ipv6_stream_update (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_igmp_port_forward_mode_cfg (const char *buf, size_t len);
@@ -107,6 +109,9 @@
extern void sfs_tpm_cfg_set_no_omci_channel (const char *buf, size_t len);
extern void sfs_tpm_cfg_setup (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_mib_reset (const char *buf, size_t len);
+extern void sfs_tpm_cfg_set_active_wan (const char *buf, size_t len);
+extern void sfs_tpm_cfg_set_port_hwf_admin (const char *buf, size_t len);
+extern void sfs_tpm_cfg_hot_swap_profile (const char *buf, size_t len);
extern void sfs_tpm_cfg_add_cpu_lpbk (const char *buf, size_t len);
extern void sfs_tpm_cfg_del_cpu_lpbk (const char *buf, size_t len);
extern void sfs_tpm_cfg_dump_cpu_lpbk (const char *buf, size_t len);
@@ -166,6 +171,8 @@
extern void sfs_tpm_cfg_set_no_rule_add_mac_learn (const char *buf, size_t len);
extern void sfs_tpm_cfg_set_mac_learn_default_rule_action(const char *buf, size_t len);
extern void sfs_tpm_cfg_set_gmac0_ingr_rate_limit (const char *buf, size_t len);
+extern void sfs_tpm_cfg_set_ds_load_balance_rule_add (const char *buf, size_t len);
+extern void sfs_tpm_cfg_set_no_rule_add_ds_load_balance (const char *buf, size_t len);
/* KostaP */
extern void sfs_tpm_cfg_set_fc(const char *buf, size_t len);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_rule_db.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_rule_db.c
index cdb9456..459cfc0 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_rule_db.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_rule_db.c
@@ -2551,7 +2551,7 @@
else {
if ((pentry = find_tpm_ipv6_l4_ports_key_entry_by_name(name)) == 0)
pentry = find_free_tpm_ipv6_l4_ports_key_entry();
-
+
if (pentry == 0)
printk(KERN_INFO "IPV6 L4 ports key DB full\n");
else {
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_setup.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_setup.c
index c211f34..f466545 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_setup.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_setup.c
@@ -115,9 +115,11 @@
{"ipv4_rule_add", sfs_tpm_cfg_set_ipv4_rule_add},
{"ipv6_gen_rule_add", sfs_tpm_cfg_set_ipv6_gen_rule_add},
{"mc_ipv4_stream_add", sfs_tpm_cfg_set_mc_ipv4_stream_add},
+ {"mc_ipv4_stream_set_queue_add", sfs_tpm_cfg_set_mc_ipv4_stream_set_queue_add},
{"mc_ipv4_stream_update", sfs_tpm_cfg_set_mc_ipv4_stream_update},
- {"mc_ipv6_stream_add", sfs_tpm_cfg_set_mc_ipv6_stream_add},
- {"mc_ipv6_stream_update", sfs_tpm_cfg_set_mc_ipv6_stream_update},
+ {"mc_ipv6_stream_add", sfs_tpm_cfg_set_mc_ipv6_stream_add},
+ {"mc_ipv6_stream_set_queue_add", sfs_tpm_cfg_set_mc_ipv6_stream_set_queue_add},
+ {"mc_ipv6_stream_update", sfs_tpm_cfg_set_mc_ipv6_stream_update},
{"igmp_port_forward_mode_cfg", sfs_tpm_cfg_set_igmp_port_forward_mode_cfg},
{"mc_vid_key_reset", sfs_tpm_cfg_set_mc_vid_key_reset},
{"mc_vid_key_set", sfs_tpm_cfg_set_mc_vid_key_set},
@@ -135,6 +137,9 @@
{"no_omci_channel", sfs_tpm_cfg_set_no_omci_channel},
{"tpm_setup", sfs_tpm_cfg_setup},
{"mib_reset", sfs_tpm_cfg_set_mib_reset},
+ {"set_active_wan", sfs_tpm_cfg_set_active_wan},
+ {"hot_swap_profile", sfs_tpm_cfg_hot_swap_profile},
+ {"set_port_hwf_admin", sfs_tpm_cfg_set_port_hwf_admin},
{"erase_section", sfs_tpm_cfg_set_erase_section},
{"add_cpu_lpbk", sfs_tpm_cfg_add_cpu_lpbk},
{"del_cpu_lpbk", sfs_tpm_cfg_del_cpu_lpbk},
@@ -176,6 +181,8 @@
{"no_rule_add_ipv6_dip_5t", sfs_tpm_cfg_set_no_rule_add_ipv6_dip_5t},
{"ipv6_l4_ports_5t_rule_add", sfs_tpm_cfg_set_ipv6_l4_ports_5t_rule_add},
{"no_rule_add_ipv6_l4_ports_5t", sfs_tpm_cfg_set_no_rule_add_ipv6_l4_ports_5t},
+ {"add_ds_load_balance", sfs_tpm_cfg_set_ds_load_balance_rule_add},
+ {"del_ds_load_balance", sfs_tpm_cfg_set_no_rule_add_ds_load_balance},
// zeev
{"ipv6_nh_acl_rule_add", sfs_tpm_cfg_set_ipv6_nh_acl_rule_add},
@@ -280,7 +287,11 @@
{"help_no_oam_omci_channel", sfs_help_no_oam_omci_channel},
{"help_tpm_setup", sfs_help_setup},
{"help_mib_reset", sfs_help_mib_reset},
+ {"help_set_active_wan", sfs_help_set_active_wan},
+ {"help_hot_swap_profile", sfs_help_hot_swap_profile},
+ {"help_set_port_hwf_admin", sfs_help_set_port_hwf_admin},
{"help_cfg_cpu_lpbk", sfs_help_cfg_cpu_lpbk},
+ {"help_ds_load_balance_rule", sfs_help_ds_load_balance_rule},
{"help_cfg_age_count", sfs_help_cfg_age_count},
{"help_rate_limit", sfs_help_rate_limit},
{"help_pkt_mod_add", sfs_help_pkt_mod_add},
@@ -391,7 +402,11 @@
static DEVICE_ATTR(help_no_oam_omci_channel, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(help_tpm_setup, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(help_mib_reset, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(help_set_active_wan, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(help_hot_swap_profile, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(help_set_port_hwf_admin, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(help_cfg_cpu_lpbk, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(help_ds_load_balance_rule, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(help_cfg_age_count, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(help_rate_limit, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(help_pkt_mod_add, S_IRUSR, tpm_cfg_show, tpm_cfg_store);
@@ -460,8 +475,10 @@
static DEVICE_ATTR(ipv6_gen_rule_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(ipv6_dip_rule_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(mc_ipv4_stream_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(mc_ipv4_stream_set_queue_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(mc_ipv4_stream_update, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(mc_ipv6_stream_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(mc_ipv6_stream_set_queue_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(mc_ipv6_stream_update, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(ipv6_nh_acl_rule_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(ipv6_l4_ports_acl_rule_add, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
@@ -505,6 +522,9 @@
static DEVICE_ATTR(no_omci_channel, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(tpm_setup, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(mib_reset, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(set_active_wan, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(hot_swap_profile, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(set_port_hwf_admin, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(add_cpu_lpbk, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(del_cpu_lpbk, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(dump_cpu_lpbk, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
@@ -531,6 +551,8 @@
static DEVICE_ATTR(tpm_self_check, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(flush_atu, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(flush_vtu, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(add_ds_load_balance, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
+static DEVICE_ATTR(del_ds_load_balance, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(fc_config_set, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
static DEVICE_ATTR(fc_us_period_set, S_IWUSR, tpm_cfg_show, tpm_cfg_store);
@@ -900,6 +922,7 @@
#endif /* CONFIG_MV_TPM_SYSFS_HELP */
&dev_attr_mc_ipv4_stream_add.attr,
+ &dev_attr_mc_ipv4_stream_set_queue_add.attr,
&dev_attr_igmp_port_forward_mode_cfg.attr,
&dev_attr_igmp_cpu_queue_cfg.attr,
&dev_attr_igmp_proxy_sa_mac.attr,
@@ -911,6 +934,7 @@
&dev_attr_mc_vid_cfg_set.attr,
&dev_attr_mc_ipv6_stream_add.attr,
+ &dev_attr_mc_ipv6_stream_set_queue_add.attr,
&dev_attr_no_mc_stream_add_ipv6.attr,
&dev_attr_mc_ipv6_stream_update.attr,
@@ -934,6 +958,9 @@
#ifdef CONFIG_MV_TPM_SYSFS_HELP
&dev_attr_help_tpm_setup.attr,
&dev_attr_help_mib_reset.attr,
+ &dev_attr_help_set_active_wan.attr,
+ &dev_attr_help_hot_swap_profile.attr,
+ &dev_attr_help_set_port_hwf_admin.attr,
&dev_attr_help_erase_section.attr,
&dev_attr_help_send_genquery_to_uni.attr,
&dev_attr_help_tpm_self_check.attr,
@@ -946,6 +973,9 @@
&dev_attr_send_genquery_to_uni.attr,
&dev_attr_mib_reset.attr,
+ &dev_attr_set_active_wan.attr,
+ &dev_attr_hot_swap_profile.attr,
+ &dev_attr_set_port_hwf_admin.attr,
&dev_attr_erase_section.attr,
&dev_attr_tpm_self_check.attr,
&dev_attr_flush_vtu.attr,
@@ -982,6 +1012,26 @@
.attrs = tpm_cfg_cpu_lpbk_sw_attrs
};
+/******************************************************************************/
+/* ========================================================================== */
+/* TPM cfg_ds_load_balance SYS FS STORE ROUTINE SWITCHER */
+/* ========================================================================== */
+
+static struct attribute *tpm_cfg_ds_load_balance_sw_attrs[] =
+{
+#ifdef CONFIG_MV_TPM_SYSFS_HELP
+ &dev_attr_help_ds_load_balance_rule.attr,
+#endif /* CONFIG_MV_TPM_SYSFS_HELP */
+ &dev_attr_add_ds_load_balance.attr,
+ &dev_attr_del_ds_load_balance.attr,
+ NULL
+};
+
+static struct attribute_group tpm_cfg_ds_load_balance_sw_group =
+{
+ .name = "cfg_ds_load_balance",
+ .attrs = tpm_cfg_ds_load_balance_sw_attrs
+};
/******************************************************************************/
/* ========================================================================== */
@@ -1078,6 +1128,10 @@
&dev_attr_help_no_oam_omci_channel.attr,
&dev_attr_help_tpm_setup.attr,
&dev_attr_help_mib_reset.attr,
+ &dev_attr_help_set_active_wan.attr,
+ &dev_attr_help_hot_swap_profile.attr,
+ &dev_attr_help_set_port_hwf_admin.attr,
+ &dev_attr_help_ds_load_balance_rule.attr,
&dev_attr_help_cfg_cpu_lpbk.attr,
&dev_attr_help_rate_limit.attr,
&dev_attr_help_pkt_mod_add.attr,
@@ -1128,8 +1182,10 @@
&dev_attr_ipv6_gen_rule_add.attr,
&dev_attr_ipv6_dip_rule_add.attr,
&dev_attr_mc_ipv4_stream_add.attr,
+ &dev_attr_mc_ipv4_stream_set_queue_add.attr,
&dev_attr_mc_ipv4_stream_update.attr,
&dev_attr_mc_ipv6_stream_add.attr,
+ &dev_attr_mc_ipv6_stream_set_queue_add.attr,
&dev_attr_mc_ipv6_stream_update.attr,
&dev_attr_ipv6_nh_acl_rule_add.attr,
&dev_attr_ipv6_l4_ports_acl_rule_add.attr,
@@ -1162,6 +1218,9 @@
&dev_attr_tpm_setup.attr,
&dev_attr_mib_reset.attr,
+ &dev_attr_set_active_wan.attr,
+ &dev_attr_hot_swap_profile.attr,
+ &dev_attr_set_port_hwf_admin.attr,
&dev_attr_rate_limit_queue_set.attr,
&dev_attr_scheduling_mode_queue_set.attr,
@@ -1171,7 +1230,6 @@
&dev_attr_pkt_mod_eng_entry_del.attr,
&dev_attr_pkt_mod_eng_purge.attr,
-
NULL
};
@@ -1210,6 +1268,7 @@
{"cfg_traffic", &tpm_cfg_traffic_sw_group},
{"cfg_misc", &tpm_cfg_misc_sw_group},
{"cfg_cpu_lpbk", &tpm_cfg_cpu_lpbk_sw_group},
+ {"cfg_ds_load_balance", &tpm_cfg_ds_load_balance_sw_group},
{"cfg_age_count", &tpm_cfg_age_count_sw_group},
{"cfg_flat", &tpm_cfg_flat_sw_group},
{"cfg_mtu", &tpm_cfg_mtu_sw_group},
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_utils.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_utils.c
index be993dc..00099a5 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_utils.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_sysfs_utils.c
@@ -564,6 +564,7 @@
{ERR_MC_STREAM_INVALID, "ERR_MC_STREAM_INVALID"},
{ERR_MC_STREAM_EXISTS , "ERR_MC_STREAM_EXISTS "},
{ERR_MC_DST_PORT_INVALID, "ERR_MC_DST_PORT_INVALID"},
+ {ERR_MC_DST_QUEUE_INVALID, "ERR_MC_DST_QUEUE_INVALID"},
{ERR_IPV4_MC_DST_IP_INVALID, "ERR_IPV4_MC_DST_IP_INVALID"},
{ERR_IPV6_MC_DST_IP_INVALID, "ERR_IPV6_MC_DST_IP_INVALID"},
{ERR_OMCI_TCONT_INVALID, "ERR_OMCI_TCONT_INVALID"},
@@ -1720,7 +1721,7 @@
int indx;
for (indx = 0; indx < tpm_ipv6_l4_ports_key_db.max_num_entries; indx++, pentry++) {
- if (strcmp(pentry->name, name) == 0)
+ if (strcmp(pentry->name, name) == 0)
return pentry;
}
return 0;
@@ -1732,7 +1733,7 @@
int indx;
for (indx = 0; indx < tpm_ipv6_l4_ports_key_db.max_num_entries; indx++, pentry++) {
- if (pentry->name[0] == 0)
+ if (pentry->name[0] == 0)
return pentry;
}
return 0;
@@ -1764,7 +1765,7 @@
if (pentry->name[0] != 0) {
off += sprintf(buf+off, "%s: \n", pentry->name);
- off += sprintf(buf+off, "\tsrc_port %d, dst_port %d\n",
+ off += sprintf(buf+off, "\tsrc_port %d, dst_port %d\n",
pentry->l4_ports.l4_src_port, pentry->l4_ports.l4_dst_port);
printk(KERN_INFO "%s\n", buf);
@@ -1777,14 +1778,14 @@
void tpm_reset_mc_vid_key(void)
{
tpm_src_port_type_t src_port;
-
+
memset(&mc_vid_key, 0, sizeof(mc_vid_key));
-
+
for ( src_port = TPM_SRC_PORT_UNI_0; src_port <= TPM_SRC_PORT_UNI_VIRT; src_port++)
{
mc_vid_key.mc_vid_port_vids[src_port - TPM_SRC_PORT_UNI_0].tpm_src_port = src_port;
}
-
+
return;
}
@@ -1799,11 +1800,11 @@
printk(KERN_INFO "illegal input src port(%d)\n", src_port);
return GT_FALSE;
}
-
+
mc_vid_key.mc_vid_port_vids[src_port - TPM_SRC_PORT_UNI_0].mc_uni_port_mode = mc_uni_xlate_mode;
mc_vid_key.mc_vid_port_vids[src_port - TPM_SRC_PORT_UNI_0].tpm_src_port = src_port;
mc_vid_key.mc_vid_port_vids[src_port - TPM_SRC_PORT_UNI_0].uni_port_vid = mc_uni_xlate_vid;
-
+
return GT_TRUE;
}
@@ -1812,7 +1813,7 @@
)
{
tpm_error_code_t ret;
-
+
ret = tpm_proc_set_mc_vid_port_vids (0, mc_vid, &mc_vid_key);
return ret;
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_usr_if.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_usr_if.c
index c38ab83..b54523a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_usr_if.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/perf/tpm_usr_if.c
@@ -792,7 +792,7 @@
tpm_phy_get_port_speed_mode(owner_id, (tpm_src_port_type_t)lport, &speed);
- printk(KERN_INFO "The speed status of lport[%d] is [%d]('0'-10M, '1'-100M, '2'-1000M)\n", lport, speed);
+ printk(KERN_INFO "The speed status of lport[%d] is [%d]('0'-10M, '1'-100M, '2'-1000M, '3'-UNKOWN)\n", lport, speed);
return;
@@ -3441,6 +3441,145 @@
tpm_sw_set_port_mirror(owner_id, src_port, dst_port, mirror_mode, mirror_state);
}
+
+/*******************************************************************************
+* sfs_tpm_sw_set_trunk_ports
+*
+* DESCRIPTION:
+* This function set port mirror.
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* trunk_id - valid from 0x0 to 0xf
+* ports_mask - mask for real switch port, not logical port like TPM_SRC_PORT_UNI_0.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* None.
+*
+*
+*******************************************************************************/
+void sfs_tpm_sw_set_trunk_ports
+(
+ IN uint32_t owner_id,
+ IN uint32_t trunk_id,
+ IN uint32_t ports_mask
+)
+{
+ tpm_sw_set_trunk_ports(owner_id, trunk_id, ports_mask);
+}
+/*******************************************************************************
+* sfs_tpm_sw_set_trunk_mask
+*
+* DESCRIPTION:
+* This function set port mirror.
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* mask_num - trunk mask number, valid from 0 to 7.
+* trunk_mask - mask for real switch port, not logical port like TPM_SRC_PORT_UNI_0.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* None.
+*
+*
+*******************************************************************************/
+void sfs_tpm_sw_set_trunk_mask
+(
+ IN uint32_t owner_id,
+ IN uint32_t mask_num,
+ IN uint32_t trunk_mask
+)
+{
+ tpm_sw_set_trunk_mask(owner_id, mask_num, trunk_mask);
+}
+
+/*******************************************************************************
+* sfs_tpm_sw_set_port_speed_duplex
+*
+* DESCRIPTION:
+* This function set the port speed and duplex together
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* lport - Packet origination.
+* speed_mode - speed mode, '0'-10M, '1'-100M, '2'-1000M.
+* mode - duplex mode, 1:enable, 0:disable.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* None
+*
+* COMMENTS:
+* None.
+*
+*******************************************************************************/
+void sfs_tpm_sw_set_port_speed_duplex
+(
+ MV_U32 owner_id,
+ MV_U32 lport,
+ MV_U32 speed_mode,
+ MV_U32 mode
+)
+{
+ tpm_phy_speed_t speed;
+ bool duplex_mode;
+
+ if((tpm_phy_speed_t)speed_mode > TPM_PHY_SPEED_1000_MBPS)
+ speed = (tpm_phy_speed_t)TPM_PHY_SPEED_1000_MBPS;
+ else
+ speed = (tpm_phy_speed_t)speed_mode;
+
+ duplex_mode = ((1 == mode) ? true: false);
+
+ tpm_phy_set_port_speed_duplex_mode(owner_id, (tpm_src_port_type_t)lport, speed, duplex_mode);
+
+ return;
+}
+
+/*******************************************************************************
+* sfs_tpm_sw_port_add_vid_set_egrs_mode
+*
+* DESCRIPTION:
+* The API adds a VID to the list of allowed VIDs per lport,
+* and set the port's egress mode.
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* lport - lport for adding the vid.
+* vid - VLAN id.
+* eMode - port egress mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* None
+*
+* COMMENTS:
+* None.
+*
+*******************************************************************************/
+void sfs_tpm_sw_port_add_vid_set_egrs_mode
+(
+ MV_U32 owner_id,
+ MV_U32 lport,
+ MV_U16 vid,
+ MV_U8 eMode
+)
+{
+ tpm_sw_port_add_vid_set_egrs_mode(owner_id,(tpm_src_port_type_t)lport,vid,eMode);
+
+ return;
+}
+
#ifdef CONFIG_MV_TPM_SYSFS_HELP
/*******************************************************************************
**
@@ -3483,9 +3622,10 @@
off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [allow_flood ('1'-permit,'0'-not)] > set_port_flooding - permit flooding of unknown DA\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [allow_flood ('1'-permit,'0'-not)] > set_port_mc_flooding - permit flooding of unknown multicast\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
off += sprintf(buf+off, "echo [owner_id] [always_on ('1'-permit,'0'-use mc rules)] > set_bc_flooding - permit flooding of broadcast\n");
- off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [allow_tagged('1'-drop, '0'-not)] > set_port_tagged - allows or drops tagged packets\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
- off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [allow_untagged('1'-drop,'0'-not)] > set_port_untagged - allows or drops untagged packets\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
+ off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [drop_tagged('1'-drop, '0'-not)] > set_port_tagged - allows or drops tagged packets\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
+ off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [drop_untagged('1'-drop,'0'-not)] > set_port_untagged - allows or drops untagged packets\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [vid_filter('1'-Drop,'0'-not)] > set_vid_filter_per_port - set the filtering mod VID\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
+ off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [speed('0'-10M,'1'-100M,'2'-1000M)] [duplex('1'-enable,'0'-disable)] > set_port_speed_duplex - set port speed and duplex mode\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
off += sprintf(buf+off, "====================================================================================================================================================\n");
return(off);
@@ -3531,6 +3671,9 @@
off += sprintf(buf+off, "echo [owner_id] [dscp 0-63] [q 0-3] > set_ip_pri_mapping - map ip pri to queue\n");
off += sprintf(buf+off, "echo [owner_id] [gmac('0'-GMAC0, '1'-GMAC1, '2'-PMAC, '3'-switch)] [mtu] > set_gmac_mtu - set GMAC MTU\n");
off += sprintf(buf+off, "echo [owner_id] [src port] [dst port] [mode('0'-ingress), '1'-egress] [state] > set_port_mirror - set port mirror, src/dst port is UNI port(1-4), state('1'-enable,'0'-disable)\n");
+ off += sprintf(buf+off, "echo [owner_id] [trunk_id] [port mask] > set_trunk_ports - set trunk ID and port mask\n");
+ off += sprintf(buf+off, "echo [owner_id] [mask num] [trunk mask] > set_trunk_mask - set trunk mask\n");
+ off += sprintf(buf+off, "echo [owner_id] [UNI port %.1d-%.1d] [vid(1-4094)] [egr_mode] > add_port_vid_set_egr_mode - add a VID to lport and set the egress mode('0'-AS_IS, '2'-RM_TAG, '3'-ADD_TAG)\n", TPM_SRC_PORT_UNI_0, TPM_SRC_PORT_UNI_3);
off += sprintf(buf+off, "====================================================================================================================================================\n");
return(off);
@@ -3666,15 +3809,15 @@
{
const char* name = attr->attr.name;
// unsigned long flags = 0;
- unsigned int param1 = 0;
- unsigned int param2 = 0;
- unsigned int param3 = 0;
- unsigned int param4 = 0;
- unsigned int param5 = 0;
- unsigned int param6 = 0;
- unsigned int param7 = 0;
- unsigned int param8 = 0;
- unsigned int param9 = 0;
+ int param1 = 0;
+ int param2 = 0;
+ int param3 = 0;
+ int param4 = 0;
+ int param5 = 0;
+ int param6 = 0;
+ int param7 = 0;
+ int param8 = 0;
+ int param9 = 0;
MV_U8 static_mac[6] = {0,0,0,0,0,0};
MV_U32 memPorts[6];
@@ -3787,6 +3930,18 @@
printk(KERN_INFO "param1[%d],param2[%d],param3[%d],param4[%d],param5[%d],param6[%d],param7[%d],param8[%d] param9[%d] \n",
param1,param2,param3,param4,
param5,param6,param7,param8,param9);
+ if (param1 < 0 ||
+ param2 < 0 ||
+ param3 < 0 ||
+ param4 < 0 ||
+ param5 < 0 ||
+ param6 < 0 ||
+ param7 < 0 ||
+ param8 < 0 ||
+ param9 < 0) {
+ printk("ERROR %s: illegal negative parameter <%s>\n", __FUNCTION__, attr->attr.name);
+ return (len);
+ }
// raw_local_irq_save(flags);
@@ -3917,6 +4072,18 @@
else if
(!strcmp(name, "set_port_mirror"))
sfs_tpm_sw_set_port_mirror((MV_U32)param1,(MV_U32)param2,(MV_U32)param3,(MV_U32)param4,(MV_U32)param5);
+ else if
+ (!strcmp(name, "set_trunk_mask"))
+ sfs_tpm_sw_set_trunk_mask((MV_U32)param1,(MV_U32)param2,(MV_U32)param3);
+ else if
+ (!strcmp(name, "set_trunk_ports"))
+ sfs_tpm_sw_set_trunk_ports((MV_U32)param1,(MV_U32)param2,(MV_U32)param3);
+ else if
+ (!strcmp(name, "set_port_speed_duplex"))
+ sfs_tpm_sw_set_port_speed_duplex((MV_U32)param1,(MV_U32)param2, (MV_U32)param3, (MV_U32)param4);
+ else if
+ (!strcmp(name, "add_port_vid_set_egr_mode"))
+ sfs_tpm_sw_port_add_vid_set_egrs_mode((MV_U32)param1,(MV_U32)param2, (MV_U16)param3, (MV_U8)param4);
else
printk("%s: illegal operation <%s>\n", __FUNCTION__, attr->attr.name);
@@ -4099,6 +4266,8 @@
static DEVICE_ATTR(set_ip_pri_mapping, S_IWUSR, set_sw_show, set_sw_store);
static DEVICE_ATTR(set_gmac_mtu, S_IWUSR, set_sw_show, set_sw_store);
static DEVICE_ATTR(set_port_mirror, S_IWUSR, set_sw_show, set_sw_store);
+static DEVICE_ATTR(set_trunk_mask, S_IWUSR, set_sw_show, set_sw_store);
+static DEVICE_ATTR(set_trunk_ports, S_IWUSR, set_sw_show, set_sw_store);
#ifdef CONFIG_MV_TPM_SYSFS_HELP
static DEVICE_ATTR(help_sw_set_cfg_1, S_IRUSR, set_sw_show, set_sw_store);
static DEVICE_ATTR(help_sw_set_cfg_2, S_IRUSR, set_sw_show, set_sw_store);
@@ -4106,7 +4275,8 @@
static DEVICE_ATTR(rate_limit_menu, S_IRUSR, set_sw_show, set_sw_store);
static DEVICE_ATTR(egr_rate_limit_menu, S_IRUSR, set_sw_show, set_sw_store);
static DEVICE_ATTR(init_pri_menu, S_IRUSR, set_sw_show, set_sw_store);
-
+static DEVICE_ATTR(set_port_speed_duplex, S_IWUSR, set_sw_show, set_sw_store);
+static DEVICE_ATTR(add_port_vid_set_egr_mode, S_IWUSR, set_sw_show, set_sw_store);
static struct attribute *set_sw_attrs[] = {
&dev_attr_set_port_admin.attr,
@@ -4149,6 +4319,9 @@
&dev_attr_set_ip_pri_mapping.attr,
&dev_attr_set_gmac_mtu.attr,
&dev_attr_set_port_mirror.attr,
+ &dev_attr_set_trunk_mask.attr,
+ &dev_attr_set_trunk_ports.attr,
+ &dev_attr_set_port_speed_duplex.attr,
#ifdef CONFIG_MV_TPM_SYSFS_HELP
&dev_attr_help_sw_set_cfg_1.attr,
&dev_attr_help_sw_set_cfg_2.attr,
@@ -4156,6 +4329,7 @@
&dev_attr_rate_limit_menu.attr,
&dev_attr_egr_rate_limit_menu.attr,
&dev_attr_init_pri_menu.attr,
+ &dev_attr_add_port_vid_set_egr_mode.attr,
NULL
};
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.c
index c93c182..3dd1dec 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.c
@@ -1239,6 +1239,7 @@
entry_p = tpm_mod2_get_chain_from_pattern_set(pattern_data->pattern_set, pattern_data->main_chain_type, pattern_data->main_chain_id);
if (main_chain_id != TPM_MOD2_INVALID_CHAIN_ID)
{
+ tpm_db_mod2_rollback_chain_entry(gmac_port, TPM_CHAIN_TYPE_MH, pattern_data->main_chain_id, false);
pattern_data->main_chain_id = main_chain_id;
}
}
@@ -1741,7 +1742,7 @@
else
eth_type_sel = TPM_MOD2_TP_FROM_VLAN_2;
}
-
+
*conf_data = eth_type_sel;
return TPM_OK;
}
@@ -2328,7 +2329,8 @@
tpm_chain_type_t subr_chain = TPM_CHAIN_TYPE_PPPOE;
tpm_mod2_entry_t *tmp_pattern = ipv4_pattern;
uint32_t entry_num = TPM_MOD2_PPPOE_ADD_CMD_ENTRIES;
-
+ uint32_t gmac_mh_en;
+
memset(ipv4_pattern, 0, sizeof(ipv4_pattern));
memset(ipv6_pattern, 0, sizeof(ipv6_pattern));
@@ -2344,12 +2346,15 @@
tmp_pattern = ipv6_pattern;
entry_num = TPM_MOD2_IPV6_PPPOE_ADD_CMD_ENTRIES;
}
-
+
/* Build pattern entries */
if (bm & TPM_IPV6_UPDATE) {
memcpy(tmp_pattern, tpm_mod2_ipv6_pppoe_pattern.entry,
entry_num * sizeof(tpm_mod2_entry_t));
tmp_pattern[2].data = mod_data->pppoe_mod.ppp_session;
+ tpm_db_gmac_mh_en_conf_get(gmac_port, &gmac_mh_en);
+ if (!gmac_mh_en)
+ tmp_pattern[3].data = TPM_MOD2_DEFAULT_PPPOE_LEN_MH_DIS;
} else {
memcpy(tmp_pattern, tpm_mod2_pattern_array[cmd_idx].entry,
entry_num * sizeof(tpm_mod2_entry_t));
@@ -3409,7 +3414,7 @@
max_sz = tpm_db_mod2_get_chain_max_size(entry_p->chain_type);
if (entry_p->line_num > max_sz)
{
- TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "chain(%d) PMT entry number(%d) exceeds the maximum chain size(%d)\n",
+ TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "chain(%d) PMT entry number(%d) exceeds the maximum chain size(%d)\n",
entry_p->chain_type, entry_p->line_num, max_sz);
return TPM_FAIL;
}
@@ -3585,7 +3590,7 @@
{
uint16_t set_id;
tpm_pattern_entry_t *pattern_set = NULL;
-
+
if (pattern_data == NULL)
{
TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "NULL pointer\n");
@@ -3604,7 +3609,7 @@
}
spin_unlock_bh(&tpmMod2JumpEntryLock);
}
-
+
if (pattern_data->main_chain_type != TPM_CHAIN_TYPE_NONE) {
for (set_id = 1; set_id < TPM_MOD2_MAX_PATTERN_SETS; set_id++)
{
@@ -3622,7 +3627,7 @@
}
}
}
-
+
return TPM_OK;
}
@@ -4365,15 +4370,27 @@
*******************************************************************************/
int32_t tpm_mod2_registers_init (tpm_gmacs_enum_t gmac_port, uint16_t txp)
{
+ uint32_t gmac_mh_en;
TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "\n");
/* Init PPPOE registers*/
MV_REG_WRITE (NETA_TX_PMT_PPPOE_TYPE_REG(gmac_port, txp), TPM_MOD2_DEFAULT_PPPOE_ETY);
MV_REG_WRITE (NETA_TX_PMT_PPPOE_DATA_REG(gmac_port, txp), TPM_MOD2_DEFAULT_PPPOE_DATA);
- MV_REG_WRITE (NETA_TX_PMT_PPPOE_LEN_REG(gmac_port, txp), TPM_MOD2_DEFAULT_PPPOE_LEN);
MV_REG_WRITE (NETA_TX_PMT_PPPOE_PROTO_REG(gmac_port, txp), TPM_MOD2_DEFAULT_PPPOE_PROTO);
+ if ((TPM_ENUM_GMAC_0 == gmac_port) || (TPM_ENUM_GMAC_1 == gmac_port))
+ tpm_db_gmac_mh_en_conf_get(gmac_port, &gmac_mh_en);
+ else
+ gmac_mh_en = 1;
+
+ TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "GMAC: (%d), mh_en: (%d)\n", gmac_port, gmac_mh_en);
+
+ if (gmac_mh_en)
+ MV_REG_WRITE (NETA_TX_PMT_PPPOE_LEN_REG(gmac_port, txp), TPM_MOD2_DEFAULT_PPPOE_LEN_MH_EN);
+ else
+ MV_REG_WRITE (NETA_TX_PMT_PPPOE_LEN_REG(gmac_port, txp), TPM_MOD2_DEFAULT_PPPOE_LEN_MH_DIS);
+
return TPM_OK;
}
@@ -4518,7 +4535,7 @@
tpm_db_mod2_split_mod_increase_vlan_user_num(port, mod_data);
return(TPM_OK);
}
-
+
db_ret = tpm_db_mod2_split_mod_insert_vlan(port, mod_data);
if (TPM_DB_OK != db_ret)
{
@@ -4567,7 +4584,7 @@
{
int32_t tpm_ret;
tpm_pkt_mod_t mod_data;
-
+
if (TPM_SPLIT_MOD_DISABLED == tpm_db_split_mod_get_enable())
{
TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "SPLIT_MOD_DISABLED\n");
@@ -4601,16 +4618,51 @@
return TPM_OK;
}
-int32_t tpm_mod2_split_mod_try_pmt_entry_del(tpm_api_sections_t api_section,
+void tpm_mod2_split_mod_entry_del(tpm_gmacs_enum_t gmac_port,
+ uint32_t mod_entry,
+ uint32_t vlan_index)
+{
+ int32_t tpm_ret;
+ uint32_t i = 0;
+ uint32_t num_pbits;
+ uint32_t user_num = 0;
+
+ /* decrease user number of this vlan */
+ tpm_ret = tpm_db_mod2_split_mod_decrease_vlan_user_num(gmac_port, vlan_index, &user_num);
+ if (TPM_DB_OK != tpm_ret)
+ {
+ TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "failed to decrease vlan user num, index: %d\n", vlan_index);
+ return;
+ }
+
+ /* still other usr, do not remove */
+ if (user_num != 0)
+ {
+ TPM_OS_INFO(TPM_MODZ2_HM_MOD, "still other usr, do not remove, usr num: %d\n", user_num);
+ return;
+ }
+
+ /* remove all the PMT entry for this VLAN */
+ num_pbits = TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX;
+ for(i = 0; i <= num_pbits; i++) {
+ tpm_ret = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, gmac_port, (vlan_index * 16 + i));
+ if (TPM_DB_OK != tpm_ret)
+ {
+ TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "failed to del split mod, index: %d\n", (vlan_index * 16 + i));
+ return;
+ }
+ }
+
+ return;
+}
+int32_t tpm_mod2_split_mod_try_pmt_entry_del(tpm_api_sections_t api_section,
tpm_gmacs_enum_t gmac_port,
uint32_t mod_entry)
{
uint32_t num_vlans;
- uint32_t num_pbits;
uint32_t vlan_index;
- uint32_t user_num = 0;
- int32_t tpm_ret;
- uint32_t i = 0;
+ tpm_gmacs_enum_t duplicate_gmac;
+ tpm_db_ds_mac_based_trunk_enable_t ds_mac_based_trunk_enable;
if (!mod_entry) {
TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "mod_entry is zero, PMT do not need to be removed\n");
@@ -4621,13 +4673,16 @@
TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "SPLIT_MOD_DISABLED, PMT need to be removed\n");
return(TPM_FAIL);
}
-
- if ( (TPM_IPV4_ACL == api_section)
- && (mod_entry <= TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX)) {
- TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "IPv4 split mod, PMT do not need to be removed\n");
+
+ if ( ( (TPM_IPV4_ACL == api_section)
+ || (TPM_L4_ACL == api_section)
+ || (TPM_IPV6_GEN_ACL == api_section)
+ || (TPM_IPV6_DIP_ACL == api_section))
+ && (mod_entry <= TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX)) {
+ TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "IPv4/6 split mod, PMT do not need to be removed\n");
return(TPM_OK);
}
-
+
if (TPM_L2_PRIM_ACL != api_section) {
TPM_OS_DEBUG(TPM_MODZ2_HM_MOD, "Not L2 ACL, PMT need to be removed\n");
return(TPM_FAIL);
@@ -4651,32 +4706,22 @@
return(TPM_OK);
}
- /* decrease user number of this vlan */
- tpm_ret = tpm_db_mod2_split_mod_decrease_vlan_user_num(gmac_port, vlan_index, &user_num);
- if (TPM_DB_OK != tpm_ret)
- {
- TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "failed to decrease vlan user num, index: %d\n", vlan_index);
- return(TPM_OK);
- }
+ tpm_mod2_split_mod_entry_del(gmac_port, mod_entry, vlan_index);
- /* still other usr, do not remove */
- if (user_num != 0)
- {
- TPM_OS_INFO(TPM_MODZ2_HM_MOD, "still other usr, do not remove, usr num: %d\n", user_num);
- return(TPM_OK);
+ /* when ds load balance on G0 and G1 is enabled, need to duplicate DS PMT on G0/1 */
+ tpm_db_ds_mac_based_trunk_enable_get(&ds_mac_based_trunk_enable);
+ if ( (TPM_DS_MAC_BASED_TRUNK_ENABLED == ds_mac_based_trunk_enable)
+ && (TPM_ENUM_GMAC_0 == gmac_port || TPM_ENUM_GMAC_1 == gmac_port)) {
+
+ /* if this is DS and DS_MAC_BASED_TRUNK is ENABLED */
+ if (gmac_port == TPM_ENUM_GMAC_0)
+ duplicate_gmac = TPM_ENUM_GMAC_1;
+ else
+ duplicate_gmac = TPM_ENUM_GMAC_0;
+
+ tpm_mod2_split_mod_entry_del(duplicate_gmac, mod_entry, vlan_index);
}
-
- /* remove all the PMT entry for this VLAN */
- num_pbits = TPM_DB_SPLIT_MOD_P_BIT_NUM_MAX;
- for(i = 0; i <= num_pbits; i++) {
- tpm_ret = tpm_mod2_entry_del(TPM_MOD_OWNER_TPM, gmac_port, (vlan_index * 16 + i));
- if (TPM_DB_OK != tpm_ret)
- {
- TPM_OS_ERROR(TPM_MODZ2_HM_MOD, "failed to del split mod, index: %d\n", (vlan_index * 16 + i));
- return(TPM_OK);
- }
- }
- return TPM_OK;
+ return TPM_OK;
}
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.h
index 60af2b1..672227a 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_modz2_mgr.h
@@ -112,11 +112,14 @@
#define TPM_MOD2_DEFAULT_ETY (0x8100)
#define TPM_MOD2_DEFAULT_PPPOE_ETY (0x8864)
#define TPM_MOD2_DEFAULT_PPPOE_DATA (0x1100)
-#define TPM_MOD2_DEFAULT_PPPOE_LEN (0x7000)
+#define TPM_MOD2_DEFAULT_PPPOE_LEN_MH_EN (0x7000)
+#define TPM_MOD2_DEFAULT_PPPOE_LEN_MH_DIS (0x7202)
#define TPM_MOD2_DEFAULT_PPPOE_PROTO (0x0021)
/* Self-defined Ethernet type for CPU loopback frames*/
#define TPM_MOD2_CPU_LOOPBACK_ETY (0xAABB)
+/* Self-defined Marvell header for MAC learning frames on Media Convert*/
+#define TPM_MOD2_MAC_LEARN_MH (0xAACC)
/* Max number of modification entries per command */
#define TPM_MOD2_MAX_CMD_ENTRIES (5)
@@ -287,7 +290,7 @@
int32_t tpm_mod2_init(void);
int32_t tpm_mod2_split_mod_init(tpm_gmacs_enum_t port);
int32_t tpm_mod2_split_mod_create_l2_pmts(tpm_gmacs_enum_t port, tpm_pkt_mod_t *mod_data, bool init_flag);
-int32_t tpm_mod2_split_mod_try_pmt_entry_del(tpm_api_sections_t api_section,
+int32_t tpm_mod2_split_mod_try_pmt_entry_del(tpm_api_sections_t api_section,
tpm_gmacs_enum_t gmac_port,
uint32_t mod_entry);
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.c b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.c
index ede6176..e62bce4 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.c
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.c
@@ -79,6 +79,7 @@
#include "tpm_common.h"
#include "tpm_header.h"
+#include "../../mv_mac_learn/mv_mac_learn_header.h"
uint32_t trace_sw_dbg_flag = 0;
@@ -91,7 +92,7 @@
#define SWITCH_INIT_CHECK()\
int32_t ret_init_check;\
ret_init_check = tpm_sw_init_check();\
- IF_ERROR(ret_init_check);
+ IF_ERROR(ret_init_check)
/*******************************************************************************
* tpm_sw_init_check
@@ -126,6 +127,113 @@
}
/*******************************************************************************
+* tpm_phy_access_check
+*
+* DESCRIPTION:
+* This function check the PHY access path, direct or through switch.
+*
+* INPUTS:
+* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
+*
+* OUTPUTS:
+* phy_ctrl - the PHY SMI master indication
+* phy_direct_addr - PHY address if PHY accessed directly
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* NONE.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_phy_access_check(tpm_src_port_type_t src_port,
+ tpm_phy_ctrl_t *phy_access_way,
+ uint32_t *phy_direct_addr)
+{
+ tpm_init_gmac_conn_conf_t gmac_conn_info;
+ uint32_t i;
+ tpm_db_chip_conn_t chip_con;
+ tpm_db_int_conn_t int_con;
+ uint32_t switch_port;
+
+ /* Para check*/
+ if ((NULL == phy_access_way) || (NULL == phy_direct_addr)) {
+ printk(KERN_ERR "ERROR: Invalid pointer\n");
+ return ERR_GENERAL;
+ }
+
+ /* Check gmac port connection info */
+ for (i = 0; i < TPM_MAX_NUM_GMACS; i++) {
+ if (TPM_DB_OK != tpm_db_gmac_conn_conf_get(i, &gmac_conn_info)) {
+ printk(KERN_ERR "ERROR: (%s:%d) Gmac port(%d) connection info get failed\n", __FUNCTION__, __LINE__, i);
+ return ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ if (TPM_TRUE == gmac_conn_info.valid && src_port == gmac_conn_info.port_src) {
+ /* PHY access directly */
+ *phy_access_way = PHY_SMI_MASTER_CPU;
+ /*get PHY addr on GMAC*/
+ *phy_direct_addr = mvBoardPhyAddrGet(i);
+
+ if (trace_sw_dbg_flag)
+ printk(KERN_INFO "Port%d PHY access directly, phyaddr %d\n", src_port, *phy_direct_addr);
+
+ return TPM_RC_OK;
+ }
+ }
+
+ /* Check eth port connection info */
+ if (TPM_DB_OK != tpm_db_eth_port_conf_get(src_port, &chip_con, &int_con, &switch_port)) {
+ printk(KERN_ERR "ERROR: (%s:%d) Eth port(%d) connection info get failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ /* Check QSGMII */
+ if (TPM_CONN_QSGMII == chip_con && TPM_INTCON_SWITCH == int_con) {
+ /* Check MPP register, if value of MPP29 and MPP30 are both 4, then access PHY directly */
+ if ((mvBoardMppGet(3) & DB_88F6535_MPP24_31) == DB_88F6535_MPP24_31) {
+ /* PHY access directly */
+ *phy_access_way = PHY_SMI_MASTER_CPU;
+ /*get PHY addr on GMAC*/
+ *phy_direct_addr = (uint32_t)src_port;
+ if (trace_sw_dbg_flag)
+ printk(KERN_INFO "Port%d QSGMII PHY access directly, phyaddr %d\n", src_port, *phy_direct_addr);
+ return TPM_RC_OK;
+ }
+ }
+
+ *phy_access_way = PHY_SMI_MASTER_SWT;
+ if (trace_sw_dbg_flag)
+ printk(KERN_INFO "Port%d PHY access through switch\n", src_port);
+
+ return TPM_RC_OK;
+}
+
+tpm_error_code_t tpm_src_port_mac_map(tpm_src_port_type_t src_port,
+ tpm_gmacs_enum_t *gmac)
+{
+ tpm_init_gmac_conn_conf_t gmac_conn_info;
+ uint32_t i;
+
+ /* Check gmac port connection info */
+ for (i = 0; i < TPM_MAX_NUM_GMACS; i++) {
+ if (TPM_DB_OK != tpm_db_gmac_conn_conf_get(i, &gmac_conn_info)) {
+ printk(KERN_ERR "ERROR: (%s:%d) Gmac port(%d) connection info get failed\n", __FUNCTION__, __LINE__, i);
+ return ERR_GENERAL;
+ }
+ if (TPM_TRUE == gmac_conn_info.valid && src_port == gmac_conn_info.port_src) {
+ *gmac = i;
+ return TPM_RC_OK;
+ }
+ }
+ if (i == TPM_MAX_NUM_GMACS) {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) map to MAC failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ return TPM_RC_OK;
+}
+
+/*******************************************************************************
* tpm_sw_set_debug_trace_flag
*
* DESCRIPTION:
@@ -185,8 +293,7 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
if (trace_sw_dbg_flag)
{
@@ -196,14 +303,30 @@
__FUNCTION__,owner_id,src_port, static_mac[0],static_mac[1],static_mac[2],static_mac[3],static_mac[4],static_mac[5]);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_static_entry_add(&(static_mac[0]));
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) MAC learn not supported\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_add_static_mac(lPort, &(static_mac[0]));
+ retVal = mv_switch_add_static_mac(lPort, &(static_mac[0]));
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -247,9 +370,7 @@
uint8_t static_mac[6]
)
{
- tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_error_code_t retVal = TPM_RC_OK;
if (trace_sw_dbg_flag)
{
@@ -259,7 +380,19 @@
__FUNCTION__,owner_id,static_mac[0],static_mac[1],static_mac[2],static_mac[3],static_mac[4],static_mac[5]);
}
- retVal = mv_switch_del_static_mac(&(static_mac[0]));
+ if (tpm_sw_init_check()) {
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_static_entry_del(&(static_mac[0]));
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) MAC learn not supported\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ retVal = mv_switch_del_static_mac(&(static_mac[0]));
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -305,7 +438,10 @@
uint8_t static_mac[6]
)
{
- tpm_error_code_t retVal;
+ tpm_error_code_t retVal = TPM_RC_OK;
+#ifdef CONFIG_MV_MAC_LEARN
+ static uint32_t mask_check = 1;
+#endif
SWITCH_INIT_CHECK();
@@ -324,7 +460,20 @@
static_mac[5]);
}
- retVal = mv_switch_mac_addr_set(&(static_mac[0]), 0, ports_mask, 1);
+ if (tpm_sw_init_check()) {
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get()) {
+ if (ports_mask & mask_check)
+ retVal = mv_mac_learn_static_entry_add(&(static_mac[0]));
+ } else {
+ printk(KERN_ERR "ERROR: (%s:%d) MAC learn not supported\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ retVal = mv_switch_mac_addr_set(&(static_mac[0]), 0, ports_mask, 1);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -341,6 +490,203 @@
}
/*******************************************************************************
+* tpm_sw_set_trunk_ports
+*
+* DESCRIPTION:
+* This function creates trunk ports and trunk id
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* trunk_id - valid from 0x0 to 0xf
+* ports_mask - mask for real switch port, not logical port like TPM_SRC_PORT_UNI_0.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_set_trunk_ports
+(
+ uint32_t owner_id,
+ uint32_t trunk_id,
+ uint32_t ports_mask
+)
+{
+ tpm_error_code_t ret;
+ uint16_t reg_tmp = 0;
+ uint32_t switch_port = 0;
+
+ SWITCH_INIT_CHECK();
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: owner_id[%d], trunk_id[0x%x], ports_mask[0x%x]\n\r",
+ __FUNCTION__, owner_id, trunk_id, ports_mask);
+ }
+
+ if (trunk_id > SW_TRUNK_ID_MAX)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: trunk_id[0x%x] is bigger than [0x%x]\n\r",
+ __FUNCTION__,trunk_id, SW_TRUNK_ID_MAX);
+ }
+
+ for (switch_port = 0; switch_port <= TPM_SWITCH_NUM_PORTS; switch_port++)
+ {
+ if(0 == (ports_mask & (1 << switch_port)))
+ {
+ continue;
+ }
+
+ /* get trunk reg from HW */
+ ret = mv_switch_reg_read(switch_port, SW_TRUNK_ID_REG, MV_SWITCH_PORT_ACCESS, ®_tmp);
+ if (0 != ret) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to get trunk reg, ret(%d)\n", ret);
+ return (TPM_FAIL);
+ }
+
+ /* set bits 8, 9 to 11, as trunk_id */
+ SW_CLEAR_REG_BIT(reg_tmp, SW_TRUNK_ID_BIT_OFF, SW_TRUNK_ID_BIT_LEN);
+ reg_tmp |= (trunk_id << SW_TRUNK_ID_BIT_OFF);
+ /* set bit 14, as trunk bit */
+ reg_tmp |= (1 << SW_TRUNK_BIT_OFF);
+ ret = mv_switch_reg_write(switch_port, SW_TRUNK_ID_REG, MV_SWITCH_PORT_ACCESS, reg_tmp);
+ if (0 != ret) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set trunk reg, ret(%d)\n", ret);
+ return (TPM_FAIL);
+ }
+ }
+
+ /* get trunk mapping reg from HW */
+ ret = mv_switch_reg_read(0, SW_TRUNK_MAPPING_REG, MV_SWITCH_GLOBAL2_ACCESS, ®_tmp);
+ if (0 != ret) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to get trunk mapping reg, ret(%d)\n", ret);
+ return (TPM_FAIL);
+ }
+
+ /* set bits 11 to 14, as trunk_id */
+ SW_CLEAR_REG_BIT(reg_tmp, SW_TRUNK_MAPPING_ID_BIT_OFF, SW_TRUNK_ID_BIT_LEN);
+ reg_tmp |= (trunk_id << SW_TRUNK_MAPPING_ID_BIT_OFF);
+
+ /* set bits 0 to 6, as trunk map */
+ SW_CLEAR_REG_BIT(reg_tmp, SW_TRUNK_MAPPING_BIT_OFF, SW_TRUNK_MAPPING_BIT_LEN);
+ reg_tmp |= (ports_mask << SW_TRUNK_MAPPING_BIT_OFF);
+
+ /* set bits 15, as udpate bit */
+ reg_tmp |= (1 << SW_REG_UPDATE_BIT_OFF);
+
+ ret = mv_switch_reg_write(0, SW_TRUNK_MAPPING_REG, MV_SWITCH_GLOBAL2_ACCESS, reg_tmp);
+ if (0 != ret) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set trunk mapping reg, ret(%d)\n", ret);
+ return (TPM_FAIL);
+ }
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==EXIT== %s:\n\r",__FUNCTION__);
+ }
+
+ return ret;
+}
+
+
+/*******************************************************************************
+* tpm_sw_set_trunk_mask
+*
+* DESCRIPTION:
+* This function sets trunk mask
+*
+* INPUTS:
+* owner_id - APP owner id - should be used for all API calls.
+* mask_num - trunk mask number, valid from 0 to 7.
+* trunk_mask - mask for real switch port, not logical port like TPM_SRC_PORT_UNI_0.
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+*
+* COMMENTS:
+* None.
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_set_trunk_mask
+(
+ uint32_t owner_id,
+ uint32_t mask_num,
+ uint32_t trunk_mask
+)
+{
+ tpm_error_code_t ret;
+ uint16_t reg_tmp = 0;
+
+ SWITCH_INIT_CHECK();
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: owner_id[%d],mask_num[0x%x],trunk_mask[0x%x]\n\r",
+ __FUNCTION__, owner_id, mask_num, trunk_mask);
+ }
+
+ if (mask_num > SW_TRUNK_MASK_NUM_MAX)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: mask_num[0x%x] is bigger than [0x%x]\n\r",
+ __FUNCTION__,mask_num, SW_TRUNK_MASK_NUM_MAX);
+ }
+
+ if (trunk_mask > SW_TRUNK_MASK_MAX)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: trunk_mask[0x%x] is bigger than [0x%x]\n\r",
+ __FUNCTION__,trunk_mask, SW_TRUNK_MASK_MAX);
+ }
+
+ /* get trunk mask reg from HW */
+ ret = mv_switch_reg_read(0, SW_TRUNK_MASK_REG, MV_SWITCH_GLOBAL2_ACCESS, ®_tmp);
+ if (0 != ret) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to get trunk mask reg, ret(%d)\n", ret);
+ return (TPM_FAIL);
+ }
+
+ /* set bits 11 to 14, as mask_num */
+ SW_CLEAR_REG_BIT(reg_tmp, SW_TRUNK_MASK_NUM_BIT_OFF, SW_TRUNK_MASK_NUM_BIT_LEN);
+ reg_tmp |= (mask_num << SW_TRUNK_MASK_NUM_BIT_OFF);
+
+ /* set bits 0 to 6, as trunk_mask */
+ SW_CLEAR_REG_BIT(reg_tmp, SW_TRUNK_MASK_BIT_OFF, SW_TRUNK_MASK_BIT_LEN);
+ reg_tmp |= (trunk_mask << SW_TRUNK_MASK_BIT_OFF);
+
+ /* set bits 15, as udpate bit */
+ reg_tmp |= (1 << SW_REG_UPDATE_BIT_OFF);
+
+ ret = mv_switch_reg_write(0, SW_TRUNK_MASK_REG, MV_SWITCH_GLOBAL2_ACCESS, reg_tmp);
+ if (0 != ret) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "Fail to set trunk mask reg, ret(%d)\n", ret);
+ return (TPM_FAIL);
+ }
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==EXIT== %s:\n\r",__FUNCTION__);
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
* tpm_sw_clear_dynamic_mac
*
* DESCRIPTION:
@@ -422,7 +768,7 @@
tpm_error_code_t retVal;
GT_BOOL state;
uint32_t sw_sport;
- uint32_t sw_dport;
+ uint32_t sw_dport;
SWITCH_INIT_CHECK();
@@ -440,7 +786,7 @@
state = GT_FALSE;
sw_sport = tpm_db_eth_port_switch_port_get(sport);
- sw_dport = tpm_db_eth_port_switch_port_get(dport);
+ sw_dport = tpm_db_eth_port_switch_port_get(dport);
if (TPM_DB_ERR_PORT_NUM == sw_sport || TPM_DB_ERR_PORT_NUM == sw_dport){
TPM_OS_ERROR(TPM_INIT_MOD, "invalid port (sw_sport %d, sw_dport %d)\n", sw_sport, sw_dport);
@@ -590,29 +936,23 @@
for (i=TPM_SRC_PORT_UNI_0; i<TPM_MAX_NUM_UNI_PORTS; i++)
{
- sw_port_num = tpm_db_eth_port_switch_port_get(i);
+ sw_port_num = tpm_db_eth_port_switch_port_get(i);
- if (TPM_DB_ERR_PORT_NUM == sw_port_num)
- continue;
+ if (TPM_DB_ERR_PORT_NUM == sw_port_num)
+ continue;
- if (sw_port_num >= MEM_PORTS_NR) {
- TPM_OS_ERROR(TPM_INIT_MOD, "sw_port_num too big! (%d >= MEM_PORTS_NR) \n", sw_port_num);
- return ERR_SRC_PORT_INVALID;
- }
+ if (sw_port_num >= MEM_PORTS_NR) {
+ TPM_OS_ERROR(TPM_INIT_MOD, "sw_port_num too big! (%d >= MEM_PORTS_NR) \n", sw_port_num);
+ return ERR_SRC_PORT_INVALID;
+ }
if(port_vector & (1 << i))
{
memPorts[sw_port_num] = sw_port_num;
- printk(KERN_INFO
- "==ENTER==%s: 1 i[%d] sw_port_num[%d]\n\r",
- __FUNCTION__, i, sw_port_num);
}
else
{
memPorts[sw_port_num] = 0x80;
- printk(KERN_INFO
- "==ENTER==%s: 2 i[%d] sw_port_num[%d]\n\r",
- __FUNCTION__, i, sw_port_num);
}
}
@@ -744,8 +1084,7 @@
)
{
tpm_error_code_t retVal = TPM_RC_OK;
-
- SWITCH_INIT_CHECK();
+ uint32_t switch_init = 0;
if (trace_sw_dbg_flag)
{
@@ -770,8 +1109,10 @@
retVal = mv_eth_set_mtu(2, mtu);
break;
case TPM_NETA_MTU_SWITCH:
- /*Set switch MTU*/
- retVal = mv_switch_set_mtu(mtu);
+ /*Set switch MTU if exist*/
+ tpm_db_switch_init_get(&switch_init);
+ if (switch_init)
+ retVal = mv_switch_set_mtu(mtu);
break;
default:
break;
@@ -822,8 +1163,6 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
- SWITCH_INIT_CHECK();
-
if (trace_sw_dbg_flag)
{
printk(KERN_INFO
@@ -847,8 +1186,11 @@
retVal = mv_eth_get_mtu(2, mtu);
break;
case TPM_NETA_MTU_SWITCH:
- /*Get switch MTU*/
- retVal = mv_switch_get_mtu(mtu);
+ /*Get switch MTU if exist*/
+ if (!tpm_sw_init_check())
+ retVal = mv_switch_get_mtu(mtu);
+ else
+ retVal = ERR_GENERAL;
break;
default:
break;
@@ -904,8 +1246,7 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
if (trace_sw_dbg_flag)
{
@@ -914,14 +1255,30 @@
__FUNCTION__, owner_id, src_port, mac_per_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+#ifdef CONFIG_MV_MAC_LEARN
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_max_count_set(mac_per_port);
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) MAC learn not supported\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_set_port_max_macs(lPort, mac_per_port);
+ retVal = mv_switch_set_port_max_macs(lPort, mac_per_port);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -983,8 +1340,8 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
+ tpm_db_pnc_range_conf_t range_conf;
if (trace_sw_dbg_flag)
{
@@ -993,14 +1350,34 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Check GMAC1 lpk status */
+ if (tpm_db_gmac1_lpbk_en_get()) {
+ if (tpm_db_pnc_rng_conf_get(TPM_PNC_MAC_LEARN, &range_conf)) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_db_pnc_rng_conf_get failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+ *limit = range_conf.api_end - range_conf.api_start + 1;
+ if (*limit > MAC_LEARN_FDB_MAX_COUNT)
+ *limit = MAC_LEARN_FDB_MAX_COUNT;
+ } else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) MAC learn not supported\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_get_port_max_macs(lPort, limit);
+ retVal = mv_switch_get_port_max_macs(lPort, limit);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -1026,7 +1403,7 @@
* INPUTS:
* owner_id - APP owner id - should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
-* allow_tagged - set to 1 = discard tagged packets per UNI port
+* drop_tagged - set to 1 = drop tagged packets per UNI port
* set to 0 = allow tagged packets per UNI port.
*
* OUTPUTS:
@@ -1044,7 +1421,7 @@
(
uint32_t owner_id,
tpm_src_port_type_t src_port,
- uint8_t allow_tagged
+ uint8_t drop_tagged
)
{
tpm_error_code_t retVal = TPM_RC_OK;
@@ -1056,8 +1433,8 @@
if (trace_sw_dbg_flag)
{
printk(KERN_INFO
- "==ENTER==%s: owner_id[%d],src_port[%d],allow_tagged[%d]\r\n",
- __FUNCTION__,owner_id,src_port,allow_tagged);
+ "==ENTER==%s: owner_id[%d],src_port[%d],drop_tagged[%d]\r\n",
+ __FUNCTION__,owner_id,src_port,drop_tagged);
}
@@ -1068,7 +1445,7 @@
return ERR_SRC_PORT_INVALID;
}
- if (allow_tagged == 1)
+ if (drop_tagged == 1)
{
mode = 1/*GT_TRUE*/;
}
@@ -1165,7 +1542,7 @@
* INPUTS:
* owner_id - APP owner id - should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
-* allow_untagged - set to 1 = discard untagged packets per UNI port
+* drop_untagged - set to 1 = drop untagged packets per UNI port
* set to 0 = alow untagged packets per UNI port.
*
* OUTPUTS:
@@ -1183,7 +1560,7 @@
(
uint32_t owner_id,
tpm_src_port_type_t src_port,
- uint8_t allow_untagged
+ uint8_t drop_untagged
)
{
tpm_error_code_t retVal = TPM_RC_OK;
@@ -1195,11 +1572,11 @@
if (trace_sw_dbg_flag)
{
printk(KERN_INFO
- "==ENTER==%s: owner_id[%d],src_port[%d],allow_untagged[%d]\r\n",
- __FUNCTION__,owner_id,src_port,allow_untagged);
+ "==ENTER==%s: owner_id[%d],src_port[%d],drop_untagged[%d]\r\n",
+ __FUNCTION__,owner_id,src_port,drop_untagged);
}
- if (allow_untagged == 1)
+ if (drop_untagged == 1)
{
mode = 1/*GT_TRUE*/;
}
@@ -2467,9 +2844,9 @@
uint8_t weight
)
{
- tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_error_code_t retVal = GT_OK;
+ tpm_gmacs_enum_t gmac_i;
+ tpm_db_gmac_func_t gmac_func;
if (trace_sw_dbg_flag)
{
@@ -2478,15 +2855,24 @@
__FUNCTION__,owner_id,queue_id,weight);
}
- if ((queue_id == 0) ||
- (queue_id > SW_QOS_NUM_OF_QUEUES))
- {
- printk(KERN_INFO
- "%s:%d:==ERROR== invalid queue[%d]\r\n", __FUNCTION__,__LINE__,queue_id);
- return ERR_SW_TM_QUEUE_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ for (gmac_i = TPM_ENUM_GMAC_0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
+ tpm_db_gmac_func_get(gmac_i, &gmac_func);
+ if (TPM_GMAC_FUNC_LAN_UNI == gmac_func ||
+ TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI == gmac_func)
+ retVal |= mvNetaTxqWrrPrioSet(gmac_i, 0, queue_id, weight);
+ }
+ } else {
+ if ((queue_id == 0) ||
+ (queue_id > SW_QOS_NUM_OF_QUEUES))
+ {
+ printk(KERN_INFO
+ "%s:%d:==ERROR== invalid queue[%d]\r\n", __FUNCTION__,__LINE__,queue_id);
+ return ERR_SW_TM_QUEUE_INVALID;
+ }
- retVal = mv_switch_set_uni_q_weight(queue_id, weight);
+ retVal = mv_switch_set_uni_q_weight(queue_id, weight);
+ }
if (retVal != GT_OK)
{
printk(KERN_ERR
@@ -2543,8 +2929,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PIRL2_COUNT_MODE mode;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
+ tpm_db_gmac_lpk_uni_ingr_rate_limit_t rate_limit;
if (trace_sw_dbg_flag)
{
@@ -2553,16 +2939,38 @@
__FUNCTION__,owner_id,src_port,count_mode, cir, cbs,ebs);
}
- mode = (GT_PIRL2_COUNT_MODE)count_mode;
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Check GMAC1 lpk status, if no lpk, no ingress rate for ingress */
+ if (tpm_db_gmac1_lpbk_en_get()) {
+ retVal = tpm_tm_set_gmac0_ingr_rate_lim(owner_id, cir, cbs);
+ if (retVal == TPM_RC_OK) {
+ rate_limit.count_mode = count_mode;
+ rate_limit.cir = cir;
+ rate_limit.cbs = cbs;
+ rate_limit.ebs = ebs;
+ retVal = tpm_db_gmac_lpk_uni_ingr_rate_limit_set(src_port, rate_limit);
+ }
+ } else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) ingr rate limit not support\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+ } else {
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ mode = (GT_PIRL2_COUNT_MODE)count_mode;
+
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_set_uni_ingr_police_rate(lPort, (GT_PIRL2_COUNT_MODE)mode, cir, cbs, ebs);
}
-
- retVal = mv_switch_set_uni_ingr_police_rate(lPort, (GT_PIRL2_COUNT_MODE)mode, cir, cbs, ebs);
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -2620,8 +3028,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PIRL2_COUNT_MODE mode;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
+ tpm_db_gmac_lpk_uni_ingr_rate_limit_t rate_limit;
if (trace_sw_dbg_flag)
{
@@ -2630,14 +3038,34 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Check GMAC1 lpk status, if no lpk, no ingress rate for ingress */
+ if (tpm_db_gmac1_lpbk_en_get()) {
+ retVal = tpm_db_gmac_lpk_uni_ingr_rate_limit_get(src_port, &rate_limit);
+ if (retVal == TPM_RC_OK) {
+ mode = (GT_PIRL2_COUNT_MODE)rate_limit.count_mode;
+ *cir = rate_limit.cir;
+ *cbs = rate_limit.cbs;
+ *ebs = rate_limit.ebs;
+ }
+ } else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) ingr rate limit not support\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_get_uni_ingr_police_rate(lPort, &mode, cir, cbs, ebs);
+ retVal = mv_switch_get_uni_ingr_police_rate(lPort, &mode, cir, cbs, ebs);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -2836,8 +3264,7 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
if (trace_sw_dbg_flag)
{
@@ -2846,14 +3273,27 @@
__FUNCTION__,owner_id,src_port,mode,frame_rate_limit_val);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Set tx port rate limit on gmac_i */
+ retVal = tpm_tm_set_tx_port_rate_lim(owner_id, gmac_i, frame_rate_limit_val, 0);
+ if (retVal == TPM_RC_OK) {
+ retVal = tpm_db_gmac_uni_egr_rate_limit_set(src_port, frame_rate_limit_val);
+ }
+ } else {
- retVal = mv_switch_set_uni_egr_rate_limit(lPort, (GT_PIRL_ELIMIT_MODE)mode, frame_rate_limit_val);
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_set_uni_egr_rate_limit(lPort, (GT_PIRL_ELIMIT_MODE)mode, frame_rate_limit_val);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -2905,8 +3345,7 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PIRL_ELIMIT_MODE limit_mode;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
if (trace_sw_dbg_flag)
{
@@ -2915,14 +3354,24 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Set tx port rate limit on gmac_i */
+ retVal = tpm_db_gmac_uni_egr_rate_limit_get(src_port, frame_rate_limit_val);
+ limit_mode = GT_PIRL_ELIMIT_FRAME;
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_get_uni_egr_rate_limit(lPort, &limit_mode, frame_rate_limit_val);
+ retVal = mv_switch_get_uni_egr_rate_limit(lPort, &limit_mode, frame_rate_limit_val);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -3033,9 +3482,7 @@
uint32_t time_out
)
{
- tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_error_code_t retVal = TPM_RC_OK;
if (trace_sw_dbg_flag)
{
@@ -3044,7 +3491,19 @@
__FUNCTION__,owner_id,time_out);
}
- retVal = mv_switch_set_age_time(time_out);
+ if (tpm_sw_init_check()) {
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_expire_time_set(time_out);
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) MAC learn not supported\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ retVal = mv_switch_set_age_time(time_out);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -3086,9 +3545,7 @@
uint32_t *time_out
)
{
- tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_error_code_t retVal = TPM_RC_OK;
if (trace_sw_dbg_flag)
{
@@ -3097,7 +3554,19 @@
__FUNCTION__,owner_id);
}
- retVal = mv_switch_get_age_time(time_out);
+ if (tpm_sw_init_check()) {
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_expire_time_get(time_out);
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) MAC learn not supported\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ retVal = mv_switch_get_age_time(time_out);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -3147,8 +3616,7 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
if (trace_sw_dbg_flag)
{
@@ -3162,14 +3630,30 @@
else
state = GT_FALSE;
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+#ifdef CONFIG_MV_MAC_LEARN
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_enable_set(state);
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) MAC learn not supported\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_set_mac_learn(lPort, state);
+ retVal = mv_switch_set_mac_learn(lPort, state);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -3218,8 +3702,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
+ bool mac_learn_enable = false;
if (trace_sw_dbg_flag)
{
@@ -3228,14 +3712,34 @@
__FUNCTION__,owner_id, src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get())
+ retVal = mv_mac_learn_enable_get(&mac_learn_enable);
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) src port(%d) MAC learn not supported\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_GENERAL;
+ }
+ if(mac_learn_enable)
+ state = GT_TRUE;
+ else
+ state = GT_FALSE;
+#endif
+ } else {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_get_mac_learn(lPort, &state);
+ retVal = mv_switch_get_mac_learn(lPort, &state);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -4302,8 +4806,7 @@
tpm_src_port_type_t *extern_port)
{
tpm_error_code_t retVal = TPM_RC_OK;
-
- SWITCH_INIT_CHECK();
+ tpm_init_gmac_conn_conf_t gmac_conn_info;
if (trace_sw_dbg_flag)
{
@@ -4312,8 +4815,19 @@
__FUNCTION__, owner_id, switch_port);
}
- *extern_port = tpm_db_phy_convert_port_index(switch_port);
- if (*extern_port == TPM_DB_ERR_PORT_NUM)
+ if (tpm_sw_init_check()) {
+ if (tpm_db_gmac_conn_conf_get((tpm_gmacs_enum_t)switch_port, &gmac_conn_info)) {
+ printk(KERN_ERR "ERROR: (%s:%d) switch_port(%d) invalid\n", __FUNCTION__, __LINE__, switch_port);
+ return ERR_GENERAL;
+ }
+ if (TPM_TRUE == gmac_conn_info.valid)
+ *extern_port = gmac_conn_info.port_src;
+ else
+ *extern_port = TPM_DB_ERR_PORT_NUM;
+ } else {
+ *extern_port = tpm_db_phy_convert_port_index(switch_port);
+ }
+ if (*extern_port == (tpm_src_port_type_t)TPM_DB_ERR_PORT_NUM)
{
printk(KERN_ERR "ERROR: (%s:%d) switch_port(%d) is invalid\n", __FUNCTION__, __LINE__, switch_port);
return ERR_SRC_PORT_INVALID;
@@ -4374,8 +4888,12 @@
int32_t lPort = 0;
GT_BOOL state, prev_state;
GT_PHY_AUTO_MODE prev_mode;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ uint16_t lsp_mode = PHY_AUTO_NEGO_MODE_HALF_10 |
+ PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_HALF_100 |
+ PHY_AUTO_NEGO_MODE_FULL_100;
if (trace_sw_dbg_flag)
{
@@ -4389,26 +4907,102 @@
else
state = GT_FALSE;
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ switch (autoneg_mode) {
+ case TPM_SPEED_AUTO_DUPLEX_AUTO:
+ lsp_mode = PHY_AUTO_NEGO_MODE_HALF_10 |
+ PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_HALF_100 |
+ PHY_AUTO_NEGO_MODE_FULL_100 |
+ PHY_AUTO_NEGO_MODE_HALF_1000 |
+ PHY_AUTO_NEGO_MODE_FULL_1000;
+ break;
+ case TPM_SPEED_1000_DUPLEX_AUTO:
+ lsp_mode = PHY_AUTO_NEGO_MODE_HALF_1000 |
+ PHY_AUTO_NEGO_MODE_FULL_1000;
+ break;
+ case TPM_SPEED_100_DUPLEX_AUTO:
+ lsp_mode = PHY_AUTO_NEGO_MODE_FULL_100 |
+ PHY_AUTO_NEGO_MODE_HALF_100;
+ break;
+ case TPM_SPEED_10_DUPLEX_AUTO:
+ lsp_mode = PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_HALF_10;
+ break;
+ case TPM_SPEED_AUTO_DUPLEX_FULL:
+ lsp_mode = PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_FULL_100 |
+ PHY_AUTO_NEGO_MODE_FULL_1000;
+ break;
+ case TPM_SPEED_AUTO_DUPLEX_HALF:
+ lsp_mode = PHY_AUTO_NEGO_MODE_HALF_1000 |
+ PHY_AUTO_NEGO_MODE_HALF_100 |
+ PHY_AUTO_NEGO_MODE_HALF_10;
+ break;
+ case TPM_SPEED_1000_DUPLEX_FULL:
+ lsp_mode = PHY_AUTO_NEGO_MODE_FULL_1000;
+ break;
+ case TPM_SPEED_1000_DUPLEX_HALF:
+ lsp_mode = PHY_AUTO_NEGO_MODE_HALF_1000;
+ break;
+ case TPM_SPEED_100_DUPLEX_FULL:
+ lsp_mode = PHY_AUTO_NEGO_MODE_FULL_100;
+ break;
+ case TPM_SPEED_100_DUPLEX_HALF:
+ lsp_mode = PHY_AUTO_NEGO_MODE_HALF_100;
+ break;
+ case TPM_SPEED_10_DUPLEX_FULL:
+ lsp_mode = PHY_AUTO_NEGO_MODE_FULL_10;
+ break;
+ case TPM_SPEED_10_DUPLEX_HALF:
+ lsp_mode = PHY_AUTO_NEGO_MODE_HALF_10;
+ break;
+ default:
+ printk(KERN_ERR "ERROR: (%s:%d) invalid autoneg_mode\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
}
-
- if (TPM_RC_OK == (retVal = mv_switch_get_port_autoneg_mode(lPort, &prev_state, &prev_mode)))
- {
- if (prev_state != state || prev_mode != (GT_PHY_AUTO_MODE)autoneg_mode)
- {
- retVal = mv_switch_set_port_autoneg_mode(lPort, state, (GT_PHY_AUTO_MODE)autoneg_mode);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyAutoNegoSet(phy_direct_addr, state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ if (state && (retVal == TPM_RC_OK)) {
+ if (mvEthPhyAdvertiseSet(phy_direct_addr, lsp_mode)) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ if (TPM_RC_OK == (retVal = mv_switch_get_port_autoneg_mode(lPort, &prev_state, &prev_mode)))
+ {
+ if (prev_state != state || prev_mode != (GT_PHY_AUTO_MODE)autoneg_mode)
+ {
+ retVal = mv_switch_set_port_autoneg_mode(lPort, state, (GT_PHY_AUTO_MODE)autoneg_mode);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
}
}
-
if (trace_sw_dbg_flag)
{
printk(KERN_INFO
@@ -4465,8 +5059,9 @@
int32_t lPort = 0;
GT_BOOL state;
GT_PHY_AUTO_MODE mode;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ uint16_t lsp_mode;
if (trace_sw_dbg_flag)
{
@@ -4475,18 +5070,97 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_autoneg_mode(lPort, &state, &mode);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyAutoNegoGet(phy_direct_addr, (int *)&state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ if (state && (retVal == TPM_RC_OK)) {
+ if (mvEthPhyAdvertiseGet(phy_direct_addr, &lsp_mode)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ switch (lsp_mode) {
+ case (PHY_AUTO_NEGO_MODE_HALF_10 |
+ PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_HALF_100 |
+ PHY_AUTO_NEGO_MODE_FULL_100 |
+ PHY_AUTO_NEGO_MODE_HALF_1000 |
+ PHY_AUTO_NEGO_MODE_FULL_1000):
+ mode = TPM_SPEED_AUTO_DUPLEX_AUTO;
+ break;
+ case (PHY_AUTO_NEGO_MODE_HALF_1000 |
+ PHY_AUTO_NEGO_MODE_FULL_1000):
+ mode = TPM_SPEED_1000_DUPLEX_AUTO;
+ break;
+ case (PHY_AUTO_NEGO_MODE_FULL_100 |
+ PHY_AUTO_NEGO_MODE_HALF_100):
+ mode = TPM_SPEED_100_DUPLEX_AUTO;
+ break;
+ case (PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_HALF_10):
+ mode = TPM_SPEED_10_DUPLEX_AUTO;
+ break;
+ case (PHY_AUTO_NEGO_MODE_FULL_10 |
+ PHY_AUTO_NEGO_MODE_FULL_100 |
+ PHY_AUTO_NEGO_MODE_FULL_1000):
+ mode = TPM_SPEED_AUTO_DUPLEX_FULL;
+ break;
+ case (PHY_AUTO_NEGO_MODE_HALF_1000 |
+ PHY_AUTO_NEGO_MODE_HALF_100 |
+ PHY_AUTO_NEGO_MODE_HALF_10):
+ mode = TPM_SPEED_AUTO_DUPLEX_HALF;
+ break;
+ case PHY_AUTO_NEGO_MODE_FULL_1000:
+ mode = TPM_SPEED_1000_DUPLEX_FULL;
+ break;
+ case PHY_AUTO_NEGO_MODE_HALF_1000:
+ mode = TPM_SPEED_1000_DUPLEX_HALF;
+ break;
+ case PHY_AUTO_NEGO_MODE_FULL_100:
+ mode = TPM_SPEED_100_DUPLEX_FULL;
+ break;
+ case PHY_AUTO_NEGO_MODE_HALF_100:
+ mode = TPM_SPEED_100_DUPLEX_HALF;
+ break;
+ case PHY_AUTO_NEGO_MODE_FULL_10:
+ mode = TPM_SPEED_10_DUPLEX_FULL;
+ break;
+ case PHY_AUTO_NEGO_MODE_HALF_10:
+ mode = TPM_SPEED_10_DUPLEX_HALF;
+ break;
+ default:
+ mode = TPM_SPEED_AUTO_DUPLEX_AUTO;
+ break;
+ }
+ } else {
+ mode = TPM_SPEED_AUTO_DUPLEX_AUTO;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_get_port_autoneg_mode(lPort, &state, &mode);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if(GT_TRUE == state)
@@ -4510,6 +5184,8 @@
*
* DESCRIPTION:
* The API restart the auto negotiation of an Ethernet UNI port.
+* If AutoNegotiation is not enabled, it'll enable it.
+* Loopback and Power Down will be disabled by this routine.
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
@@ -4535,8 +5211,9 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+
if (trace_sw_dbg_flag)
{
@@ -4545,18 +5222,35 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_restart_port_autoneg(lPort);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyRestartAN(phy_direct_addr, 0)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_restart_port_autoneg(lPort);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if (trace_sw_dbg_flag)
@@ -4601,8 +5295,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state, prev_state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -4616,22 +5310,39 @@
else
state = GT_FALSE;
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
}
-
- if (TPM_RC_OK == (retVal = mv_switch_get_phy_port_state(lPort, &prev_state)))
- {
- if (prev_state != state)
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhySetAdminState(phy_direct_addr, (int)state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
{
- retVal = mv_switch_set_phy_port_state(lPort, state);
- if (retVal != TPM_RC_OK)
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ if (TPM_RC_OK == (retVal = mv_switch_get_phy_port_state(lPort, &prev_state)))
+ {
+ if (prev_state != state)
{
- printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ retVal = mv_switch_set_phy_port_state(lPort, state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
}
}
@@ -4677,8 +5388,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -4686,19 +5397,35 @@
"==ENTER==%s: owner_id[%d],src_port[%d]\n\r",
__FUNCTION__,owner_id,src_port);
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_phy_port_state(lPort, &state);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyGetAdminState(phy_direct_addr, (int *)&state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_get_phy_port_state(lPort, &state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if(state == GT_TRUE)
@@ -4747,8 +5474,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -4756,19 +5483,31 @@
"==ENTER==%s: owner_id[%d],src_port[%d]\n\r",
__FUNCTION__,owner_id,src_port);
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_link_status(lPort, &state);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ state = (GT_BOOL)mvEthPhyCheckLink(phy_direct_addr);
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_get_port_link_status(lPort, &state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if(state == GT_TRUE)
@@ -4804,7 +5543,11 @@
* On error different types are returned according to the case, see tpm_error_code_t.
*
* COMMENTS:
-*
+* This function is different from tpm_phy_get_port_duplex_mode, it reflects the real duplex status happening
+* in PHY now. If there is a switch, through PPU function, switch can get the duplex info from PHY and
+* store it in switch port register, so duplex info can be got from switch port register. It is a
+* "get_xxx_oper" function. If there is no switch, this info can be read from PHY spec status register,
+* offset 17
*
*******************************************************************************/
tpm_error_code_t tpm_phy_get_port_duplex_status
@@ -4816,9 +5559,9 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
- GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ GT_BOOL state, status_valid;
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -4826,19 +5569,41 @@
"==ENTER==%s: owner_id[%d],src_port[%d]\n\r",
__FUNCTION__,owner_id,src_port);
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_duplex_status(lPort, &state);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyDuplexOperGet(phy_direct_addr, (int *)&status_valid, (int *)&state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+
+ if (status_valid == GT_FALSE) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY duplex status is not valid on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_STATUS_UNKNOWN;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_get_port_duplex_status(lPort, &state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if(state == GT_TRUE)
@@ -4875,8 +5640,11 @@
* On error different types are returned according to the case, see tpm_error_code_t.
*
* COMMENTS:
-*
-*
+* This function is different from "tpm_phy_get_port_speed ", it reflects what really happens
+* in PHY. If there is a switch, this function will get the stats info from switch register,
+* because the PPU function will make the switch get the PHY status info and store it in port
+* register. If there is no switch, speed mode info can be got from PHY register spec status
+* register, offset is 17.
*******************************************************************************/
tpm_error_code_t tpm_phy_get_port_speed_mode
(
@@ -4888,8 +5656,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PORT_SPEED_MODE tmpSpeed;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -4897,19 +5665,41 @@
"==ENTER==%s: owner_id[%d],src_port[%d]\n\r",
__FUNCTION__,owner_id,src_port);
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_speed_mode(lPort, &tmpSpeed);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhySpeedOperGet(phy_direct_addr, (uint32_t *)&tmpSpeed)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+
+ if (tmpSpeed == PORT_SPEED_UNKNOWN) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY speed status is not valid on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_STATUS_UNKNOWN;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_get_port_speed_mode(lPort, &tmpSpeed);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
*speed = (uint32_t)tmpSpeed;
@@ -4943,7 +5733,8 @@
* On success - TPM_RC_OK.
* On error different types are returned according to the case - see tpm_error_code_t.
* COMMENTS:
-* data sheet register 4.10 Autonegotiation Advertisement Register
+* This function reflect flow control configuration info, it only access PHY register,
+* that is data sheet register 4.10 Autonegotiation Advertisement Register.
*******************************************************************************/
tpm_error_code_t tpm_phy_set_port_flow_control_support
@@ -4956,8 +5747,10 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PHY_PAUSE_MODE pause_state, prev_state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ uint32_t switch_init;
+ tpm_gmacs_enum_t gmac_port;
if (trace_sw_dbg_flag)
{
@@ -4971,33 +5764,100 @@
else
pause_state = GT_PHY_NO_PAUSE;
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
}
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (tpm_db_switch_init_get(&switch_init) != TPM_DB_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_db_switch_init_get Failed\n", __FUNCTION__, __LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+ /* Only PHY connected to GMAC, need write GMAC register */
+ if (!switch_init) {
+ for (gmac_port = TPM_ENUM_GMAC_0; gmac_port < TPM_MAX_NUM_GMACS; gmac_port++) {
+ if (phy_direct_addr == mvBoardPhyAddrGet(gmac_port))
+ break;
+ }
+ if (gmac_port == TPM_MAX_NUM_GMACS) {
+ printk(KERN_ERR "ERROR: (%s:%d) Can not find gmac port\n", __FUNCTION__, __LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
- if (TPM_RC_OK == (retVal = mv_switch_get_port_pause(lPort, &prev_state)))
- {
- if (prev_state != pause_state)
- {
- retVal = mv_switch_set_port_pause(lPort, pause_state);
- if (retVal != TPM_RC_OK)
+ /* Write Flow Control reg on GMAC port */
+ switch(pause_state) {
+ case GT_PHY_NO_PAUSE:
+ if (mvNetaFlowCtrlSet((int)gmac_port, MV_ETH_FC_DISABLE) != MV_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) mvNetaFlowCtrlSet Failed\n", __FUNCTION__, __LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+ break;
+ case GT_PHY_PAUSE:
+ if (mvNetaFlowCtrlSet((int)gmac_port, MV_ETH_FC_ENABLE) != MV_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) mvNetaFlowCtrlSet Failed\n", __FUNCTION__, __LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+ break;
+ default:
+ printk(KERN_ERR "ERROR: (%s:%d)Invalid flow control mode%d\n", __FUNCTION__, __LINE__, pause_state);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+ } else {
+ /* Flow control info can not be got from linkpartner through QSGMII auto negitiation, so manual needed */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
{
- printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ /* Set force FC value */
+ if ((retVal = mv_switch_set_port_forced_fc_value(lPort, state)) != TPM_RC_OK) {
+ printk(KERN_ERR "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ return retVal;
+ }
+ /* Set force FC */
+ if ((retVal = mv_switch_set_port_forced_flow_control(lPort, state)) != TPM_RC_OK) {
+ printk(KERN_ERR "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ return retVal;
+ }
+ }
+ if (mvEthPhyPauseSet(phy_direct_addr, (uint32_t)pause_state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ if (TPM_RC_OK == (retVal = mv_switch_get_port_pause(lPort, &prev_state)))
+ {
+ if (prev_state != pause_state)
+ {
+ retVal = mv_switch_set_port_pause(lPort, pause_state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
}
}
- //retVal = mv_switch_restart_port_autoneg(port);
- // if (retVal != TPM_RC_OK)
- // {
- // printk(KERN_ERR
- // "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
- // }
-
if (trace_sw_dbg_flag)
{
printk(KERN_INFO
@@ -5037,8 +5897,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PHY_PAUSE_MODE pause_state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -5046,19 +5906,35 @@
"==ENTER==%s: owner_id[%d],src_port[%d]\n\r",
__FUNCTION__,owner_id,src_port);
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_pause(lPort, &pause_state);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyPauseAdminGet(phy_direct_addr, (uint32_t *)&pause_state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_get_port_pause(lPort, &pause_state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if(pause_state == GT_PHY_NO_PAUSE)
@@ -5096,7 +5972,11 @@
* On success - TPM_RC_OK.
* On error different types are returned according to the case, see tpm_error_code_t.
* COMMENTS:
-* None.
+* This function is different from function tpm_phy_set_port_flow_control_support(),
+* it reflects the flow control info on MAC of PHY, so this info can only be got from
+* MAC, PHY connected to. If there is a switch, this info can be got from switch port register,
+* if there is no switch connected to PHY, this info can be got from the MAC connected to it,
+* such as GMAC0.
*******************************************************************************/
tpm_error_code_t tpm_phy_get_port_flow_control_state
(
@@ -5108,8 +5988,11 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL fc_state;
-
- SWITCH_INIT_CHECK();
+ uint32_t switch_init;
+ tpm_gmacs_enum_t gmac_port;
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ uint32_t fc_mode;
if (trace_sw_dbg_flag)
{
@@ -5118,25 +6001,61 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ /* Check swicth init or not */
+ if (tpm_db_switch_init_get(&switch_init) != TPM_DB_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_db_switch_init_get failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
}
+ if (switch_init) {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- retVal = mv_switch_get_port_pause_state(lPort, &fc_state);
- if (retVal != TPM_RC_OK)
- {
- printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ retVal = mv_switch_get_port_pause_state(lPort, &fc_state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ if(fc_state == GT_FALSE)
+ *state = false;
+ else
+ *state = true;
+ } else {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ for (gmac_port = TPM_ENUM_GMAC_0; gmac_port < TPM_MAX_NUM_GMACS; gmac_port++) {
+ if (phy_direct_addr == mvBoardPhyAddrGet(gmac_port))
+ break;
+ }
+ if (gmac_port == TPM_MAX_NUM_GMACS) {
+ printk(KERN_ERR "ERROR: (%s:%d) Can not find gmac port\n", __FUNCTION__, __LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+
+ /* Get GMAC Flow Control state */
+ if (mvNetaFlowCtrlGet((int)gmac_port, &fc_mode) != MV_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) Can not find gmac port\n", __FUNCTION__, __LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+
+ if (fc_mode == MV_ETH_FC_DISABLE)
+ *state = false;
+ else
+ *state = true;
}
- if(fc_state == GT_FALSE)
- *state = false;
- else
- *state = true;
-
if (trace_sw_dbg_flag)
{
printk(KERN_INFO
@@ -5179,8 +6098,10 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state, link_forced;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ uint32_t switch_init;
+ uint32_t gmac_idx;
if (trace_sw_dbg_flag)
{
@@ -5197,25 +6118,40 @@
{
state = GT_FALSE;
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
}
-
- switch((GT_PHY_LOOPBACK_MODE)mode)
- {
- case PHY_INTERNAL_LOOPBACK:
- if (lPort == INT_GE_PHY_SWITCH_PORT)
- {
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (PHY_INTERNAL_LOOPBACK == (GT_PHY_LOOPBACK_MODE)mode) {
+ if (mvEthPhyLoopbackSet(phy_direct_addr, state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ /* Force switch port link up if QSGMII mode with switch */
+ retVal = tpm_db_switch_init_get(&switch_init);
+ if (retVal) {
+ printk(KERN_ERR "ERROR: (%s:%d)switch init get failed\n", __FUNCTION__, __LINE__);
+ return retVal;
+ }
+ if (switch_init) {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
retVal = mv_switch_get_port_forced_link(lPort, &link_forced);
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
"%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
- break;
+ return retVal;
}
if (((state == GT_TRUE) && (link_forced == GT_FALSE)) ||
((state == GT_FALSE)&& (link_forced == GT_TRUE)))
@@ -5225,30 +6161,101 @@
{
printk(KERN_ERR
"%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
- break;
+ return retVal;
}
retVal = mv_switch_set_port_link_value(lPort, state);
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
"%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
- break;
+ return retVal;
}
}
+ } else {
+ /* get GMAC with Phyaddr */
+ for (gmac_idx = TPM_ENUM_GMAC_0; gmac_idx < TPM_MAX_NUM_GMACS; gmac_idx++) {
+ if (phy_direct_addr == mvBoardPhyAddrGet(gmac_idx))
+ break;
+ }
+ if (gmac_idx == TPM_MAX_NUM_GMACS) {
+ printk(KERN_ERR
+ "%s:%d: GMAC get with phyaddr invalid\r\n", __FUNCTION__,__LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
+ /* Force gmac link or disable it */
+ if (mvNetaForceLinkModeSet(gmac_idx, state, 0)) {
+ printk(KERN_ERR
+ "%s:%d: GMAC force link set failed\r\n", __FUNCTION__,__LINE__);
+ retVal = ERR_GENERAL;
+ return retVal;
+ }
}
- retVal = mv_switch_set_port_loopback(lPort, state);
- break;
- case PHY_EXTERNAL_LOOPBACK:
- retVal = mv_switch_set_port_line_loopback(lPort, state);
- break;
- default:
- break;
+ } else if (PHY_EXTERNAL_LOOPBACK == (GT_PHY_LOOPBACK_MODE)mode) {
+ if (mvEthPhyLineLoopbackSet(phy_direct_addr, state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ printk(KERN_INFO
+ "==ENTER==%s: mode[%d] invalid\n\r", __FUNCTION__,mode);
+ retVal = ERR_GENERAL;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- }
- if (retVal != TPM_RC_OK)
- {
- printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ switch((GT_PHY_LOOPBACK_MODE)mode)
+ {
+ case PHY_INTERNAL_LOOPBACK:
+ if (lPort == INT_GE_PHY_SWITCH_PORT)
+ {
+ retVal = mv_switch_get_port_forced_link(lPort, &link_forced);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ break;
+ }
+ if (((state == GT_TRUE) && (link_forced == GT_FALSE)) ||
+ ((state == GT_FALSE)&& (link_forced == GT_TRUE)))
+ {
+ retVal = mv_switch_set_port_forced_link(lPort, state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ break;
+ }
+ retVal = mv_switch_set_port_link_value(lPort, state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ break;
+ }
+ }
+ }
+ retVal = mv_switch_set_port_loopback(lPort, state);
+ break;
+ case PHY_EXTERNAL_LOOPBACK:
+ retVal = mv_switch_set_port_line_loopback(lPort, state);
+ break;
+ default:
+ break;
+
+ }
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if (trace_sw_dbg_flag)
@@ -5291,8 +6298,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -5300,29 +6307,57 @@
"==ENTER==%s: owner_id[%d],src_port[%d], mode[%d]\n\r",
__FUNCTION__,owner_id,src_port, mode);
}
-
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- switch((GT_PHY_LOOPBACK_MODE)mode)
- {
- case PHY_INTERNAL_LOOPBACK:
- retVal = mv_switch_get_port_loopback(lPort, &state);
- break;
- case PHY_EXTERNAL_LOOPBACK:
- retVal = mv_switch_get_port_line_loopback(lPort, &state);
- break;
- default:
- break;
- }
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (PHY_INTERNAL_LOOPBACK == (GT_PHY_LOOPBACK_MODE)mode) {
+ if (mvEthPhyLoopbackGet(phy_direct_addr, (int *)&state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else if (PHY_EXTERNAL_LOOPBACK == (GT_PHY_LOOPBACK_MODE)mode) {
+ if (mvEthPhyLineLoopbackGet(phy_direct_addr, (int *)&state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ printk(KERN_INFO
+ "==ENTER==%s: mode[%d] invalid\n\r", __FUNCTION__,mode);
+ retVal = ERR_GENERAL;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ switch((GT_PHY_LOOPBACK_MODE)mode)
+ {
+ case PHY_INTERNAL_LOOPBACK:
+ retVal = mv_switch_get_port_loopback(lPort, &state);
+ break;
+ case PHY_EXTERNAL_LOOPBACK:
+ retVal = mv_switch_get_port_line_loopback(lPort, &state);
+ break;
+ default:
+ break;
+ }
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if(state == GT_TRUE)
@@ -5377,8 +6412,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -5396,18 +6431,35 @@
state = GT_FALSE;
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_set_port_duplex_mode(lPort, state);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyDuplexModeSet(phy_direct_addr, state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_set_port_duplex_mode(lPort, state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if (trace_sw_dbg_flag)
@@ -5438,7 +6490,8 @@
* On error different types are returned according to the case , see tpm_error_code_t.
*
* COMMENTS:
-* data sheet register 0.8 - Duplex Mode
+* This function will get the duplex configuration info just from PHY's control register
+* that is data sheet register 0.8 - Duplex Mode. It is a "get_xxx_admin" function.
*
*******************************************************************************/
tpm_error_code_t tpm_phy_get_port_duplex_mode
@@ -5451,8 +6504,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_BOOL state;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -5461,27 +6514,43 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_duplex_mode(lPort, &state);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
}
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhyDuplexModeAdminGet(phy_direct_addr, (int *)&state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- if (trace_sw_dbg_flag)
- {
- printk(KERN_INFO
- "==EXIT== %s:enable[%d]\n\r",__FUNCTION__, *enable);
+ retVal = mv_switch_get_port_duplex_mode(lPort, &state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==EXIT== %s:enable[%d]\n\r",__FUNCTION__, *enable);
+ }
}
-
if(state == GT_TRUE)
{
*enable = true;
@@ -5527,8 +6596,8 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -5537,18 +6606,35 @@
__FUNCTION__,owner_id,src_port, (uint32_t)speed);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_set_port_speed(lPort, (GT_PHY_SPEED)speed);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhySpeedSet(phy_direct_addr, speed)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_set_port_speed(lPort, (GT_PHY_SPEED)speed);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
}
if (trace_sw_dbg_flag)
@@ -5581,6 +6667,8 @@
* On success - TPM_RC_OK.
* On error different types are returned according to the case - see tpm_error_code_t.
* COMMENTS:
+* This function get the PHY config information from PHY controlregister, it is a
+* "get_xxx_admin" function, it reflect the configuration to PHY and it only access PHY register.
*
*******************************************************************************/
tpm_error_code_t tpm_phy_get_port_speed
@@ -5593,8 +6681,8 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_PHY_SPEED lSpeed;
-
- SWITCH_INIT_CHECK();
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
if (trace_sw_dbg_flag)
{
@@ -5603,21 +6691,38 @@
__FUNCTION__,owner_id,src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
-
- retVal = mv_switch_get_port_speed(lPort, &lSpeed);
- if (retVal != TPM_RC_OK)
- {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
}
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhySpeedAdminGet(phy_direct_addr, speed)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- *speed = (tpm_phy_speed_t)lSpeed;
+ retVal = mv_switch_get_port_speed(lPort, &lSpeed);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ *speed = (tpm_phy_speed_t)lSpeed;
+ }
if (trace_sw_dbg_flag)
{
@@ -5658,9 +6763,9 @@
void
)
{
- tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_error_code_t retVal = TPM_RC_OK;
+ tpm_gmacs_enum_t gmac_i;
+ tpm_db_gmac_func_t gfunc;
if (trace_sw_dbg_flag)
{
@@ -5668,7 +6773,17 @@
"==ENTER==%s:\n\r",__FUNCTION__);
}
- retVal = mv_switch_clear_port_counters();
+ if (tpm_sw_init_check()) {
+ for (gmac_i = TPM_ENUM_GMAC_0; gmac_i < TPM_MAX_NUM_GMACS; gmac_i++) {
+ tpm_db_gmac_func_get(gmac_i, &gfunc);
+ if (gfunc == TPM_GMAC_FUNC_LAN_UNI ||
+ gfunc == TPM_GMAC_FUNC_US_MAC_LEARN_DS_LAN_UNI) {
+ MV_NETA_PORT_CTRL *pPortCtrl = mvNetaPortHndlGet(gmac_i);
+ mvNetaMibCountersClear(gmac_i, pPortCtrl->txpNum);
+ }
+ }
+ } else
+ retVal = mv_switch_clear_port_counters();
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -5938,8 +7053,7 @@
)
{
tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_gmacs_enum_t gmac_i;
if (trace_sw_dbg_flag)
{
@@ -5948,7 +7062,14 @@
__FUNCTION__,owner_id,lport);
}
- retVal = mv_switch_print_port_counters(lport);
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(lport, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, lport);
+ return ERR_SRC_PORT_INVALID;
+ }
+ retVal = tpm_sw_pm_print_from_gmac(gmac_i);
+ } else
+ retVal = mv_switch_print_port_counters(lport);
if (retVal != TPM_RC_OK)
{
printk(KERN_INFO
@@ -5994,6 +7115,8 @@
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
+ tpm_gmacs_enum_t gmac_i;
+ MV_NETA_PORT_CTRL *pPortCtrl;
SWITCH_INIT_CHECK();
@@ -6003,14 +7126,24 @@
"==ENTER==%s:\n\r",__FUNCTION__);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
- }
+ if (tpm_sw_init_check()) {
+ if (tpm_src_port_mac_map(src_port, &gmac_i)) {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) map to mac failed\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+ pPortCtrl = mvNetaPortHndlGet(gmac_i);
+ mvNetaMibCountersClear(gmac_i, pPortCtrl->txpNum);
+ } else {
- retVal = mv_switch_clean_port_counters(lPort);
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_clean_port_counters(lPort);
+ }
if (retVal != TPM_RC_OK)
{
printk(KERN_ERR
@@ -6027,6 +7160,205 @@
}
/*******************************************************************************
+* tpm_sw_pm_from_gmac
+*
+*
+* INPUTS:
+* port - GMAC port.
+* OUTPUTS:
+* tpm_swport_pm_1 - Holds PM data1
+* tpm_swport_pm_3 - Holds PM data all
+*
+* RETURNS:
+* TPM_RC_OK - on success, else error code
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_pm_from_gmac(int port,
+ tpm_swport_pm_1_t *tpm_swport_pm_1,
+ tpm_swport_pm_3_all_t *tpm_swport_pm_3)
+{
+ uint32_t regVaLo, regValHi = 0;
+ int32_t mib = 0;
+
+ /* Check Input */
+ if (tpm_swport_pm_1 == NULL || tpm_swport_pm_3 == NULL) {
+ printk(KERN_ERR "ERROR: (%s:%d) Invalid Input\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+
+ /* Check GMAC Port */
+ if (mvNetaTxpCheck(port, mib)) {
+ printk(KERN_ERR "ERROR: (%s:%d) mvNetaTxpCheck failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+ if (!mvNetaPortHndlGet(port)) {
+ printk(KERN_ERR "ERROR: (%s:%d) mvNetaPortHndlGet failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+
+ /* Initialize tpm_swport_pm_3 as Zero */
+ memset(tpm_swport_pm_1, 0, sizeof(tpm_swport_pm_1_t));
+ memset(tpm_swport_pm_3, 0, sizeof(tpm_swport_pm_3_all_t));
+
+ /* Read counter */
+ tpm_swport_pm_3->dropEvents = MV_REG_READ(ETH_RX_DISCARD_PKTS_CNTR_REG(port));
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW, ®ValHi);
+ tpm_swport_pm_3->InGoodOctetsLo = regVaLo;
+ tpm_swport_pm_3->InGoodOctetsHi = regValHi;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_BAD_OCTETS_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->InBadOctets = regVaLo;
+
+ tpm_swport_pm_3->Deferred = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
+ tpm_swport_pm_1->deferredTransmissionCounter = tpm_swport_pm_3->Deferred;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_BROADCAST_FRAMES_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->InBroadcasts = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_MULTICAST_FRAMES_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->InMulticasts = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAMES_64_OCTETS, ®ValHi);
+ tpm_swport_pm_3->Octets64 = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAMES_65_TO_127_OCTETS, ®ValHi);
+ tpm_swport_pm_3->Octets127 = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAMES_128_TO_255_OCTETS, ®ValHi);
+ tpm_swport_pm_3->Octets255 = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAMES_256_TO_511_OCTETS, ®ValHi);
+ tpm_swport_pm_3->Octets511 = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAMES_512_TO_1023_OCTETS, ®ValHi);
+ tpm_swport_pm_3->Octets1023 = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, ®ValHi);
+ tpm_swport_pm_3->OctetsMax = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_GOOD_OCTETS_SENT_LOW, ®ValHi);
+ tpm_swport_pm_3->OutOctetsLo = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_GOOD_OCTETS_SENT_HIGH, ®ValHi);
+ tpm_swport_pm_3->OutOctetsHi = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_EXCESSIVE_COLLISION, ®ValHi);
+ tpm_swport_pm_1->excessiveCollisionCounter = regVaLo;
+ tpm_swport_pm_3->Excessive = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_MULTICAST_FRAMES_SENT, ®ValHi);
+ tpm_swport_pm_3->OutMulticasts = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_BROADCAST_FRAMES_SENT, ®ValHi);
+ tpm_swport_pm_3->OutBroadcasts = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FC_SENT, ®ValHi);
+ tpm_swport_pm_3->OutPause = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_GOOD_FC_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->InPause = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_UNDERSIZE_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->Undersize = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_FRAGMENTS_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->Fragments = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_OVERSIZE_RECEIVED, ®ValHi);
+ tpm_swport_pm_1->frameTooLongs = regVaLo;
+ tpm_swport_pm_3->Oversize = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_JABBER_RECEIVED, ®ValHi);
+ tpm_swport_pm_3->Jabber = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_MAC_RECEIVE_ERROR, ®ValHi);
+ tpm_swport_pm_3->InMACRcvErr = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_BAD_CRC_EVENT, ®ValHi);
+ tpm_swport_pm_3->InFCSErr = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_COLLISION, ®ValHi);
+ tpm_swport_pm_3->Collisions = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_LATE_COLLISION, ®ValHi);
+ tpm_swport_pm_3->Late = regVaLo;
+
+ regVaLo = mvNetaMibCounterRead(port, mib, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, ®ValHi);
+ tpm_swport_pm_1->internalMacTransmitErrorCounter = regVaLo;
+
+ return TPM_RC_OK;
+}
+
+/*******************************************************************************
+* tpm_sw_pm_print_from_gmac
+*
+*
+* INPUTS:
+* port - GMAC port.
+* OUTPUTS:
+* tpm_swport_pm_1 - Holds PM data1
+* tpm_swport_pm_3 - Holds PM data all
+*
+* RETURNS:
+* TPM_RC_OK - on success, else error code
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_pm_print_from_gmac(int port)
+{
+ tpm_error_code_t retVal = TPM_RC_OK;
+ tpm_swport_pm_3_all_t tpm_swport_pm_3;
+ tpm_swport_pm_1_t tpm_swport_pm_1;
+ MV_NETA_PORT_CTRL *pPortCtrl = mvNetaPortHndlGet(port);
+
+ retVal = tpm_sw_pm_from_gmac(port, &tpm_swport_pm_1, &tpm_swport_pm_3);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ return retVal;
+ }
+ printk("=======Counters from port[%d]=======\n",port);
+ printk("InGoodOctetsLo %08d ", tpm_swport_pm_3.InGoodOctetsLo);
+ printk("InGoodOctetsHi %08d \n", tpm_swport_pm_3.InGoodOctetsHi);
+ printk("InBadOctets %08d ", tpm_swport_pm_3.InBadOctets);
+ printk("OutFCSErr %08d \n", tpm_swport_pm_3.OutFCSErr);
+ printk("InUnicasts %08d ", tpm_swport_pm_3.InUnicasts);
+ printk("Deferred %08d \n", tpm_swport_pm_3.Deferred);
+ printk("InBroadcasts %08d ", tpm_swport_pm_3.InBroadcasts);
+ printk("InMulticasts %08d \n", tpm_swport_pm_3.InMulticasts);
+ printk("64Octets %08d ", tpm_swport_pm_3.Octets64);
+ printk("127Octets %08d \n", tpm_swport_pm_3.Octets127);
+ printk("255Octets %08d ", tpm_swport_pm_3.Octets255);
+ printk("511Octets %08d \n", tpm_swport_pm_3.Octets511);
+ printk("1023Octets %08d ", tpm_swport_pm_3.Octets1023);
+ printk("MaxOctets %08d \n", tpm_swport_pm_3.OctetsMax);
+ printk("OutOctetsLo %08d ", tpm_swport_pm_3.OutOctetsLo);
+ printk("OutOctetsHi %08d \n", tpm_swport_pm_3.OutOctetsHi);
+ printk("OutUnicasts %08d ", tpm_swport_pm_3.OutUnicasts);
+ printk("Excessive %08d \n", tpm_swport_pm_3.Excessive);
+ printk("OutMulticasts %08d ", tpm_swport_pm_3.OutMulticasts);
+ printk("OutBroadcasts %08d \n", tpm_swport_pm_3.OutBroadcasts);
+ printk("Single %08d ", tpm_swport_pm_3.Single);
+ printk("OutPause %08d \n", tpm_swport_pm_3.OutPause);
+ printk("InPause %08d ", tpm_swport_pm_3.InPause);
+ printk("Multiple %08d \n", tpm_swport_pm_3.Multiple);
+ printk("Undersize %08d ", tpm_swport_pm_3.Undersize);
+ printk("Fragments %08d \n", tpm_swport_pm_3.Fragments);
+ printk("Oversize %08d ", tpm_swport_pm_3.Oversize);
+ printk("Jabber %08d \n", tpm_swport_pm_3.Jabber);
+ printk("InMACRcvErr %08d ", tpm_swport_pm_3.InMACRcvErr);
+ printk("InFCSErr %08d \n", tpm_swport_pm_3.InFCSErr);
+ printk("Collisions %08d ", tpm_swport_pm_3.Collisions);
+ printk("Late %08d \n", tpm_swport_pm_3.Late);
+
+ /* Flush all counters */
+ mvNetaMibCountersClear(port, pPortCtrl->txpNum);
+
+ return retVal;
+}
+
+/*******************************************************************************
* tpm_sw_pm_1_read
*
*
@@ -6052,8 +7384,11 @@
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_STATS_COUNTER_SET3 statsCounterSet;
-
- SWITCH_INIT_CHECK();
+ uint32_t switch_init;
+ tpm_gmacs_enum_t gmac_port;
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ tpm_swport_pm_3_all_t tpm_swport_pm_3;
if (trace_sw_dbg_flag)
{
@@ -6062,34 +7397,65 @@
__FUNCTION__,owner_id, src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ /* Check swicth init or not */
+ if (tpm_db_switch_init_get(&switch_init) != TPM_DB_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_db_switch_init_get failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
}
- retVal = mv_switch_get_port_counters(lPort, &statsCounterSet);
- if (retVal != TPM_RC_OK)
- {
- printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
- }
+ if (switch_init) {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- tpm_swport_pm_1->fcsErrors = statsCounterSet.InFCSErr;
- tpm_swport_pm_1->excessiveCollisionCounter = statsCounterSet.Excessive;
- tpm_swport_pm_1->lateCollisionCounter = statsCounterSet.Late;
- tpm_swport_pm_1->frameTooLongs = statsCounterSet.Oversize;
- tpm_swport_pm_1->bufferOverflowsOnReceive = 0;
- tpm_swport_pm_1->bufferOverflowsOnTransmit = 0;
- tpm_swport_pm_1->singleCollisionFrameCounter = statsCounterSet.Single;
- tpm_swport_pm_1->multipleCollisionsFrameCounter = statsCounterSet.Multiple;
- tpm_swport_pm_1->sqeCounter = 0;
- tpm_swport_pm_1->deferredTransmissionCounter = statsCounterSet.Deferred;
- tpm_swport_pm_1->internalMacTransmitErrorCounter = 0;
- tpm_swport_pm_1->carrierSenseErrorCounter = 0;
- tpm_swport_pm_1->alignmentErrorCounter = 0;
- tpm_swport_pm_1->internalMacReceiveErrorCounter = statsCounterSet.InMACRcvErr;
+ retVal = mv_switch_get_port_counters(lPort, &statsCounterSet);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ tpm_swport_pm_1->fcsErrors = statsCounterSet.InFCSErr;
+ tpm_swport_pm_1->excessiveCollisionCounter = statsCounterSet.Excessive;
+ tpm_swport_pm_1->lateCollisionCounter = statsCounterSet.Late;
+ tpm_swport_pm_1->frameTooLongs = statsCounterSet.Oversize;
+ tpm_swport_pm_1->bufferOverflowsOnReceive = 0;
+ tpm_swport_pm_1->bufferOverflowsOnTransmit = 0;
+ tpm_swport_pm_1->singleCollisionFrameCounter = statsCounterSet.Single;
+ tpm_swport_pm_1->multipleCollisionsFrameCounter = statsCounterSet.Multiple;
+ tpm_swport_pm_1->sqeCounter = 0;
+ tpm_swport_pm_1->deferredTransmissionCounter = statsCounterSet.Deferred;
+ tpm_swport_pm_1->internalMacTransmitErrorCounter = 0;
+ tpm_swport_pm_1->carrierSenseErrorCounter = 0;
+ tpm_swport_pm_1->alignmentErrorCounter = 0;
+ tpm_swport_pm_1->internalMacReceiveErrorCounter = statsCounterSet.InMACRcvErr;
+ } else {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ for (gmac_port = TPM_ENUM_GMAC_0; gmac_port < TPM_MAX_NUM_GMACS; gmac_port++) {
+ if (phy_direct_addr == mvBoardPhyAddrGet(gmac_port))
+ break;
+ }
+ if (gmac_port == TPM_MAX_NUM_GMACS) {
+ printk(KERN_ERR "ERROR: (%s:%d) Can not find gmac port\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+
+ /* Read counter from GMAC */
+ retVal = tpm_sw_pm_from_gmac((int)gmac_port, tpm_swport_pm_1, &tpm_swport_pm_3);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_sw_pm_3_from_gmac failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+ }
if (trace_sw_dbg_flag)
{
@@ -6107,7 +7473,7 @@
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
-* tpm_swport_pm_3 - Holds PM data
+* tpm_swport_pm_3_all_t - Holds PM data
*
* OUTPUTS:
* PM data is supplied structure.
@@ -6120,14 +7486,18 @@
(
uint32_t owner_id,
tpm_src_port_type_t src_port,
- tpm_swport_pm_3_t *tpm_swport_pm_3
+ tpm_swport_pm_3_all_t *tpm_swport_pm_3
)
{
tpm_error_code_t retVal = TPM_RC_OK;
int32_t lPort = 0;
GT_STATS_COUNTER_SET3 statsCounterSet;
-
- SWITCH_INIT_CHECK();
+ GT_PORT_STAT2 ctr;
+ uint32_t switch_init;
+ tpm_gmacs_enum_t gmac_port;
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ tpm_swport_pm_1_t tpm_swport_pm_1;
if (trace_sw_dbg_flag)
{
@@ -6136,34 +7506,95 @@
__FUNCTION__,owner_id, src_port);
}
- lPort = tpm_db_eth_port_switch_port_get(src_port);
- if (lPort == TPM_DB_ERR_PORT_NUM)
- {
- printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
- return ERR_SRC_PORT_INVALID;
+ /* Initialize statsCounterSet and ctr as zero */
+ memset(&statsCounterSet, 0, sizeof(GT_STATS_COUNTER_SET3));
+ memset(&ctr, 0, sizeof(GT_PORT_STAT2));
+
+ /* Check swicth init or not */
+ if (tpm_db_switch_init_get(&switch_init) != TPM_DB_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_db_switch_init_get failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
}
- retVal = mv_switch_get_port_counters(lPort, &statsCounterSet);
- if (retVal != TPM_RC_OK)
- {
- printk(KERN_ERR
- "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
- }
+ if (switch_init) {
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
- tpm_swport_pm_3->dropEvents = 0;
- tpm_swport_pm_3->octets = statsCounterSet.InGoodOctetsLo;
- tpm_swport_pm_3->packets = statsCounterSet.InUnicasts;
- tpm_swport_pm_3->broadcastPackets = statsCounterSet.InBroadcasts;
- tpm_swport_pm_3->multicastPackets = statsCounterSet.InMulticasts;
- tpm_swport_pm_3->undersizePackets = 0;
- tpm_swport_pm_3->fragments = statsCounterSet.Fragments;
- tpm_swport_pm_3->jabbers = statsCounterSet.Jabber;
- tpm_swport_pm_3->packets_64Octets = statsCounterSet.Octets64;
- tpm_swport_pm_3->packets_65_127Octets = statsCounterSet.Octets127;
- tpm_swport_pm_3->packets_128_255Octets = statsCounterSet.Octets255;
- tpm_swport_pm_3->packets_256_511Octets = statsCounterSet.Octets511;
- tpm_swport_pm_3->packets_512_1023Octets = statsCounterSet.Octets1023;
- tpm_swport_pm_3->packets_1024_1518Octets = statsCounterSet.OctetsMax;
+ retVal = mv_switch_get_port_counters(lPort, &statsCounterSet);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function mv_switch_get_port_counters failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ retVal = mv_switch_get_port_drop_counters(lPort, &ctr);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function mv_switch_get_port_drop_counters failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ tpm_swport_pm_3->dropEvents = (ctr.inDiscardHi<<16) + ctr.inDiscardLo;
+ tpm_swport_pm_3->InGoodOctetsLo = statsCounterSet.InGoodOctetsLo;
+ tpm_swport_pm_3->InGoodOctetsHi = statsCounterSet.InGoodOctetsHi;
+ tpm_swport_pm_3->InBadOctets = statsCounterSet.InBadOctets;
+ tpm_swport_pm_3->OutFCSErr = statsCounterSet.OutFCSErr;
+ tpm_swport_pm_3->InUnicasts = statsCounterSet.InUnicasts;
+ tpm_swport_pm_3->Deferred = statsCounterSet.Deferred;
+ tpm_swport_pm_3->InBroadcasts = statsCounterSet.InBroadcasts;
+ tpm_swport_pm_3->InMulticasts = statsCounterSet.InMulticasts;
+ tpm_swport_pm_3->Octets64 = statsCounterSet.Octets64;
+ tpm_swport_pm_3->Octets127 = statsCounterSet.Octets127;
+ tpm_swport_pm_3->Octets255 = statsCounterSet.Octets255;
+ tpm_swport_pm_3->Octets511 = statsCounterSet.Octets511;
+ tpm_swport_pm_3->Octets1023 = statsCounterSet.Octets1023;
+ tpm_swport_pm_3->OctetsMax = statsCounterSet.OctetsMax;
+ tpm_swport_pm_3->OutOctetsLo = statsCounterSet.OutOctetsLo;
+ tpm_swport_pm_3->OutOctetsHi = statsCounterSet.OutOctetsHi;
+ tpm_swport_pm_3->OutUnicasts = statsCounterSet.OutUnicasts;
+ tpm_swport_pm_3->Excessive = statsCounterSet.Excessive;
+ tpm_swport_pm_3->OutMulticasts = statsCounterSet.OutMulticasts;
+ tpm_swport_pm_3->OutBroadcasts = statsCounterSet.OutBroadcasts;
+ tpm_swport_pm_3->Single = statsCounterSet.Single;
+ tpm_swport_pm_3->OutPause = statsCounterSet.OutPause;
+ tpm_swport_pm_3->InPause = statsCounterSet.InPause;
+ tpm_swport_pm_3->Multiple = statsCounterSet.Multiple;
+ tpm_swport_pm_3->Undersize = statsCounterSet.Undersize;
+ tpm_swport_pm_3->Fragments = statsCounterSet.Fragments;
+ tpm_swport_pm_3->Oversize = statsCounterSet.Oversize;
+ tpm_swport_pm_3->Jabber = statsCounterSet.Jabber;
+ tpm_swport_pm_3->InMACRcvErr = statsCounterSet.InMACRcvErr;
+ tpm_swport_pm_3->InFCSErr = statsCounterSet.InFCSErr;
+ tpm_swport_pm_3->Collisions = statsCounterSet.Collisions;
+ tpm_swport_pm_3->Late = statsCounterSet.Late;
+ } else {
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ for (gmac_port = TPM_ENUM_GMAC_0; gmac_port < TPM_MAX_NUM_GMACS; gmac_port++) {
+ if (phy_direct_addr == mvBoardPhyAddrGet(gmac_port))
+ break;
+ }
+ if (gmac_port == TPM_MAX_NUM_GMACS) {
+ printk(KERN_ERR "ERROR: (%s:%d) Can not find gmac port\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+
+ /* Read counter from GMAC */
+ retVal = tpm_sw_pm_from_gmac((int)gmac_port, &tpm_swport_pm_1, tpm_swport_pm_3);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR "ERROR: (%s:%d) tpm_sw_pm_3_from_gmac failed\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+ }
if (trace_sw_dbg_flag)
{
@@ -6265,9 +7696,7 @@
uint16_t db_num
)
{
- tpm_error_code_t retVal;
-
- SWITCH_INIT_CHECK();
+ tpm_error_code_t retVal = TPM_RC_OK;
if (trace_sw_dbg_flag)
{
@@ -6276,7 +7705,19 @@
__FUNCTION__,owner_id,db_num);
}
- retVal = mv_switch_print_fdb(db_num);
+ if (tpm_sw_init_check()) {
+ /* Check GMAC1 lpk status, if no lpk, no way to add static MAC */
+#ifdef CONFIG_MV_MAC_LEARN
+ if (tpm_db_gmac1_lpbk_en_get())
+ mac_learn_db_valid_print();
+ else {
+ printk(KERN_ERR "ERROR: (%s:%d) MAC learn not supported\n", __FUNCTION__, __LINE__);
+ return ERR_GENERAL;
+ }
+#endif
+ } else {
+ retVal = mv_switch_print_fdb(db_num);
+ }
if ((retVal != TPM_RC_OK) && (retVal != GT_NO_SUCH))
{
printk(KERN_INFO
@@ -6377,6 +7818,176 @@
}
/*******************************************************************************
+* tpm_phy_set_port_speed_duplex_mode
+*
+* DESCRIPTION:
+* This routine will disable auto-negotiation and set the PHY port speed and duplex mode.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
+* speed - PHY_SPEED_10_MBPS - 10Mbps
+* PHY_SPEED_100_MBPS - 100Mbps
+* PHY_SPEED_1000_MBPS - 1000Mbps.
+* enable - Enable/Disable full dulpex mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_phy_set_port_speed_duplex_mode
+(
+ uint32_t owner_id,
+ tpm_src_port_type_t src_port,
+ tpm_phy_speed_t speed,
+ bool enable
+)
+{
+ tpm_error_code_t retVal = TPM_RC_OK;
+ int32_t lPort = 0;
+ tpm_phy_ctrl_t phy_access_way;
+ uint32_t phy_direct_addr;
+ GT_BOOL state;
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: owner_id[%d],src_port[%d],speed[%d]\n\r",
+ __FUNCTION__,owner_id,src_port, (uint32_t)speed);
+ }
+
+ if(enable == true)
+ {
+ state = GT_TRUE;
+ }
+ else
+ {
+ state = GT_FALSE;
+ }
+
+ /* check PHY access way */
+ retVal = tpm_phy_access_check(src_port, &phy_access_way, &phy_direct_addr);
+ if (retVal != TPM_RC_OK) {
+ printk(KERN_ERR
+ "Port%d PHY access way check failed\n", src_port);
+ return retVal;
+ }
+ /* PHY accessed directly, call lsp API */
+ if (PHY_SMI_MASTER_CPU == phy_access_way) {
+ if (mvEthPhySpeedDuplexModeSet(phy_direct_addr, speed, state)) {
+ printk(KERN_ERR
+ "ERROR: (%s:%d) PHY LSP API call failed on port(%d)\n", __FUNCTION__, __LINE__, src_port);
+ retVal = ERR_PHY_SRC_PORT_CONN_INVALID;
+ }
+ } else {
+ /* PHY accessed through switch, as original do */
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_set_port_speed_duplex_mode(lPort, (GT_PHY_SPEED)speed, state);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
+ }
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==EXIT== %s:\n\r",__FUNCTION__);
+ }
+
+ return retVal;
+}
+
+/*******************************************************************************
+* tpm_sw_port_add_vid_set_egrs_mode
+*
+* DESCRIPTION:
+* The API adds a VID to the list of the allowed VIDs per UNI port,
+* and sets the egress mode for the port.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
+* vid - vlan id
+* eMode - egress mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case see tpm_error_code_t.
+*
+* COMMENTS:
+* MEMBER_EGRESS_UNMODIFIED - 0
+* NOT_A_MEMBER - 1
+* MEMBER_EGRESS_UNTAGGED - 2
+* MEMBER_EGRESS_TAGGED - 3
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_port_add_vid_set_egrs_mode
+(
+ uint32_t owner_id,
+ tpm_src_port_type_t src_port,
+ uint16_t vid,
+ uint8_t eMode
+)
+{
+ tpm_error_code_t retVal = TPM_RC_OK;
+ int32_t lPort = 0;
+
+ SWITCH_INIT_CHECK();
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==ENTER==%s: owner_id[%d],src_port[%d],vid[%d],egress mode[%d]\n",
+ __FUNCTION__,owner_id,src_port,vid,eMode);
+ }
+
+ if (vid >= TPM_MAX_VID)
+ {
+ printk(KERN_INFO
+ "%s:%d:==ERROR== invalid VID[%d]\r\n", __FUNCTION__,__LINE__,vid);
+ return ERR_SW_VID_INVALID;
+ }
+
+ lPort = tpm_db_eth_port_switch_port_get(src_port);
+ if (lPort == TPM_DB_ERR_PORT_NUM)
+ {
+ printk(KERN_ERR "ERROR: (%s:%d) source port(%d) is invalid\n", __FUNCTION__, __LINE__, src_port);
+ return ERR_SRC_PORT_INVALID;
+ }
+
+ retVal = mv_switch_port_add_vid_set_egrs_mode(lPort, vid, TPM_GMAC0_AMBER_PORT_NUM, eMode);
+ if (retVal != TPM_RC_OK)
+ {
+ printk(KERN_ERR
+ "%s:%d: function failed\r\n", __FUNCTION__,__LINE__);
+ }
+
+ if (trace_sw_dbg_flag)
+ {
+ printk(KERN_INFO
+ "==EXIT== %s:\n\r",__FUNCTION__);
+ }
+
+ return retVal;
+}
+
+/*******************************************************************************
* tpm_sw_init
*
* DESCRIPTION:
diff --git a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.h b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.h
index 2026e27..0f6141c 100755
--- a/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.h
+++ b/arch/arm/plat-feroceon/mv_drivers_lsp/mv_tpm/plat/tpm_switch_mgr.h
@@ -89,6 +89,35 @@
#define INT_GE_PHY_SWITCH_PORT (0)
+#define SW_TRUNK_ID_MAX (0xf)
+#define SW_TRUNK_MASK_NUM_MAX (0x7)
+#define SW_TRUNK_MASK_MAX (0x7f)
+
+#define SW_TRUNK_ID_REG (5)
+#define SW_TRUNK_ID_BIT_OFF (8)
+#define SW_TRUNK_BIT_OFF (14)
+#define SW_TRUNK_ID_BIT_LEN (4)
+
+#define SW_TRUNK_MAPPING_REG (8)
+#define SW_TRUNK_MAPPING_BIT_OFF (0)
+#define SW_TRUNK_MAPPING_BIT_LEN (7)
+#define SW_TRUNK_MAPPING_ID_BIT_OFF (11)
+#define SW_REG_UPDATE_BIT_OFF (15)
+
+#define SW_TRUNK_MASK_REG (7)
+#define SW_TRUNK_MASK_NUM_BIT_OFF (12)
+#define SW_TRUNK_MASK_NUM_BIT_LEN (3)
+#define SW_TRUNK_MASK_BIT_OFF (0)
+#define SW_TRUNK_MASK_BIT_LEN (7)
+
+#define SW_CLEAR_REG_BIT(REG, OFF, LEN) (REG) = (~((0xFFFF >> (16 - (LEN))) << OFF) & (REG))
+
+/* enum of PHY access way */
+typedef enum {
+ PHY_SMI_MASTER_CPU,/*Phy directly accessed through LSP function*/
+ PHY_SMI_MASTER_SWT,/*Phy accessed through switch*/
+} tpm_phy_ctrl_t;
+
/*******************************************************************************
* tpm_sw_set_static_mac_w_ports_mask
*
@@ -897,7 +926,7 @@
* INPUTS:
* owner_id - APP owner id should be used for all API calls.
* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
-* tpm_swport_pm_3 - Holds PM data
+* tpm_swport_pm_3_all_t - Holds PM data
*
* OUTPUTS:
* PM data is supplied structure.
@@ -910,7 +939,7 @@
(
uint32_t owner_id,
tpm_src_port_type_t src_port,
- tpm_swport_pm_3_t *tpm_swport_pm_3
+ tpm_swport_pm_3_all_t *tpm_swport_pm_3
);
/*******************************************************************************
@@ -1014,6 +1043,72 @@
tpm_error_code_t tpm_sw_flush_atu(uint32_t owner_id, tpm_flush_atu_type_t flush_type, uint16_t db_num);
/*******************************************************************************
+* tpm_phy_set_port_speed_duplex_mode
+*
+* DESCRIPTION:
+* This routine will disable auto-negotiation and set the PHY port speed and duplex mode.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
+* speed - PHY_SPEED_10_MBPS - 10Mbps
+* PHY_SPEED_100_MBPS - 100Mbps
+* PHY_SPEED_1000_MBPS - 1000Mbps.
+* enable - Enable/Disable full dulpex mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case - see tpm_error_code_t.
+* COMMENTS:
+*
+*******************************************************************************/
+tpm_error_code_t tpm_phy_set_port_speed_duplex_mode
+(
+ uint32_t owner_id,
+ tpm_src_port_type_t src_port,
+ tpm_phy_speed_t speed,
+ bool enable
+);
+
+/*******************************************************************************
+* tpm_sw_port_add_vid_set_egrs_mode
+*
+* DESCRIPTION:
+* The API adds a VID to the list of the allowed VIDs per UNI port,
+* and sets the egress mode for the port.
+*
+* INPUTS:
+* owner_id - APP owner id should be used for all API calls.
+* src_port - Source port in UNI port index, UNI0, UNI1...UNI4.
+* vid - vlan id
+* eMode - egress mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* On success - TPM_RC_OK.
+* On error different types are returned according to the case see tpm_error_code_t.
+*
+* COMMENTS:
+* MEMBER_EGRESS_UNMODIFIED - 0
+* NOT_A_MEMBER - 1
+* MEMBER_EGRESS_UNTAGGED - 2
+* MEMBER_EGRESS_TAGGED - 3
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_port_add_vid_set_egrs_mode
+(
+ uint32_t owner_id,
+ tpm_src_port_type_t src_port,
+ uint16_t vid,
+ uint8_t eMode
+);
+
+/*******************************************************************************
* tpm_sw_init
*
* DESCRIPTION:
@@ -1061,5 +1156,20 @@
uint32_t enDis
);
+/*******************************************************************************
+* tpm_sw_pm_print_from_gmac
+*
+*
+* INPUTS:
+* port - GMAC port.
+* OUTPUTS:
+* tpm_swport_pm_1 - Holds PM data1
+* tpm_swport_pm_3 - Holds PM data all
+*
+* RETURNS:
+* TPM_RC_OK - on success, else error code
+*
+*******************************************************************************/
+tpm_error_code_t tpm_sw_pm_print_from_gmac(int port);
#endif
diff --git a/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.c b/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.c
index 52c5a33..7371cdb 100755
--- a/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.c
+++ b/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.c
@@ -69,6 +69,8 @@
#include "mvSysEthPhyConfig.h"
#include "mvEthPhyRegs.h"
#include "mvEthPhy.h"
+#include "gbe/mvNeta.h"
+#include "boardEnv/mvBoardEnvLib.h"
static MV_VOID mvEthPhyPower(MV_U32 ethPortNum, MV_BOOL enable);
@@ -441,6 +443,7 @@
*
* INPUT:
* phyAddr - Phy address.
+* data - PHY control register value want to be, if 0xFFFF, use original value
* timeout - in millisec
*
* OUTPUT:
@@ -450,17 +453,30 @@
* MV_TIMEOUT - Timeout
*
*******************************************************************************/
-MV_STATUS mvEthPhyReset(MV_U32 phyAddr, int timeout)
+MV_STATUS mvEthPhyReset(MV_U32 phyAddr, MV_U16 data, int timeout)
{
- MV_U16 phyRegData;
+ MV_U16 phyRegData, temp;
+ MV_BOOL power_down = 0;
/* Reset the PHY */
- if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &temp) != MV_OK)
return MV_FAIL;
- /* Set bit 15 to reset the PHY */
- phyRegData |= ETH_PHY_CTRL_RESET_MASK;
- mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, phyRegData);
+ if (temp & ETH_PHY_CTRL_POWER_DOWN_MASK)
+ power_down = 1;
+
+ if (data != 0xFFFF)
+ temp = data;
+
+ if (power_down)
+ temp |= ETH_PHY_CTRL_POWER_DOWN_MASK;
+ else
+ temp |= ETH_PHY_CTRL_RESET_MASK;
+
+ mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, temp);
+
+ if (power_down)
+ return MV_OK;
/* Wait untill Reset completed */
while (timeout > 0) {
@@ -482,6 +498,8 @@
*
* DESCRIPTION:
* This function resets a given ethernet Phy.
+* If AutoNegotiation is not enabled, it'll enable it.
+* Loopback and Power Down will be disabled by this routine
*
* INPUT:
* phyAddr - Phy address.
@@ -498,10 +516,17 @@
{
MV_U16 phyRegData;
- /* Reset the PHY */
+ /* Disable internal loopback first, in order to restore value of related register */
+ if (mvEthPhyLoopbackSet(phyAddr, MV_FALSE) != MV_OK)
+ return MV_FAIL;
+
+ /* Read Control reg of the PHY */
if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
return MV_FAIL;
+ /* disable loopback and power down */
+ phyRegData &= (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_SPEED_LSB_MASK | ETH_PHY_CTRL_SPEED_MSB_MASK);
+
/* Set bit 12 to Enable autonegotiation of the PHY */
phyRegData |= ETH_PHY_CTRL_AN_ENABLE_MASK;
@@ -624,7 +649,7 @@
regVal &= ~(BIT5 | BIT6 | BIT8 | BIT9);
mvEthPhyRegWrite(phyAddr, ETH_PHY_SPEC_CTRL_REG, regVal);
- status = mvEthPhyReset(phyAddr, 1000);
+ status = mvEthPhyReset(phyAddr, 0xFFFF, MV_PHY_RESET_EXPIRE_COUNT);
if (status != MV_OK) {
mvOsPrintf("mvEthPhyReset failed: status=0x%x\n", status);
return status;
@@ -636,9 +661,8 @@
} else {
/* Cancel Loopback */
ctrlVal &= ~ETH_PHY_CTRL_LOOPBACK_MASK;
- mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, ctrlVal);
- status = mvEthPhyReset(phyAddr, 1000);
+ status = mvEthPhyReset(phyAddr, ctrlVal, MV_PHY_RESET_EXPIRE_COUNT);
if (status != MV_OK) {
mvOsPrintf("mvEthPhyReset failed: status=0x%x\n", status);
return status;
@@ -650,7 +674,7 @@
regVal |= (BIT5 | BIT6 | BIT8 | BIT9);
mvEthPhyRegWrite(phyAddr, ETH_PHY_SPEC_CTRL_REG, regVal);
- status = mvEthPhyReset(phyAddr, 1000);
+ status = mvEthPhyReset(phyAddr, 0xFFFF, MV_PHY_RESET_EXPIRE_COUNT);
if (status != MV_OK) {
mvOsPrintf("mvEthPhyReset failed: status=0x%x\n", status);
return status;
@@ -808,6 +832,14 @@
regVal = regVal & (~ETH_PHY_1000BASE_ADVERTISE_MASK);
regVal = regVal | (tmp << ETH_PHY_1000BASE_ADVERTISE_OFFSET);
mvEthPhyRegWrite(phyAddr, ETH_PHY_1000BASE_T_CTRL_REG, regVal);
+
+ /* Reset PHY */
+ mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &tmp);
+ mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, tmp | ETH_PHY_CTRL_RESET_MASK);
+ mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &tmp);
+ while(tmp & ETH_PHY_CTRL_RESET_MASK)
+ mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &tmp);
+
return MV_OK;
}
@@ -2046,3 +2078,879 @@
}
}
+/* Check GEPHY or FEPHY through Reg1.8 */
+static MV_STATUS mvEthPhyIsFe(MV_U32 phyAddr, MV_BOOL *Is_Fe_PHY)
+{
+ MV_U16 phyRegData;
+ MV_BOOL isfe = 0;
+
+ /* Check PHY exist or not */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_ID2_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ if (phyRegData == ETH_PHY_SMI_DATA_MASK)
+ return MV_FAIL;
+
+ /* Judge PHY is FE or GE through reg1.8 */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_STATUS_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ if (ETH_PHY_STATUS_EXTEND_MASK & phyRegData)
+ isfe = 0;
+ else
+ isfe = 1;
+
+ *Is_Fe_PHY = isfe;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhySetAdminState - Set phy power down state.
+*
+* DESCRIPTION:
+* The API Configures the PHY state on the eth port.
+* INPUTS:
+* phyAddr - Phy address.
+* phy_state - PHY port state to set.
+* 0:power down
+* 1:power up
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+
+MV_STATUS mvEthPhySetAdminState(MV_U32 phyAddr, MV_BOOL phy_state)
+{
+ MV_U16 phyRegData;
+ MV_BOOL pre_state;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ pre_state = (phyRegData & ETH_PHY_CTRL_POWER_DOWN_MASK) ? 0 : 1;
+
+ if (pre_state != phy_state) {
+ if (!phy_state) {
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, phyRegData | ETH_PHY_CTRL_POWER_DOWN_MASK) != MV_OK)
+ return MV_FAIL;
+ } else {
+ /* from down to normal, 0.11 and 16.2 must be set 0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, phyRegData & (~ETH_PHY_CTRL_POWER_DOWN_MASK)) != MV_OK)
+ return MV_FAIL;
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_SPEC_CTRL_REG, phyRegData & (~ETH_PHY_SPEC_CTRL_POWER_DOWN_MASK)) != MV_OK)
+ return MV_FAIL;
+ }
+ }
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyGetAdminState - Get PHY power down dtate.
+*
+* DESCRIPTION:
+* The API get the PHY state on the eth port.
+* INPUTS:
+* phyAddr - Phy address.
+* phy_state - PHY port state to set.
+* 0:power down
+* 1:power up
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyGetAdminState(MV_U32 phyAddr, MV_BOOL *phy_state)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ *phy_state = (phyRegData & ETH_PHY_CTRL_POWER_DOWN_MASK) ? 0 : 1;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyGetLinkStatus - Get PHY link state.
+*
+* DESCRIPTION:
+* The API get the PHY link state on the eth port.
+* INPUTS:
+* phyAddr - Phy address.
+* link_state - PHY link state to set.
+* 0:link down
+* 1:link up
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyGetLinkStatus(MV_U32 phyAddr, MV_BOOL *link_state)
+{
+ MV_U16 phyRegData;
+
+ /* Check if the PHY exist */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_ID2_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ if (phyRegData == ETH_PHY_SMI_DATA_MASK)
+ return MV_FAIL;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_STATUS_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ /* Check status valid or not */
+ if (!(phyRegData & ETH_PHY_SPEC_STATUS_RESOLVE_MASK))
+ return MV_FAIL;
+
+ *link_state = (phyRegData & ETH_PHY_SPEC_STATUS_LINK_MASK) ? 1 : 0;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyDuplexOperGet - Get PHYduplex info.
+*
+* DESCRIPTION:
+* The API get the PHY duplex status on the eth port. It reflects the real
+* configuration happened in PHY.
+* INPUTS:
+* phyAddr - Phy address.
+* state_valid - indicates PHY state is valid or not
+* 0: invalid
+* 1: valid
+* duplex_state - PHY link state to set.
+* 0:half duplex
+* 1:full duplex
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+* COMMENT: Reg17.13
+*******************************************************************************/
+MV_STATUS mvEthPhyDuplexOperGet(MV_U32 phyAddr, MV_BOOL *state_valid, MV_BOOL *duplex_state)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_STATUS_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ /* Check status valid or not */
+ if (!(phyRegData & ETH_PHY_SPEC_STATUS_RESOLVE_MASK)) {
+ *state_valid = MV_FALSE;
+ return MV_OK;
+ }
+ *state_valid = MV_TRUE;
+
+ *duplex_state = (phyRegData & ETH_PHY_SPEC_STATUS_DUPLEX_MASK) ? 1 : 0;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyPauseSet - Set pause of PHY.
+*
+* DESCRIPTION:
+* The API set pause state.
+* INPUTS:
+* phyAddr - Phy address.
+* pause_state - pause state set to
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyPauseSet(MV_U32 phyAddr, MV_U32 pause_state)
+{
+ MV_U16 phyRegData;
+ MV_U32 pre_state = MV_ETHPHY_NO_PAUSE;
+
+ /* read current pause state */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_AUTONEGO_AD_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ if (phyRegData & ETH_PHY_SPEC_CTRL_PAUSE_MASK)
+ pre_state |= MV_ETHPHY_PAUSE;
+ if (phyRegData & ETH_PHY_SPEC_CTRL_ASY_PAUSE_MASK)
+ pre_state |= MV_ETHPHY_ASYMMETRIC_PAUSE;
+
+ if (pause_state == pre_state)
+ return MV_OK;
+
+ /*set expected PAUSE state*/
+ phyRegData &= ((~ETH_PHY_SPEC_CTRL_PAUSE_MASK) & (~ETH_PHY_SPEC_CTRL_ASY_PAUSE_MASK));
+ switch (pause_state) {
+ case MV_ETHPHY_NO_PAUSE:
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_AUTONEGO_AD_REG, phyRegData) != MV_OK)
+ return MV_FAIL;
+ break;
+ case MV_ETHPHY_PAUSE:
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_AUTONEGO_AD_REG, phyRegData |
+ ETH_PHY_SPEC_CTRL_PAUSE_MASK) != MV_OK)
+ return MV_FAIL;
+ break;
+ case MV_ETHPHY_ASYMMETRIC_PAUSE:
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_AUTONEGO_AD_REG, phyRegData |
+ ETH_PHY_SPEC_CTRL_ASY_PAUSE_MASK) != MV_OK)
+ return MV_FAIL;
+ break;
+ case MV_ETHPHY_BOTH_PAUSE:
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_AUTONEGO_AD_REG, phyRegData |
+ ETH_PHY_SPEC_CTRL_ASY_PAUSE_MASK |
+ ETH_PHY_SPEC_CTRL_PAUSE_MASK) != MV_OK)
+ return MV_FAIL;
+ break;
+ default:
+ return MV_FAIL;
+ }
+
+ /*restart auto-nego, let set above take effect*/
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ phyRegData = phyRegData | ETH_PHY_CTRL_AN_RESTART_MASK;
+
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyPauseAdminGet - Get pause state of PHY.
+*
+* DESCRIPTION:
+* The API get pause state.
+* INPUTS:
+* phyAddr - Phy address.
+* pause_state - pause state set to
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+* COMMENT: Reg4.10 4.11
+*******************************************************************************/
+MV_STATUS mvEthPhyPauseAdminGet(MV_U32 phyAddr, MV_U32 *pause_state)
+{
+ MV_U16 phyRegData;
+ MV_U32 pre_state = MV_ETHPHY_NO_PAUSE;
+
+ /* read current pause state */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_AUTONEGO_AD_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ if (phyRegData & ETH_PHY_SPEC_CTRL_PAUSE_MASK)
+ pre_state |= MV_ETHPHY_PAUSE;
+ if (phyRegData & ETH_PHY_SPEC_CTRL_ASY_PAUSE_MASK)
+ pre_state |= MV_ETHPHY_ASYMMETRIC_PAUSE;
+
+ *pause_state = pre_state;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyLoopbackSet - Set loopback state of PHY.
+*
+* DESCRIPTION:
+* The API set loopback state.
+* INPUTS:
+* phyAddr - Phy address.
+* isEnable - loopback state.
+* 0--disable
+* 1--enabled
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyLoopbackSet(MV_U32 phyAddr, MV_BOOL isEnable)
+{
+ MV_U16 phyRegData, ctrlVal;
+ MV_BOOL isfe = 0;
+
+ if (mvEthPhyIsFe(phyAddr, &isfe))
+ return MV_FAIL;
+
+ /* Set loopback speed and duplex accordingly with current */
+ /* Bits: 6, 8, 13 */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &ctrlVal) != MV_OK)
+ return MV_FAIL;
+
+ if (isEnable) {
+ if (!isfe) {
+ /* select page 2 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 2) != MV_OK)
+ return MV_FAIL;
+
+ /* Set register 21_2 */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_CTRL2_PAGE2, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ phyRegData &= ~(ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_SPEED_LSB_MASK |
+ ETH_PHY_CTRL_SPEED_MSB_MASK | ETH_PHY_CTRL_AN_ENABLE_MASK);
+ phyRegData |= (ctrlVal & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_SPEED_LSB_MASK |
+ ETH_PHY_CTRL_SPEED_MSB_MASK | ETH_PHY_CTRL_AN_ENABLE_MASK));
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_SPEC_CTRL2_PAGE2, phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ /* restore page0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0) != MV_OK)
+ return MV_FAIL;
+
+ /* Force master */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_1000BASE_T_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ phyRegData |= ETH_PHY_1000BASE_MASTER_ENABLE_MASK;
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_1000BASE_T_CTRL_REG, phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ /*reset PHY */
+ if (mvEthPhyReset(phyAddr, 0xFFFF, MV_PHY_RESET_EXPIRE_COUNT) != MV_OK)
+ return MV_FAIL;
+ /* When auto-nego is disabled, 2 PHY reset is needed */
+ if (mvEthPhyReset(phyAddr, 0xFFFF, MV_PHY_RESET_EXPIRE_COUNT) != MV_OK)
+ return MV_FAIL;
+
+ /* Select page 0x00FA, there is no description in reference */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0x00FA) != MV_OK)
+ return MV_FAIL;
+
+ /* write register 7, force 1000M link, dfault is 0x200*/
+ if (mvEthPhyRegWrite(phyAddr, 7, 0x020c) != MV_OK)
+ return MV_FAIL;
+
+ /* restore page0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0) != MV_OK)
+ return MV_FAIL;
+ }
+
+ /* Set loopback */
+ ctrlVal |= ETH_PHY_CTRL_LOOPBACK_MASK;
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_CTRL_REG, ctrlVal) != MV_OK)
+ return MV_FAIL;
+ } else {
+ if (!isfe) {
+ /*restore original setting*/
+ /* Select page 0x00FA */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0x00FA) != MV_OK)
+ return MV_FAIL;
+
+ /* write register 7, restore default is 0x200*/
+ if (mvEthPhyRegWrite(phyAddr, 7, 0x0200) != MV_OK)
+ return MV_FAIL;
+
+ /* restore page0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0) != MV_OK)
+ return MV_FAIL;
+
+ /* Cancel Force master */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_1000BASE_T_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ phyRegData &= (~ETH_PHY_1000BASE_MASTER_ENABLE_MASK);
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_1000BASE_T_CTRL_REG, phyRegData) != MV_OK)
+ return MV_FAIL;
+ }
+ /*disable loopback*/
+ ctrlVal &= (~ETH_PHY_CTRL_LOOPBACK_MASK);
+ if (mvEthPhyReset(phyAddr, ctrlVal, MV_PHY_RESET_EXPIRE_COUNT) !=MV_OK)
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyLoopbackGet - Get loopback state of PHY.
+*
+* DESCRIPTION:
+* The API get loopback state.
+* INPUTS:
+* phyAddr - Phy address.
+*
+* OUTPUT:
+* isEnable - loopback state.
+* 0--disable
+* 1--enabled
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyLoopbackGet(MV_U32 phyAddr, MV_BOOL *isEnable)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ *isEnable = (phyRegData & ETH_PHY_CTRL_LOOPBACK_MASK) ? 1 : 0;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyLineLoopbackSet - Set line loopback state of PHY.
+*
+* DESCRIPTION:
+* The API set loopback state.
+* INPUTS:
+* phyAddr - Phy address.
+* isEnable - loopback state.
+* 0--disable
+* 1--enabled
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyLineLoopbackSet(MV_U32 phyAddr, MV_BOOL isEnable)
+{
+ MV_U16 phyRegData;
+ MV_BOOL isfe = 0;
+
+ if (mvEthPhyIsFe(phyAddr, &isfe))
+ return MV_FAIL;
+
+ if (isEnable) {
+ if (!isfe) {
+ /* select page 2 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 2) != MV_OK)
+ return MV_FAIL;
+ /* set speed to 1000Mbps */
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_CTRL2_PAGE2, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ phyRegData &= 0xFFFFFFF8;
+ phyRegData |= ETH_PHY_SPEC_CTRL2_PAGE2_MAC_SPEED_1000M;
+ phyRegData |= ETH_PHY_SPEC_CTRL2_PAGE2_LINE_LPK_MASK;
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_SPEC_CTRL2_PAGE2, phyRegData) != MV_OK)
+ return MV_FAIL;
+ /* restore page0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0) != MV_OK)
+ return MV_FAIL;
+ } else {
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_FE_SPEC_CTRL2, &phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ phyRegData |= ETH_PHY_SPEC_CTRL2_FE_LINE_LPK_MASK;
+
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_FE_SPEC_CTRL2, phyRegData) != MV_OK)
+ return MV_FAIL;
+ }
+ } else {
+ if (!isfe) {
+ /* select page 2 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 2) != MV_OK)
+ return MV_FAIL;
+ phyRegData &= (~ETH_PHY_SPEC_CTRL2_PAGE2_LINE_LPK_MASK);
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_SPEC_CTRL2_PAGE2, phyRegData) != MV_OK)
+ return MV_FAIL;
+ /* restore page0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0) != MV_OK)
+ return MV_FAIL;
+ } else {
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_FE_SPEC_CTRL2, &phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ phyRegData &= (~ETH_PHY_SPEC_CTRL2_FE_LINE_LPK_MASK);
+
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_FE_SPEC_CTRL2, phyRegData) != MV_OK)
+ return MV_FAIL;
+ }
+ }
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyLineLoopbackGet - Get line loopback state of PHY, external loopback
+*
+* DESCRIPTION:
+* The API get loopback state.
+* INPUTS:
+* phyAddr - Phy address.
+*
+* OUTPUT:
+* isEnable - loopback state.
+* 0--disable
+* 1--enabled
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyLineLoopbackGet(MV_U32 phyAddr, MV_BOOL *isEnable)
+{
+ MV_U16 phyRegData;
+ MV_BOOL isfe = 0;
+
+ if (mvEthPhyIsFe(phyAddr, &isfe))
+ return MV_FAIL;
+
+ if (!isfe) {
+ /* select page 2 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 2) != MV_OK)
+ return MV_FAIL;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_CTRL2_PAGE2, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ /* restore page0 */
+ if (mvEthPhyRegWrite(phyAddr, ETH_PHY_PAGE_ADDR, 0) != MV_OK)
+ return MV_FAIL;
+
+ *isEnable = (phyRegData & ETH_PHY_SPEC_CTRL2_PAGE2_LINE_LPK_MASK) ? 1 : 0;
+ } else {
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_FE_SPEC_CTRL2, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ *isEnable = (phyRegData & ETH_PHY_SPEC_CTRL2_FE_LINE_LPK_MASK) ? 1 : 0;
+ }
+
+ return MV_OK;
+}
+
+
+/*******************************************************************************
+* mvEthPhyDuplexModeSet - Set duplex mode of PHY.
+*
+* DESCRIPTION:
+* This function will keep the speed and loopback mode to the
+* previous value, but disable others, such as Autonegotiation.
+* INPUTS:
+* phyAddr - Phy address.
+* isEnable - duplex state
+* 0--half duplex
+* 1--full duplex
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyDuplexModeSet(MV_U32 phyAddr, MV_BOOL isEnable)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ if (isEnable)
+ phyRegData = phyRegData | ETH_PHY_CTRL_DUPLEX_MASK;
+ else
+ phyRegData = phyRegData & (~ETH_PHY_CTRL_DUPLEX_MASK);
+
+ phyRegData = phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK |
+ ETH_PHY_CTRL_LOOPBACK_MASK |
+ ETH_PHY_CTRL_SPEED_LSB_MASK |
+ ETH_PHY_CTRL_SPEED_MSB_MASK);
+ /* Write Control reg and reset PHY */
+ if (mvEthPhyReset(phyAddr, phyRegData, MV_PHY_RESET_EXPIRE_COUNT) != MV_OK)
+ return MV_FAIL;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyDuplexModeAdminGet - Get configured duplex mode of PHY.
+*
+* DESCRIPTION:
+* The API get duplex mode.
+* INPUTS:
+* phyAddr - Phy address.
+*
+* OUTPUT:
+* isEnable - duplex state
+* 0--half duplex
+* 1--full duplex
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+* Comment: reg0.8
+*******************************************************************************/
+MV_STATUS mvEthPhyDuplexModeAdminGet(MV_U32 phyAddr, MV_BOOL *isEnable)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ *isEnable = (phyRegData & ETH_PHY_CTRL_DUPLEX_MASK) ? 1 : 0;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhySpeedSet - Set speed of PHY.
+*
+* DESCRIPTION:
+* This function will keep the duplex mode and loopback mode to the
+* previous value, but disable others, such as Autonegotiation.
+* INPUTS:
+* phyAddr - Phy address.
+* speed - PHY speed
+* 0--10 Mbps
+* 1--100 Mbps
+* 2--1000 Mbps
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhySpeedSet(MV_U32 phyAddr, MV_U32 speed)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ phyRegData = phyRegData & ((~ETH_PHY_CTRL_SPEED_LSB_MASK) & (~ETH_PHY_CTRL_SPEED_MSB_MASK));
+
+ switch (speed) {
+ case MV_ETHPHY_SPEED_10_MBPS:
+ phyRegData = phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_LOOPBACK_MASK);
+ break;
+ case MV_ETHPHY_SPEED_100_MBPS:
+ phyRegData = (phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_LOOPBACK_MASK)) |
+ ETH_PHY_CTRL_SPEED_LSB_MASK;
+ break;
+ case MV_ETHPHY_SPEED_1000_MBPS:
+ phyRegData = (phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_LOOPBACK_MASK)) |
+ ETH_PHY_CTRL_SPEED_MSB_MASK;
+ break;
+ default:
+ return MV_FAIL;
+ }
+
+ if (mvEthPhyReset(phyAddr, phyRegData, MV_PHY_RESET_EXPIRE_COUNT) != MV_OK)
+ return MV_FAIL;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhySpeedOperGet - Get PHYduplex info.
+*
+* DESCRIPTION:
+* The API get the PHY speed status on the eth port. It reflects the real
+* configuration happened in PHY.
+* INPUTS:
+* phyAddr - Phy address.
+* speed - PHY connection speed.
+* 0--10 Mbps
+* 1--100 Mbps
+* 2--1000 Mbps
+* 3--Unknown
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+* COMMENT: Reg17.14 and 17.15
+*******************************************************************************/
+MV_STATUS mvEthPhySpeedOperGet(MV_U32 phyAddr, MV_U32 *speed)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_SPEC_STATUS_REG, &phyRegData) != MV_OK)
+ return MV_ERROR;
+ /* Check status valid or not */
+ if (!(phyRegData & ETH_PHY_SPEC_STATUS_RESOLVE_MASK)) {
+ *speed = MV_ETHPHY_SPEED_UNKNOWN;
+ return MV_OK;
+ }
+
+ switch (phyRegData & ETH_PHY_SPEC_STATUS_SPEED_MASK) {
+ case ETH_PHY_SPEC_STATUS_SPEED_1000MBPS:
+ *speed = MV_ETHPHY_SPEED_1000_MBPS;
+ break;
+ case ETH_PHY_SPEC_STATUS_SPEED_100MBPS:
+ *speed = MV_ETHPHY_SPEED_100_MBPS;
+ break;
+ case ETH_PHY_SPEC_STATUS_SPEED_10MBPS:
+ *speed = MV_ETHPHY_SPEED_10_MBPS;
+ break;
+ default:
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhySpeedAdminGet - Get Configured speed of PHY.
+*
+* DESCRIPTION:
+* The API get speed.
+* INPUTS:
+* phyAddr - Phy address.
+*
+* OUTPUT:
+* speed - duplex state
+* 0--10 Mbps
+* 1--100 Mbps
+* 2--1000 Mbps
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+* Comment: Reg0.6, 0.13
+*******************************************************************************/
+MV_STATUS mvEthPhySpeedAdminGet(MV_U32 phyAddr, MV_U32 *speed)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_ERROR;
+
+ /* MSB = 1, LSB = 0, 1000M */
+ if ((phyRegData & ETH_PHY_CTRL_SPEED_MSB_MASK) && (!(phyRegData & ETH_PHY_CTRL_SPEED_LSB_MASK)))
+ *speed = MV_ETHPHY_SPEED_1000_MBPS;
+ /* MSB = 0, LSB = 1, 100M */
+ else if ((phyRegData & ETH_PHY_CTRL_SPEED_LSB_MASK) && (!(phyRegData & ETH_PHY_CTRL_SPEED_MSB_MASK)))
+ *speed = MV_ETHPHY_SPEED_100_MBPS;
+ /* MSB = 0, LSB = 0, 10M */
+ else if ((!(phyRegData & ETH_PHY_CTRL_SPEED_LSB_MASK)) && (!(phyRegData & ETH_PHY_CTRL_SPEED_MSB_MASK)))
+ *speed = MV_ETHPHY_SPEED_10_MBPS;
+ else
+ return MV_FAIL;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhySpeedDuplexModeSet - Set Speed and duplex mode of PHY.
+*
+* DESCRIPTION:
+* This function will keep the loopback mode to the
+* previous value, but disable others, such as Autonegotiation.
+* INPUTS:
+* phyAddr - Phy address.
+* speed - PHY speed
+* 0--10 Mbps
+* 1--100 Mbps
+* 2--1000 Mbps
+* isEnable - duplex state
+* 0--half duplex
+* 1--full duplex
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhySpeedDuplexModeSet(MV_U32 phyAddr, MV_U32 speed, MV_BOOL isEnable)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+
+ if (isEnable)
+ phyRegData = phyRegData | ETH_PHY_CTRL_DUPLEX_MASK;
+ else
+ phyRegData = phyRegData & (~ETH_PHY_CTRL_DUPLEX_MASK);
+
+ phyRegData = phyRegData & ((~ETH_PHY_CTRL_SPEED_LSB_MASK) & (~ETH_PHY_CTRL_SPEED_MSB_MASK));
+
+ switch (speed) {
+ case MV_ETHPHY_SPEED_10_MBPS:
+ phyRegData = phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_LOOPBACK_MASK);
+ break;
+ case MV_ETHPHY_SPEED_100_MBPS:
+ phyRegData = (phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_LOOPBACK_MASK)) |
+ ETH_PHY_CTRL_SPEED_LSB_MASK;
+ break;
+ case MV_ETHPHY_SPEED_1000_MBPS:
+ phyRegData = (phyRegData & (ETH_PHY_CTRL_DUPLEX_MASK | ETH_PHY_CTRL_LOOPBACK_MASK)) |
+ ETH_PHY_CTRL_SPEED_MSB_MASK;
+ break;
+ default:
+ return MV_FAIL;
+ }
+
+ if (mvEthPhyReset(phyAddr, phyRegData, MV_PHY_RESET_EXPIRE_COUNT) != MV_OK)
+ return MV_FAIL;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyAutoNegoSet - Set auto nego of PHY.
+*
+* DESCRIPTION:
+* The API set auto nego.
+* INPUTS:
+* phyAddr - Phy address.
+* isEnable - auto nego state
+* 0--disable auto nego
+* 1--enable auto nego
+*
+* OUTPUT:
+* None.
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyAutoNegoSet(MV_U32 phyAddr, MV_BOOL isEnable)
+{
+ MV_U16 phyRegData;
+ MV_BOOL pre_state;
+
+ /* Disable internal loopback first if enable auto-nego, in order to restore value of related register */
+ if (isEnable) {
+ if (mvEthPhyLoopbackSet(phyAddr, MV_FALSE) != MV_OK)
+ return MV_FAIL;
+ }
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ pre_state = (phyRegData & ETH_PHY_CTRL_AN_ENABLE_MASK) ? 1 : 0;
+ if (isEnable == pre_state)
+ return MV_OK;
+ if (isEnable)
+ phyRegData |= ETH_PHY_CTRL_AN_ENABLE_MASK;
+ else
+ phyRegData &= (~ETH_PHY_CTRL_AN_ENABLE_MASK);
+
+ /*reset PHY, let set above take effect*/
+ if (mvEthPhyReset(phyAddr, phyRegData, MV_PHY_RESET_EXPIRE_COUNT) != MV_OK)
+ return MV_FAIL;
+
+ return MV_OK;
+}
+
+/*******************************************************************************
+* mvEthPhyAutoNegoGet - Get auto nego of PHY.
+*
+* DESCRIPTION:
+* The API get duplex mode.
+* INPUTS:
+* phyAddr - Phy address.
+*
+* OUTPUT:
+* isEnable - auto nego state
+* 0--disable
+* 1--enable
+*
+* RETURN: MV_OK - Success
+* MV_FAIL - Failure
+*******************************************************************************/
+MV_STATUS mvEthPhyAutoNegoGet(MV_U32 phyAddr, MV_BOOL *isEnable)
+{
+ MV_U16 phyRegData;
+
+ if (mvEthPhyRegRead(phyAddr, ETH_PHY_CTRL_REG, &phyRegData) != MV_OK)
+ return MV_FAIL;
+ *isEnable = (phyRegData & ETH_PHY_CTRL_AN_ENABLE_MASK) ? 1 : 0;
+
+ return MV_OK;
+}
+
+
diff --git a/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.h b/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.h
index d621d81..69a581b 100755
--- a/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.h
+++ b/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhy.h
@@ -103,6 +103,17 @@
#define MV_IS_MARVELL_OUI(_reg2, _reg3) \
(((_reg2) == 0x0141) && (((_reg3)&0xFC00) == 0x0C00))
+/* PHY nego mode macro */
+#define PHY_AUTO_NEGO_MODE_HALF_10 0x1
+#define PHY_AUTO_NEGO_MODE_FULL_10 0x2
+#define PHY_AUTO_NEGO_MODE_HALF_100 0x4
+#define PHY_AUTO_NEGO_MODE_FULL_100 0x8
+#define PHY_AUTO_NEGO_MODE_HALF_1000 0x10
+#define PHY_AUTO_NEGO_MODE_FULL_1000 0x20
+
+/* PHY reset expire time */
+#define MV_PHY_RESET_EXPIRE_COUNT 1000
+
typedef struct {
MV_U8 ctrlRevId;
MV_U32 phyAddr[MV_ETH_MAX_PORTS];
@@ -119,11 +130,50 @@
MV_STATUS (*mvExtPhyReadFunc)(MV_U32 phyAddr, MV_U32 regAddr, MV_U16 *data);
} MV_ETHPHY_HAL_DATA;
+/*
+* typedef: enum MV_ETHPHY_PAUSE_MODE
+*
+* Description: Enumeration of Pause Mode in the Phy.
+*
+* Enumerations:
+* MV_ETHPHY_NO_PAUSE - disable pause
+* MV_ETHPHY_PAUSE - support pause
+* MV_ETHPHY_ASYMMETRIC_PAUSE - support asymmetric pause
+* MV_ETHPHY_BOTH_PAUSE - support both pause and asymmetric pause
+*/
+typedef enum
+{
+ MV_ETHPHY_NO_PAUSE = 0,
+ MV_ETHPHY_PAUSE,
+ MV_ETHPHY_ASYMMETRIC_PAUSE,
+ MV_ETHPHY_BOTH_PAUSE
+} MV_ETHPHY_PAUSE_MODE;
+
+/*
+* typedef: enum MV_ETHPHY_SPEED
+*
+* Description: Enumeration of Phy Speed
+*
+* Enumerations:
+* MV_ETHPHY_SPEED_10_MBPS - 10Mbps
+* MV_ETHPHY_SPEED_100_MBPS - 100Mbps
+* MV_ETHPHY_SPEED_1000_MBPS - 1000Mbps
+* MV_ETHPHY_SPEED_UNKNOWN - Unknown speed
+*/
+typedef enum
+{
+ MV_ETHPHY_SPEED_10_MBPS,
+ MV_ETHPHY_SPEED_100_MBPS,
+ MV_ETHPHY_SPEED_1000_MBPS,
+ MV_ETHPHY_SPEED_UNKNOWN
+} MV_ETHPHY_SPEED;
+
+
MV_STATUS mvEthPhyHalInit(MV_ETHPHY_HAL_DATA *halData);
MV_STATUS mvEthPhyInit(MV_U32 ethPortNum, MV_BOOL eeeEnable);
MV_STATUS mvEthPhyRegRead(MV_U32 phyAddr, MV_U32 regOffs, MV_U16 *data);
MV_STATUS mvEthPhyRegWrite(MV_U32 phyAddr, MV_U32 regOffs, MV_U16 data);
-MV_STATUS mvEthPhyReset(MV_U32 phyAddr, int timeout);
+MV_STATUS mvEthPhyReset(MV_U32 phyAddr, MV_U16 data, int timeout);
MV_STATUS mvEthPhyRestartAN(MV_U32 phyAddr, int timeout);
MV_STATUS mvEthPhyDisableAN(MV_U32 phyAddr, int speed, int duplex);
MV_STATUS mvEthPhyLoopback(MV_U32 phyAddr, MV_BOOL isEnable);
@@ -149,6 +199,24 @@
MV_VOID mvEth131xPhyBasicInit(MV_U32 phyAddr);
MV_VOID mvEthE1512PhyBasicInit(MV_U32 ethPortNum, MV_BOOL eeeEnable);
/* MV_VOID mvEthInternal3FEPhyBasicInit(MV_U32 port); */
+MV_STATUS mvEthPhySetAdminState(MV_U32 phyAddr, MV_BOOL phy_state);
+MV_STATUS mvEthPhyGetAdminState(MV_U32 phyAddr, MV_BOOL *phy_state);
+MV_STATUS mvEthPhyGetLinkStatus(MV_U32 phyAddr, MV_BOOL *link_state);
+MV_STATUS mvEthPhyDuplexOperGet(MV_U32 phyAddr, MV_BOOL *state_valid, MV_BOOL *duplex_state);
+MV_STATUS mvEthPhyPauseSet(MV_U32 phyAddr, MV_U32 pause_state);
+MV_STATUS mvEthPhyPauseAdminGet(MV_U32 phyAddr, MV_U32 *pause_state);
+MV_STATUS mvEthPhyLoopbackSet(MV_U32 phyAddr, MV_BOOL isEnable);
+MV_STATUS mvEthPhyLoopbackGet(MV_U32 phyAddr, MV_BOOL *isEnable);
+MV_STATUS mvEthPhyLineLoopbackSet(MV_U32 phyAddr, MV_BOOL isEnable);
+MV_STATUS mvEthPhyLineLoopbackGet(MV_U32 phyAddr, MV_BOOL *isEnable);
+MV_STATUS mvEthPhyDuplexModeSet(MV_U32 phyAddr, MV_BOOL isEnable);
+MV_STATUS mvEthPhyDuplexModeAdminGet(MV_U32 phyAddr, MV_BOOL *isEnable);
+MV_STATUS mvEthPhySpeedSet(MV_U32 phyAddr, MV_U32 speed);
+MV_STATUS mvEthPhySpeedOperGet(MV_U32 phyAddr, MV_U32 *speed);
+MV_STATUS mvEthPhySpeedAdminGet(MV_U32 phyAddr, MV_U32 *speed);
+MV_STATUS mvEthPhySpeedDuplexModeSet(MV_U32 phyAddr, MV_U32 speed, MV_BOOL isEnable);
+MV_STATUS mvEthPhyAutoNegoSet(MV_U32 phyAddr, MV_BOOL isEnable);
+MV_STATUS mvEthPhyAutoNegoGet(MV_U32 phyAddr, MV_BOOL *isEnable);
#ifdef __cplusplus
}
diff --git a/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhyRegs.h b/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhyRegs.h
index c91984d..e3b58b5 100755
--- a/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhyRegs.h
+++ b/arch/arm/plat-feroceon/mv_hal/eth-phy/mvEthPhyRegs.h
@@ -99,10 +99,14 @@
/* PHY registers and bits */
#define ETH_PHY_CTRL_REG 0
#define ETH_PHY_STATUS_REG 1
-#define ETH_PHY_AUTONEGO_AD_REG 4
-#define ETH_PHY_1000BASE_T_CTRL_REG 9
+#define ETH_PHY_ID2_REG 3
+#define ETH_PHY_AUTONEGO_AD_REG 4
+#define ETH_PHY_1000BASE_T_CTRL_REG 9
#define ETH_PHY_SPEC_CTRL_REG 16
#define ETH_PHY_SPEC_STATUS_REG 17
+#define ETH_PHY_SPEC_CTRL2_PAGE2 21
+#define ETH_PHY_PAGE_ADDR 22
+#define ETH_PHY_FE_SPEC_CTRL2 28
/* ETH_PHY_CTRL_REG bits */
#define ETH_PHY_CTRL_SPEED_MSB_BIT 6
@@ -139,13 +143,28 @@
#define ETH_PHY_STATUS_AN_DONE_BIT 5
#define ETH_PHY_STATUS_AN_DONE_MASK (1 << ETH_PHY_STATUS_AN_DONE_BIT)
+#define ETH_PHY_STATUS_EXTEND_BIT 8
+#define ETH_PHY_STATUS_EXTEND_MASK (1 << ETH_PHY_STATUS_EXTEND_BIT)
+
/* ETH_PHY_AUTONEGO_AD_REG bits */
#define ETH_PHY_10_100_BASE_ADVERTISE_OFFSET 5
#define ETH_PHY_10_100_BASE_ADVERTISE_MASK (0xf << ETH_PHY_10_100_BASE_ADVERTISE_OFFSET)
+#define ETH_PHY_SPEC_CTRL_PAUSE_BIT 10
+#define ETH_PHY_SPEC_CTRL_PAUSE_MASK (1 << ETH_PHY_SPEC_CTRL_PAUSE_BIT)
+
+#define ETH_PHY_SPEC_CTRL_ASY_PAUSE_BIT 11
+#define ETH_PHY_SPEC_CTRL_ASY_PAUSE_MASK (1 << ETH_PHY_SPEC_CTRL_ASY_PAUSE_BIT)
+
/* ETH_PHY_1000BASE_T_CTRL_REG bits */
#define ETH_PHY_1000BASE_ADVERTISE_OFFSET 8
#define ETH_PHY_1000BASE_ADVERTISE_MASK (0x3 << ETH_PHY_1000BASE_ADVERTISE_OFFSET)
+#define ETH_PHY_1000BASE_MASTER_ENABLE_OFFSET 12
+#define ETH_PHY_1000BASE_MASTER_ENABLE_MASK (1 << ETH_PHY_1000BASE_MASTER_ENABLE_OFFSET)
+
+/*ETH_PHY_SPEC_CTRL_REG bits */
+#define ETH_PHY_SPEC_CTRL_POWER_DOWN_BIT 2
+#define ETH_PHY_SPEC_CTRL_POWER_DOWN_MASK (1 << ETH_PHY_CTRL_POWER_DOWN_BIT)
/* ETH_PHY_SPEC_STATUS_REG bits */
#define ETH_PHY_SPEC_STATUS_SPEED_OFFS 14
@@ -155,16 +174,31 @@
#define ETH_PHY_SPEC_STATUS_SPEED_100MBPS (0x1 << ETH_PHY_SPEC_STATUS_SPEED_OFFS)
#define ETH_PHY_SPEC_STATUS_SPEED_1000MBPS (0x2 << ETH_PHY_SPEC_STATUS_SPEED_OFFS)
-
#define ETH_PHY_SPEC_STATUS_DUPLEX_BIT 13
#define ETH_PHY_SPEC_STATUS_DUPLEX_MASK (0x1 << ETH_PHY_SPEC_STATUS_DUPLEX_BIT)
+#define ETH_PHY_SPEC_STATUS_RESOLVE_BIT 11
+#define ETH_PHY_SPEC_STATUS_RESOLVE_MASK (0x1 << ETH_PHY_SPEC_STATUS_RESOLVE_BIT)
+
#define ETH_PHY_SPEC_STATUS_LINK_BIT 10
#define ETH_PHY_SPEC_STATUS_LINK_MASK (0x1 << ETH_PHY_SPEC_STATUS_LINK_BIT)
/* ETH_PHY_SPEC_STATUS_REG bits */
#define ETH_PHY_LED_ACT_LNK_DV 0x4109
+/* ETH_PHY_SPEC_CTRL2_PAGE2 bits*/
+#define ETH_PHY_SPEC_CTRL2_PAGE2_MAC_SPEED_OFFS 0
+#define ETH_PHY_SPEC_CTRL2_PAGE2_MAC_SPEED_10M 4
+#define ETH_PHY_SPEC_CTRL2_PAGE2_MAC_SPEED_100M 5
+#define ETH_PHY_SPEC_CTRL2_PAGE2_MAC_SPEED_1000M 6
+
+#define ETH_PHY_SPEC_CTRL2_PAGE2_LINE_LPK_BIT 14
+#define ETH_PHY_SPEC_CTRL2_PAGE2_LINE_LPK_MASK (0x1 << ETH_PHY_SPEC_CTRL2_PAGE2_LINE_LPK_BIT)
+
+/* ETH_PHY_FE_SPEC_CTRL2 bits*/
+#define ETH_PHY_SPEC_CTRL2_FE_LINE_LPK_BIT 4
+#define ETH_PHY_SPEC_CTRL2_FE_LINE_LPK_MASK (0x1 << ETH_PHY_SPEC_CTRL2_FE_LINE_LPK_BIT)
+
#ifdef __cplusplus
}
#endif
diff --git a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvHwf.c b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvHwf.c
index e57702c..69b6a4c 100755
--- a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvHwf.c
+++ b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvHwf.c
@@ -235,6 +235,19 @@
return MV_OK;
}
+MV_STATUS mvNetaHwfTxqNextIndexGet(int port, int tx_port, int txp, int txq, int *val)
+{
+ MV_U32 regVal;
+
+ regVal = NETA_HWF_TX_PORT_MASK(tx_port + txp) | NETA_HWF_TXQ_MASK(txq) | NETA_HWF_REG_MASK(3);
+ MV_REG_WRITE(NETA_HWF_TX_PTR_REG(port), regVal);
+
+ regVal = MV_REG_READ(NETA_HWF_MEMORY_REG(port));
+ if (val)
+ *val = (int)((regVal >> 16) & 0x3fff);
+
+ return MV_OK;
+}
/*******************************************************************************
* mvNetaHwfTxqEnable - Enable / Disable HWF from the rx_port to tx_port/txp/txq
diff --git a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNeta.h b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNeta.h
index ad3679c..5a9ac64 100755
--- a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNeta.h
+++ b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNeta.h
@@ -474,6 +474,30 @@
return sent_desc;
}
+/* Invalidate TXQ descriptor - buffer will not be sent, buffer will not be returned */
+static INLINE void mvNetaTxqDescInv(NETA_TX_DESC *pTxDesc)
+{
+ pTxDesc->command |= NETA_TX_HWF_MASK;
+ pTxDesc->command &= ~NETA_TX_BM_ENABLE_MASK;
+ pTxDesc->hw_cmd |= NETA_TX_ES_MASK;
+}
+
+/* Return: 1 - TX descriptor is valid, 0 - TX descriptor is invalid */
+static INLINE int mvNetaTxqDescIsValid(NETA_TX_DESC *pTxDesc)
+{
+ return ((pTxDesc->hw_cmd & NETA_TX_ES_MASK) == 0);
+}
+
+/* Get index of descripotor to be processed next in the specific TXQ */
+static INLINE int mvNetaTxqNextIndexGet(int port, int txp, int txq)
+{
+ MV_U32 regVal;
+
+ regVal = MV_REG_READ(NETA_TXQ_INDEX_REG(port, txp, txq));
+
+ return (regVal & NETA_TXQ_NEXT_DESC_INDEX_MASK) >> NETA_TXQ_NEXT_DESC_INDEX_OFFS;
+}
+
/* Get number of TX descriptors didn't send by HW yet and waiting for TX */
static INLINE int mvNetaTxqPendDescNumGet(int port, int txp, int txq)
{
@@ -755,6 +779,8 @@
MV_STATUS mvNetaHwfTxqDropSet(int port, int p, int txp, int txq, int thresh, int bits);
MV_STATUS mvNetaHwfMhSrcSet(int port, MV_NETA_HWF_MH_SRC src);
MV_STATUS mvNetaHwfMhSelSet(int port, MV_U8 mhSel);
+MV_STATUS mvNetaHwfTxqNextIndexGet(int port, int tx_port, int txp, int txq, int *val);
+
void mvNetaHwfRxpRegs(int port);
void mvNetaHwfTxpRegs(int port, int p, int txp);
diff --git a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaDebug.c b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaDebug.c
index 2a487d0..4db75e3 100755
--- a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaDebug.c
+++ b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaDebug.c
@@ -599,16 +599,20 @@
mvEthMibPrint(port, mib, ETH_MIB_BAD_CRC_EVENT, "BAD_CRC_EVENT");
mvEthRegPrint0(ETH_RX_DISCARD_PKTS_CNTR_REG(port), "RX_DISCARD_PKTS_CNTR_REG");
mvEthRegPrint0(ETH_RX_OVERRUN_PKTS_CNTR_REG(port), "RX_OVERRUN_PKTS_CNTR_REG");
+
mvOsPrintf("\n[Tx]\n");
mvEthMibPrint(port, mib, ETH_MIB_GOOD_FRAMES_SENT, "GOOD_FRAMES_SENT");
mvEthMibPrint(port, mib, ETH_MIB_BROADCAST_FRAMES_SENT, "BROADCAST_FRAMES_SENT");
mvEthMibPrint(port, mib, ETH_MIB_MULTICAST_FRAMES_SENT, "MULTICAST_FRAMES_SENT");
mvEthMibPrint(port, mib, ETH_MIB_GOOD_OCTETS_SENT_LOW, "GOOD_OCTETS_SENT");
+
mvOsPrintf("\n[Tx Errors]\n");
mvEthMibPrint(port, mib, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, "INTERNAL_MAC_TRANSMIT_ERR");
mvEthMibPrint(port, mib, ETH_MIB_EXCESSIVE_COLLISION, "EXCESSIVE_COLLISION");
mvEthMibPrint(port, mib, ETH_MIB_COLLISION, "COLLISION");
mvEthMibPrint(port, mib, ETH_MIB_LATE_COLLISION, "LATE_COLLISION");
+ mvEthRegPrint0(NETA_TX_BAD_FCS_CNTR_REG(port, mib), "NETA_TX_BAD_FCS_CNTR_REG");
+ mvEthRegPrint0(NETA_TX_DROP_CNTR_REG(port, mib), "NETA_TX_DROP_CNTR_REG");
mvOsPrintf("\n[FC control]\n");
mvEthMibPrint(port, mib, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, "UNREC_MAC_CONTROL_RECEIVED");
diff --git a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaRegs.h b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaRegs.h
index 7b0d73b..435ce51 100755
--- a/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaRegs.h
+++ b/arch/arm/plat-feroceon/mv_hal/neta/gbe/mvNetaRegs.h
@@ -313,6 +313,10 @@
#define NETA_HWF_TXQ_OFFS 8
#define NETA_HWF_TXQ_ALL_MASK (0x7 << NETA_HWF_TXQ_OFFS)
#define NETA_HWF_TXQ_MASK(txq) ((txq) << NETA_HWF_TXQ_OFFS)
+
+#define NETA_HWF_REG_OFFS 0
+#define NETA_HWF_REG_ALL_MASK (0x7 << NETA_HWF_REG_OFFS)
+#define NETA_HWF_REG_MASK(reg) ((reg) << NETA_HWF_REG_OFFS)
/*-----------------------------------------------------------------------------------*/
#define NETA_HWF_DROP_TH_REG(p) (NETA_REG_BASE(p) + 0x1d40)
diff --git a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.c b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.c
index 85741ef..3d4d2d0 100755
--- a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.c
+++ b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.c
@@ -239,6 +239,29 @@
/*******************************************************************************
**
+** mvOnuGponMacRxFecHysteresisSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function set Rx PSA FEC Hysteresis config register
+**
+** PARAMETERS: MV_U32 fecHyst
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS mvOnuGponMacRxFecHysteresisSet(MV_U32 fecHyst)
+{
+ MV_STATUS status;
+
+ status = asicOntGlbRegWrite(mvAsicReg_GPON_RX_PSA_CONFIG_FHM1, fecHyst, 0);
+
+ return(status);
+}
+
+/*******************************************************************************
+**
** mvOnuGponMacRxFecConfigSet
** ____________________________________________________________________________
**
@@ -1449,6 +1472,68 @@
return(status);
}
+/*******************************************************************************
+**
+** mvOnuGponMacUtmActiveTxBitmapSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function set the active TX bitmap
+**
+** PARAMETERS: MV_U32 bitmap
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS mvOnuGponMacUtmActiveTxBitmapSet(MV_U32 bitmap)
+{
+ return(asicOntGlbRegWrite(mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP, bitmap, 0));
+}
+
+/*******************************************************************************
+**
+** mvOnuGponMacUtmActiveTxBitmapValidSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function set the active TX bitmap valid
+**
+** PARAMETERS: MV_U32 valid
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS mvOnuGponMacUtmActiveTxBitmapValidSet(MV_U32 valid)
+{
+ return(asicOntGlbRegWrite(mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP_VALID, valid, 0));
+}
+
+/*******************************************************************************
+**
+** mvOnuGponMacUtmActiveTxBitmapConfigGet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function return the active TX bitmap configuration
+**
+** PARAMETERS: MV_U32 *bitmap
+** MV_U32 *valid
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or error
+**
+*******************************************************************************/
+MV_STATUS mvOnuGponMacUtmActiveTxBitmapConfigGet(MV_U32 *bitmap, MV_U32 *valid)
+{
+ MV_STATUS status;
+
+ status = asicOntGlbRegRead(mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP, bitmap, 0);
+ status |= asicOntGlbRegRead(mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP_VALID, valid, 0);
+
+ return(status);
+}
/******************************************************************************/
/* ========================================================================== */
@@ -2436,7 +2521,7 @@
MV_U8 dataPattern1,
MV_U8 dataPattern2)
{
- MV_U32 reg = 0;
+ MV_U32 reg = 0;
if (busrtMode != GPON_TX_AC_COUPL_BUST_MODE_0)
reg = 1 << 30;
@@ -4305,6 +4390,52 @@
/*******************************************************************************
**
+** mvOnuEponMacPcsRxEnableSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function sets PcsRxEnable register
+**
+** PARAMETERS: MV_U32 rxEnable
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or MV_ERROR
+**
+*******************************************************************************/
+MV_STATUS mvOnuEponMacPcsRxEnableSet(MV_U32 rxEnable)
+{
+ MV_STATUS status;
+
+ status = asicOntGlbRegWrite(mvAsicReg_EPON_PCS_CONFIGURATION_RX_ENABLE, rxEnable, 0);
+
+ return (status);
+}
+
+/*******************************************************************************
+**
+** mvOnuEponMacPcsTxEnableSet
+** ____________________________________________________________________________
+**
+** DESCRIPTION: The function sets PcsTxEnable register
+**
+** PARAMETERS: MV_U32 txEnable
+**
+** OUTPUTS: None
+**
+** RETURNS: MV_OK or MV_ERROR
+**
+*******************************************************************************/
+MV_STATUS mvOnuEponMacPcsTxEnableSet(MV_U32 txEnable)
+{
+ MV_STATUS status;
+
+ status = asicOntGlbRegWrite(mvAsicReg_EPON_PCS_CONFIGURATION_TX_ENABLE, txEnable, 0);
+
+ return (status);
+}
+
+/*******************************************************************************
+**
** mvOnuEponMacOnuEnableSet
** ____________________________________________________________________________
**
@@ -4320,12 +4451,15 @@
*******************************************************************************/
MV_STATUS mvOnuEponMacOnuEnableSet(MV_U32 rxEnable, MV_U32 txEnable)
{
- MV_STATUS status;
+ MV_STATUS status;
- status = asicOntGlbRegWrite(mvAsicReg_EPON_GEN_ONT_RX_ENABLE, rxEnable, 0);
- status |= asicOntGlbRegWrite(mvAsicReg_EPON_GEN_ONT_TX_ENABLE, txEnable, 0);
+ status = asicOntGlbRegWrite(mvAsicReg_EPON_PCS_CONFIGURATION_RX_ENABLE, rxEnable, 0);
+ status |= asicOntGlbRegWrite(mvAsicReg_EPON_GEN_ONT_RX_ENABLE, rxEnable, 0);
- return(status);
+ status |= asicOntGlbRegWrite(mvAsicReg_EPON_PCS_CONFIGURATION_TX_ENABLE, txEnable, 0);
+ status |= asicOntGlbRegWrite(mvAsicReg_EPON_GEN_ONT_TX_ENABLE, txEnable, 0);
+
+ return (status);
}
/*******************************************************************************
@@ -4333,7 +4467,7 @@
** mvOnuEponMacOnuRxEnableSet
** ____________________________________________________________________________
**
-** DESCRIPTION: The function set onu Rx & Tx enable
+** DESCRIPTION: The function set onu Rx enable
**
** PARAMETERS: MV_U32 rxEnable
**
@@ -4344,11 +4478,13 @@
*******************************************************************************/
MV_STATUS mvOnuEponMacOnuRxEnableSet(MV_U32 rxEnable)
{
- MV_STATUS status;
+ MV_STATUS status;
- status = asicOntGlbRegWrite(mvAsicReg_EPON_GEN_ONT_RX_ENABLE, rxEnable, 0);
+ status = asicOntGlbRegWrite(mvAsicReg_EPON_PCS_CONFIGURATION_RX_ENABLE, rxEnable, 0);
- return(status);
+ status |= asicOntGlbRegWrite(mvAsicReg_EPON_GEN_ONT_RX_ENABLE, rxEnable, 0);
+
+ return (status);
}
/*******************************************************************************
diff --git a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.h b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.h
index 7c1f720..41c62b8 100755
--- a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.h
+++ b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuMac.h
@@ -200,10 +200,19 @@
/*AC coupling burst mode*/
#define GPON_TX_AC_COUPL_BUST_MODE_0 (0)
#define GPON_TX_AC_COUPL_BUST_MODE_1 (1)
-#define GPON_TX_AC_COUPL_PREACT_BURST_TIME (0x0)
-#define GPON_TX_AC_COUPL_DATA_PATTERN_1 (0x0)
+#define GPON_TX_AC_COUPL_PREACT_BURST_TIME (0x30)
+#define GPON_TX_AC_COUPL_DATA_PATTERN_1 (0x66)
#define GPON_TX_AC_COUPL_DATA_PATTERN_2 (0x0)
+/*UTM Active TX Bitmap*/
+#define GPON_UTM_ACTIVE_TX_BITMAP (0xFFFF)
+#define GPON_UTM_ACTIVE_TX_BITMAP_VALID (1)
+
+/*GSE Transmit threshold*/
+#define GPON_GST_TX_DATA_SHIFT (12)
+#define GPON_GST_TX_DATA_THRESHOLD (0x30)
+#define GPON_GST_TX_IDLE_THRESHOLD (0x10)
+
/* Typedefs
------------------------------------------------------------------------------*/
typedef MV_STATUS (*MACTXPLOAMCTRFUNC)(MV_U8 msgId, MV_BOOL status);
@@ -272,6 +281,7 @@
MV_STATUS mvOnuGponMacRxConfigSet(MV_BOOL enable);
MV_STATUS mvOnuGponMacRxConfigBitOrderSet(MV_U32 value);
MV_STATUS mvOnuGponMacRxPsaConfigSet(MV_U32 syncFsmM1, MV_U32 syncFsmM2, MV_U32 syncFsmM3, MV_U32 fecHyst);
+MV_STATUS mvOnuGponMacRxFecHysteresisSet(MV_U32 fecHyst);
MV_STATUS mvOnuGponMacRxFecConfigSet(MV_BOOL swIndication, MV_BOOL forceSw, MV_BOOL ignoreParity);
MV_STATUS mvOnuGponMacRxFecStatusGet(MV_U32 *fecStatus);
MV_STATUS mvOnuGponMacRxPloamDataGet(MV_U32 *ploamData);
@@ -333,6 +343,9 @@
MV_STATUS mvOnuGponMacUtmTcPeriodSet(MV_U32 period );
MV_STATUS mvOnuGponMacUtmTcValidSet(MV_U32 valid);
MV_STATUS mvOnuGponMacUtmTcConfigGet(MV_U32 *period, MV_U32 *valid);
+MV_STATUS mvOnuGponMacUtmActiveTxBitmapSet(MV_U32 bitmap);
+MV_STATUS mvOnuGponMacUtmActiveTxBitmapValidSet(MV_U32 valid);
+MV_STATUS mvOnuGponMacUtmActiveTxBitmapConfigGet(MV_U32 *bitmap, MV_U32 *valid);
/* ========================================================================== */
/* Interrupt Functions Section */
/* ========================================================================== */
@@ -480,6 +493,21 @@
#define EPON_DDM_TX_XVR_POL_DEFAULT (0)
#define EPON_DDM_TX_BURST_ENA_DEFAULT (0)
+/* PCS RX */
+#define EPON_PCS_CONFIG_RX_ENABLE (1)
+#define EPON_PCS_CONFIG_RX_DISABLE (0)
+
+/* EPON 2K packet supported */
+#define EPON_MAC_RXP_DATA_FIFO_THRESHOLD_2K_SUPP (0x800)
+#define EPON_MAC_PCS_FRAME_SIZE_LIMIT_SIZE_2K_SUPP (0x800)
+#define EPON_MAC_PCS_FRAME_SIZE_LIMIT_LATENCY_2K_SUPP (0x1324)
+
+/* Default value of these registers */
+#define EPON_MAC_RXP_DATA_FIFO_THRESHOLD_DEF (0x780)
+#define EPON_MAC_PCS_FRAME_SIZE_LIMIT_SIZE_DEF (0x640)
+#define EPON_MAC_PCS_FRAME_SIZE_LIMIT_LATENCY_DEF (0xED8)
+
+
/* Global functions
------------------------------------------------------------------------------*/
@@ -494,6 +522,8 @@
/* General Functions Section */
/* ========================================================================== */
MV_STATUS mvOnuEponMacVersionGet(MV_U32 *version);
+MV_STATUS mvOnuEponMacPcsRxEnableSet(MV_U32 rxEnable);
+MV_STATUS mvOnuEponMacPcsTxEnableSet(MV_U32 txEnable);
MV_STATUS mvOnuEponMacOnuEnableSet(MV_U32 rxEnable, MV_U32 txEnable);
MV_STATUS mvOnuEponMacOnuRxEnableSet(MV_U32 rxEnable);
MV_STATUS mvOnuEponMacOnuTxEnableSet(MV_U32 txEnable, MV_U32 macId);
diff --git a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.c b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.c
index 497a288..8ce83f0 100755
--- a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.c
+++ b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.c
@@ -256,7 +256,7 @@
[mvAsicReg_GPON_TX_STAT_GEM_IDLE] = {mvAsicReg_GPON_TX_STAT_GEM_IDLE, MV_ASIC_ONT_GLB_ADDR + 0x1034, 0x1034, asicRO, 0xFFFFFFFF, 0, 0, 0, 0, "Total num of trans idle gem frames"},
[mvAsicReg_GPON_TX_STAT_TX_EN_CNT] = {mvAsicReg_GPON_TX_STAT_TX_EN_CNT, MV_ASIC_ONT_GLB_ADDR + 0x1038, 0x1038, asicRO, 0xFFFFFFFF, 0, 0, 0, 0, "Total num of cycles with tx enable indication asserted"},
[mvAsicReg_GPON_TX_CONFIG_EN_THRESHOLD] = {mvAsicReg_GPON_TX_CONFIG_EN_THRESHOLD, MV_ASIC_ONT_GLB_ADDR + 0x103C, 0x103C, asicRW, 0xFFFFFFFF, 0, 0, 0, 0, "Saturation threshold for tx enable indication counter"},
- [mvAsicReg_GPON_TX_GSE_TRANS_THRESHOLD] = {mvAsicReg_GPON_TX_GSE_TRANS_THRESHOLD, MV_ASIC_ONT_GLB_ADDR + 0x1040, 0x1040, asicRO, 0x00FFFFFF, 0, 0, 0, 0, "GSE threshold for starting forwarding data to the tx burst fifo"},
+ [mvAsicReg_GPON_TX_GSE_TRANS_THRESHOLD] = {mvAsicReg_GPON_TX_GSE_TRANS_THRESHOLD, MV_ASIC_ONT_GLB_ADDR + 0x1040, 0x1040, asicRW, 0x00FFFFFF, 0, 0, 0, 0, "GSE threshold for starting forwarding data to the tx burst fifo"},
[mvAsicReg_GPON_TX_CFG_AC_COUPLING] = {mvAsicReg_GPON_TX_CFG_AC_COUPLING, MV_ASIC_ONT_GLB_ADDR + 0x104C, 0x104C, asicRW, 0xFFFFFFFF, 0, 0, 0, 0, "Transmit Configuration AC Coupling"},
[mvAsicReg_GPON_TX_STAT_TCONT_i_ETH_FRAMES] = {mvAsicReg_GPON_TX_STAT_TCONT_i_ETH_FRAMES, MV_ASIC_ONT_GLB_ADDR + 0x10A0, 0x10A0, asicRO, 0xFFFFFFFF, 0, 8, 1, 0, "Num of ethernet frames trans via tcont i"},
[mvAsicReg_GPON_TX_STAT_TCONT_i_ETH_BYTES] = {mvAsicReg_GPON_TX_STAT_TCONT_i_ETH_BYTES, MV_ASIC_ONT_GLB_ADDR + 0x10C8, 0x10C8, asicRO, 0xFFFFFFFF, 0, 8, 1, 0, "Num of ethernet payload bytes trans via tcont i"},
@@ -270,6 +270,8 @@
[mvAsicReg_GPON_UTM_CONFIG_OMCI_PORT_VALID] = {mvAsicReg_GPON_UTM_CONFIG_OMCI_PORT_VALID, MV_ASIC_ONT_GLB_ADDR + 0x1404, 0x1404, asicRW, 0x00000001, 0, 0, 0, 0, "Omci gem port valid - upstream direction"},
[mvAsicReg_GPON_UTM_CONFIG_TC_PERIOD] = {mvAsicReg_GPON_UTM_CONFIG_TC_PERIOD, MV_ASIC_ONT_GLB_ADDR + 0x1408, 0x1408, asicRW, 0xFFFFFFFF, 0, 0, 0, 0, "Num of cycles to pause between two counter gathering sweeps"},
[mvAsicReg_GPON_UTM_CONFIG_TC_PERIOD_VALID] = {mvAsicReg_GPON_UTM_CONFIG_TC_PERIOD_VALID, MV_ASIC_ONT_GLB_ADDR + 0x140C, 0x140C, asicRW, 0x00000001, 0, 0, 0, 0, "Tc period valid"},
+ [mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP] = {mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP, MV_ASIC_ONT_GLB_ADDR + 0x1410, 0x1410, asicRW, 0x000000FF, 0, 0, 0, 0, "Active TX bitmap"},
+ [mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP_VALID] = {mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP_VALID, MV_ASIC_ONT_GLB_ADDR + 0x1414, 0x1414, asicRW, 0x00000001, 0, 0, 0, 0, "Active TX bitmap valid"},
/* =========================== */
/* SGL Registers */
@@ -494,6 +496,8 @@
/* EPON PCS Registers */
/* =========================== */
[mvAsicReg_EPON_PCS_CONFIGURATION] = {mvAsicReg_EPON_PCS_CONFIGURATION, MV_ASIC_ONT_GLB_ADDR + 0x1414, 0x1414, asicRW, 0x00000033, 0, 0, 0, 0, "PCS configuration"},
+ [mvAsicReg_EPON_PCS_CONFIGURATION_RX_ENABLE] = {mvAsicReg_EPON_PCS_CONFIGURATION_RX_ENABLE, MV_ASIC_ONT_GLB_ADDR + 0x1414, 0x1414, asicRW, 0x00000001, 0, 0, 0, 0, "PCS configuration Rx enable"},
+ [mvAsicReg_EPON_PCS_CONFIGURATION_TX_ENABLE] = {mvAsicReg_EPON_PCS_CONFIGURATION_TX_ENABLE, MV_ASIC_ONT_GLB_ADDR + 0x1414, 0x1414, asicRW, 0x00000001, 4, 0, 0, 0, "PCS configuration Tx enable"},
[mvAsicReg_EPON_PCS_DELAY_CONFIG] = {mvAsicReg_EPON_PCS_DELAY_CONFIG, MV_ASIC_ONT_GLB_ADDR + 0x1418, 0x1418, asicRW, 0x00001FFF, 0, 0, 0, 0, "PCS delay config"},
[mvAsicReg_EPON_PCS_STATS_FEC_0] = {mvAsicReg_EPON_PCS_STATS_FEC_0, MV_ASIC_ONT_GLB_ADDR + 0x141C, 0x141C, asicRW, 0xFFFFFFFF, 0, 0, 0, 0, "PCS stats Fec 0"},
[mvAsicReg_EPON_PCS_STATS_FEC_1] = {mvAsicReg_EPON_PCS_STATS_FEC_1, MV_ASIC_ONT_GLB_ADDR + 0x1420, 0x1420, asicRW, 0xFFFFFFFF, 0, 0, 0, 0, "PCS stats Fec 1"},
diff --git a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.h b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.h
index 6fa151b..96a6ba3 100755
--- a/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.h
+++ b/arch/arm/plat-feroceon/mv_hal/pon/mvPonOnuRegs.h
@@ -256,6 +256,8 @@
mvAsicReg_GPON_UTM_CONFIG_OMCI_PORT_VALID = 134, /* UtmCfgOmciPvalid */
mvAsicReg_GPON_UTM_CONFIG_TC_PERIOD = 135, /* UtmCfgTcPeriod */
mvAsicReg_GPON_UTM_CONFIG_TC_PERIOD_VALID = 136, /* UtmCfgTcPeriodValid */
+ mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP = 137, /* UtmActiveTxBitmap */
+ mvAsicReg_GPON_UTM_ACTIVE_TX_BITMAP_VALID = 138, /* UtmActiveTxBitmapValid */
/* SGL Registers */
/* ============= */
@@ -419,52 +421,56 @@
/* EPON PCS Registers */
/* =========================== */
- mvAsicReg_EPON_PCS_CONFIGURATION = 284,
- mvAsicReg_EPON_PCS_DELAY_CONFIG = 285,
- mvAsicReg_EPON_PCS_STATS_FEC_0 = 286,
- mvAsicReg_EPON_PCS_STATS_FEC_1 = 287,
- mvAsicReg_EPON_PCS_STATS_FEC_2 = 288,
- mvAsicReg_EPON_PCS_STATS_0 = 290,
- mvAsicReg_EPON_PCS_STATS_1 = 291,
- mvAsicReg_EPON_PCS_STATS_2 = 292,
- mvAsicReg_EPON_PCS_STATS_3 = 293,
- mvAsicReg_EPON_PCS_STATS_4 = 294,
- mvAsicReg_EPON_PCS_FRAME_SZ_LIMITS = 295,
+ mvAsicReg_EPON_PCS_CONFIGURATION = 284,
+
+ mvAsicReg_EPON_PCS_CONFIGURATION_RX_ENABLE = 285,
+ mvAsicReg_EPON_PCS_CONFIGURATION_TX_ENABLE = 286,
+
+ mvAsicReg_EPON_PCS_DELAY_CONFIG = 287,
+ mvAsicReg_EPON_PCS_STATS_FEC_0 = 288,
+ mvAsicReg_EPON_PCS_STATS_FEC_1 = 289,
+ mvAsicReg_EPON_PCS_STATS_FEC_2 = 290,
+ mvAsicReg_EPON_PCS_STATS_0 = 292,
+ mvAsicReg_EPON_PCS_STATS_1 = 293,
+ mvAsicReg_EPON_PCS_STATS_2 = 294,
+ mvAsicReg_EPON_PCS_STATS_3 = 295,
+ mvAsicReg_EPON_PCS_STATS_4 = 296,
+ mvAsicReg_EPON_PCS_FRAME_SZ_LIMITS = 297,
/* EPON DDM Registers */
/* =========================== */
- mvAsicReg_EPON_DDM_DELAY_CONFIG = 296,
- mvAsicReg_EPON_DDM_TX_POLARITY = 297,
+ mvAsicReg_EPON_DDM_DELAY_CONFIG = 298,
+ mvAsicReg_EPON_DDM_TX_POLARITY = 299,
/* statistics */
- mvAsicReg_EPON_STAT_RXP_FCS_ERROR_CNT = 298,
- mvAsicReg_EPON_STAT_RXP_SHORT_ERROR_CNT = 299,
- mvAsicReg_EPON_STAT_RXP_LONG_ERROR_CNT = 300,
- mvAsicReg_EPON_STAT_RXP_DATA_FRAMES_CNT = 301,
- mvAsicReg_EPON_STAT_RXP_CTRL_FRAMES_CNT = 302,
- mvAsicReg_EPON_STAT_RXP_REPORT_FRAMES_CNT = 303,
- mvAsicReg_EPON_STAT_RXP_GATE_FRAMES_CNT = 304,
- mvAsicReg_EPON_STAT_TXP_CTRL_REG_REQ_FRAMES_CNT = 305,
- mvAsicReg_EPON_STAT_TXP_CTRL_REG_ACK_FRAMES_CNT = 306,
- mvAsicReg_EPON_STAT_TXP_CTRL_REPORT_FRAMES_CNT = 307,
- mvAsicReg_EPON_STAT_TXP_DATA_FRAMES_CNT = 308,
- mvAsicReg_EPON_STAT_TXP_TX_ALLOWED_BYTE_CNT = 309,
+ mvAsicReg_EPON_STAT_RXP_FCS_ERROR_CNT = 300,
+ mvAsicReg_EPON_STAT_RXP_SHORT_ERROR_CNT = 301,
+ mvAsicReg_EPON_STAT_RXP_LONG_ERROR_CNT = 302,
+ mvAsicReg_EPON_STAT_RXP_DATA_FRAMES_CNT = 303,
+ mvAsicReg_EPON_STAT_RXP_CTRL_FRAMES_CNT = 304,
+ mvAsicReg_EPON_STAT_RXP_REPORT_FRAMES_CNT = 305,
+ mvAsicReg_EPON_STAT_RXP_GATE_FRAMES_CNT = 306,
+ mvAsicReg_EPON_STAT_TXP_CTRL_REG_REQ_FRAMES_CNT = 307,
+ mvAsicReg_EPON_STAT_TXP_CTRL_REG_ACK_FRAMES_CNT = 308,
+ mvAsicReg_EPON_STAT_TXP_CTRL_REPORT_FRAMES_CNT = 309,
+ mvAsicReg_EPON_STAT_TXP_DATA_FRAMES_CNT = 310,
+ mvAsicReg_EPON_STAT_TXP_TX_ALLOWED_BYTE_CNT = 311,
/* EPON Control Packet queue Registers */
/* ===================================== */
- mvAsicReg_EPON_CPQ_RX_CTRL_Q_READ = 310,
- mvAsicReg_EPON_CPQ_RX_CTRL_Q_USED = 311,
- mvAsicReg_EPON_CPQ_RX_RPRT_Q_READ = 312,
- mvAsicReg_EPON_CPQ_RX_RPRT_Q_USED = 313,
- mvAsicReg_EPON_CPQ_RX_CTRL_HQ_READ_L = 314,
- mvAsicReg_EPON_CPQ_RX_CTRL_HQ_READ_H = 315,
- mvAsicReg_EPON_CPQ_RX_CTRL_HQ_USED = 316,
- mvAsicReg_EPON_CPQ_RX_RPRT_HQ_READ_L = 317,
- mvAsicReg_EPON_CPQ_RX_RPRT_HQ_READ_H = 318,
- mvAsicReg_EPON_CPQ_RX_RPRT_HQ_USED = 319,
- mvAsicReg_EPON_CPQ_TX_CTRL_Q_WRITE = 320,
- mvAsicReg_EPON_CPQ_TX_CTRL_Q_FREE = 321,
- mvAsicReg_EPON_CPQ_TX_CTRL_HQ_WRITE = 322,
- mvAsicReg_EPON_CPQ_TX_CTRL_HQ_FREE = 323,
+ mvAsicReg_EPON_CPQ_RX_CTRL_Q_READ = 312,
+ mvAsicReg_EPON_CPQ_RX_CTRL_Q_USED = 313,
+ mvAsicReg_EPON_CPQ_RX_RPRT_Q_READ = 314,
+ mvAsicReg_EPON_CPQ_RX_RPRT_Q_USED = 315,
+ mvAsicReg_EPON_CPQ_RX_CTRL_HQ_READ_L = 316,
+ mvAsicReg_EPON_CPQ_RX_CTRL_HQ_READ_H = 317,
+ mvAsicReg_EPON_CPQ_RX_CTRL_HQ_USED = 318,
+ mvAsicReg_EPON_CPQ_RX_RPRT_HQ_READ_L = 319,
+ mvAsicReg_EPON_CPQ_RX_RPRT_HQ_READ_H = 320,
+ mvAsicReg_EPON_CPQ_RX_RPRT_HQ_USED = 321,
+ mvAsicReg_EPON_CPQ_TX_CTRL_Q_WRITE = 322,
+ mvAsicReg_EPON_CPQ_TX_CTRL_Q_FREE = 323,
+ mvAsicReg_EPON_CPQ_TX_CTRL_HQ_WRITE = 324,
+ mvAsicReg_EPON_CPQ_TX_CTRL_HQ_FREE = 325,
/* P2P Registers */
diff --git a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/h/msApi/msApiInternal.h b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/h/msApi/msApiInternal.h
index c5c0f4b..76f69cc 100755
--- a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/h/msApi/msApiInternal.h
+++ b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/h/msApi/msApiInternal.h
@@ -723,6 +723,8 @@
#define DEV_IP_MAPPING_TABLE ( DEV_88E6351_FAMILY )
#define DEV_EEPROM ( DEV_88E6351_FAMILY )
+/*PIRL Alpha factor macro for 6510 internal switch*/
+#define PIRL_ALPHA 6250000
/* Macros to utilize Device Group */
diff --git a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiDefs.h b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiDefs.h
index 6e238e6..4b41fef 100755
--- a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiDefs.h
+++ b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiDefs.h
@@ -3895,6 +3895,63 @@
};
+/*
+ * typedef: struct PIRL_PARA_TBL_T
+ *
+ * Description: PIRL parameter table structure
+ *
+ * Fields:
+ * BI - bucket increment
+ * BRF - bucket rate factor
+ * CBS - Committed Burst Size
+ * EBS - Excess Burst Size
+ */
+typedef struct {
+ GT_U32 BI;
+ GT_U32 BRF;
+ GT_U32 CBS;
+ GT_U32 EBS;
+} PIRL_PARA_TBL_T;
+
+/*special rate which can not be calculated by formula*/
+typedef enum {
+ PIRL_RATE_NO_LIMIT = 0,
+ PIRL_RATE_64K,
+ PIRL_RATE_128K,
+ PIRL_RATE_192K,
+ PIRL_RATE_256K,
+ PIRL_RATE_320K,
+ PIRL_RATE_384K,
+ PIRL_RATE_448K,
+ PIRL_RATE_512K,
+ PIRL_RATE_576K,
+ PIRL_RATE_640K,
+ PIRL_RATE_704K,
+ PIRL_RATE_768K,
+ PIRL_RATE_832K,
+ PIRL_RATE_896K,
+ PIRL_RATE_960K,
+ PIRL_RATE_1M,
+ PIRL_RATE_2M,
+ PIRL_RATE_3M,
+ PIRL_RATE_4M,
+ PIRL_RATE_5M,
+ PIRL_RATE_6M,
+ PIRL_RATE_7M,
+ PIRL_RATE_8M,
+ PIRL_RATE_9M,
+ PIRL_RATE_10M,
+ PIRL_RATE_11M,
+ PIRL_RATE_12M,
+ PIRL_RATE_13M,
+ PIRL_RATE_14M,
+ PIRL_RATE_15M,
+ PIRL_RATE_16M,
+ PIRL_RATE_17M,
+ PIRL_RATE_18M,
+ PIRL_RATE_19M,
+ PIRL_RATE_20M
+} PIRL_SPECIAL_RATE_ENUM_T;
#ifdef __cplusplus
}
diff --git a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiPrototype.h b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiPrototype.h
index f02972e..d2828e7 100755
--- a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiPrototype.h
+++ b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/Include/msApiPrototype.h
@@ -3199,6 +3199,42 @@
IN GT_BOOL mode
);
+/*******************************************************************************
+* gprtSetPortSpeedDuplexMode
+*
+* DESCRIPTION:
+* Sets speed and duplex mode for a specific logical port. This function
+* will keep the loopback mode to the previous value, but disable others,
+* such as Autonegotiation.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+* The physical address, if SERDES device is accessed
+* speed - port speed.
+* PHY_SPEED_10_MBPS for 10Mbps
+* PHY_SPEED_100_MBPS for 100Mbps
+* PHY_SPEED_1000_MBPS for 1000Mbps
+* dMode - Duplex mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* GT_OK - on success
+* GT_FAIL - on error
+*
+* COMMENTS:
+* data sheet register 0.13 - Speed Selection (LSB)
+* data sheet register 0.6 - Speed Selection (MSB)
+* data sheet register 0.8 - Duplex mode
+*******************************************************************************/
+GT_STATUS gprtSetPortSpeedDuplexMode
+(
+IN GT_QD_DEV *dev,
+IN GT_LPORT port,
+IN GT_PHY_SPEED speed,
+IN GT_BOOL dMode
+);
/*******************************************************************************
* gqosSetPortDefaultTc
diff --git a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtBrgVtu.c b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtBrgVtu.c
index efe1f05..4b14c5b 100755
--- a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtBrgVtu.c
+++ b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtBrgVtu.c
@@ -515,9 +515,6 @@
GT_STATUS retVal;
GT_U8 port;
GT_LPORT lport;
- GT_VTU_ENTRY tmpVtuEntry;
- GT_BOOL found;
- int count = 5000;
GT_VTU_ENTRY entry;
DBG_INFO(("gvtuAddEntry Called.\n"));
@@ -611,25 +608,6 @@
return retVal;
}
- /* verify that the given entry has been added */
- tmpVtuEntry.vid = vtuEntry->vid;
- tmpVtuEntry.DBNum = vtuEntry->DBNum;
-
- if((retVal = gvtuFindVidEntry(dev,&tmpVtuEntry,&found)) != GT_OK)
- {
- while(count--);
- if((retVal = gvtuFindVidEntry(dev,&tmpVtuEntry,&found)) != GT_OK)
- {
- DBG_INFO(("Added entry cannot be found\n"));
- return retVal;
- }
- }
- if(found == GT_FALSE)
- {
- DBG_INFO(("Added entry cannot be found\n"));
- return GT_FAIL;
- }
-
DBG_INFO(("OK.\n"));
return GT_OK;
}
diff --git a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPIRL2.c b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPIRL2.c
index f5b2193..28717e0 100755
--- a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPIRL2.c
+++ b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPIRL2.c
@@ -20,6 +20,46 @@
#include <linux/init.h>
#include <linux/string.h>
+/* special ingress rate limit para */
+static PIRL_PARA_TBL_T pirl2RateLimitParaTbl[] = {
+ /* BI----BRF-----CBS-------EBS--------------------*/
+ {0x000, 0x00, 0x000000, 0x000000},/*No rate limit*/
+ {0x186, 0x04, 0xD06470, 0xFFFFF0},/*PIRL_RATE_64K*/
+ {0x30D, 0x10, 0x415370, 0xFFFFF0},/*PIRL_RATE_128K*/
+ {0x186, 0x0C, 0x712D70, 0xFFFFF0},/*PIRL_RATE_192K*/
+ {0x186, 0x10, 0xA0C8F0, 0xFFFFF0},/*PIRL_RATE_256K*/
+ {0x138, 0x10, 0x4191F0, 0xFFFFF0},/*PIRL_RATE_320K*/
+ {0x0C3, 0x0C, 0x712D70, 0xFFFFF0},/*PIRL_RATE_384K*/
+ {0x0C3, 0x0E, 0x595FB0, 0xFFFFF0},/*PIRL_RATE_448K*/
+ {0x0C3, 0x10, 0x4191F0, 0xFFFFF0},/*PIRL_RATE_512K*/
+ {0x0C3, 0x12, 0x29C430, 0xFFFFF0},/*PIRL_RATE_576K*/
+ {0x09C, 0x10, 0x4191F0, 0xFFFFF0},/*PIRL_RATE_640K*/
+ {0x07C, 0x0E, 0x597EF0, 0xFFFFF0},/*PIRL_RATE_704K*/
+ {0x082, 0x10, 0x71E8F0, 0xFFFFF0},/*PIRL_RATE_768K*/
+ {0x078, 0x10, 0x4191F0, 0xFFFFF0},/*PIRL_RATE_832K*/
+ {0x084, 0x13, 0x1E69F0, 0xFFFFF0},/*PIRL_RATE_896K*/
+ {0x027, 0x06, 0xB896B0, 0xFFFFF0},/*PIRL_RATE_960K*/
+ {0x031, 0x08, 0xA28A28, 0xFFFFF0},/*PIRL_RATE_1M*/
+ {0x031, 0x10, 0x451460, 0xFFFFF0},/*PIRL_RATE_2M*/
+ {0x021, 0x10, 0x432C18, 0xFFFFF0},/*PIRL_RATE_3M*/
+ {0x01C, 0x12, 0x2A6070, 0xFFFFF0},/*PIRL_RATE_4M*/
+ {0x065, 0x51, 0x029810, 0xFFFFF0},/*PIRL_RATE_5M*/
+ {0x037, 0x35, 0x0186A0, 0xFFFFF0},/*PIRL_RATE_6M*/
+ {0x051, 0x5B, 0x0222E0, 0xFFFFF0},/*PIRL_RATE_7M*/
+ {0x035, 0x44, 0x0186A0, 0xFFFFF0},/*PIRL_RATE_8M*/
+ {0x03B, 0x55, 0x0186A0, 0xFFFFF0},/*PIRL_RATE_9M*/
+ {0x030, 0x4D, 0x015F90, 0xFFFFF0},/*PIRL_RATE_10M*/
+ {0x033, 0x5A, 0x0186A0, 0xFFFFF0},/*PIRL_RATE_11M*/
+ {0x033, 0x62, 0x015F90, 0xFFFFF0},/*PIRL_RATE_12M*/
+ {0x02F, 0x62, 0x015F90, 0xFFFFF0},/*PIRL_RATE_13M*/
+ {0x02D, 0x65, 0x013880, 0xFFFFF0},/*PIRL_RATE_14M*/
+ {0x02A, 0x65, 0x013880, 0xFFFFF0},/*PIRL_RATE_15M*/
+ {0x030, 0x7B, 0x015F90, 0xFFFFF0},/*PIRL_RATE_16M*/
+ {0x02F, 0x80, 0x015F90, 0xFFFFF0},/*PIRL_RATE_17M*/
+ {0x02A, 0x79, 0x013880, 0xFFFFF0},/*PIRL_RATE_18M*/
+ {0x02D, 0x89, 0x013880, 0xFFFFF0},/*PIRL_RATE_19M*/
+ {0x02C, 0x8D, 0x013880, 0xFFFFF0},/*PIRL_RATE_20M*/
+};
/****************************************************************************/
/* PIRL operation function declaration. */
@@ -989,6 +1029,37 @@
return GT_OK;
}
+/*find the greatest common divisor for two interger
+*used to calculate BRF and BI
+*/
+static GT_U32 pirl2GetGCD
+( IN GT_U32 data1,
+ IN GT_U32 data2
+)
+{
+ GT_U32 temp1, temp2, temp;
+
+ if (data1 == 0 || data2 == 0)
+ return 1;
+
+ temp1 = data1;
+ temp2 = data2;
+
+ if (temp1 < temp2) {
+ temp = temp1;
+ temp1 = temp2;
+ temp2 = temp;
+ }
+ temp = temp1 % temp2;
+ while(temp) {
+ temp1 = temp2;
+ temp2 = temp;
+ temp = temp1 % temp2;
+ }
+
+ return temp2;
+}
+
/*
* convert PIRL Data structure to PIRL Resource structure.
* if PIRL Data is not valid, return GT_BAD_PARARM;
@@ -1002,8 +1073,9 @@
{
GT_U32 typeMask;
GT_U32 data;
- GT_U32 bktIncrementFactor = 1;
-
+ GT_U32 burst_allocation;
+ GT_U32 pirl2_cir;
+ GT_U32 pirl_gcd = 1;
gtMemSet((void*)res,0,sizeof(GT_PIRL2_RESOURCE));
@@ -1086,60 +1158,55 @@
return GT_BAD_PARAM;
}
- if(pirlData->ingressRate < 1000) /* less than 1Mbps */
- {
+ if (pirlData->ingressRate < 1000) { /* less than 1Mbps */
/* it should be divided by 64 */
if(pirlData->ingressRate % 64)
{
DBG_INFO(("GT_BAD_PARAM ingressRate(%i)\n",pirlData->ingressRate));
return GT_BAD_PARAM;
}
- res->bktRateFactor = pirlData->ingressRate/64 * 32;
- }
- else if(pirlData->ingressRate < 10000) /* less than or equal to 10Mbps */
- {
+ /* Less than 1Mbps, use special value */
+ res->bktIncrement = pirl2RateLimitParaTbl[pirlData->ingressRate / 64].BI;
+ res->bktRateFactor = pirl2RateLimitParaTbl[pirlData->ingressRate / 64].BRF;
+ res->cbsLimit = pirl2RateLimitParaTbl[pirlData->ingressRate / 64].CBS;
+ res->ebsLimit = pirl2RateLimitParaTbl[pirlData->ingressRate / 64].EBS;
+ } else if(pirlData->ingressRate <= 20000) {/* greater or equal to 1Mbps, and less than or equal to 20Mbps */
/* it should be divided by 1000 */
if(pirlData->ingressRate % 1000)
{
DBG_INFO(("GT_BAD_PARAM ingressRate(%i)\n",pirlData->ingressRate));
return GT_BAD_PARAM;
}
- res->bktRateFactor = pirlData->ingressRate/1000 * 4;
- }
- else /* greater than or equal to 10Mbps */
- {
- /* it should be divided by 1000 */
- if(pirlData->ingressRate % 1000)
- {
- DBG_INFO(("GT_BAD_PARAM ingressRate(%i)\n",pirlData->ingressRate));
- return GT_BAD_PARAM;
+ res->bktIncrement = pirl2RateLimitParaTbl[PIRL_RATE_960K + pirlData->ingressRate / 1000].BI;
+ res->bktRateFactor = pirl2RateLimitParaTbl[PIRL_RATE_960K + pirlData->ingressRate / 1000].BRF;
+ res->cbsLimit = pirl2RateLimitParaTbl[PIRL_RATE_960K + pirlData->ingressRate / 1000].CBS;
+ res->ebsLimit = pirl2RateLimitParaTbl[PIRL_RATE_960K + pirlData->ingressRate / 1000].EBS;
+ } else {/* greater than 20Mbps */
+ if (pirlData->ingressRate < 100000) {
+ /* it should be divided by 1000, if less than 100Mbps*/
+ if(pirlData->ingressRate % 1000)
+ {
+ DBG_INFO(("GT_BAD_PARAM ingressRate(%i)\n",pirlData->ingressRate));
+ return GT_BAD_PARAM;
+ }
+ } else {
+ /* it should be divided by 10000, if more or equal than 100Mbps */
+ if(pirlData->ingressRate % 10000)
+ {
+ DBG_INFO(("GT_BAD_PARAM ingressRate(%i)\n",pirlData->ingressRate));
+ return GT_BAD_PARAM;
+ }
}
- res->bktRateFactor = pirlData->ingressRate/1000 * 8;
- bktIncrementFactor = 10;
-
- }
-
- /*If custom ebslimit exists, use the custom value, otherwize use recommended value*/
- if(pirlData->customSetup.ebsLimit)
- {
- res->ebsLimit = pirlData->customSetup.ebsLimit;
- }
- else
- {
- res->ebsLimit = RECOMMENDED_ESB_LIMIT(dev, pirlData->ingressRate);
- }
+ pirl2_cir = pirlData->ingressRate * 1000;
- /*If custom cbslimit exists, use the custom value, otherwize use recommended value*/
- if(pirlData->customSetup.cbsLimit)
- {
- res->cbsLimit = pirlData->customSetup.cbsLimit;
+ burst_allocation = pirl2_cir;
+
+ pirl_gcd = pirl2GetGCD(pirl2_cir, PIRL_ALPHA);
+ res->bktRateFactor = pirl2_cir / pirl_gcd;
+ res->bktIncrement = PIRL_ALPHA / pirl_gcd;
+ res->ebsLimit = RECOMMENDED_ESB_LIMIT(dev, pirlData->ingressRate);
+ res->cbsLimit = RECOMMENDED_CBS_LIMIT(dev, pirlData->ingressRate);
}
- else
- {
- res->cbsLimit = RECOMMENDED_CBS_LIMIT(dev, pirlData->ingressRate);
- }
-
- res->bktIncrement = RECOMMENDED_BUCKET_INCREMENT(dev, pirlData->ingressRate)*bktIncrementFactor;
}
switch(pirlData->bktRateType)
diff --git a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPhyCtrl.c b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPhyCtrl.c
index edec2c3..bff23d3 100755
--- a/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPhyCtrl.c
+++ b/arch/arm/plat-feroceon/mv_hal/qd-dsdt/src/msapi/gtPhyCtrl.c
@@ -406,12 +406,12 @@
IN GT_PHY_AUTO_MODE mode
)
{
- GT_U16 u16Data;
+ GT_U16 u16Data;
GT_STATUS status;
- GT_BOOL autoOn;
- GT_U16 pageReg;
+ GT_BOOL autoOn;
+ GT_U16 pageReg;
- DBG_INFO(("phySetAutoMode Called.\n"));
+ DBG_INFO(("phySetAutoMode Called.\n"));
if (!(phyInfo->flag & GT_PHY_GIGABIT))
{
@@ -420,10 +420,13 @@
return status;
}
- u16Data = QD_PHY_SPEED | QD_PHY_DUPLEX | QD_PHY_AUTONEGO;
+ if (hwReadPhyReg(dev, hwPort, QD_PHY_CONTROL_REG, &u16Data) != GT_OK)
+ return GT_FAIL;
- DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
- hwPort,QD_PHY_CONTROL_REG,u16Data));
+ u16Data = (u16Data & (QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;
+
+ DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
+ hwPort,QD_PHY_CONTROL_REG,u16Data));
/* soft reset */
return hwPhyReset(dev,hwPort,u16Data);
@@ -434,6 +437,10 @@
return GT_FAIL;
}
+ /* Read to Phy Control Register. */
+ if(hwReadPagedPhyReg(dev, hwPort, 0, QD_PHY_CONTROL_REG, phyInfo->anyPage, &u16Data) != GT_OK)
+ return GT_FAIL;
+
if(phyInfo->flag & GT_PHY_COPPER)
{
if((status=gigCopperSetAutoMode(dev,hwPort,phyInfo,mode)) != GT_OK)
@@ -441,14 +448,14 @@
return status;
}
- u16Data = QD_PHY_AUTONEGO;
+ u16Data = (u16Data & (QD_PHY_SPEED_MSB | QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;
- DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
- hwPort,QD_PHY_CONTROL_REG,u16Data));
+ DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
+ hwPort,QD_PHY_CONTROL_REG,u16Data));
- /* Write to Phy Control Register. */
- if(hwWritePagedPhyReg(dev,hwPort,0,QD_PHY_CONTROL_REG,phyInfo->anyPage,u16Data) != GT_OK)
- return GT_FAIL;
+ /* Write to Phy Control Register. */
+ if(hwWritePagedPhyReg(dev,hwPort,0,QD_PHY_CONTROL_REG,phyInfo->anyPage,u16Data) != GT_OK)
+ return GT_FAIL;
}
else if(phyInfo->flag & GT_PHY_FIBER)
{
@@ -456,14 +463,14 @@
{
return status;
}
- u16Data = QD_PHY_AUTONEGO;
+ u16Data = (u16Data & (QD_PHY_SPEED_MSB | QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;
- DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
- hwPort,QD_PHY_CONTROL_REG,u16Data));
+ DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
+ hwPort,QD_PHY_CONTROL_REG,u16Data));
- /* Write to Phy Control Register. */
- if(hwWritePagedPhyReg(dev,hwPort,1,QD_PHY_CONTROL_REG,phyInfo->anyPage,u16Data) != GT_OK)
- return GT_FAIL;
+ /* Write to Phy Control Register. */
+ if(hwWritePagedPhyReg(dev,hwPort,1,QD_PHY_CONTROL_REG,phyInfo->anyPage,u16Data) != GT_OK)
+ return GT_FAIL;
}
if(driverPagedAccessStop(dev,hwPort,phyInfo->pageType,autoOn,pageReg) != GT_OK)
@@ -1037,15 +1044,15 @@
IN GT_PHY_SPEED speed
)
{
- GT_U8 hwPort; /* the physical port number */
- GT_U16 u16Data;
- GT_PHY_INFO phyInfo;
- GT_STATUS retVal;
+ GT_U8 hwPort; /* the physical port number */
+ GT_U16 u16Data;
+ GT_PHY_INFO phyInfo;
+ GT_STATUS retVal;
- DBG_INFO(("gprtSetPortSpeed Called.\n"));
-
- /* translate LPORT to hardware port */
- hwPort = GT_LPORT_2_PHY(port);
+ DBG_INFO(("gprtSetPortSpeed Called.\n"));
+
+ /* translate LPORT to hardware port */
+ hwPort = GT_LPORT_2_PHY(port);
gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
@@ -1063,11 +1070,11 @@
return GT_FAIL;
}
- if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
+ if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
{
- DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
+ DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
gtSemGive(dev,dev->phyRegsSem);
- return GT_FAIL;
+ return GT_FAIL;
}
switch(speed)
@@ -1078,10 +1085,10 @@
gtSemGive(dev,dev->phyRegsSem);
return GT_BAD_PARAM;
}
- u16Data = u16Data & (QD_PHY_LOOPBACK | QD_PHY_AUTONEGO | QD_PHY_DUPLEX);
+ u16Data = u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX);
break;
case PHY_SPEED_100_MBPS:
- u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_AUTONEGO | QD_PHY_DUPLEX)) | QD_PHY_SPEED;
+ u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED;
break;
case PHY_SPEED_1000_MBPS:
if (!(phyInfo.flag & GT_PHY_GIGABIT))
@@ -1089,15 +1096,15 @@
gtSemGive(dev,dev->phyRegsSem);
return GT_BAD_PARAM;
}
- u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_AUTONEGO | QD_PHY_DUPLEX)) | QD_PHY_SPEED_MSB;
+ u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED_MSB;
break;
default:
gtSemGive(dev,dev->phyRegsSem);
return GT_FAIL;
}
- DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
- hwPort,QD_PHY_CONTROL_REG,u16Data));
+ DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
+ hwPort,QD_PHY_CONTROL_REG,u16Data));
retVal = hwPhyReset(dev,hwPort,u16Data);
gtSemGive(dev,dev->phyRegsSem);
@@ -1258,11 +1265,11 @@
if(state)
{
- u16Data = (u16Data & (QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;
+ u16Data = (u16Data & (QD_PHY_SPEED_MSB | QD_PHY_SPEED | QD_PHY_DUPLEX)) | QD_PHY_AUTONEGO;
}
else
{
- u16Data = u16Data & (QD_PHY_SPEED | QD_PHY_DUPLEX);
+ u16Data = u16Data & (QD_PHY_SPEED_MSB |QD_PHY_SPEED | QD_PHY_DUPLEX | QD_PHY_LOOPBACK);
}
@@ -1519,7 +1526,7 @@
return GT_FAIL;
}
- u16Data &= (QD_PHY_DUPLEX | QD_PHY_SPEED);
+ u16Data &= (QD_PHY_DUPLEX | QD_PHY_SPEED | QD_PHY_SPEED_MSB);
u16Data |= (QD_PHY_RESTART_AUTONEGO | QD_PHY_AUTONEGO);
DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
@@ -1678,6 +1685,116 @@
}
/*******************************************************************************
+* gprtSetPortSpeedDuplexMode
+*
+* DESCRIPTION:
+* Sets speed and duplex mode for a specific logical port. This function
+* will keep the loopback mode to the previous value, but disable others,
+* such as Autonegotiation.
+*
+* INPUTS:
+* port - The logical port number, unless SERDES device is accessed
+* The physical address, if SERDES device is accessed
+* speed - port speed.
+* PHY_SPEED_10_MBPS for 10Mbps
+* PHY_SPEED_100_MBPS for 100Mbps
+* PHY_SPEED_1000_MBPS for 1000Mbps
+* dMode - Duplex mode
+*
+* OUTPUTS:
+* None.
+*
+* RETURNS:
+* GT_OK - on success
+* GT_FAIL - on error
+*
+* COMMENTS:
+* data sheet register 0.13 - Speed Selection (LSB)
+* data sheet register 0.6 - Speed Selection (MSB)
+* data sheet register 0.8 - Duplex mode
+*******************************************************************************/
+GT_STATUS gprtSetPortSpeedDuplexMode
+(
+IN GT_QD_DEV *dev,
+IN GT_LPORT port,
+IN GT_PHY_SPEED speed,
+IN GT_BOOL dMode
+)
+{
+ GT_U8 hwPort; /* the physical port number */
+ GT_U16 u16Data;
+ GT_PHY_INFO phyInfo;
+ GT_STATUS retVal;
+
+ DBG_INFO(("gprtSetPortSpeed Called.\n"));
+
+ /* translate LPORT to hardware port */
+ hwPort = GT_LPORT_2_PHY(port);
+
+ gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER);
+
+ /* check if the port is configurable */
+ if((phyInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY)
+ {
+ gtSemGive(dev,dev->phyRegsSem);
+ return GT_NOT_SUPPORTED;
+ }
+
+ if(driverFindPhyInformation(dev,hwPort,&phyInfo) != GT_OK)
+ {
+ DBG_INFO(("Unknown PHY device.\n"));
+ gtSemGive(dev,dev->phyRegsSem);
+ return GT_FAIL;
+ }
+
+ if(hwReadPhyReg(dev,hwPort,QD_PHY_CONTROL_REG,&u16Data) != GT_OK)
+ {
+ DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,QD_PHY_CONTROL_REG));
+ gtSemGive(dev,dev->phyRegsSem);
+ return GT_FAIL;
+ }
+
+ /* Set Duplex mode */
+ if (dMode)
+ u16Data = u16Data | QD_PHY_DUPLEX;
+ else
+ u16Data = u16Data & (~QD_PHY_DUPLEX);
+
+ switch(speed)
+ {
+ case PHY_SPEED_10_MBPS:
+ if ((phyInfo.flag & GT_PHY_GIGABIT) && !(phyInfo.flag & GT_PHY_COPPER))
+ {
+ gtSemGive(dev,dev->phyRegsSem);
+ return GT_BAD_PARAM;
+ }
+ u16Data = u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX);
+ break;
+ case PHY_SPEED_100_MBPS:
+ u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED;
+ break;
+ case PHY_SPEED_1000_MBPS:
+ if (!(phyInfo.flag & GT_PHY_GIGABIT))
+ {
+ gtSemGive(dev,dev->phyRegsSem);
+ return GT_BAD_PARAM;
+ }
+ u16Data = (u16Data & (QD_PHY_LOOPBACK | QD_PHY_DUPLEX)) | QD_PHY_SPEED_MSB;
+ break;
+ default:
+ gtSemGive(dev,dev->phyRegsSem);
+ return GT_FAIL;
+ }
+
+ DBG_INFO(("Write to phy(%d) register: regAddr 0x%x, data %#x",
+ hwPort,QD_PHY_CONTROL_REG,u16Data));
+
+ retVal = hwPhyReset(dev,hwPort,u16Data);
+ gtSemGive(dev,dev->phyRegsSem);
+ return retVal;
+}
+
+/*******************************************************************************
* gprtSetPortAutoMode
*
* DESCRIPTION:
diff --git a/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.c b/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.c
index 8d382d0..3217041 100755
--- a/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.c
+++ b/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.c
@@ -851,7 +851,7 @@
}
/* Low level TDM interrupt service routine */
-MV_VOID mvCommUnitIntLow(MV_TDM_INT_INFO *pTdmIntInfo)
+MV_32 mvCommUnitIntLow(MV_TDM_INT_INFO *pTdmIntInfo)
{
MV_U32 causeReg, maskReg, causeAndMask;
MV_U32 intAckBits = 0, currDesc;
@@ -895,7 +895,7 @@
if (tdmEnable == MV_FALSE) {
MV_TRC_REC("TDM is disabled - quit low level ISR\n");
MV_REG_WRITE(TDM_CAUSE_REG, ~intAckBits);
- return;
+ return 0;
}
/* Handle TDM Error/s */
@@ -943,7 +943,7 @@
MV_REG_WRITE(TDM_CAUSE_REG, ~intAckBits);
TRC_REC("<-%s\n", __func__);
- return;
+ return 0;
}
static MV_VOID mvCommUnitDescChainBuild(MV_VOID)
diff --git a/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.h b/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.h
index 620e458..966027d 100755
--- a/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.h
+++ b/arch/arm/plat-feroceon/mv_hal/voiceband/commUnit/mvCommUnit.h
@@ -188,7 +188,7 @@
/* CommUnit APIs */
MV_STATUS mvCommUnitHalInit(MV_TDM_PARAMS *pTdmParams, MV_TDM_HAL_DATA *halData);
MV_STATUS mvCommUnitWinInit(MV_UNIT_WIN_INFO *pAddrWinMap);
- MV_VOID mvCommUnitIntLow(MV_TDM_INT_INFO *pTdmIntInfo);
+ MV_32 mvCommUnitIntLow(MV_TDM_INT_INFO *pTdmIntInfo);
MV_VOID mvCommUnitPcmStart(MV_VOID);
MV_VOID mvCommUnitPcmStop(MV_VOID);
MV_STATUS mvCommUnitTx(MV_U8 *pTdmTxBuff);
diff --git a/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.c b/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.c
index eb76460..55bf2d9 100755
--- a/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.c
+++ b/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.c
@@ -107,6 +107,19 @@
static MV_BAND_MODE tdmBandMode;
static MV_TDM_CH_INFO *tdmChInfo[MV_TDM_TOTAL_CHANNELS] = { NULL, NULL };
+static MV_U8 intLock;
+static MV_U32 intRxCount;
+static MV_U32 intTxCount;
+static MV_U32 intRx0Count;
+static MV_U32 intTx0Count;
+static MV_U32 intRx1Count;
+static MV_U32 intTx1Count;
+static MV_U32 intRx0Miss;
+static MV_U32 intTx0Miss;
+static MV_U32 intRx1Miss;
+static MV_U32 intTx1Miss;
+static MV_U32 pcmRestartCount;
+
MV_STATUS mvTdmHalInit(MV_TDM_PARAMS *tdmParams, MV_TDM_HAL_DATA *halData)
{
MV_U8 ch;
@@ -119,9 +132,15 @@
/* Init globals */
rxInt = txInt = 0;
rxFull = txEmpty = BUFF_INVALID;
- tdmEnable = 0;
+ tdmEnable = 0, intLock = 0;
spiMode = halData->spiMode;
pcmFormat = tdmParams->pcmFormat;
+ intRxCount = 0, intTxCount = 0;
+ intRx0Count = 0, intTx0Count = 0;
+ intRx1Count = 0, intTx1Count = 0;
+ intRx0Miss = 0, intTx0Miss = 0;
+ intRx1Miss = 0, intTx1Miss = 0;
+ pcmRestartCount = 0;
if (tdmParams->samplingPeriod > MV_TDM_MAX_SAMPLING_PERIOD)
factor = 1; /* use base sample period(10ms) */
@@ -160,8 +179,8 @@
}
/* Config TDM */
- MV_REG_BIT_RESET(TDM_SPI_MUX_REG, 1); /* enable TDM/SPI interface */
- MV_REG_BIT_SET(TDM_MISC_REG, BIT0); /* sw reset to TDM for 5181L-A1 & up */
+ MV_REG_BIT_RESET(TDM_SPI_MUX_REG, BIT0); /* enable TDM/SPI interface */
+ MV_REG_BIT_SET(TDM_MISC_REG, BIT0); /* sw reset to TDM for 5181L-A1 & up */
MV_REG_WRITE(INT_RESET_SELECT_REG, CLEAR_ON_ZERO); /* int cause is not clear on read */
MV_REG_WRITE(INT_EVENT_MASK_REG, 0x3ffff); /* all interrupt bits latched in status */
MV_REG_WRITE(INT_STATUS_MASK_REG, 0); /* disable interrupts */
@@ -344,6 +363,7 @@
MV_TRC_REC("->%s\n", __func__);
tdmEnable = 1; /* TDM is enabled */
+ intLock = 0;
mvTdmReset();
for (ch = 0; ch < MV_TDM_TOTAL_CHANNELS; ch++) {
@@ -471,9 +491,12 @@
}
/* Low level TDM interrupt service routine */
-MV_VOID mvTdmIntLow(MV_TDM_INT_INFO *tdmIntInfo)
+MV_32 mvTdmIntLow(MV_TDM_INT_INFO *tdmIntInfo)
{
MV_U32 statusReg, maskReg, statusAndMask;
+ MV_32 ret = 0;
+ MV_32 intTxMiss = -1;
+ MV_32 intRxMiss = -1;
MV_U8 ch;
MV_TRC_REC("->%s\n", __func__);
@@ -512,68 +535,107 @@
}
for (ch = 0; ch < MV_TDM_TOTAL_CHANNELS; ch++) {
- if (statusAndMask & TDM_INT_TX(ch)) {
- /* Give next buff to TDM and set curr buff as empty */
- if ((statusAndMask & TX_BIT(ch)) && tdmEnable) {
- MV_TRC_REC("Tx interrupt(ch%d) !!!\n", ch);
- /* MV_OK -> Tx is done for both channels */
- if (mvTdmChTxLow(ch) == MV_OK) {
- MV_TRC_REC("Assign Tx aggregate buffer for further processing\n");
- tdmIntInfo->tdmTxBuff = txAggrBuffVirt;
- tdmIntInfo->intType |= MV_TX_INT;
+ /* Give next buff to TDM and set curr buff as empty */
+ if ((statusAndMask & TX_BIT(ch)) && tdmEnable && !intLock) {
+ MV_TRC_REC("Tx interrupt(ch%d) !!!\n", ch);
+
+ intTxCount++;
+ if (ch == 0) {
+ intTx0Count++;
+ if (intTx0Count <= intTx1Count) {
+ intTxMiss = 0;
+ intTx0Miss++;
+ }
+ } else {
+ intTx1Count++;
+ if (intTx1Count < intTx0Count) {
+ intTxMiss = 1;
+ intTx1Miss++;
}
}
- if (statusAndMask & TX_UNDERFLOW_BIT(ch)) {
- MV_TRC_REC("Tx underflow(ch%d) - checking for root cause...\n", ch);
- if (tdmEnable) {
- MV_TRC_REC("Tx underflow ERROR\n");
- tdmIntInfo->intType |= MV_TX_ERROR_INT;
- if (!(statusAndMask & TX_BIT(ch))) {
- MV_TRC_REC("Trying to recover for ch(%d)\n", ch);
- /* Set HW ownership */
- MV_REG_BYTE_WRITE(CH_BUFF_OWN_REG(ch) + TX_OWN_BYTE_OFFS, OWN_BY_HW);
- /* Enable Tx */
- MV_REG_BYTE_WRITE(CH_ENABLE_REG(ch) + TX_ENABLE_BYTE_OFFS, CH_ENABLE);
+ /* MV_OK -> Tx is done for both channels */
+ if (mvTdmChTxLow(ch) == MV_OK) {
+ MV_TRC_REC("Assign Tx aggregate buffer for further processing\n");
+ tdmIntInfo->tdmTxBuff = txAggrBuffVirt;
+ tdmIntInfo->intType |= MV_TX_INT;
+ }
+ }
+ }
+
+ for (ch = 0; ch < MV_TDM_TOTAL_CHANNELS; ch++) {
+
+ if ((statusAndMask & RX_BIT(ch)) && tdmEnable && !intLock) {
+ MV_TRC_REC("Rx interrupt(ch%d) !!!\n", ch);
+
+ intRxCount++;
+ if (ch == 0) {
+ intRx0Count++;
+ if (intRx0Count <= intRx1Count) {
+ intRxMiss = 0;
+ intRx0Miss++;
+ }
+ } else {
+ intRx1Count++;
+ if (intRx1Count < intRx0Count) {
+ intRxMiss = 1;
+ intRx1Miss++;
+ }
+ }
+
+ /* MV_OK -> Rx is done for both channels */
+ if (mvTdmChRxLow(ch) == MV_OK) {
+ MV_TRC_REC("Assign Rx aggregate buffer for further processing\n");
+ tdmIntInfo->tdmRxBuff = rxAggrBuffVirt;
+ tdmIntInfo->intType |= MV_RX_INT;
+ }
+ }
+ }
+
+ for (ch = 0; ch < MV_TDM_TOTAL_CHANNELS; ch++) {
+
+ if (statusAndMask & TX_UNDERFLOW_BIT(ch)) {
+
+ MV_TRC_REC("Tx underflow(ch%d) - checking for root cause...\n", ch);
+ if (tdmEnable) {
+ MV_TRC_REC("Tx underflow ERROR\n");
+ tdmIntInfo->intType |= MV_TX_ERROR_INT;
+ if (!(statusAndMask & TX_BIT(ch))) {
+ ret = -1;
+ /* MV_OK -> Tx is done for both channels */
+ if (mvTdmChTxLow(ch) == MV_OK) {
+ MV_TRC_REC("Assign Tx aggregate buffer for further processing\n");
+ tdmIntInfo->tdmTxBuff = txAggrBuffVirt;
+ tdmIntInfo->intType |= MV_TX_INT;
}
- } else {
- MV_TRC_REC("Expected Tx underflow(not an error)\n");
+ }
+ } else {
+ MV_TRC_REC("Expected Tx underflow(not an error)\n");
MV_REG_WRITE(INT_STATUS_MASK_REG,
MV_REG_READ(INT_STATUS_MASK_REG) & (~(TDM_INT_TX(ch))));
- }
}
}
- if (statusAndMask & TDM_INT_RX(ch)) {
- if ((statusAndMask & RX_BIT(ch)) && tdmEnable) {
- MV_TRC_REC("Rx interrupt(ch%d) !!!\n", ch);
- /* MV_OK -> Rx is done for both channels */
- if (mvTdmChRxLow(ch) == MV_OK) {
- MV_TRC_REC("Assign Rx aggregate buffer for further processing\n");
- tdmIntInfo->tdmRxBuff = rxAggrBuffVirt;
- tdmIntInfo->intType |= MV_RX_INT;
- }
- }
-
- if (statusAndMask & RX_OVERFLOW_BIT(ch)) {
- MV_TRC_REC("Rx overflow(ch%d) - checking for root cause...\n", ch);
- if (tdmEnable) {
- MV_TRC_REC("Rx overflow ERROR\n");
- tdmIntInfo->intType |= MV_RX_ERROR_INT;
- if (!(statusAndMask & RX_BIT(ch))) {
- MV_TRC_REC("Trying to recover for ch(%d)\n", ch);
- /* Set HW ownership */
- MV_REG_BYTE_WRITE(CH_BUFF_OWN_REG(ch) + RX_OWN_BYTE_OFFS, OWN_BY_HW);
- /* Enable Rx */
- MV_REG_BYTE_WRITE(CH_ENABLE_REG(ch) + RX_ENABLE_BYTE_OFFS, CH_ENABLE);
+ if (statusAndMask & RX_OVERFLOW_BIT(ch)) {
+ MV_TRC_REC("Rx overflow(ch%d) - checking for root cause...\n", ch);
+ if (tdmEnable) {
+ MV_TRC_REC("Rx overflow ERROR\n");
+ tdmIntInfo->intType |= MV_RX_ERROR_INT;
+ if (!(statusAndMask & RX_BIT(ch))) {
+ ret = -1;
+ /* MV_OK -> Rx is done for both channels */
+ if (mvTdmChRxLow(ch) == MV_OK) {
+ MV_TRC_REC("Assign Rx aggregate buffer for further processing\n");
+ tdmIntInfo->tdmRxBuff = rxAggrBuffVirt;
+ tdmIntInfo->intType |= MV_RX_INT;
}
- } else {
- MV_TRC_REC("Expected Rx overflow(not an error)\n");
- MV_REG_WRITE(INT_STATUS_MASK_REG,
- MV_REG_READ(INT_STATUS_MASK_REG) & (~(TDM_INT_RX(ch))));
}
+ } else {
+ MV_TRC_REC("Expected Rx overflow(not an error)\n");
+ MV_REG_WRITE(INT_STATUS_MASK_REG,
+ MV_REG_READ(INT_STATUS_MASK_REG) & (~(TDM_INT_RX(ch))));
}
}
}
@@ -581,8 +643,32 @@
/* clear TDM interrupts */
MV_REG_WRITE(INT_STATUS_REG, ~statusReg);
+ /* Check if interrupt was missed -> restart */
+ if (intTxMiss != -1) {
+ MV_TRC_REC("Missing Tx Interrupt Detected ch%d!!!\n", intTxMiss);
+ if (intTxMiss)
+ intTx1Count = intTx0Count;
+ else
+ intTx0Count = (intTx1Count + 1);
+ ret = -1;
+ }
+
+ if (intRxMiss != -1) {
+ MV_TRC_REC("Missing Rx Interrupt Detected ch%d!!!\n", intRxMiss);
+ if (intRxMiss)
+ intRx1Count = intRx0Count;
+ else
+ intRx0Count = (intRx1Count + 1);
+ ret = -1;
+ }
+
+ if (ret == -1) {
+ intLock = 1;
+ pcmRestartCount++;
+ }
+
MV_TRC_REC("<-%s\n", __func__);
- return;
+ return ret;
}
static INLINE MV_STATUS mvTdmChTxLow(MV_U8 ch)
@@ -933,3 +1019,39 @@
MV_TRC_REC("<-%s\n", __func__);
}
+
+MV_VOID mvTdmPcmIfReset(MV_VOID)
+{
+ MV_TRC_REC("->%s\n", __func__);
+
+ MV_REG_BIT_RESET(PCM_CTRL_REG, BIT0);
+
+ /* Wait a bit - might be fine tuned */
+ mvOsDelay(10);
+
+ MV_REG_WRITE(TDM_MISC_REG, 0);
+
+ /* Wait a bit more - might be fine tuned */
+ mvOsDelay(100);
+
+ MV_TRC_REC("<-%s\n", __func__);
+}
+
+#ifdef MV_TDM_EXT_STATS
+MV_VOID mvTdmExtStatsGet(MV_TDM_EXTENDED_STATS* tdmExtStats)
+{
+ tdmExtStats->intRxCount = intRxCount;
+ tdmExtStats->intTxCount = intTxCount;
+ tdmExtStats->intRx0Count = intRx0Count;
+ tdmExtStats->intTx0Count = intTx0Count;
+ tdmExtStats->intRx1Count = intRx1Count;
+ tdmExtStats->intTx1Count = intTx1Count;
+ tdmExtStats->intRx0Miss = intRx0Miss;
+ tdmExtStats->intTx0Miss = intTx0Miss;
+ tdmExtStats->intRx1Miss = intRx1Miss;
+ tdmExtStats->intTx1Miss = intTx1Miss;
+ tdmExtStats->pcmRestartCount = pcmRestartCount;
+
+ return;
+}
+#endif
diff --git a/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.h b/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.h
index 3909a7f..1240739 100755
--- a/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.h
+++ b/arch/arm/plat-feroceon/mv_hal/voiceband/tdm/mvTdm.h
@@ -164,11 +164,27 @@
MV_FRAME_TS frameTs;
} MV_TDM_HAL_DATA;
+#ifdef MV_TDM_EXT_STATS
+typedef struct {
+ MV_U32 intRxCount;
+ MV_U32 intTxCount;
+ MV_U32 intRx0Count;
+ MV_U32 intTx0Count;
+ MV_U32 intRx1Count;
+ MV_U32 intTx1Count;
+ MV_U32 intRx0Miss;
+ MV_U32 intTx0Miss;
+ MV_U32 intRx1Miss;
+ MV_U32 intTx1Miss;
+ MV_U32 pcmRestartCount;
+} MV_TDM_EXTENDED_STATS;
+#endif
+
/* APIs */
MV_STATUS mvTdmHalInit(MV_TDM_PARAMS *tdmParams, MV_TDM_HAL_DATA *halData);
MV_STATUS mvTdmWinInit(MV_UNIT_WIN_INFO *addrWinMap);
MV_VOID mvTdmRelease(MV_VOID);
-MV_VOID mvTdmIntLow(MV_TDM_INT_INFO *tdmIntInfo);
+MV_32 mvTdmIntLow(MV_TDM_INT_INFO *tdmIntInfo);
MV_VOID mvTdmPcmStart(MV_VOID);
MV_VOID mvTdmPcmStop(MV_VOID);
MV_STATUS mvTdmTx(MV_U8 *tdmTxBuff);
@@ -180,4 +196,9 @@
MV_U8 currTxSampleGet(MV_U8 ch);
MV_VOID mvTdmIntEnable(MV_VOID);
MV_VOID mvTdmIntDisable(MV_VOID);
+MV_VOID mvTdmPcmIfReset(MV_VOID);
+#ifdef MV_TDM_EXT_STATS
+MV_VOID mvTdmExtStatsGet(MV_TDM_EXTENDED_STATS* tdmExtStats);
+#endif
+
#endif /* __INCmvTdmh */